bgp_nexthop.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /* BGP nexthop scan
  2. Copyright (C) 2000 Kunihiro Ishiguro
  3. This file is part of GNU Zebra.
  4. GNU Zebra is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU Zebra is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Zebra; see the file COPYING. If not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA. */
  16. #include <zebra.h>
  17. #include "command.h"
  18. #include "thread.h"
  19. #include "prefix.h"
  20. #include "zclient.h"
  21. #include "stream.h"
  22. #include "network.h"
  23. #include "log.h"
  24. #include "memory.h"
  25. #include "hash.h"
  26. #include "jhash.h"
  27. #include "filter.h"
  28. #include "nexthop.h"
  29. #include "bgpd/bgpd.h"
  30. #include "bgpd/bgp_table.h"
  31. #include "bgpd/bgp_route.h"
  32. #include "bgpd/bgp_attr.h"
  33. #include "bgpd/bgp_nexthop.h"
  34. #include "bgpd/bgp_nht.h"
  35. #include "bgpd/bgp_debug.h"
  36. #include "bgpd/bgp_damp.h"
  37. #include "zebra/rib.h"
  38. #include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
  39. /* Route table for next-hop lookup cache. */
  40. struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
  41. static struct bgp_table *cache1_table[AFI_MAX];
  42. /* Route table for connected route. */
  43. static struct bgp_table *bgp_connected_table[AFI_MAX];
  44. char *
  45. bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size)
  46. {
  47. prefix2str(&(bnc->node->p), buf, size);
  48. return buf;
  49. }
  50. void
  51. bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
  52. {
  53. struct nexthop *nexthop;
  54. struct nexthop *next = NULL;
  55. for (nexthop = bnc->nexthop; nexthop; nexthop = next)
  56. {
  57. next = nexthop->next;
  58. XFREE (MTYPE_NEXTHOP, nexthop);
  59. }
  60. }
  61. struct bgp_nexthop_cache *
  62. bnc_new (void)
  63. {
  64. struct bgp_nexthop_cache *bnc;
  65. bnc = XCALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
  66. LIST_INIT(&(bnc->paths));
  67. return bnc;
  68. }
  69. void
  70. bnc_free (struct bgp_nexthop_cache *bnc)
  71. {
  72. bnc_nexthop_free (bnc);
  73. XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
  74. }
  75. /* If nexthop exists on connected network return 1. */
  76. int
  77. bgp_nexthop_onlink (afi_t afi, struct attr *attr)
  78. {
  79. struct bgp_node *rn;
  80. /* Lookup the address is onlink or not. */
  81. if (afi == AFI_IP)
  82. {
  83. rn = bgp_node_match_ipv4 (bgp_connected_table[AFI_IP], &attr->nexthop);
  84. if (rn)
  85. {
  86. bgp_unlock_node (rn);
  87. return 1;
  88. }
  89. }
  90. else if (afi == AFI_IP6)
  91. {
  92. if (attr->extra->mp_nexthop_len == 32)
  93. return 1;
  94. else if (attr->extra->mp_nexthop_len == 16)
  95. {
  96. if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
  97. return 1;
  98. rn = bgp_node_match_ipv6 (bgp_connected_table[AFI_IP6],
  99. &attr->extra->mp_nexthop_global);
  100. if (rn)
  101. {
  102. bgp_unlock_node (rn);
  103. return 1;
  104. }
  105. }
  106. }
  107. return 0;
  108. }
  109. /* BGP own address structure */
  110. struct bgp_addr
  111. {
  112. struct in_addr addr;
  113. int refcnt;
  114. };
  115. static struct hash *bgp_address_hash;
  116. static void *
  117. bgp_address_hash_alloc (void *p)
  118. {
  119. struct in_addr *val = p;
  120. struct bgp_addr *addr;
  121. addr = XMALLOC (MTYPE_BGP_ADDR, sizeof (struct bgp_addr));
  122. addr->refcnt = 0;
  123. addr->addr.s_addr = val->s_addr;
  124. return addr;
  125. }
  126. static unsigned int
  127. bgp_address_hash_key_make (void *p)
  128. {
  129. const struct bgp_addr *addr = p;
  130. return jhash_1word(addr->addr.s_addr, 0);
  131. }
  132. static int
  133. bgp_address_hash_cmp (const void *p1, const void *p2)
  134. {
  135. const struct bgp_addr *addr1 = p1;
  136. const struct bgp_addr *addr2 = p2;
  137. return addr1->addr.s_addr == addr2->addr.s_addr;
  138. }
  139. void
  140. bgp_address_init (void)
  141. {
  142. bgp_address_hash = hash_create (bgp_address_hash_key_make,
  143. bgp_address_hash_cmp);
  144. }
  145. void
  146. bgp_address_destroy (void)
  147. {
  148. if (bgp_address_hash == NULL)
  149. return;
  150. hash_clean(bgp_address_hash, NULL);
  151. hash_free(bgp_address_hash);
  152. bgp_address_hash = NULL;
  153. }
  154. static void
  155. bgp_address_add (struct prefix *p)
  156. {
  157. struct bgp_addr tmp;
  158. struct bgp_addr *addr;
  159. tmp.addr = p->u.prefix4;
  160. addr = hash_get (bgp_address_hash, &tmp, bgp_address_hash_alloc);
  161. if (!addr)
  162. return;
  163. addr->refcnt++;
  164. }
  165. static void
  166. bgp_address_del (struct prefix *p)
  167. {
  168. struct bgp_addr tmp;
  169. struct bgp_addr *addr;
  170. tmp.addr = p->u.prefix4;
  171. addr = hash_lookup (bgp_address_hash, &tmp);
  172. /* may have been deleted earlier by bgp_interface_down() */
  173. if (addr == NULL)
  174. return;
  175. addr->refcnt--;
  176. if (addr->refcnt == 0)
  177. {
  178. hash_release (bgp_address_hash, addr);
  179. XFREE (MTYPE_BGP_ADDR, addr);
  180. }
  181. }
  182. struct bgp_connected_ref
  183. {
  184. unsigned int refcnt;
  185. };
  186. void
  187. bgp_connected_add (struct connected *ifc)
  188. {
  189. struct prefix p;
  190. struct prefix *addr;
  191. struct interface *ifp;
  192. struct bgp_node *rn;
  193. struct bgp_connected_ref *bc;
  194. ifp = ifc->ifp;
  195. if (! ifp)
  196. return;
  197. if (if_is_loopback (ifp))
  198. return;
  199. addr = ifc->address;
  200. p = *(CONNECTED_PREFIX(ifc));
  201. if (addr->family == AF_INET)
  202. {
  203. apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
  204. if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
  205. return;
  206. bgp_address_add (addr);
  207. rn = bgp_node_get (bgp_connected_table[AFI_IP], (struct prefix *) &p);
  208. if (rn->info)
  209. {
  210. bc = rn->info;
  211. bc->refcnt++;
  212. }
  213. else
  214. {
  215. bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
  216. bc->refcnt = 1;
  217. rn->info = bc;
  218. }
  219. }
  220. else if (addr->family == AF_INET6)
  221. {
  222. apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
  223. if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
  224. return;
  225. if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
  226. return;
  227. rn = bgp_node_get (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
  228. if (rn->info)
  229. {
  230. bc = rn->info;
  231. bc->refcnt++;
  232. }
  233. else
  234. {
  235. bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
  236. bc->refcnt = 1;
  237. rn->info = bc;
  238. }
  239. }
  240. }
  241. void
  242. bgp_connected_delete (struct connected *ifc)
  243. {
  244. struct prefix p;
  245. struct prefix *addr;
  246. struct interface *ifp;
  247. struct bgp_node *rn;
  248. struct bgp_connected_ref *bc;
  249. ifp = ifc->ifp;
  250. if (if_is_loopback (ifp))
  251. return;
  252. addr = ifc->address;
  253. p = *(CONNECTED_PREFIX(ifc));
  254. if (addr->family == AF_INET)
  255. {
  256. apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
  257. if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
  258. return;
  259. bgp_address_del (addr);
  260. rn = bgp_node_lookup (bgp_connected_table[AFI_IP], &p);
  261. if (! rn)
  262. return;
  263. bc = rn->info;
  264. bc->refcnt--;
  265. if (bc->refcnt == 0)
  266. {
  267. XFREE (MTYPE_BGP_CONN, bc);
  268. rn->info = NULL;
  269. }
  270. bgp_unlock_node (rn);
  271. bgp_unlock_node (rn);
  272. }
  273. else if (addr->family == AF_INET6)
  274. {
  275. apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
  276. if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
  277. return;
  278. if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
  279. return;
  280. rn = bgp_node_lookup (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
  281. if (! rn)
  282. return;
  283. bc = rn->info;
  284. bc->refcnt--;
  285. if (bc->refcnt == 0)
  286. {
  287. XFREE (MTYPE_BGP_CONN, bc);
  288. rn->info = NULL;
  289. }
  290. bgp_unlock_node (rn);
  291. bgp_unlock_node (rn);
  292. }
  293. }
  294. int
  295. bgp_nexthop_self (struct attr *attr)
  296. {
  297. struct bgp_addr tmp, *addr;
  298. tmp.addr = attr->nexthop;
  299. addr = hash_lookup (bgp_address_hash, &tmp);
  300. if (addr)
  301. return 1;
  302. return 0;
  303. }
  304. int
  305. bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
  306. {
  307. struct bgp_node *rn1;
  308. struct bgp_node *rn2;
  309. struct prefix p;
  310. int ret;
  311. p.family = AF_INET;
  312. p.prefixlen = IPV4_MAX_BITLEN;
  313. p.u.prefix4 = nexthop;
  314. rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p);
  315. if (!rn1)
  316. return 0;
  317. p.family = AF_INET;
  318. p.prefixlen = IPV4_MAX_BITLEN;
  319. p.u.prefix4 = peer->su.sin.sin_addr;
  320. rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p);
  321. if (!rn2)
  322. {
  323. bgp_unlock_node(rn1);
  324. return 0;
  325. }
  326. ret = (rn1 == rn2) ? 1 : 0;
  327. bgp_unlock_node(rn1);
  328. bgp_unlock_node(rn2);
  329. return (ret);
  330. }
  331. static int
  332. show_ip_bgp_nexthop_table (struct vty *vty, int detail)
  333. {
  334. struct bgp_node *rn;
  335. struct bgp_nexthop_cache *bnc;
  336. char buf[INET6_ADDRSTRLEN];
  337. struct nexthop *nexthop;
  338. time_t tbuf;
  339. afi_t afi;
  340. vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
  341. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  342. {
  343. if (!bgp_nexthop_cache_table[afi])
  344. continue;
  345. for (rn = bgp_table_top (bgp_nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
  346. {
  347. if ((bnc = rn->info) != NULL)
  348. {
  349. if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
  350. {
  351. vty_out (vty, " %s valid [IGP metric %d], #paths %d%s",
  352. inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)),
  353. bnc->metric, bnc->path_count, VTY_NEWLINE);
  354. if (detail)
  355. for (nexthop = bnc->nexthop ; nexthop; nexthop = nexthop->next)
  356. switch (nexthop->type)
  357. {
  358. case NEXTHOP_TYPE_IPV6:
  359. vty_out (vty, " gate %s%s",
  360. inet_ntop (AF_INET6, &nexthop->gate.ipv6,
  361. buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
  362. break;
  363. case NEXTHOP_TYPE_IPV6_IFINDEX:
  364. vty_out(vty, " gate %s, if %s%s",
  365. inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
  366. INET6_ADDRSTRLEN),
  367. ifindex2ifname(nexthop->ifindex),
  368. VTY_NEWLINE);
  369. break;
  370. case NEXTHOP_TYPE_IPV4:
  371. vty_out (vty, " gate %s%s",
  372. inet_ntop (AF_INET, &nexthop->gate.ipv4, buf,
  373. INET6_ADDRSTRLEN), VTY_NEWLINE);
  374. break;
  375. case NEXTHOP_TYPE_IFINDEX:
  376. vty_out (vty, " if %s%s",
  377. ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
  378. break;
  379. case NEXTHOP_TYPE_IPV4_IFINDEX:
  380. vty_out (vty, " gate %s, if %s%s",
  381. inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
  382. INET6_ADDRSTRLEN),
  383. ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
  384. break;
  385. default:
  386. vty_out (vty, " invalid nexthop type %u%s",
  387. nexthop->type, VTY_NEWLINE);
  388. }
  389. }
  390. else
  391. vty_out (vty, " %s invalid%s",
  392. inet_ntop (AF_INET, &rn->p.u.prefix, buf, sizeof (buf)), VTY_NEWLINE);
  393. #ifdef HAVE_CLOCK_MONOTONIC
  394. tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
  395. vty_out (vty, " Last update: %s", ctime(&tbuf));
  396. #else
  397. vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
  398. #endif /* HAVE_CLOCK_MONOTONIC */
  399. vty_out(vty, "%s", VTY_NEWLINE);
  400. }
  401. }
  402. }
  403. return CMD_SUCCESS;
  404. }
  405. DEFUN (show_ip_bgp_nexthop,
  406. show_ip_bgp_nexthop_cmd,
  407. "show ip bgp nexthop",
  408. SHOW_STR
  409. IP_STR
  410. BGP_STR
  411. "BGP nexthop table\n")
  412. {
  413. return show_ip_bgp_nexthop_table (vty, 0);
  414. }
  415. DEFUN (show_ip_bgp_nexthop_detail,
  416. show_ip_bgp_nexthop_detail_cmd,
  417. "show ip bgp nexthop detail",
  418. SHOW_STR
  419. IP_STR
  420. BGP_STR
  421. "BGP nexthop table\n")
  422. {
  423. return show_ip_bgp_nexthop_table (vty, 1);
  424. }
  425. void
  426. bgp_scan_init (void)
  427. {
  428. cache1_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
  429. bgp_nexthop_cache_table[AFI_IP] = cache1_table[AFI_IP];
  430. bgp_connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
  431. cache1_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
  432. bgp_nexthop_cache_table[AFI_IP6] = cache1_table[AFI_IP6];
  433. bgp_connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
  434. cache1_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
  435. bgp_nexthop_cache_table[AFI_ETHER] = cache1_table[AFI_ETHER];
  436. bgp_connected_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
  437. }
  438. void
  439. bgp_scan_vty_init()
  440. {
  441. install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
  442. install_element (VIEW_NODE, &show_ip_bgp_nexthop_detail_cmd);
  443. }
  444. void
  445. bgp_scan_finish (void)
  446. {
  447. if (cache1_table[AFI_IP])
  448. bgp_table_unlock (cache1_table[AFI_IP]);
  449. cache1_table[AFI_IP] = NULL;
  450. if (bgp_connected_table[AFI_IP])
  451. bgp_table_unlock (bgp_connected_table[AFI_IP]);
  452. bgp_connected_table[AFI_IP] = NULL;
  453. if (cache1_table[AFI_IP6])
  454. bgp_table_unlock (cache1_table[AFI_IP6]);
  455. cache1_table[AFI_IP6] = NULL;
  456. if (bgp_connected_table[AFI_IP6])
  457. bgp_table_unlock (bgp_connected_table[AFI_IP6]);
  458. bgp_connected_table[AFI_IP6] = NULL;
  459. if (cache1_table[AFI_ETHER])
  460. bgp_table_unlock (cache1_table[AFI_ETHER]);
  461. cache1_table[AFI_ETHER] = NULL;
  462. if (bgp_connected_table[AFI_ETHER])
  463. bgp_table_unlock (bgp_connected_table[AFI_ETHER]);
  464. bgp_connected_table[AFI_ETHER] = NULL;
  465. }
  466. void
  467. bgp_scan_destroy (void)
  468. {
  469. bgp_scan_finish();
  470. }