ospf6_neighbor.c 26 KB

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