ospf6_neighbor.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. /*
  2. * Copyright (C) 2003 Yasuhiro Ohara
  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
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "log.h"
  23. #include "memory.h"
  24. #include "thread.h"
  25. #include "linklist.h"
  26. #include "vty.h"
  27. #include "command.h"
  28. #include "ospf6d.h"
  29. #include "ospf6_proto.h"
  30. #include "ospf6_lsa.h"
  31. #include "ospf6_lsdb.h"
  32. #include "ospf6_message.h"
  33. #include "ospf6_top.h"
  34. #include "ospf6_area.h"
  35. #include "ospf6_interface.h"
  36. #include "ospf6_neighbor.h"
  37. #include "ospf6_intra.h"
  38. #include "ospf6_flood.h"
  39. unsigned char conf_debug_ospf6_neighbor = 0;
  40. char *ospf6_neighbor_state_str[] =
  41. { "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
  42. "Loading", "Full", NULL };
  43. int
  44. ospf6_neighbor_cmp (void *va, void *vb)
  45. {
  46. struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
  47. struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
  48. return (ntohl (ona->router_id) - ntohl (onb->router_id));
  49. }
  50. struct ospf6_neighbor *
  51. ospf6_neighbor_lookup (u_int32_t router_id,
  52. struct ospf6_interface *oi)
  53. {
  54. listnode n;
  55. struct ospf6_neighbor *on;
  56. for (n = listhead (oi->neighbor_list); n; nextnode (n))
  57. {
  58. on = (struct ospf6_neighbor *) getdata (n);
  59. if (on->router_id == router_id)
  60. return on;
  61. }
  62. return (struct ospf6_neighbor *) NULL;
  63. }
  64. /* create ospf6_neighbor */
  65. struct ospf6_neighbor *
  66. ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
  67. {
  68. struct ospf6_neighbor *on;
  69. char buf[16];
  70. on = (struct ospf6_neighbor *)
  71. XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
  72. if (on == NULL)
  73. {
  74. zlog_warn ("neighbor: malloc failed");
  75. return NULL;
  76. }
  77. memset (on, 0, sizeof (struct ospf6_neighbor));
  78. inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
  79. snprintf (on->name, sizeof (on->name), "%s%%%s",
  80. buf, oi->interface->name);
  81. on->ospf6_if = oi;
  82. on->state = OSPF6_NEIGHBOR_DOWN;
  83. gettimeofday (&on->last_changed, (struct timezone *) NULL);
  84. on->router_id = router_id;
  85. on->summary_list = ospf6_lsdb_create ();
  86. on->request_list = ospf6_lsdb_create ();
  87. on->retrans_list = ospf6_lsdb_create ();
  88. on->dbdesc_list = ospf6_lsdb_create ();
  89. on->lsreq_list = ospf6_lsdb_create ();
  90. on->lsupdate_list = ospf6_lsdb_create ();
  91. on->lsack_list = ospf6_lsdb_create ();
  92. listnode_add_sort (oi->neighbor_list, on);
  93. return on;
  94. }
  95. void
  96. ospf6_neighbor_delete (struct ospf6_neighbor *on)
  97. {
  98. struct ospf6_lsa *lsa;
  99. ospf6_lsdb_remove_all (on->summary_list);
  100. ospf6_lsdb_remove_all (on->request_list);
  101. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  102. lsa = ospf6_lsdb_next (lsa))
  103. {
  104. ospf6_decrement_onretrans (lsa);
  105. ospf6_lsdb_remove (lsa, on->retrans_list);
  106. }
  107. ospf6_lsdb_remove_all (on->dbdesc_list);
  108. ospf6_lsdb_remove_all (on->lsreq_list);
  109. ospf6_lsdb_remove_all (on->lsupdate_list);
  110. ospf6_lsdb_remove_all (on->lsack_list);
  111. ospf6_lsdb_delete (on->summary_list);
  112. ospf6_lsdb_delete (on->request_list);
  113. ospf6_lsdb_delete (on->retrans_list);
  114. ospf6_lsdb_delete (on->dbdesc_list);
  115. ospf6_lsdb_delete (on->lsreq_list);
  116. ospf6_lsdb_delete (on->lsupdate_list);
  117. ospf6_lsdb_delete (on->lsack_list);
  118. THREAD_OFF (on->inactivity_timer);
  119. THREAD_OFF (on->thread_send_dbdesc);
  120. THREAD_OFF (on->thread_send_lsreq);
  121. THREAD_OFF (on->thread_send_lsupdate);
  122. THREAD_OFF (on->thread_send_lsack);
  123. XFREE (MTYPE_OSPF6_NEIGHBOR, on);
  124. }
  125. static void
  126. ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
  127. {
  128. u_char prev_state;
  129. prev_state = on->state;
  130. on->state = next_state;
  131. if (prev_state == next_state)
  132. return;
  133. gettimeofday (&on->last_changed, (struct timezone *) NULL);
  134. /* log */
  135. if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
  136. {
  137. zlog_info ("Neighbor state change %s: [%s]->[%s]", on->name,
  138. ospf6_neighbor_state_str[prev_state],
  139. ospf6_neighbor_state_str[next_state]);
  140. }
  141. if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
  142. {
  143. OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
  144. if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
  145. {
  146. OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
  147. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
  148. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
  149. }
  150. }
  151. #ifdef XXX
  152. if (prev_state == NBS_FULL || next_state == NBS_FULL)
  153. nbs_full_change (on->ospf6_interface);
  154. /* check for LSAs that already reached MaxAge */
  155. if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
  156. prev_state == OSPF6_NEIGHBOR_LOADING) &&
  157. (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
  158. next_state != OSPF6_NEIGHBOR_LOADING))
  159. {
  160. ospf6_maxage_remover ();
  161. }
  162. #endif /*XXX*/
  163. }
  164. /* RFC2328 section 10.4 */
  165. int
  166. need_adjacency (struct ospf6_neighbor *on)
  167. {
  168. if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
  169. on->ospf6_if->state == OSPF6_INTERFACE_DR ||
  170. on->ospf6_if->state == OSPF6_INTERFACE_BDR)
  171. return 1;
  172. if (on->ospf6_if->drouter == on->router_id ||
  173. on->ospf6_if->bdrouter == on->router_id)
  174. return 1;
  175. return 0;
  176. }
  177. int
  178. hello_received (struct thread *thread)
  179. {
  180. struct ospf6_neighbor *on;
  181. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  182. assert (on);
  183. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  184. zlog_info ("Neighbor Event %s: *HelloReceived*", on->name);
  185. /* reset Inactivity Timer */
  186. THREAD_OFF (on->inactivity_timer);
  187. on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
  188. on->ospf6_if->dead_interval);
  189. if (on->state <= OSPF6_NEIGHBOR_DOWN)
  190. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
  191. return 0;
  192. }
  193. int
  194. twoway_received (struct thread *thread)
  195. {
  196. struct ospf6_neighbor *on;
  197. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  198. assert (on);
  199. if (on->state > OSPF6_NEIGHBOR_INIT)
  200. return 0;
  201. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  202. zlog_info ("Neighbor Event %s: *2Way-Received*", on->name);
  203. thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  204. if (! need_adjacency (on))
  205. {
  206. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
  207. return 0;
  208. }
  209. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  210. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  211. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  212. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  213. THREAD_OFF (on->thread_send_dbdesc);
  214. on->thread_send_dbdesc =
  215. thread_add_event (master, ospf6_dbdesc_send, on, 0);
  216. return 0;
  217. }
  218. int
  219. negotiation_done (struct thread *thread)
  220. {
  221. struct ospf6_neighbor *on;
  222. struct ospf6_lsa *lsa;
  223. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  224. assert (on);
  225. if (on->state != OSPF6_NEIGHBOR_EXSTART)
  226. return 0;
  227. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  228. zlog_info ("Neighbor Event %s: *NegotiationDone*", on->name);
  229. /* clear ls-list */
  230. ospf6_lsdb_remove_all (on->summary_list);
  231. ospf6_lsdb_remove_all (on->request_list);
  232. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  233. lsa = ospf6_lsdb_next (lsa))
  234. {
  235. ospf6_decrement_onretrans (lsa);
  236. ospf6_lsdb_remove (lsa, on->retrans_list);
  237. }
  238. /* Interface scoped LSAs */
  239. for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
  240. lsa = ospf6_lsdb_next (lsa))
  241. {
  242. if (IS_OSPF6_DEBUG_LSA (DATABASE))
  243. zlog_info ("Add copy of %s to %s of %s", lsa->name,
  244. (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
  245. "summary_list"), on->name);
  246. if (OSPF6_LSA_IS_MAXAGE (lsa))
  247. {
  248. lsa->onretrans++;
  249. ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  250. }
  251. else
  252. ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  253. }
  254. /* Area scoped LSAs */
  255. for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
  256. lsa = ospf6_lsdb_next (lsa))
  257. {
  258. if (IS_OSPF6_DEBUG_LSA (DATABASE))
  259. zlog_info ("Add copy of %s to %s of %s", lsa->name,
  260. (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
  261. "summary_list"), on->name);
  262. if (OSPF6_LSA_IS_MAXAGE (lsa))
  263. {
  264. lsa->onretrans++;
  265. ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  266. }
  267. else
  268. ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  269. }
  270. /* AS scoped LSAs */
  271. for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
  272. lsa = ospf6_lsdb_next (lsa))
  273. {
  274. if (IS_OSPF6_DEBUG_LSA (DATABASE))
  275. zlog_info ("Add copy of %s to %s of %s", lsa->name,
  276. (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
  277. "summary_list"), on->name);
  278. if (OSPF6_LSA_IS_MAXAGE (lsa))
  279. {
  280. lsa->onretrans++;
  281. ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  282. }
  283. else
  284. ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  285. }
  286. UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  287. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on);
  288. return 0;
  289. }
  290. int
  291. exchange_done (struct thread *thread)
  292. {
  293. struct ospf6_neighbor *on;
  294. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  295. assert (on);
  296. if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
  297. return 0;
  298. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  299. zlog_info ("Neighbor Event %s: *ExchangeDone*", on->name);
  300. THREAD_OFF (on->thread_send_dbdesc);
  301. ospf6_lsdb_remove_all (on->dbdesc_list);
  302. /* XXX
  303. thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
  304. on->ospf6_if->dead_interval);
  305. */
  306. if (on->request_list->count == 0)
  307. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
  308. else
  309. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on);
  310. return 0;
  311. }
  312. int
  313. loading_done (struct thread *thread)
  314. {
  315. struct ospf6_neighbor *on;
  316. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  317. assert (on);
  318. if (on->state != OSPF6_NEIGHBOR_LOADING)
  319. return 0;
  320. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  321. zlog_info ("Neighbor Event %s: *LoadingDone*", on->name);
  322. assert (on->request_list->count == 0);
  323. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
  324. return 0;
  325. }
  326. int
  327. adj_ok (struct thread *thread)
  328. {
  329. struct ospf6_neighbor *on;
  330. struct ospf6_lsa *lsa;
  331. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  332. assert (on);
  333. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  334. zlog_info ("Neighbor Event %s: *AdjOK?*", on->name);
  335. if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
  336. {
  337. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  338. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  339. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  340. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  341. THREAD_OFF (on->thread_send_dbdesc);
  342. on->thread_send_dbdesc =
  343. thread_add_event (master, ospf6_dbdesc_send, on, 0);
  344. }
  345. else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
  346. ! need_adjacency (on))
  347. {
  348. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
  349. ospf6_lsdb_remove_all (on->summary_list);
  350. ospf6_lsdb_remove_all (on->request_list);
  351. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  352. lsa = ospf6_lsdb_next (lsa))
  353. {
  354. ospf6_decrement_onretrans (lsa);
  355. ospf6_lsdb_remove (lsa, on->retrans_list);
  356. }
  357. }
  358. return 0;
  359. }
  360. int
  361. seqnumber_mismatch (struct thread *thread)
  362. {
  363. struct ospf6_neighbor *on;
  364. struct ospf6_lsa *lsa;
  365. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  366. assert (on);
  367. if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
  368. return 0;
  369. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  370. zlog_info ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
  371. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  372. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  373. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  374. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  375. ospf6_lsdb_remove_all (on->summary_list);
  376. ospf6_lsdb_remove_all (on->request_list);
  377. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  378. lsa = ospf6_lsdb_next (lsa))
  379. {
  380. ospf6_decrement_onretrans (lsa);
  381. ospf6_lsdb_remove (lsa, on->retrans_list);
  382. }
  383. THREAD_OFF (on->thread_send_dbdesc);
  384. on->thread_send_dbdesc =
  385. thread_add_event (master, ospf6_dbdesc_send, on, 0);
  386. return 0;
  387. }
  388. int
  389. bad_lsreq (struct thread *thread)
  390. {
  391. struct ospf6_neighbor *on;
  392. struct ospf6_lsa *lsa;
  393. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  394. assert (on);
  395. if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
  396. return 0;
  397. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  398. zlog_info ("Neighbor Event %s: *BadLSReq*", on->name);
  399. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  400. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  401. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  402. SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  403. ospf6_lsdb_remove_all (on->summary_list);
  404. ospf6_lsdb_remove_all (on->request_list);
  405. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  406. lsa = ospf6_lsdb_next (lsa))
  407. {
  408. ospf6_decrement_onretrans (lsa);
  409. ospf6_lsdb_remove (lsa, on->retrans_list);
  410. }
  411. THREAD_OFF (on->thread_send_dbdesc);
  412. on->thread_send_dbdesc =
  413. thread_add_event (master, ospf6_dbdesc_send, on, 0);
  414. return 0;
  415. }
  416. int
  417. oneway_received (struct thread *thread)
  418. {
  419. struct ospf6_neighbor *on;
  420. struct ospf6_lsa *lsa;
  421. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  422. assert (on);
  423. if (on->state < OSPF6_NEIGHBOR_TWOWAY)
  424. return 0;
  425. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  426. zlog_info ("Neighbor Event %s: *1Way-Received*", on->name);
  427. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
  428. thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  429. ospf6_lsdb_remove_all (on->summary_list);
  430. ospf6_lsdb_remove_all (on->request_list);
  431. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  432. lsa = ospf6_lsdb_next (lsa))
  433. {
  434. ospf6_decrement_onretrans (lsa);
  435. ospf6_lsdb_remove (lsa, on->retrans_list);
  436. }
  437. THREAD_OFF (on->thread_send_dbdesc);
  438. THREAD_OFF (on->thread_send_lsreq);
  439. THREAD_OFF (on->thread_send_lsupdate);
  440. THREAD_OFF (on->thread_send_lsack);
  441. return 0;
  442. }
  443. int
  444. inactivity_timer (struct thread *thread)
  445. {
  446. struct ospf6_neighbor *on;
  447. on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  448. assert (on);
  449. if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  450. zlog_info ("Neighbor Event %s: *InactivityTimer*", on->name);
  451. on->inactivity_timer = NULL;
  452. on->drouter = on->prev_drouter = 0;
  453. on->bdrouter = on->prev_bdrouter = 0;
  454. ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on);
  455. thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  456. listnode_delete (on->ospf6_if->neighbor_list, on);
  457. ospf6_neighbor_delete (on);
  458. return 0;
  459. }
  460. /* vty functions */
  461. /* show neighbor structure */
  462. void
  463. ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
  464. {
  465. char router_id[16];
  466. char duration[16];
  467. struct timeval now, res;
  468. char nstate[16];
  469. char deadtime[16];
  470. long h, m, s;
  471. /* Router-ID (Name) */
  472. inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  473. #ifdef HAVE_GETNAMEINFO
  474. {
  475. }
  476. #endif /*HAVE_GETNAMEINFO*/
  477. gettimeofday (&now, NULL);
  478. /* Dead time */
  479. h = m = s = 0;
  480. if (on->inactivity_timer)
  481. {
  482. s = on->inactivity_timer->u.sands.tv_sec - now.tv_sec;
  483. h = s / 3600;
  484. s -= h * 3600;
  485. m = s / 60;
  486. s -= m * 60;
  487. }
  488. snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
  489. /* Neighbor State */
  490. if (if_is_pointopoint (on->ospf6_if->interface))
  491. snprintf (nstate, sizeof (nstate), "PointToPoint");
  492. else
  493. {
  494. if (on->router_id == on->drouter)
  495. snprintf (nstate, sizeof (nstate), "DR");
  496. else if (on->router_id == on->bdrouter)
  497. snprintf (nstate, sizeof (nstate), "BDR");
  498. else
  499. snprintf (nstate, sizeof (nstate), "DROther");
  500. }
  501. /* Duration */
  502. timersub (&now, &on->last_changed, &res);
  503. timerstring (&res, duration, sizeof (duration));
  504. /*
  505. vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
  506. "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
  507. "I/F", "State", VTY_NEWLINE);
  508. */
  509. vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
  510. router_id, on->priority, deadtime,
  511. ospf6_neighbor_state_str[on->state], nstate, duration,
  512. on->ospf6_if->interface->name,
  513. ospf6_interface_state_str[on->ospf6_if->state], VTY_NEWLINE);
  514. }
  515. void
  516. ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
  517. {
  518. char router_id[16];
  519. char drouter[16], bdrouter[16];
  520. char duration[16];
  521. struct timeval now, res;
  522. /*
  523. vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  524. "RouterID", "State", "Duration", "DR", "BDR", "I/F",
  525. "State", VTY_NEWLINE);
  526. */
  527. inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  528. inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  529. inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
  530. gettimeofday (&now, NULL);
  531. timersub (&now, &on->last_changed, &res);
  532. timerstring (&res, duration, sizeof (duration));
  533. vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  534. router_id, ospf6_neighbor_state_str[on->state],
  535. duration, drouter, bdrouter, on->ospf6_if->interface->name,
  536. ospf6_interface_state_str[on->ospf6_if->state],
  537. VTY_NEWLINE);
  538. }
  539. void
  540. ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
  541. {
  542. char drouter[16], bdrouter[16];
  543. char linklocal_addr[64], duration[32];
  544. struct timeval now, res;
  545. struct ospf6_lsa *lsa;
  546. inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
  547. sizeof (linklocal_addr));
  548. inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  549. inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
  550. gettimeofday (&now, NULL);
  551. timersub (&now, &on->last_changed, &res);
  552. timerstring (&res, duration, sizeof (duration));
  553. vty_out (vty, " Neighbor %s%s", on->name,
  554. VTY_NEWLINE);
  555. vty_out (vty, " Area %s via interface %s (ifindex %d)%s",
  556. on->ospf6_if->area->name,
  557. on->ospf6_if->interface->name,
  558. on->ospf6_if->interface->ifindex,
  559. VTY_NEWLINE);
  560. vty_out (vty, " His IfIndex: %d Link-local address: %s%s",
  561. on->ifindex, linklocal_addr,
  562. VTY_NEWLINE);
  563. vty_out (vty, " State %s for a duration of %s%s",
  564. ospf6_neighbor_state_str[on->state], duration,
  565. VTY_NEWLINE);
  566. vty_out (vty, " His choice of DR/BDR %s/%s, Priority %d%s",
  567. drouter, bdrouter, on->priority,
  568. VTY_NEWLINE);
  569. vty_out (vty, " DbDesc status: %s%s%s SeqNum: %#lx%s",
  570. (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
  571. (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
  572. (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
  573. "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
  574. VTY_NEWLINE);
  575. vty_out (vty, " Summary-List: %d LSAs%s", on->summary_list->count,
  576. VTY_NEWLINE);
  577. for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
  578. lsa = ospf6_lsdb_next (lsa))
  579. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  580. vty_out (vty, " Request-List: %d LSAs%s", on->request_list->count,
  581. VTY_NEWLINE);
  582. for (lsa = ospf6_lsdb_head (on->request_list); lsa;
  583. lsa = ospf6_lsdb_next (lsa))
  584. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  585. vty_out (vty, " Retrans-List: %d LSAs%s", on->retrans_list->count,
  586. VTY_NEWLINE);
  587. for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  588. lsa = ospf6_lsdb_next (lsa))
  589. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  590. timerclear (&res);
  591. if (on->thread_send_dbdesc)
  592. timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
  593. timerstring (&res, duration, sizeof (duration));
  594. vty_out (vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
  595. on->dbdesc_list->count, duration,
  596. (on->thread_send_dbdesc ? "on" : "off"),
  597. VTY_NEWLINE);
  598. for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
  599. lsa = ospf6_lsdb_next (lsa))
  600. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  601. timerclear (&res);
  602. if (on->thread_send_lsreq)
  603. timersub (&on->thread_send_lsreq->u.sands, &now, &res);
  604. timerstring (&res, duration, sizeof (duration));
  605. vty_out (vty, " %d Pending LSAs for LSReq in Time %s [thread %s]%s",
  606. on->lsreq_list->count, duration,
  607. (on->thread_send_lsreq ? "on" : "off"),
  608. VTY_NEWLINE);
  609. for (lsa = ospf6_lsdb_head (on->lsreq_list); lsa;
  610. lsa = ospf6_lsdb_next (lsa))
  611. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  612. timerclear (&res);
  613. if (on->thread_send_lsupdate)
  614. timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
  615. timerstring (&res, duration, sizeof (duration));
  616. vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
  617. on->lsupdate_list->count, duration,
  618. (on->thread_send_lsupdate ? "on" : "off"),
  619. VTY_NEWLINE);
  620. for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
  621. lsa = ospf6_lsdb_next (lsa))
  622. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  623. timerclear (&res);
  624. if (on->thread_send_lsack)
  625. timersub (&on->thread_send_lsack->u.sands, &now, &res);
  626. timerstring (&res, duration, sizeof (duration));
  627. vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s",
  628. on->lsack_list->count, duration,
  629. (on->thread_send_lsack ? "on" : "off"),
  630. VTY_NEWLINE);
  631. for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
  632. lsa = ospf6_lsdb_next (lsa))
  633. vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE);
  634. }
  635. DEFUN (show_ipv6_ospf6_neighbor,
  636. show_ipv6_ospf6_neighbor_cmd,
  637. "show ipv6 ospf6 neighbor",
  638. SHOW_STR
  639. IP6_STR
  640. OSPF6_STR
  641. "Neighbor list\n"
  642. )
  643. {
  644. struct ospf6_neighbor *on;
  645. struct ospf6_interface *oi;
  646. struct ospf6_area *oa;
  647. listnode i, j, k;
  648. void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  649. OSPF6_CMD_CHECK_RUNNING ();
  650. showfunc = ospf6_neighbor_show;
  651. if (argc)
  652. {
  653. if (! strncmp (argv[0], "de", 2))
  654. showfunc = ospf6_neighbor_show_detail;
  655. else if (! strncmp (argv[0], "dr", 2))
  656. showfunc = ospf6_neighbor_show_drchoice;
  657. }
  658. if (showfunc == ospf6_neighbor_show)
  659. vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
  660. "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
  661. "I/F", "State", VTY_NEWLINE);
  662. else if (showfunc == ospf6_neighbor_show_drchoice)
  663. vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  664. "RouterID", "State", "Duration", "DR", "BDR", "I/F",
  665. "State", VTY_NEWLINE);
  666. for (i = listhead (ospf6->area_list); i; nextnode (i))
  667. {
  668. oa = (struct ospf6_area *) getdata (i);
  669. for (j = listhead (oa->if_list); j; nextnode (j))
  670. {
  671. oi = (struct ospf6_interface *) getdata (j);
  672. for (k = listhead (oi->neighbor_list); k; nextnode (k))
  673. {
  674. on = (struct ospf6_neighbor *) getdata (k);
  675. (*showfunc) (vty, on);
  676. }
  677. }
  678. }
  679. return CMD_SUCCESS;
  680. }
  681. ALIAS (show_ipv6_ospf6_neighbor,
  682. show_ipv6_ospf6_neighbor_detail_cmd,
  683. "show ipv6 ospf6 neighbor (detail|drchoice)",
  684. SHOW_STR
  685. IP6_STR
  686. OSPF6_STR
  687. "Neighbor list\n"
  688. "Display details\n"
  689. "Display DR choices\n"
  690. );
  691. DEFUN (show_ipv6_ospf6_neighbor_one,
  692. show_ipv6_ospf6_neighbor_one_cmd,
  693. "show ipv6 ospf6 neighbor A.B.C.D",
  694. SHOW_STR
  695. IP6_STR
  696. OSPF6_STR
  697. "Neighbor list\n"
  698. "Specify Router-ID as IPv4 address notation\n"
  699. )
  700. {
  701. struct ospf6_neighbor *on;
  702. struct ospf6_interface *oi;
  703. struct ospf6_area *oa;
  704. listnode i, j, k;
  705. void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  706. u_int32_t router_id;
  707. OSPF6_CMD_CHECK_RUNNING ();
  708. showfunc = ospf6_neighbor_show_detail;
  709. if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
  710. {
  711. vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
  712. VTY_NEWLINE);
  713. return CMD_SUCCESS;
  714. }
  715. for (i = listhead (ospf6->area_list); i; nextnode (i))
  716. {
  717. oa = (struct ospf6_area *) getdata (i);
  718. for (j = listhead (oa->if_list); j; nextnode (j))
  719. {
  720. oi = (struct ospf6_interface *) getdata (j);
  721. for (k = listhead (oi->neighbor_list); k; nextnode (k))
  722. {
  723. on = (struct ospf6_neighbor *) getdata (k);
  724. if (on->router_id == router_id)
  725. (*showfunc) (vty, on);
  726. }
  727. }
  728. }
  729. return CMD_SUCCESS;
  730. }
  731. void
  732. ospf6_neighbor_init ()
  733. {
  734. install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
  735. install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  736. install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
  737. install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  738. }
  739. DEFUN (debug_ospf6_neighbor,
  740. debug_ospf6_neighbor_cmd,
  741. "debug ospf6 neighbor",
  742. DEBUG_STR
  743. OSPF6_STR
  744. "Debug OSPFv3 Neighbor\n"
  745. )
  746. {
  747. unsigned char level = 0;
  748. if (argc)
  749. {
  750. if (! strncmp (argv[0], "s", 1))
  751. level = OSPF6_DEBUG_NEIGHBOR_STATE;
  752. if (! strncmp (argv[0], "e", 1))
  753. level = OSPF6_DEBUG_NEIGHBOR_EVENT;
  754. }
  755. else
  756. level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
  757. OSPF6_DEBUG_NEIGHBOR_ON (level);
  758. return CMD_SUCCESS;
  759. }
  760. ALIAS (debug_ospf6_neighbor,
  761. debug_ospf6_neighbor_detail_cmd,
  762. "debug ospf6 neighbor (state|event)",
  763. DEBUG_STR
  764. OSPF6_STR
  765. "Debug OSPFv3 Neighbor\n"
  766. "Debug OSPFv3 Neighbor State Change\n"
  767. "Debug OSPFv3 Neighbor Event\n"
  768. );
  769. DEFUN (no_debug_ospf6_neighbor,
  770. no_debug_ospf6_neighbor_cmd,
  771. "no debug ospf6 neighbor",
  772. NO_STR
  773. DEBUG_STR
  774. OSPF6_STR
  775. "Debug OSPFv3 Neighbor\n"
  776. )
  777. {
  778. unsigned char level = 0;
  779. if (argc)
  780. {
  781. if (! strncmp (argv[0], "s", 1))
  782. level = OSPF6_DEBUG_NEIGHBOR_STATE;
  783. if (! strncmp (argv[0], "e", 1))
  784. level = OSPF6_DEBUG_NEIGHBOR_EVENT;
  785. }
  786. else
  787. level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
  788. OSPF6_DEBUG_NEIGHBOR_OFF (level);
  789. return CMD_SUCCESS;
  790. }
  791. ALIAS (no_debug_ospf6_neighbor,
  792. no_debug_ospf6_neighbor_detail_cmd,
  793. "no debug ospf6 neighbor (state|event)",
  794. NO_STR
  795. DEBUG_STR
  796. OSPF6_STR
  797. "Debug OSPFv3 Neighbor\n"
  798. "Debug OSPFv3 Neighbor State Change\n"
  799. "Debug OSPFv3 Neighbor Event\n"
  800. );
  801. int
  802. config_write_ospf6_debug_neighbor (struct vty *vty)
  803. {
  804. if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
  805. IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  806. vty_out (vty, "debug ospf6 neighbor%s", VTY_NEWLINE);
  807. else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
  808. vty_out (vty, "debug ospf6 neighbor state%s", VTY_NEWLINE);
  809. else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  810. vty_out (vty, "debug ospf6 neighbor event%s", VTY_NEWLINE);
  811. return 0;
  812. }
  813. void
  814. install_element_ospf6_debug_neighbor ()
  815. {
  816. install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
  817. install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
  818. install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
  819. install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
  820. install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
  821. install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
  822. install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
  823. install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
  824. }