ospf6_neighbor.c 29 KB

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