bgp_nht.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /* BGP Nexthop tracking
  2. * Copyright (C) 2013 Cumulus Networks, Inc.
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "command.h"
  23. #include "thread.h"
  24. #include "prefix.h"
  25. #include "zclient.h"
  26. #include "stream.h"
  27. #include "network.h"
  28. #include "log.h"
  29. #include "memory.h"
  30. #include "nexthop.h"
  31. #include "filter.h"
  32. #include "bgpd/bgpd.h"
  33. #include "bgpd/bgp_table.h"
  34. #include "bgpd/bgp_route.h"
  35. #include "bgpd/bgp_attr.h"
  36. #include "bgpd/bgp_nexthop.h"
  37. #include "bgpd/bgp_debug.h"
  38. #include "bgpd/bgp_nht.h"
  39. #include "bgpd/bgp_fsm.h"
  40. extern struct zclient *zclient;
  41. extern struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
  42. static void register_nexthop(struct bgp_nexthop_cache *bnc);
  43. static void unregister_nexthop (struct bgp_nexthop_cache *bnc);
  44. static void evaluate_paths(struct bgp_nexthop_cache *bnc);
  45. static int make_prefix(int afi, struct bgp_info *ri, struct prefix *p);
  46. static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
  47. int keep);
  48. int
  49. bgp_find_nexthop (struct bgp_info *path, int connected)
  50. {
  51. struct bgp_nexthop_cache *bnc = path->nexthop;
  52. if (!bnc)
  53. return 0;
  54. if (connected && !(CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)))
  55. return 0;
  56. return (bgp_zebra_num_connects() == 0 ||
  57. CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
  58. }
  59. static void
  60. bgp_unlink_nexthop_check (struct bgp_nexthop_cache *bnc)
  61. {
  62. if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
  63. {
  64. if (BGP_DEBUG(nht, NHT))
  65. {
  66. char buf[INET6_ADDRSTRLEN];
  67. zlog_debug("bgp_unlink_nexthop: freeing bnc %s",
  68. bnc_str(bnc, buf, INET6_ADDRSTRLEN));
  69. }
  70. unregister_nexthop(bnc);
  71. bnc->node->info = NULL;
  72. bgp_unlock_node(bnc->node);
  73. bnc->node = NULL;
  74. bnc_free(bnc);
  75. }
  76. }
  77. void
  78. bgp_unlink_nexthop (struct bgp_info *path)
  79. {
  80. struct bgp_nexthop_cache *bnc = path->nexthop;
  81. if (!bnc)
  82. return;
  83. path_nh_map(path, NULL, 0);
  84. bgp_unlink_nexthop_check (bnc);
  85. }
  86. void
  87. bgp_unlink_nexthop_by_peer (struct peer *peer)
  88. {
  89. struct prefix p;
  90. struct bgp_node *rn;
  91. struct bgp_nexthop_cache *bnc;
  92. afi_t afi = family2afi(peer->su.sa.sa_family);
  93. if (afi == AFI_IP)
  94. {
  95. p.family = AF_INET;
  96. p.prefixlen = IPV4_MAX_BITLEN;
  97. p.u.prefix4 = peer->su.sin.sin_addr;
  98. }
  99. else if (afi == AFI_IP6)
  100. {
  101. p.family = AF_INET6;
  102. p.prefixlen = IPV6_MAX_BITLEN;
  103. p.u.prefix6 = peer->su.sin6.sin6_addr;
  104. }
  105. else
  106. return;
  107. rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p);
  108. if (!rn->info)
  109. return;
  110. bnc = rn->info;
  111. /* cleanup the peer reference */
  112. bnc->nht_info = NULL;
  113. bgp_unlink_nexthop_check (bnc);
  114. }
  115. int
  116. bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, struct peer *peer,
  117. int connected)
  118. {
  119. struct bgp_node *rn;
  120. struct bgp_nexthop_cache *bnc;
  121. struct prefix p;
  122. if (ri)
  123. {
  124. if (make_prefix(afi, ri, &p) < 0)
  125. return 1;
  126. }
  127. else if (peer)
  128. {
  129. if (afi == AFI_IP)
  130. {
  131. p.family = AF_INET;
  132. p.prefixlen = IPV4_MAX_BITLEN;
  133. p.u.prefix4 = peer->su.sin.sin_addr;
  134. }
  135. else if (afi == AFI_IP6)
  136. {
  137. p.family = AF_INET6;
  138. p.prefixlen = IPV6_MAX_BITLEN;
  139. p.u.prefix6 = peer->su.sin6.sin6_addr;
  140. }
  141. }
  142. rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p);
  143. if (!rn->info)
  144. {
  145. bnc = bnc_new();
  146. rn->info = bnc;
  147. bnc->node = rn;
  148. bgp_lock_node(rn);
  149. if (connected)
  150. SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
  151. }
  152. bnc = rn->info;
  153. bgp_unlock_node (rn);
  154. if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
  155. register_nexthop(bnc);
  156. if (ri)
  157. {
  158. path_nh_map(ri, bnc, 1); /* updates NHT ri list reference */
  159. if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
  160. (bgp_info_extra_get(ri))->igpmetric = bnc->metric;
  161. else if (ri->extra)
  162. ri->extra->igpmetric = 0;
  163. }
  164. else if (peer)
  165. bnc->nht_info = (void *)peer; /* NHT peer reference */
  166. return (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
  167. }
  168. void
  169. bgp_parse_nexthop_update (void)
  170. {
  171. struct stream *s;
  172. struct bgp_node *rn;
  173. struct bgp_nexthop_cache *bnc;
  174. struct nexthop *nexthop;
  175. struct nexthop *oldnh;
  176. struct nexthop *nhlist_head = NULL;
  177. struct nexthop *nhlist_tail = NULL;
  178. uint32_t metric;
  179. u_char nexthop_num;
  180. struct prefix p;
  181. int i;
  182. s = zclient->ibuf;
  183. memset(&p, 0, sizeof(struct prefix));
  184. p.family = stream_getw(s);
  185. p.prefixlen = stream_getc(s);
  186. switch (p.family)
  187. {
  188. case AF_INET:
  189. p.u.prefix4.s_addr = stream_get_ipv4 (s);
  190. break;
  191. case AF_INET6:
  192. stream_get(&p.u.prefix6, s, 16);
  193. break;
  194. default:
  195. break;
  196. }
  197. rn = bgp_node_lookup(bgp_nexthop_cache_table[family2afi(p.family)], &p);
  198. if (!rn || !rn->info)
  199. {
  200. if (BGP_DEBUG(nht, NHT))
  201. {
  202. char buf[INET6_ADDRSTRLEN];
  203. prefix2str(&p, buf, INET6_ADDRSTRLEN);
  204. zlog_debug("parse nexthop update(%s): rn not found", buf);
  205. }
  206. if (rn)
  207. bgp_unlock_node (rn);
  208. return;
  209. }
  210. bnc = rn->info;
  211. bgp_unlock_node (rn);
  212. bnc->last_update = bgp_clock();
  213. bnc->change_flags = 0;
  214. metric = stream_getl (s);
  215. nexthop_num = stream_getc (s);
  216. /* debug print the input */
  217. if (BGP_DEBUG(nht, NHT))
  218. {
  219. char buf[INET6_ADDRSTRLEN];
  220. prefix2str(&p, buf, INET6_ADDRSTRLEN);
  221. zlog_debug("parse nexthop update(%s): metric=%d, #nexthop=%d", buf,
  222. metric, nexthop_num);
  223. }
  224. if (metric != bnc->metric)
  225. bnc->change_flags |= BGP_NEXTHOP_METRIC_CHANGED;
  226. if(nexthop_num != bnc->nexthop_num)
  227. bnc->change_flags |= BGP_NEXTHOP_CHANGED;
  228. if (nexthop_num)
  229. {
  230. bnc->flags |= BGP_NEXTHOP_VALID;
  231. bnc->metric = metric;
  232. bnc->nexthop_num = nexthop_num;
  233. for (i = 0; i < nexthop_num; i++)
  234. {
  235. nexthop = nexthop_new();
  236. nexthop->type = stream_getc (s);
  237. switch (nexthop->type)
  238. {
  239. case ZEBRA_NEXTHOP_IPV4:
  240. nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
  241. break;
  242. case ZEBRA_NEXTHOP_IFINDEX:
  243. case ZEBRA_NEXTHOP_IFNAME:
  244. nexthop->ifindex = stream_getl (s);
  245. break;
  246. case ZEBRA_NEXTHOP_IPV4_IFINDEX:
  247. case ZEBRA_NEXTHOP_IPV4_IFNAME:
  248. nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
  249. nexthop->ifindex = stream_getl (s);
  250. break;
  251. #ifdef HAVE_IPV6
  252. case ZEBRA_NEXTHOP_IPV6:
  253. stream_get (&nexthop->gate.ipv6, s, 16);
  254. break;
  255. case ZEBRA_NEXTHOP_IPV6_IFINDEX:
  256. case ZEBRA_NEXTHOP_IPV6_IFNAME:
  257. stream_get (&nexthop->gate.ipv6, s, 16);
  258. nexthop->ifindex = stream_getl (s);
  259. break;
  260. #endif
  261. default:
  262. /* do nothing */
  263. break;
  264. }
  265. if (nhlist_tail)
  266. {
  267. nhlist_tail->next = nexthop;
  268. nhlist_tail = nexthop;
  269. }
  270. else
  271. {
  272. nhlist_tail = nexthop;
  273. nhlist_head = nexthop;
  274. }
  275. /* No need to evaluate the nexthop if we have already determined
  276. * that there has been a change.
  277. */
  278. if (bnc->change_flags & BGP_NEXTHOP_CHANGED)
  279. continue;
  280. for (oldnh = bnc->nexthop; oldnh; oldnh = oldnh->next)
  281. if (nexthop_same_no_recurse(oldnh, nexthop))
  282. break;
  283. if (!oldnh)
  284. bnc->change_flags |= BGP_NEXTHOP_CHANGED;
  285. }
  286. bnc_nexthop_free(bnc);
  287. bnc->nexthop = nhlist_head;
  288. }
  289. else
  290. {
  291. bnc->flags &= ~BGP_NEXTHOP_VALID;
  292. UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
  293. bnc_nexthop_free(bnc);
  294. bnc->nexthop = NULL;
  295. }
  296. evaluate_paths(bnc);
  297. }
  298. /**
  299. * make_prefix - make a prefix structure from the path (essentially
  300. * path's node.
  301. */
  302. static int
  303. make_prefix (int afi, struct bgp_info *ri, struct prefix *p)
  304. {
  305. memset (p, 0, sizeof (struct prefix));
  306. switch (afi)
  307. {
  308. case AFI_IP:
  309. p->family = AF_INET;
  310. p->prefixlen = IPV4_MAX_BITLEN;
  311. p->u.prefix4 = ri->attr->nexthop;
  312. break;
  313. #ifdef HAVE_IPV6
  314. case AFI_IP6:
  315. if (ri->attr->extra->mp_nexthop_len != 16
  316. || IN6_IS_ADDR_LINKLOCAL (&ri->attr->extra->mp_nexthop_global))
  317. return -1;
  318. p->family = AF_INET6;
  319. p->prefixlen = IPV6_MAX_BITLEN;
  320. p->u.prefix6 = ri->attr->extra->mp_nexthop_global;
  321. break;
  322. #endif
  323. default:
  324. break;
  325. }
  326. return 0;
  327. }
  328. /**
  329. * sendmsg_nexthop -- Format and send a nexthop register/Unregister
  330. * command to Zebra.
  331. * ARGUMENTS:
  332. * struct bgp_nexthop_cache *bnc -- the nexthop structure.
  333. * int command -- either ZEBRA_NEXTHOP_REGISTER or ZEBRA_NEXTHOP_UNREGISTER
  334. * RETURNS:
  335. * void.
  336. */
  337. static void
  338. sendmsg_nexthop (struct bgp_nexthop_cache *bnc, int command)
  339. {
  340. struct stream *s;
  341. struct prefix *p;
  342. int ret;
  343. /* Check socket. */
  344. if (!zclient || zclient->sock < 0)
  345. {
  346. zlog_debug("%s: Can't send NH register, Zebra client not established",
  347. __FUNCTION__);
  348. return;
  349. }
  350. p = &(bnc->node->p);
  351. s = zclient->obuf;
  352. stream_reset (s);
  353. zclient_create_header (s, command, VRF_DEFAULT);
  354. if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
  355. stream_putc(s, 1);
  356. else
  357. stream_putc(s, 0);
  358. stream_putw(s, PREFIX_FAMILY(p));
  359. stream_putc(s, p->prefixlen);
  360. switch (PREFIX_FAMILY(p))
  361. {
  362. case AF_INET:
  363. stream_put_in_addr (s, &p->u.prefix4);
  364. break;
  365. case AF_INET6:
  366. stream_put(s, &(p->u.prefix6), 16);
  367. break;
  368. default:
  369. break;
  370. }
  371. stream_putw_at (s, 0, stream_get_endp (s));
  372. ret = zclient_send_message(zclient);
  373. /* TBD: handle the failure */
  374. if (ret < 0)
  375. zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
  376. if (command == ZEBRA_NEXTHOP_REGISTER)
  377. SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
  378. else if (command == ZEBRA_NEXTHOP_UNREGISTER)
  379. UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
  380. return;
  381. }
  382. /**
  383. * register_nexthop - register a nexthop with Zebra for notification
  384. * when the route to the nexthop changes.
  385. * ARGUMENTS:
  386. * struct bgp_nexthop_cache *bnc -- the nexthop structure.
  387. * RETURNS:
  388. * void.
  389. */
  390. static void
  391. register_nexthop (struct bgp_nexthop_cache *bnc)
  392. {
  393. /* Check if we have already registered */
  394. if (bnc->flags & BGP_NEXTHOP_REGISTERED)
  395. return;
  396. sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_REGISTER);
  397. }
  398. /**
  399. * unregister_nexthop -- Unregister the nexthop from Zebra.
  400. * ARGUMENTS:
  401. * struct bgp_nexthop_cache *bnc -- the nexthop structure.
  402. * RETURNS:
  403. * void.
  404. */
  405. static void
  406. unregister_nexthop (struct bgp_nexthop_cache *bnc)
  407. {
  408. /* Check if we have already registered */
  409. if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
  410. return;
  411. sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_UNREGISTER);
  412. }
  413. /**
  414. * evaluate_paths - Evaluate the paths/nets associated with a nexthop.
  415. * ARGUMENTS:
  416. * struct bgp_nexthop_cache *bnc -- the nexthop structure.
  417. * RETURNS:
  418. * void.
  419. */
  420. static void
  421. evaluate_paths (struct bgp_nexthop_cache *bnc)
  422. {
  423. struct bgp_node *rn;
  424. struct bgp_info *path;
  425. struct bgp *bgp = bgp_get_default();
  426. int afi;
  427. struct peer *peer = (struct peer *)bnc->nht_info;
  428. LIST_FOREACH(path, &(bnc->paths), nh_thread)
  429. {
  430. if (!(path->type == ZEBRA_ROUTE_BGP &&
  431. path->sub_type == BGP_ROUTE_NORMAL))
  432. continue;
  433. rn = path->net;
  434. afi = family2afi(rn->p.family);
  435. /* Path becomes valid/invalid depending on whether the nexthop
  436. * reachable/unreachable.
  437. */
  438. if ((CHECK_FLAG(path->flags, BGP_INFO_VALID) ? 1 : 0) !=
  439. (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) ? 1 : 0))
  440. {
  441. if (CHECK_FLAG (path->flags, BGP_INFO_VALID))
  442. {
  443. bgp_aggregate_decrement (bgp, &rn->p, path,
  444. afi, SAFI_UNICAST);
  445. bgp_info_unset_flag (rn, path, BGP_INFO_VALID);
  446. }
  447. else
  448. {
  449. bgp_info_set_flag (rn, path, BGP_INFO_VALID);
  450. bgp_aggregate_increment (bgp, &rn->p, path,
  451. afi, SAFI_UNICAST);
  452. }
  453. }
  454. /* Copy the metric to the path. Will be used for bestpath computation */
  455. if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
  456. (bgp_info_extra_get(path))->igpmetric = bnc->metric;
  457. else if (path->extra)
  458. path->extra->igpmetric = 0;
  459. if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_METRIC_CHANGED) ||
  460. CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CHANGED))
  461. SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
  462. bgp_process(bgp, rn, afi, SAFI_UNICAST);
  463. }
  464. if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
  465. {
  466. if (BGP_DEBUG(nht, NHT))
  467. zlog_debug("%s: Updating peer (%s) status with NHT", __FUNCTION__, peer->host);
  468. BGP_EVENT_ADD (peer, NHT_Update);
  469. SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
  470. }
  471. RESET_FLAG(bnc->change_flags);
  472. }
  473. /**
  474. * path_nh_map - make or break path-to-nexthop association.
  475. * ARGUMENTS:
  476. * path - pointer to the path structure
  477. * bnc - pointer to the nexthop structure
  478. * make - if set, make the association. if unset, just break the existing
  479. * association.
  480. */
  481. static void
  482. path_nh_map (struct bgp_info *path, struct bgp_nexthop_cache *bnc, int make)
  483. {
  484. if (path->nexthop)
  485. {
  486. LIST_REMOVE(path, nh_thread);
  487. path->nexthop->path_count--;
  488. path->nexthop = NULL;
  489. }
  490. if (make)
  491. {
  492. LIST_INSERT_HEAD(&(bnc->paths), path, nh_thread);
  493. path->nexthop = bnc;
  494. path->nexthop->path_count++;
  495. }
  496. }