bgp_nexthop.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551
  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. extern struct zclient *zclient;
  40. struct bgp_nexthop_cache *zlookup_query (struct in_addr);
  41. struct bgp_nexthop_cache *zlookup_query_ipv6 (struct in6_addr *);
  42. /* Only one BGP scan thread are activated at the same time. */
  43. static struct thread *bgp_scan_thread = NULL;
  44. /* BGP import thread */
  45. static struct thread *bgp_import_thread = NULL;
  46. /* BGP scan interval. */
  47. static int bgp_scan_interval;
  48. /* BGP import interval. */
  49. static int bgp_import_interval;
  50. /* Route table for next-hop lookup cache. */
  51. struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
  52. static struct bgp_table *cache1_table[AFI_MAX];
  53. static struct bgp_table *cache2_table[AFI_MAX];
  54. /* Route table for connected route. */
  55. static struct bgp_table *bgp_connected_table[AFI_MAX];
  56. /* BGP nexthop lookup query client. */
  57. struct zclient *zlookup = NULL;
  58. char *
  59. bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size)
  60. {
  61. prefix2str(&(bnc->node->p), buf, size);
  62. return buf;
  63. }
  64. /* Add nexthop to the end of the list. */
  65. static void
  66. bnc_nexthop_add (struct bgp_nexthop_cache *bnc, struct nexthop *nexthop)
  67. {
  68. struct nexthop *last;
  69. for (last = bnc->nexthop; last && last->next; last = last->next)
  70. ;
  71. if (last)
  72. last->next = nexthop;
  73. else
  74. bnc->nexthop = nexthop;
  75. nexthop->prev = last;
  76. }
  77. void
  78. bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
  79. {
  80. struct nexthop *nexthop;
  81. struct nexthop *next = NULL;
  82. for (nexthop = bnc->nexthop; nexthop; nexthop = next)
  83. {
  84. next = nexthop->next;
  85. XFREE (MTYPE_NEXTHOP, nexthop);
  86. }
  87. }
  88. struct bgp_nexthop_cache *
  89. bnc_new (void)
  90. {
  91. struct bgp_nexthop_cache *bnc;
  92. bnc = XCALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
  93. LIST_INIT(&(bnc->paths));
  94. return bnc;
  95. }
  96. void
  97. bnc_free (struct bgp_nexthop_cache *bnc)
  98. {
  99. bnc_nexthop_free (bnc);
  100. XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
  101. }
  102. static int
  103. bgp_nexthop_cache_different (struct bgp_nexthop_cache *bnc1,
  104. struct bgp_nexthop_cache *bnc2)
  105. {
  106. int i;
  107. struct nexthop *next1, *next2;
  108. if (bnc1->nexthop_num != bnc2->nexthop_num)
  109. return 1;
  110. next1 = bnc1->nexthop;
  111. next2 = bnc2->nexthop;
  112. for (i = 0; i < bnc1->nexthop_num; i++)
  113. {
  114. if (! nexthop_same_no_recurse (next1, next2))
  115. return 1;
  116. next1 = next1->next;
  117. next2 = next2->next;
  118. }
  119. return 0;
  120. }
  121. /* If nexthop exists on connected network return 1. */
  122. int
  123. bgp_nexthop_onlink (afi_t afi, struct attr *attr)
  124. {
  125. struct bgp_node *rn;
  126. /* If zebra is not enabled return */
  127. if (zlookup->sock < 0)
  128. return 1;
  129. /* Lookup the address is onlink or not. */
  130. if (afi == AFI_IP)
  131. {
  132. rn = bgp_node_match_ipv4 (bgp_connected_table[AFI_IP], &attr->nexthop);
  133. if (rn)
  134. {
  135. bgp_unlock_node (rn);
  136. return 1;
  137. }
  138. }
  139. else if (afi == AFI_IP6)
  140. {
  141. if (attr->extra->mp_nexthop_len == 32)
  142. return 1;
  143. else if (attr->extra->mp_nexthop_len == 16)
  144. {
  145. if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
  146. return 1;
  147. rn = bgp_node_match_ipv6 (bgp_connected_table[AFI_IP6],
  148. &attr->extra->mp_nexthop_global);
  149. if (rn)
  150. {
  151. bgp_unlock_node (rn);
  152. return 1;
  153. }
  154. }
  155. }
  156. return 0;
  157. }
  158. /* Check specified next-hop is reachable or not. */
  159. static int
  160. bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed,
  161. int *metricchanged)
  162. {
  163. struct bgp_node *rn;
  164. struct prefix p;
  165. struct bgp_nexthop_cache *bnc;
  166. struct attr *attr;
  167. /* If lookup is not enabled, return valid. */
  168. if (zlookup->sock < 0)
  169. {
  170. if (ri->extra)
  171. ri->extra->igpmetric = 0;
  172. return 1;
  173. }
  174. /* Only check IPv6 global address only nexthop. */
  175. attr = ri->attr;
  176. if (attr->extra->mp_nexthop_len != 16
  177. || IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
  178. return 1;
  179. memset (&p, 0, sizeof (struct prefix));
  180. p.family = AF_INET6;
  181. p.prefixlen = IPV6_MAX_BITLEN;
  182. p.u.prefix6 = attr->extra->mp_nexthop_global;
  183. /* IBGP or ebgp-multihop */
  184. rn = bgp_node_get (bgp_nexthop_cache_table[AFI_IP6], &p);
  185. if (rn->info)
  186. {
  187. bnc = rn->info;
  188. bgp_unlock_node (rn);
  189. }
  190. else
  191. {
  192. if (NULL == (bnc = zlookup_query_ipv6 (&attr->extra->mp_nexthop_global)))
  193. bnc = bnc_new ();
  194. else
  195. {
  196. if (changed)
  197. {
  198. struct bgp_table *old;
  199. struct bgp_node *oldrn;
  200. if (bgp_nexthop_cache_table[AFI_IP6] == cache1_table[AFI_IP6])
  201. old = cache2_table[AFI_IP6];
  202. else
  203. old = cache1_table[AFI_IP6];
  204. oldrn = bgp_node_lookup (old, &p);
  205. if (oldrn)
  206. {
  207. struct bgp_nexthop_cache *oldbnc = oldrn->info;
  208. bnc->changed = bgp_nexthop_cache_different (bnc, oldbnc);
  209. if (bnc->metric != oldbnc->metric)
  210. bnc->metricchanged = 1;
  211. bgp_unlock_node (oldrn);
  212. }
  213. }
  214. }
  215. rn->info = bnc;
  216. }
  217. if (changed)
  218. *changed = bnc->changed;
  219. if (metricchanged)
  220. *metricchanged = bnc->metricchanged;
  221. if (bnc->valid && bnc->metric)
  222. (bgp_info_extra_get (ri))->igpmetric = bnc->metric;
  223. else if (ri->extra)
  224. ri->extra->igpmetric = 0;
  225. return bnc->valid;
  226. }
  227. /* Check specified next-hop is reachable or not. */
  228. int
  229. bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri,
  230. int *changed, int *metricchanged)
  231. {
  232. struct bgp_node *rn;
  233. struct prefix p;
  234. struct bgp_nexthop_cache *bnc;
  235. struct in_addr addr;
  236. /* If lookup is not enabled, return valid. */
  237. if (zlookup->sock < 0)
  238. {
  239. if (ri->extra)
  240. ri->extra->igpmetric = 0;
  241. return 1;
  242. }
  243. if (afi == AFI_IP6)
  244. return bgp_nexthop_lookup_ipv6 (peer, ri, changed, metricchanged);
  245. addr = ri->attr->nexthop;
  246. memset (&p, 0, sizeof (struct prefix));
  247. p.family = AF_INET;
  248. p.prefixlen = IPV4_MAX_BITLEN;
  249. p.u.prefix4 = addr;
  250. /* IBGP or ebgp-multihop */
  251. rn = bgp_node_get (bgp_nexthop_cache_table[AFI_IP], &p);
  252. if (rn->info)
  253. {
  254. bnc = rn->info;
  255. bgp_unlock_node (rn);
  256. }
  257. else
  258. {
  259. if (NULL == (bnc = zlookup_query (addr)))
  260. bnc = bnc_new ();
  261. else
  262. {
  263. if (changed)
  264. {
  265. struct bgp_table *old;
  266. struct bgp_node *oldrn;
  267. if (bgp_nexthop_cache_table[AFI_IP] == cache1_table[AFI_IP])
  268. old = cache2_table[AFI_IP];
  269. else
  270. old = cache1_table[AFI_IP];
  271. oldrn = bgp_node_lookup (old, &p);
  272. if (oldrn)
  273. {
  274. struct bgp_nexthop_cache *oldbnc = oldrn->info;
  275. bnc->changed = bgp_nexthop_cache_different (bnc, oldbnc);
  276. if (bnc->metric != oldbnc->metric)
  277. bnc->metricchanged = 1;
  278. bgp_unlock_node (oldrn);
  279. }
  280. }
  281. }
  282. rn->info = bnc;
  283. }
  284. if (changed)
  285. *changed = bnc->changed;
  286. if (metricchanged)
  287. *metricchanged = bnc->metricchanged;
  288. if (bnc->valid && bnc->metric)
  289. (bgp_info_extra_get(ri))->igpmetric = bnc->metric;
  290. else if (ri->extra)
  291. ri->extra->igpmetric = 0;
  292. return bnc->valid;
  293. }
  294. #if BGP_SCAN_NEXTHOP
  295. /* Reset and free all BGP nexthop cache. */
  296. static void
  297. bgp_nexthop_cache_reset (struct bgp_table *table)
  298. {
  299. struct bgp_node *rn;
  300. struct bgp_nexthop_cache *bnc;
  301. for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
  302. if ((bnc = rn->info) != NULL)
  303. {
  304. bnc_free (bnc);
  305. rn->info = NULL;
  306. bgp_unlock_node (rn);
  307. }
  308. }
  309. #endif
  310. static void
  311. bgp_scan (afi_t afi, safi_t safi)
  312. {
  313. struct bgp_node *rn;
  314. struct bgp *bgp;
  315. struct bgp_info *bi;
  316. struct bgp_info *next;
  317. struct peer *peer;
  318. struct listnode *node, *nnode;
  319. #if BGP_SCAN_NEXTHOP
  320. int valid;
  321. int current;
  322. int changed;
  323. int metricchanged;
  324. /* Change cache. */
  325. if (bgp_nexthop_cache_table[afi] == cache1_table[afi])
  326. bgp_nexthop_cache_table[afi] = cache2_table[afi];
  327. else
  328. bgp_nexthop_cache_table[afi] = cache1_table[afi];
  329. #endif
  330. /* Get default bgp. */
  331. bgp = bgp_get_default ();
  332. if (bgp == NULL)
  333. return;
  334. /* Maximum prefix check */
  335. for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  336. {
  337. if (peer->status != Established)
  338. continue;
  339. if (peer->afc[afi][SAFI_UNICAST])
  340. bgp_maximum_prefix_overflow (peer, afi, SAFI_UNICAST, 1);
  341. if (peer->afc[afi][SAFI_MULTICAST])
  342. bgp_maximum_prefix_overflow (peer, afi, SAFI_MULTICAST, 1);
  343. if (peer->afc[afi][SAFI_MPLS_VPN])
  344. bgp_maximum_prefix_overflow (peer, afi, SAFI_MPLS_VPN, 1);
  345. }
  346. for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); rn;
  347. rn = bgp_route_next (rn))
  348. {
  349. for (bi = rn->info; bi; bi = next)
  350. {
  351. next = bi->next;
  352. if (bi->type == ZEBRA_ROUTE_BGP && bi->sub_type == BGP_ROUTE_NORMAL)
  353. {
  354. #if BGP_SCAN_NEXTHOP
  355. changed = 0;
  356. metricchanged = 0;
  357. if (bi->peer->sort == BGP_PEER_EBGP && bi->peer->ttl == 1
  358. && !CHECK_FLAG(bi->peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
  359. valid = bgp_nexthop_onlink (afi, bi->attr);
  360. else
  361. valid = bgp_nexthop_lookup (afi, bi->peer, bi,
  362. &changed, &metricchanged);
  363. current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;
  364. if (changed)
  365. SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
  366. else
  367. UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
  368. if (valid != current)
  369. {
  370. if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))
  371. {
  372. bgp_aggregate_decrement (bgp, &rn->p, bi,
  373. afi, SAFI_UNICAST);
  374. bgp_info_unset_flag (rn, bi, BGP_INFO_VALID);
  375. }
  376. else
  377. {
  378. bgp_info_set_flag (rn, bi, BGP_INFO_VALID);
  379. bgp_aggregate_increment (bgp, &rn->p, bi,
  380. afi, SAFI_UNICAST);
  381. }
  382. }
  383. #endif
  384. if (CHECK_FLAG (bgp->af_flags[afi][SAFI_UNICAST],
  385. BGP_CONFIG_DAMPENING)
  386. && bi->extra && bi->extra->damp_info )
  387. if (bgp_damp_scan (bi, afi, SAFI_UNICAST))
  388. bgp_aggregate_increment (bgp, &rn->p, bi,
  389. afi, SAFI_UNICAST);
  390. }
  391. }
  392. if (rn->info)
  393. bgp_process (bgp, rn, afi, SAFI_UNICAST);
  394. }
  395. #if BGP_SCAN_NEXTHOP
  396. /* Flash old cache. */
  397. if (bgp_nexthop_cache_table[afi] == cache1_table[afi])
  398. bgp_nexthop_cache_reset (cache2_table[afi]);
  399. else
  400. bgp_nexthop_cache_reset (cache1_table[afi]);
  401. #endif
  402. if (BGP_DEBUG (events, EVENTS))
  403. {
  404. if (afi == AFI_IP)
  405. zlog_debug ("scanning IPv4 Unicast routing tables");
  406. else if (afi == AFI_IP6)
  407. zlog_debug ("scanning IPv6 Unicast routing tables");
  408. }
  409. /* Reevaluate default-originate route-maps and announce/withdraw
  410. * default route if neccesary. */
  411. for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  412. {
  413. if (peer->status == Established
  414. && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
  415. && peer->default_rmap[afi][safi].name)
  416. bgp_default_originate (peer, afi, safi, 0);
  417. }
  418. }
  419. /* BGP scan thread. This thread check nexthop reachability. */
  420. static int
  421. bgp_scan_timer (struct thread *t)
  422. {
  423. bgp_scan_thread =
  424. thread_add_timer (bm->master, bgp_scan_timer, NULL, bgp_scan_interval);
  425. if (BGP_DEBUG (events, EVENTS))
  426. zlog_debug ("Performing BGP general scanning");
  427. bgp_scan (AFI_IP, SAFI_UNICAST);
  428. bgp_scan (AFI_IP6, SAFI_UNICAST);
  429. return 0;
  430. }
  431. /* BGP own address structure */
  432. struct bgp_addr
  433. {
  434. struct in_addr addr;
  435. int refcnt;
  436. };
  437. static struct hash *bgp_address_hash;
  438. static void *
  439. bgp_address_hash_alloc (void *p)
  440. {
  441. struct in_addr *val = p;
  442. struct bgp_addr *addr;
  443. addr = XMALLOC (MTYPE_BGP_ADDR, sizeof (struct bgp_addr));
  444. addr->refcnt = 0;
  445. addr->addr.s_addr = val->s_addr;
  446. return addr;
  447. }
  448. static unsigned int
  449. bgp_address_hash_key_make (void *p)
  450. {
  451. const struct bgp_addr *addr = p;
  452. return jhash_1word(addr->addr.s_addr, 0);
  453. }
  454. static int
  455. bgp_address_hash_cmp (const void *p1, const void *p2)
  456. {
  457. const struct bgp_addr *addr1 = p1;
  458. const struct bgp_addr *addr2 = p2;
  459. return addr1->addr.s_addr == addr2->addr.s_addr;
  460. }
  461. void
  462. bgp_address_init (void)
  463. {
  464. bgp_address_hash = hash_create (bgp_address_hash_key_make,
  465. bgp_address_hash_cmp);
  466. }
  467. void
  468. bgp_address_destroy (void)
  469. {
  470. if (bgp_address_hash == NULL)
  471. return;
  472. hash_clean(bgp_address_hash, NULL);
  473. hash_free(bgp_address_hash);
  474. bgp_address_hash = NULL;
  475. }
  476. static void
  477. bgp_address_add (struct prefix *p)
  478. {
  479. struct bgp_addr tmp;
  480. struct bgp_addr *addr;
  481. tmp.addr = p->u.prefix4;
  482. addr = hash_get (bgp_address_hash, &tmp, bgp_address_hash_alloc);
  483. addr->refcnt++;
  484. }
  485. static void
  486. bgp_address_del (struct prefix *p)
  487. {
  488. struct bgp_addr tmp;
  489. struct bgp_addr *addr;
  490. tmp.addr = p->u.prefix4;
  491. addr = hash_lookup (bgp_address_hash, &tmp);
  492. /* may have been deleted earlier by bgp_interface_down() */
  493. if (addr == NULL)
  494. return;
  495. addr->refcnt--;
  496. if (addr->refcnt == 0)
  497. {
  498. hash_release (bgp_address_hash, addr);
  499. XFREE (MTYPE_BGP_ADDR, addr);
  500. }
  501. }
  502. struct bgp_connected_ref
  503. {
  504. unsigned int refcnt;
  505. };
  506. void
  507. bgp_connected_add (struct connected *ifc)
  508. {
  509. struct prefix p;
  510. struct prefix *addr;
  511. struct interface *ifp;
  512. struct bgp_node *rn;
  513. struct bgp_connected_ref *bc;
  514. ifp = ifc->ifp;
  515. if (! ifp)
  516. return;
  517. if (if_is_loopback (ifp))
  518. return;
  519. addr = ifc->address;
  520. p = *(CONNECTED_PREFIX(ifc));
  521. if (addr->family == AF_INET)
  522. {
  523. apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
  524. if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
  525. return;
  526. bgp_address_add (addr);
  527. rn = bgp_node_get (bgp_connected_table[AFI_IP], (struct prefix *) &p);
  528. if (rn->info)
  529. {
  530. bc = rn->info;
  531. bc->refcnt++;
  532. }
  533. else
  534. {
  535. bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
  536. bc->refcnt = 1;
  537. rn->info = bc;
  538. }
  539. }
  540. else if (addr->family == AF_INET6)
  541. {
  542. apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
  543. if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
  544. return;
  545. if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
  546. return;
  547. rn = bgp_node_get (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
  548. if (rn->info)
  549. {
  550. bc = rn->info;
  551. bc->refcnt++;
  552. }
  553. else
  554. {
  555. bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
  556. bc->refcnt = 1;
  557. rn->info = bc;
  558. }
  559. }
  560. }
  561. void
  562. bgp_connected_delete (struct connected *ifc)
  563. {
  564. struct prefix p;
  565. struct prefix *addr;
  566. struct interface *ifp;
  567. struct bgp_node *rn;
  568. struct bgp_connected_ref *bc;
  569. ifp = ifc->ifp;
  570. if (if_is_loopback (ifp))
  571. return;
  572. addr = ifc->address;
  573. p = *(CONNECTED_PREFIX(ifc));
  574. if (addr->family == AF_INET)
  575. {
  576. apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
  577. if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
  578. return;
  579. bgp_address_del (addr);
  580. rn = bgp_node_lookup (bgp_connected_table[AFI_IP], &p);
  581. if (! rn)
  582. return;
  583. bc = rn->info;
  584. bc->refcnt--;
  585. if (bc->refcnt == 0)
  586. {
  587. XFREE (MTYPE_BGP_CONN, bc);
  588. rn->info = NULL;
  589. }
  590. bgp_unlock_node (rn);
  591. bgp_unlock_node (rn);
  592. }
  593. else if (addr->family == AF_INET6)
  594. {
  595. apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
  596. if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
  597. return;
  598. if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
  599. return;
  600. rn = bgp_node_lookup (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
  601. if (! rn)
  602. return;
  603. bc = rn->info;
  604. bc->refcnt--;
  605. if (bc->refcnt == 0)
  606. {
  607. XFREE (MTYPE_BGP_CONN, bc);
  608. rn->info = NULL;
  609. }
  610. bgp_unlock_node (rn);
  611. bgp_unlock_node (rn);
  612. }
  613. }
  614. int
  615. bgp_nexthop_self (struct attr *attr)
  616. {
  617. struct bgp_addr tmp, *addr;
  618. tmp.addr = attr->nexthop;
  619. addr = hash_lookup (bgp_address_hash, &tmp);
  620. if (addr)
  621. return 1;
  622. return 0;
  623. }
  624. static struct bgp_nexthop_cache *
  625. zlookup_read (void)
  626. {
  627. struct stream *s;
  628. uint16_t length;
  629. u_char marker;
  630. u_char version;
  631. uint16_t vrf_id;
  632. uint16_t command;
  633. int err;
  634. struct in_addr raddr __attribute__((unused));
  635. uint32_t metric;
  636. int i;
  637. u_char nexthop_num;
  638. struct nexthop *nexthop;
  639. struct bgp_nexthop_cache *bnc;
  640. s = zlookup->ibuf;
  641. stream_reset (s);
  642. err = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
  643. &vrf_id, &command);
  644. if (err < 0)
  645. {
  646. zlog_err("%s: zserv_read_header() failed", __func__);
  647. return NULL;
  648. }
  649. /* XXX: not doing anything with raddr */
  650. raddr.s_addr = stream_get_ipv4 (s);
  651. metric = stream_getl (s);
  652. nexthop_num = stream_getc (s);
  653. if (nexthop_num)
  654. {
  655. bnc = bnc_new ();
  656. bnc->valid = 1;
  657. bnc->metric = metric;
  658. bnc->nexthop_num = nexthop_num;
  659. for (i = 0; i < nexthop_num; i++)
  660. {
  661. nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
  662. nexthop->type = stream_getc (s);
  663. switch (nexthop->type)
  664. {
  665. case ZEBRA_NEXTHOP_IPV4:
  666. nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
  667. break;
  668. case ZEBRA_NEXTHOP_IPV4_IFINDEX:
  669. nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
  670. nexthop->ifindex = stream_getl (s);
  671. break;
  672. case ZEBRA_NEXTHOP_IFINDEX:
  673. case ZEBRA_NEXTHOP_IFNAME:
  674. nexthop->ifindex = stream_getl (s);
  675. break;
  676. default:
  677. /* do nothing */
  678. break;
  679. }
  680. bnc_nexthop_add (bnc, nexthop);
  681. }
  682. }
  683. else
  684. return NULL;
  685. return bnc;
  686. }
  687. struct bgp_nexthop_cache *
  688. zlookup_query (struct in_addr addr)
  689. {
  690. int ret;
  691. struct stream *s;
  692. /* Check socket. */
  693. if (zlookup->sock < 0)
  694. return NULL;
  695. s = zlookup->obuf;
  696. stream_reset (s);
  697. zclient_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, VRF_DEFAULT);
  698. stream_put_in_addr (s, &addr);
  699. stream_putw_at (s, 0, stream_get_endp (s));
  700. ret = writen (zlookup->sock, s->data, stream_get_endp (s));
  701. if (ret < 0)
  702. {
  703. zlog_err ("can't write to zlookup->sock");
  704. close (zlookup->sock);
  705. zlookup->sock = -1;
  706. return NULL;
  707. }
  708. if (ret == 0)
  709. {
  710. zlog_err ("zlookup->sock connection closed");
  711. close (zlookup->sock);
  712. zlookup->sock = -1;
  713. return NULL;
  714. }
  715. return zlookup_read ();
  716. }
  717. static struct bgp_nexthop_cache *
  718. zlookup_read_ipv6 (void)
  719. {
  720. struct stream *s;
  721. uint16_t length, vrf_id, cmd;
  722. u_char version, marker;
  723. struct in6_addr raddr;
  724. uint32_t metric;
  725. int i, err;
  726. u_char nexthop_num;
  727. struct nexthop *nexthop;
  728. struct bgp_nexthop_cache *bnc;
  729. s = zlookup->ibuf;
  730. stream_reset (s);
  731. err = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
  732. &vrf_id, &cmd);
  733. if (err < 0)
  734. {
  735. zlog_err("%s: zserv_read_header() failed", __func__);
  736. return NULL;
  737. }
  738. /* XXX: not actually doing anything with raddr */
  739. stream_get (&raddr, s, 16);
  740. metric = stream_getl (s);
  741. nexthop_num = stream_getc (s);
  742. if (nexthop_num)
  743. {
  744. bnc = bnc_new ();
  745. bnc->valid = 1;
  746. bnc->metric = metric;
  747. bnc->nexthop_num = nexthop_num;
  748. for (i = 0; i < nexthop_num; i++)
  749. {
  750. nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
  751. nexthop->type = stream_getc (s);
  752. switch (nexthop->type)
  753. {
  754. case ZEBRA_NEXTHOP_IPV6:
  755. stream_get (&nexthop->gate.ipv6, s, 16);
  756. break;
  757. case ZEBRA_NEXTHOP_IPV6_IFINDEX:
  758. case ZEBRA_NEXTHOP_IPV6_IFNAME:
  759. stream_get (&nexthop->gate.ipv6, s, 16);
  760. nexthop->ifindex = stream_getl (s);
  761. break;
  762. case ZEBRA_NEXTHOP_IFINDEX:
  763. case ZEBRA_NEXTHOP_IFNAME:
  764. nexthop->ifindex = stream_getl (s);
  765. break;
  766. default:
  767. /* do nothing */
  768. break;
  769. }
  770. bnc_nexthop_add (bnc, nexthop);
  771. }
  772. }
  773. else
  774. return NULL;
  775. return bnc;
  776. }
  777. struct bgp_nexthop_cache *
  778. zlookup_query_ipv6 (struct in6_addr *addr)
  779. {
  780. int ret;
  781. struct stream *s;
  782. /* Check socket. */
  783. if (zlookup->sock < 0)
  784. return NULL;
  785. s = zlookup->obuf;
  786. stream_reset (s);
  787. zclient_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, VRF_DEFAULT);
  788. stream_put (s, addr, 16);
  789. stream_putw_at (s, 0, stream_get_endp (s));
  790. ret = writen (zlookup->sock, s->data, stream_get_endp (s));
  791. if (ret < 0)
  792. {
  793. zlog_err ("can't write to zlookup->sock");
  794. close (zlookup->sock);
  795. zlookup->sock = -1;
  796. return NULL;
  797. }
  798. if (ret == 0)
  799. {
  800. zlog_err ("zlookup->sock connection closed");
  801. close (zlookup->sock);
  802. zlookup->sock = -1;
  803. return NULL;
  804. }
  805. return zlookup_read_ipv6 ();
  806. }
  807. static int
  808. bgp_import_check (struct prefix *p, u_int32_t *igpmetric,
  809. struct in_addr *igpnexthop)
  810. {
  811. struct stream *s;
  812. int ret;
  813. u_int16_t length, vrf_id, command;
  814. u_char version, marker;
  815. struct in_addr addr __attribute__((unused));
  816. struct in_addr nexthop;
  817. u_int32_t metric = 0;
  818. u_char nexthop_num;
  819. u_char nexthop_type;
  820. /* If lookup connection is not available return valid. */
  821. if (zlookup->sock < 0)
  822. {
  823. if (igpmetric)
  824. *igpmetric = 0;
  825. return 1;
  826. }
  827. /* Send query to the lookup connection */
  828. s = zlookup->obuf;
  829. stream_reset (s);
  830. zclient_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, VRF_DEFAULT);
  831. stream_putc (s, p->prefixlen);
  832. stream_put_in_addr (s, &p->u.prefix4);
  833. stream_putw_at (s, 0, stream_get_endp (s));
  834. /* Write the packet. */
  835. ret = writen (zlookup->sock, s->data, stream_get_endp (s));
  836. if (ret < 0)
  837. {
  838. zlog_err ("can't write to zlookup->sock");
  839. close (zlookup->sock);
  840. zlookup->sock = -1;
  841. return 1;
  842. }
  843. if (ret == 0)
  844. {
  845. zlog_err ("zlookup->sock connection closed");
  846. close (zlookup->sock);
  847. zlookup->sock = -1;
  848. return 1;
  849. }
  850. /* Get result. */
  851. stream_reset (s);
  852. ret = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
  853. &vrf_id, &command);
  854. if (ret < 0)
  855. {
  856. zlog_err("%s: zserv_read_header() failed", __func__);
  857. return 0;
  858. }
  859. /* XXX: not using addr */
  860. addr.s_addr = stream_get_ipv4 (s);
  861. metric = stream_getl (s);
  862. nexthop_num = stream_getc (s);
  863. /* Set IGP metric value. */
  864. if (igpmetric)
  865. *igpmetric = metric;
  866. /* If there is nexthop then this is active route. */
  867. if (nexthop_num)
  868. {
  869. nexthop.s_addr = 0;
  870. nexthop_type = stream_getc (s);
  871. switch (nexthop_type)
  872. {
  873. case ZEBRA_NEXTHOP_IPV4:
  874. nexthop.s_addr = stream_get_ipv4 (s);
  875. break;
  876. case ZEBRA_NEXTHOP_IPV4_IFINDEX:
  877. nexthop.s_addr = stream_get_ipv4 (s);
  878. /* ifindex */ (void)stream_getl (s);
  879. break;
  880. default:
  881. /* do nothing */
  882. break;
  883. }
  884. *igpnexthop = nexthop;
  885. return 1;
  886. }
  887. else
  888. return 0;
  889. }
  890. /* Scan all configured BGP route then check the route exists in IGP or
  891. not. */
  892. static int
  893. bgp_import (struct thread *t)
  894. {
  895. struct bgp *bgp;
  896. struct bgp_node *rn;
  897. struct bgp_static *bgp_static;
  898. struct listnode *node, *nnode;
  899. int valid;
  900. u_int32_t metric;
  901. struct in_addr nexthop;
  902. afi_t afi;
  903. safi_t safi;
  904. bgp_import_thread =
  905. thread_add_timer (bm->master, bgp_import, NULL, bgp_import_interval);
  906. if (BGP_DEBUG (events, EVENTS))
  907. zlog_debug ("Import timer expired.");
  908. for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
  909. {
  910. for (afi = AFI_IP; afi < AFI_MAX; afi++)
  911. for (safi = SAFI_UNICAST; safi < SAFI_MPLS_VPN; safi++)
  912. for (rn = bgp_table_top (bgp->route[afi][safi]); rn;
  913. rn = bgp_route_next (rn))
  914. if ((bgp_static = rn->info) != NULL)
  915. {
  916. if (bgp_static->backdoor)
  917. continue;
  918. valid = bgp_static->valid;
  919. metric = bgp_static->igpmetric;
  920. nexthop = bgp_static->igpnexthop;
  921. if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)
  922. && afi == AFI_IP && safi == SAFI_UNICAST)
  923. bgp_static->valid = bgp_import_check (&rn->p, &bgp_static->igpmetric,
  924. &bgp_static->igpnexthop);
  925. else
  926. {
  927. bgp_static->valid = 1;
  928. bgp_static->igpmetric = 0;
  929. bgp_static->igpnexthop.s_addr = 0;
  930. }
  931. if (bgp_static->valid != valid)
  932. {
  933. if (bgp_static->valid)
  934. bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
  935. else
  936. bgp_static_withdraw (bgp, &rn->p, afi, safi);
  937. }
  938. else if (bgp_static->valid)
  939. {
  940. if (bgp_static->igpmetric != metric
  941. || bgp_static->igpnexthop.s_addr != nexthop.s_addr
  942. || bgp_static->rmap.name)
  943. bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
  944. }
  945. }
  946. }
  947. return 0;
  948. }
  949. /* Connect to zebra for nexthop lookup. */
  950. static int
  951. zlookup_connect (struct thread *t)
  952. {
  953. struct zclient *zlookup;
  954. zlookup = THREAD_ARG (t);
  955. zlookup->t_connect = NULL;
  956. if (zlookup->sock != -1)
  957. return 0;
  958. if (zclient_socket_connect (zlookup) < 0)
  959. return -1;
  960. return 0;
  961. }
  962. /* Check specified multiaccess next-hop. */
  963. int
  964. bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer)
  965. {
  966. struct bgp_node *rn1;
  967. struct bgp_node *rn2;
  968. struct prefix p1;
  969. struct prefix p2;
  970. struct in_addr addr;
  971. int ret;
  972. ret = inet_aton (peer, &addr);
  973. if (! ret)
  974. return 0;
  975. memset (&p1, 0, sizeof (struct prefix));
  976. p1.family = AF_INET;
  977. p1.prefixlen = IPV4_MAX_BITLEN;
  978. p1.u.prefix4 = nexthop;
  979. memset (&p2, 0, sizeof (struct prefix));
  980. p2.family = AF_INET;
  981. p2.prefixlen = IPV4_MAX_BITLEN;
  982. p2.u.prefix4 = addr;
  983. /* If bgp scan is not enabled, return invalid. */
  984. if (zlookup->sock < 0)
  985. return 0;
  986. rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p1);
  987. if (! rn1)
  988. return 0;
  989. bgp_unlock_node (rn1);
  990. rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p2);
  991. if (! rn2)
  992. return 0;
  993. bgp_unlock_node (rn2);
  994. /* This is safe, even with above unlocks, since we are just
  995. comparing pointers to the objects, not the objects themselves. */
  996. if (rn1 == rn2)
  997. return 1;
  998. return 0;
  999. }
  1000. DEFUN (bgp_scan_time,
  1001. bgp_scan_time_cmd,
  1002. "bgp scan-time <5-60>",
  1003. "BGP specific commands\n"
  1004. "Configure background scanner interval\n"
  1005. "Scanner interval (seconds)\n")
  1006. {
  1007. bgp_scan_interval = atoi (argv[0]);
  1008. if (bgp_scan_thread)
  1009. {
  1010. thread_cancel (bgp_scan_thread);
  1011. bgp_scan_thread =
  1012. thread_add_timer (bm->master, bgp_scan_timer, NULL, bgp_scan_interval);
  1013. }
  1014. return CMD_SUCCESS;
  1015. }
  1016. DEFUN (no_bgp_scan_time,
  1017. no_bgp_scan_time_cmd,
  1018. "no bgp scan-time",
  1019. NO_STR
  1020. "BGP specific commands\n"
  1021. "Configure background scanner interval\n")
  1022. {
  1023. bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
  1024. if (bgp_scan_thread)
  1025. {
  1026. thread_cancel (bgp_scan_thread);
  1027. bgp_scan_thread =
  1028. thread_add_timer (bm->master, bgp_scan_timer, NULL, bgp_scan_interval);
  1029. }
  1030. return CMD_SUCCESS;
  1031. }
  1032. ALIAS (no_bgp_scan_time,
  1033. no_bgp_scan_time_val_cmd,
  1034. "no bgp scan-time <5-60>",
  1035. NO_STR
  1036. "BGP specific commands\n"
  1037. "Configure background scanner interval\n"
  1038. "Scanner interval (seconds)\n")
  1039. static int
  1040. show_ip_bgp_scan_tables (struct vty *vty, const char detail)
  1041. {
  1042. struct bgp_node *rn;
  1043. char buf[INET6_ADDRSTRLEN];
  1044. if (bgp_scan_thread)
  1045. vty_out (vty, "BGP scan is running%s", VTY_NEWLINE);
  1046. else
  1047. vty_out (vty, "BGP scan is not running%s", VTY_NEWLINE);
  1048. vty_out (vty, "BGP scan interval is %d%s", bgp_scan_interval, VTY_NEWLINE);
  1049. #if BGP_SCAN_NEXTHOP
  1050. vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
  1051. for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP]); rn; rn = bgp_route_next (rn))
  1052. if ((bnc = rn->info) != NULL)
  1053. {
  1054. if (bnc->valid)
  1055. {
  1056. vty_out (vty, " %s valid [IGP metric %d]%s",
  1057. inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN), bnc->metric, VTY_NEWLINE);
  1058. if (detail)
  1059. for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
  1060. switch (nexthop->type)
  1061. {
  1062. case NEXTHOP_TYPE_IPV4:
  1063. vty_out (vty, " gate %s%s", inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
  1064. break;
  1065. case NEXTHOP_TYPE_IPV4_IFINDEX:
  1066. vty_out (vty, " gate %s", inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, INET6_ADDRSTRLEN));
  1067. vty_out (vty, " ifidx %u%s", nexthop->ifindex, VTY_NEWLINE);
  1068. break;
  1069. case NEXTHOP_TYPE_IFINDEX:
  1070. vty_out (vty, " ifidx %u%s", nexthop->ifindex, VTY_NEWLINE);
  1071. break;
  1072. default:
  1073. vty_out (vty, " invalid nexthop type %u%s", nexthop->type, VTY_NEWLINE);
  1074. }
  1075. }
  1076. else
  1077. vty_out (vty, " %s invalid%s",
  1078. inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
  1079. }
  1080. {
  1081. for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP6]);
  1082. rn;
  1083. rn = bgp_route_next (rn))
  1084. if ((bnc = rn->info) != NULL)
  1085. {
  1086. if (bnc->valid)
  1087. {
  1088. vty_out (vty, " %s valid [IGP metric %d]%s",
  1089. inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN),
  1090. bnc->metric, VTY_NEWLINE);
  1091. if (detail)
  1092. for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
  1093. switch (nexthop->type)
  1094. {
  1095. case NEXTHOP_TYPE_IPV6:
  1096. vty_out (vty, " gate %s%s", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
  1097. break;
  1098. case NEXTHOP_TYPE_IFINDEX:
  1099. vty_out (vty, " ifidx %u%s", nexthop->ifindex, VTY_NEWLINE);
  1100. break;
  1101. default:
  1102. vty_out (vty, " invalid nexthop type %u%s", nexthop->type, VTY_NEWLINE);
  1103. }
  1104. }
  1105. else
  1106. vty_out (vty, " %s invalid%s",
  1107. inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN),
  1108. VTY_NEWLINE);
  1109. }
  1110. }
  1111. #else
  1112. vty_out (vty, "BGP next-hop tracking is on%s", VTY_NEWLINE);
  1113. #endif
  1114. vty_out (vty, "BGP connected route:%s", VTY_NEWLINE);
  1115. for (rn = bgp_table_top (bgp_connected_table[AFI_IP]);
  1116. rn;
  1117. rn = bgp_route_next (rn))
  1118. if (rn->info != NULL)
  1119. vty_out (vty, " %s/%d%s", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
  1120. VTY_NEWLINE);
  1121. {
  1122. for (rn = bgp_table_top (bgp_connected_table[AFI_IP6]);
  1123. rn;
  1124. rn = bgp_route_next (rn))
  1125. if (rn->info != NULL)
  1126. vty_out (vty, " %s/%d%s",
  1127. inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN),
  1128. rn->p.prefixlen,
  1129. VTY_NEWLINE);
  1130. }
  1131. return CMD_SUCCESS;
  1132. }
  1133. static int
  1134. show_ip_bgp_nexthop_table (struct vty *vty, int detail)
  1135. {
  1136. struct bgp_node *rn;
  1137. struct bgp_nexthop_cache *bnc;
  1138. char buf[INET6_ADDRSTRLEN];
  1139. struct nexthop *nexthop;
  1140. time_t tbuf;
  1141. afi_t afi;
  1142. vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
  1143. for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
  1144. {
  1145. for (rn = bgp_table_top (bgp_nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
  1146. {
  1147. if ((bnc = rn->info) != NULL)
  1148. {
  1149. if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
  1150. {
  1151. vty_out (vty, " %s valid [IGP metric %d], #paths %d%s",
  1152. inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)),
  1153. bnc->metric, bnc->path_count, VTY_NEWLINE);
  1154. if (detail)
  1155. for (nexthop = bnc->nexthop ; nexthop; nexthop = nexthop->next)
  1156. switch (nexthop->type)
  1157. {
  1158. case NEXTHOP_TYPE_IPV6:
  1159. vty_out (vty, " gate %s%s",
  1160. inet_ntop (AF_INET6, &nexthop->gate.ipv6,
  1161. buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
  1162. break;
  1163. case NEXTHOP_TYPE_IPV6_IFINDEX:
  1164. vty_out(vty, " gate %s, if %s%s",
  1165. inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
  1166. INET6_ADDRSTRLEN),
  1167. ifindex2ifname(nexthop->ifindex),
  1168. VTY_NEWLINE);
  1169. break;
  1170. case NEXTHOP_TYPE_IPV4:
  1171. vty_out (vty, " gate %s%s",
  1172. inet_ntop (AF_INET, &nexthop->gate.ipv4, buf,
  1173. INET6_ADDRSTRLEN), VTY_NEWLINE);
  1174. break;
  1175. case NEXTHOP_TYPE_IFINDEX:
  1176. vty_out (vty, " if %s%s",
  1177. ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
  1178. break;
  1179. case NEXTHOP_TYPE_IPV4_IFINDEX:
  1180. vty_out (vty, " gate %s, if %s%s",
  1181. inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
  1182. INET6_ADDRSTRLEN),
  1183. ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
  1184. break;
  1185. default:
  1186. vty_out (vty, " invalid nexthop type %u%s",
  1187. nexthop->type, VTY_NEWLINE);
  1188. }
  1189. }
  1190. else
  1191. vty_out (vty, " %s invalid%s",
  1192. inet_ntop (AF_INET, &rn->p.u.prefix, buf, sizeof (buf)), VTY_NEWLINE);
  1193. #ifdef HAVE_CLOCK_MONOTONIC
  1194. tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
  1195. vty_out (vty, " Last update: %s", ctime(&tbuf));
  1196. #else
  1197. vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
  1198. #endif /* HAVE_CLOCK_MONOTONIC */
  1199. vty_out(vty, "%s", VTY_NEWLINE);
  1200. }
  1201. }
  1202. }
  1203. return CMD_SUCCESS;
  1204. }
  1205. DEFUN (show_ip_bgp_scan,
  1206. show_ip_bgp_scan_cmd,
  1207. "show ip bgp scan",
  1208. SHOW_STR
  1209. IP_STR
  1210. BGP_STR
  1211. "BGP scan status\n")
  1212. {
  1213. return show_ip_bgp_scan_tables (vty, 0);
  1214. }
  1215. DEFUN (show_ip_bgp_scan_detail,
  1216. show_ip_bgp_scan_detail_cmd,
  1217. "show ip bgp scan detail",
  1218. SHOW_STR
  1219. IP_STR
  1220. BGP_STR
  1221. "BGP scan status\n"
  1222. "More detailed output\n")
  1223. {
  1224. return show_ip_bgp_scan_tables (vty, 1);
  1225. }
  1226. DEFUN (show_ip_bgp_nexthop,
  1227. show_ip_bgp_nexthop_cmd,
  1228. "show ip bgp nexthop",
  1229. SHOW_STR
  1230. IP_STR
  1231. BGP_STR
  1232. "BGP nexthop table\n")
  1233. {
  1234. return show_ip_bgp_nexthop_table (vty, 0);
  1235. }
  1236. DEFUN (show_ip_bgp_nexthop_detail,
  1237. show_ip_bgp_nexthop_detail_cmd,
  1238. "show ip bgp nexthop detail",
  1239. SHOW_STR
  1240. IP_STR
  1241. BGP_STR
  1242. "BGP nexthop table\n")
  1243. {
  1244. return show_ip_bgp_nexthop_table (vty, 1);
  1245. }
  1246. int
  1247. bgp_config_write_scan_time (struct vty *vty)
  1248. {
  1249. if (bgp_scan_interval != BGP_SCAN_INTERVAL_DEFAULT)
  1250. vty_out (vty, " bgp scan-time %d%s", bgp_scan_interval, VTY_NEWLINE);
  1251. return CMD_SUCCESS;
  1252. }
  1253. void
  1254. bgp_scan_init (void)
  1255. {
  1256. zlookup = zclient_new (bm->master);
  1257. zlookup->sock = -1;
  1258. zlookup->t_connect = thread_add_event (bm->master, zlookup_connect, zlookup, 0);
  1259. bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
  1260. bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT;
  1261. cache1_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
  1262. cache2_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
  1263. bgp_nexthop_cache_table[AFI_IP] = cache1_table[AFI_IP];
  1264. bgp_connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
  1265. cache1_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
  1266. cache2_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
  1267. bgp_nexthop_cache_table[AFI_IP6] = cache1_table[AFI_IP6];
  1268. bgp_connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
  1269. /* Make BGP scan thread. */
  1270. bgp_scan_thread = thread_add_timer (bm->master, bgp_scan_timer,
  1271. NULL, bgp_scan_interval);
  1272. /* Make BGP import there. */
  1273. bgp_import_thread = thread_add_timer (bm->master, bgp_import, NULL, 0);
  1274. install_element (BGP_NODE, &bgp_scan_time_cmd);
  1275. install_element (BGP_NODE, &no_bgp_scan_time_cmd);
  1276. install_element (BGP_NODE, &no_bgp_scan_time_val_cmd);
  1277. install_element (VIEW_NODE, &show_ip_bgp_scan_cmd);
  1278. install_element (VIEW_NODE, &show_ip_bgp_scan_detail_cmd);
  1279. install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
  1280. install_element (VIEW_NODE, &show_ip_bgp_nexthop_detail_cmd);
  1281. install_element (RESTRICTED_NODE, &show_ip_bgp_scan_cmd);
  1282. install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);
  1283. install_element (ENABLE_NODE, &show_ip_bgp_nexthop_cmd);
  1284. install_element (ENABLE_NODE, &show_ip_bgp_nexthop_detail_cmd);
  1285. install_element (ENABLE_NODE, &show_ip_bgp_scan_detail_cmd);
  1286. }
  1287. void
  1288. bgp_scan_finish (void)
  1289. {
  1290. if (cache1_table[AFI_IP])
  1291. bgp_table_unlock (cache1_table[AFI_IP]);
  1292. cache1_table[AFI_IP] = NULL;
  1293. if (cache2_table[AFI_IP])
  1294. bgp_table_unlock (cache2_table[AFI_IP]);
  1295. cache2_table[AFI_IP] = NULL;
  1296. if (bgp_connected_table[AFI_IP])
  1297. bgp_table_unlock (bgp_connected_table[AFI_IP]);
  1298. bgp_connected_table[AFI_IP] = NULL;
  1299. if (cache1_table[AFI_IP6])
  1300. bgp_table_unlock (cache1_table[AFI_IP6]);
  1301. cache1_table[AFI_IP6] = NULL;
  1302. if (cache2_table[AFI_IP6])
  1303. bgp_table_unlock (cache2_table[AFI_IP6]);
  1304. cache2_table[AFI_IP6] = NULL;
  1305. if (bgp_connected_table[AFI_IP6])
  1306. bgp_table_unlock (bgp_connected_table[AFI_IP6]);
  1307. bgp_connected_table[AFI_IP6] = NULL;
  1308. }
  1309. void
  1310. bgp_scan_destroy (void)
  1311. {
  1312. if (zlookup == NULL)
  1313. return;
  1314. THREAD_OFF(bgp_import_thread);
  1315. THREAD_OFF(bgp_scan_thread);
  1316. THREAD_OFF(zlookup->t_connect);
  1317. bgp_scan_finish();
  1318. zclient_free (zlookup);
  1319. zlookup = NULL;
  1320. }