ospf6_dbex.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /*
  2. * Copyright (C) 1999 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 "ospf6d.h"
  22. /* check validity and put lsa in reqestlist if needed. */
  23. /* returns -1 if SeqNumMismatch required. */
  24. int
  25. ospf6_dbex_check_dbdesc_lsa_header (struct ospf6_lsa_header *lsa_header,
  26. struct ospf6_neighbor *from)
  27. {
  28. struct ospf6_lsa *received = NULL;
  29. struct ospf6_lsa *have = NULL;
  30. received = ospf6_lsa_summary_create
  31. ((struct ospf6_lsa_header__ *) lsa_header);
  32. /* case when received is AS-External though neighbor belongs stub area */
  33. if (lsa_header->type == htons (OSPF6_LSA_TYPE_AS_EXTERNAL) &&
  34. ospf6_area_is_stub (from->ospf6_interface->area))
  35. {
  36. zlog_err ("DbDesc %s receive from %s", from->str, received->str);
  37. zlog_err (" E-bit mismatch: %s", received->str);
  38. ospf6_lsa_delete (received);
  39. return -1;
  40. }
  41. /* if already have newer database copy, check next LSA */
  42. have = ospf6_lsdb_lookup (lsa_header->type, lsa_header->ls_id,
  43. lsa_header->advrtr,
  44. ospf6_lsa_get_scope (lsa_header->type,
  45. from->ospf6_interface));
  46. if (! have)
  47. {
  48. /* if we don't have database copy, add request */
  49. if (IS_OSPF6_DUMP_DBEX)
  50. zlog_info ("Have no database copy, Request");
  51. ospf6_neighbor_request_add (received, from);
  52. }
  53. else if (have)
  54. {
  55. /* if database copy is less recent, add request */
  56. if (ospf6_lsa_check_recent (received, have) < 0)
  57. {
  58. if (IS_OSPF6_DUMP_DBEX)
  59. zlog_info ("Database copy less recent, Request");
  60. ospf6_neighbor_request_add (received, from);
  61. }
  62. }
  63. return 0;
  64. }
  65. /* Direct acknowledgement */
  66. static void
  67. ospf6_dbex_acknowledge_direct (struct ospf6_lsa *lsa,
  68. struct ospf6_neighbor *o6n)
  69. {
  70. struct iovec directack[MAXIOVLIST];
  71. assert (lsa);
  72. if (IS_OSPF6_DUMP_DBEX)
  73. zlog_info ("DBEX: [%s:%s] direct ack %s ",
  74. o6n->str, o6n->ospf6_interface->interface->name,
  75. lsa->str);
  76. /* clear pointers to fragments of packet for direct acknowledgement */
  77. iov_clear (directack, MAXIOVLIST);
  78. /* set pointer of LSA to send */
  79. OSPF6_MESSAGE_ATTACH (directack, lsa->header,
  80. sizeof (struct ospf6_lsa_header));
  81. /* age update and add InfTransDelay */
  82. ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);
  83. /* send unicast packet to neighbor's ipaddress */
  84. ospf6_message_send (OSPF6_MESSAGE_TYPE_LSACK, directack, &o6n->hisaddr,
  85. o6n->ospf6_interface->if_id);
  86. }
  87. /* Delayed acknowledgement */
  88. void
  89. ospf6_dbex_acknowledge_delayed (struct ospf6_lsa *lsa,
  90. struct ospf6_interface *o6i)
  91. {
  92. assert (o6i);
  93. if (IS_OSPF6_DUMP_DBEX)
  94. zlog_info ("DBEX: [%s] delayed ack %s", o6i->interface->name, lsa->str);
  95. /* attach delayed acknowledge list */
  96. ospf6_lsa_age_current (lsa);
  97. ospf6_interface_delayed_ack_add (lsa, o6i);
  98. /* if not yet, schedule delayed acknowledge RxmtInterval later.
  99. timers should be *less than* RxmtInterval
  100. or needless retrans will ensue */
  101. if (o6i->thread_send_lsack_delayed == NULL)
  102. o6i->thread_send_lsack_delayed
  103. = thread_add_timer (master, ospf6_send_lsack_delayed,
  104. o6i, o6i->rxmt_interval - 1);
  105. return;
  106. }
  107. /* RFC2328 section 13 (4):
  108. if MaxAge LSA and if we have no instance, and no neighbor
  109. is in states Exchange or Loading */
  110. /* returns 1 if match this case, else returns 0 */
  111. static int
  112. ospf6_dbex_is_maxage_to_be_dropped (struct ospf6_lsa *received,
  113. struct ospf6_neighbor *from)
  114. {
  115. int count;
  116. if (! IS_LSA_MAXAGE (received))
  117. return 0;
  118. if (ospf6_lsdb_lookup (received->header->type, received->header->id,
  119. received->header->adv_router,
  120. ospf6_lsa_get_scope (received->header->type,
  121. from->ospf6_interface)))
  122. return 0;
  123. if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (received->header->type)))
  124. {
  125. count = 0;
  126. (*from->ospf6_interface->foreach_nei)
  127. (from->ospf6_interface, &count, NBS_EXCHANGE, ospf6_count_state);
  128. (*from->ospf6_interface->foreach_nei)
  129. (from->ospf6_interface, &count, NBS_LOADING, ospf6_count_state);
  130. if (count)
  131. return 0;
  132. }
  133. else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (received->header->type)))
  134. {
  135. count = 0;
  136. (*from->ospf6_interface->area->foreach_nei)
  137. (from->ospf6_interface->area, &count, NBS_EXCHANGE, ospf6_count_state);
  138. (*from->ospf6_interface->area->foreach_nei)
  139. (from->ospf6_interface->area, &count, NBS_LOADING, ospf6_count_state);
  140. if (count)
  141. return 0;
  142. }
  143. else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (received->header->type)))
  144. {
  145. count = 0;
  146. (*from->ospf6_interface->area->ospf6->foreach_nei)
  147. (from->ospf6_interface->area->ospf6, &count, NBS_EXCHANGE,
  148. ospf6_count_state);
  149. (*from->ospf6_interface->area->ospf6->foreach_nei)
  150. (from->ospf6_interface->area->ospf6, &count, NBS_LOADING,
  151. ospf6_count_state);
  152. if (count)
  153. return 0;
  154. }
  155. return 1;
  156. }
  157. static void
  158. ospf6_dbex_remove_retrans (void *arg, int val, void *obj)
  159. {
  160. struct ospf6_lsa *rem;
  161. struct ospf6_neighbor *nei = (struct ospf6_neighbor *) obj;
  162. struct ospf6_lsa *lsa = (struct ospf6_lsa *) arg;
  163. rem = ospf6_lsdb_lookup_lsdb (lsa->header->type, lsa->header->id,
  164. lsa->header->adv_router, nei->retrans_list);
  165. if (rem)
  166. {
  167. ospf6_neighbor_retrans_remove (rem, nei);
  168. ospf6_maxage_remover ();
  169. }
  170. }
  171. void
  172. ospf6_dbex_remove_from_all_retrans_list (struct ospf6_lsa *lsa)
  173. {
  174. struct ospf6_interface *o6i;
  175. struct ospf6_area *o6a;
  176. if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (htons (lsa->header->type)))
  177. {
  178. o6i = lsa->scope;
  179. (*o6i->foreach_nei) (o6i, lsa, 0, ospf6_dbex_remove_retrans);
  180. }
  181. else if (OSPF6_LSA_IS_SCOPE_AREA (htons (lsa->header->type)))
  182. {
  183. o6a = lsa->scope;
  184. (*o6a->foreach_nei) (o6a, lsa, 0, ospf6_dbex_remove_retrans);
  185. }
  186. else if (OSPF6_LSA_IS_SCOPE_AS (htons (lsa->header->type)))
  187. {
  188. (*ospf6->foreach_nei) (ospf6, lsa, 0, ospf6_dbex_remove_retrans);
  189. }
  190. }
  191. /* RFC2328 section 13 */
  192. void
  193. ospf6_dbex_receive_lsa (struct ospf6_lsa_header *lsa_header,
  194. struct ospf6_neighbor *from)
  195. {
  196. struct ospf6_lsa *received, *have, *rem;
  197. struct timeval now;
  198. int ismore_recent, acktype;
  199. unsigned short cksum;
  200. struct ospf6_lsa_slot *slot;
  201. received = have = (struct ospf6_lsa *)NULL;
  202. ismore_recent = -1;
  203. recent_reason = "no instance";
  204. zlog_info ("Receive LSA (header -> %p)", lsa_header);
  205. /* make lsa structure for received lsa */
  206. received = ospf6_lsa_create (lsa_header);
  207. /* set LSA scope */
  208. if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (htons (lsa_header->type)))
  209. received->scope = from->ospf6_interface;
  210. else if (OSPF6_LSA_IS_SCOPE_AREA (htons (lsa_header->type)))
  211. received->scope = from->ospf6_interface->area;
  212. else if (OSPF6_LSA_IS_SCOPE_AS (htons (lsa_header->type)))
  213. received->scope = from->ospf6_interface->area->ospf6;
  214. /* (1) LSA Checksum */
  215. cksum = ntohs (lsa_header->checksum);
  216. if (ntohs (ospf6_lsa_checksum (lsa_header)) != cksum)
  217. {
  218. if (IS_OSPF6_DUMP_DBEX)
  219. zlog_info ("DBEX: received %s from %s%%%s"
  220. ": wrong checksum, drop",
  221. received->str, from->str,
  222. from->ospf6_interface->interface->name);
  223. ospf6_lsa_delete (received);
  224. return;
  225. }
  226. /* (3) Ebit Missmatch: AS-External-LSA */
  227. if (lsa_header->type == htons (OSPF6_LSA_TYPE_AS_EXTERNAL) &&
  228. ospf6_area_is_stub (from->ospf6_interface->area))
  229. {
  230. if (IS_OSPF6_DUMP_DBEX)
  231. zlog_info ("DBEX: received %s from %s%%%s"
  232. ": E-bit mismatch, drop",
  233. received->str, from->str,
  234. from->ospf6_interface->interface->name);
  235. ospf6_lsa_delete (received);
  236. return;
  237. }
  238. /* (4) if MaxAge LSA and if we have no instance, and no neighbor
  239. is in states Exchange or Loading */
  240. if (ospf6_dbex_is_maxage_to_be_dropped (received, from))
  241. {
  242. /* log */
  243. if (IS_OSPF6_DUMP_DBEX)
  244. zlog_info ("DBEX: received %s from %s%%%s"
  245. ": MaxAge, no instance, no neighbor exchange, drop",
  246. received->str, from->str,
  247. from->ospf6_interface->interface->name);
  248. /* a) Acknowledge back to neighbor (13.5) */
  249. /* Direct Acknowledgement */
  250. ospf6_dbex_acknowledge_direct (received, from);
  251. /* b) Discard */
  252. ospf6_lsa_delete (received);
  253. return;
  254. }
  255. /* (5) */
  256. /* lookup the same database copy in lsdb */
  257. have = ospf6_lsdb_lookup (lsa_header->type, lsa_header->ls_id,
  258. lsa_header->advrtr,
  259. ospf6_lsa_get_scope (lsa_header->type,
  260. from->ospf6_interface));
  261. if (have)
  262. {
  263. ismore_recent = ospf6_lsa_check_recent (received, have);
  264. if (ntohl (received->header->seqnum) == ntohl (have->header->seqnum))
  265. SET_FLAG (received->flag, OSPF6_LSA_FLAG_DUPLICATE);
  266. }
  267. /* if no database copy or received is more recent */
  268. if (!have || ismore_recent < 0)
  269. {
  270. /* in case we have no database copy */
  271. ismore_recent = -1;
  272. /* (a) MinLSArrival check */
  273. gettimeofday (&now, (struct timezone *)NULL);
  274. if (have && SEC_TVDIFF (&now, &have->installed) < OSPF6_MIN_LS_ARRIVAL)
  275. {
  276. //if (IS_OSPF6_DUMP_DBEX)
  277. zlog_info ("DBEX: Receive new LSA from %s: %s seq: %#x age: %d "
  278. "within MinLSArrival, drop: %ld.%06ld",
  279. from->str, received->str,
  280. ntohl (received->header->seqnum),
  281. ntohs (received->header->age),
  282. now.tv_sec, now.tv_usec);
  283. /* this will do free this lsa */
  284. ospf6_lsa_delete (received);
  285. return; /* examin next lsa */
  286. }
  287. //if (IS_OSPF6_DUMP_DBEX)
  288. zlog_info ("DBEX: Receive new LSA from %s: %s seq: %#x age: %d: "
  289. "%ld.%06ld",
  290. from->str, received->str,
  291. ntohl (received->header->seqnum),
  292. ntohs (received->header->age),
  293. now.tv_sec, now.tv_usec);
  294. /* (b) immediately flood */
  295. ospf6_dbex_flood (received, from);
  296. #if 0
  297. /* Because New LSDB do not permit two LSA having the same identifier
  298. exist in a LSDB list, above ospf6_dbex_flood() will remove
  299. the old instance automatically. thus bellow is not needed. */
  300. /* (c) remove database copy from all neighbor's retranslist */
  301. if (have)
  302. ospf6_dbex_remove_from_all_retrans_list (have);
  303. #endif
  304. /* (d), installing lsdb, which may cause routing
  305. table calculation (replacing database copy) */
  306. ospf6_lsdb_install (received);
  307. /* (e) possibly acknowledge */
  308. acktype = ack_type (received, ismore_recent, from);
  309. if (acktype == DIRECT_ACK)
  310. {
  311. if (IS_OSPF6_DUMP_DBEX)
  312. zlog_info ("DBEX: Direct Ack to %s", from->str);
  313. ospf6_dbex_acknowledge_direct (received, from);
  314. }
  315. else if (acktype == DELAYED_ACK)
  316. {
  317. if (IS_OSPF6_DUMP_DBEX)
  318. zlog_info ("DBEX: Delayed Ack to %s", from->str);
  319. ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface);
  320. }
  321. else
  322. {
  323. if (IS_OSPF6_DUMP_DBEX)
  324. zlog_info ("DBEX: No Ack to %s", from->str);
  325. }
  326. /* (f) */
  327. /* Self Originated LSA, section 13.4 */
  328. if (received->lsa_hdr->lsh_advrtr == ospf6->router_id
  329. && (! have || ismore_recent < 0))
  330. {
  331. /* we're going to make new lsa or to flush this LSA. */
  332. if (IS_OSPF6_DUMP_DBEX)
  333. zlog_info ("DBEX: Self-originated LSA %s from %s:%s",
  334. received->str, from->str,
  335. from->ospf6_interface->interface->name);
  336. if (IS_OSPF6_DUMP_DBEX)
  337. zlog_info ("DBEX: %s: Make new one/Flush", received->str);
  338. SET_FLAG (received->flag, OSPF6_LSA_FLAG_REFRESH);
  339. slot = ospf6_lsa_slot_get (received->header->type);
  340. if (slot && slot->func_refresh)
  341. {
  342. (*slot->func_refresh) (received);
  343. return;
  344. }
  345. zlog_warn ("Can't Refresh LSA: Unknown type: %#x, Flush",
  346. ntohs (received->header->type));
  347. ospf6_lsa_premature_aging (received);
  348. return;
  349. }
  350. }
  351. else if (ospf6_lsdb_lookup_lsdb (received->header->type,
  352. received->header->id,
  353. received->header->adv_router,
  354. from->request_list))
  355. /* (6) if there is instance on sending neighbor's request list */
  356. {
  357. /* if no database copy, should go above state (5) */
  358. assert (have);
  359. zlog_warn ("DBEX: [%s:%s] received LSA %s is not newer,"
  360. " and is on his requestlist: Generate BadLSReq",
  361. from->str, from->ospf6_interface->interface->name,
  362. received->str);
  363. /* BadLSReq */
  364. thread_add_event (master, bad_lsreq, from, 0);
  365. ospf6_lsa_delete (received);
  366. }
  367. else if (ismore_recent == 0) /* (7) if neither is more recent */
  368. {
  369. /* (a) if on retranslist, Treat this LSA as an Ack: Implied Ack */
  370. rem = ospf6_lsdb_lookup_lsdb (received->header->type,
  371. received->header->id,
  372. received->header->adv_router,
  373. from->retrans_list);
  374. if (rem)
  375. {
  376. if (IS_OSPF6_DUMP_DBEX)
  377. zlog_info ("DBEX: Implied Ack from %s, (remove retrans)",
  378. from->str);
  379. SET_FLAG (received->flag, OSPF6_LSA_FLAG_IMPLIEDACK);
  380. ospf6_neighbor_retrans_remove (rem, from);
  381. }
  382. /* (b) possibly acknowledge */
  383. acktype = ack_type (received, ismore_recent, from);
  384. if (acktype == DIRECT_ACK)
  385. {
  386. if (IS_OSPF6_DUMP_DBEX)
  387. zlog_info ("DBEX: Direct Ack to %s", from->str);
  388. ospf6_dbex_acknowledge_direct (received, from);
  389. }
  390. else if (acktype == DELAYED_ACK)
  391. {
  392. if (IS_OSPF6_DUMP_DBEX)
  393. zlog_info ("DBEX: Delayed Ack to %s", from->str);
  394. ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface);
  395. }
  396. else
  397. {
  398. if (IS_OSPF6_DUMP_DBEX)
  399. zlog_info ("DBEX: No Ack to %s", from->str);
  400. }
  401. ospf6_lsa_delete (received);
  402. }
  403. else /* (8) previous database copy is more recent */
  404. {
  405. /* If Seqnumber Wrapping, simply discard
  406. Otherwise, Send database copy of this LSA to this neighbor */
  407. if (! IS_LSA_MAXAGE (received) ||
  408. received->lsa_hdr->lsh_seqnum != MAX_SEQUENCE_NUMBER)
  409. {
  410. if (IS_OSPF6_DUMP_DBEX)
  411. zlog_info ("DBEX: database is more recent: send back to %s",
  412. from->str);
  413. ospf6_send_lsupdate_direct (have, from);
  414. }
  415. ospf6_lsa_delete (received);
  416. }
  417. }
  418. /* RFC2328: Table 19: Sending link state acknowledgements. */
  419. int
  420. ack_type (struct ospf6_lsa *newp, int ismore_recent,
  421. struct ospf6_neighbor *from)
  422. {
  423. struct ospf6_interface *ospf6_interface;
  424. struct ospf6_lsa *have;
  425. int count;
  426. assert (from && from->ospf6_interface);
  427. ospf6_interface = from->ospf6_interface;
  428. if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_FLOODBACK))
  429. return NO_ACK;
  430. if (ismore_recent < 0)
  431. {
  432. if (ospf6_interface->state != IFS_BDR)
  433. return DELAYED_ACK;
  434. if (ospf6_interface->dr == from->router_id)
  435. return DELAYED_ACK;
  436. return NO_ACK;
  437. }
  438. if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) &&
  439. CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK))
  440. {
  441. if (ospf6_interface->state != IFS_BDR)
  442. return NO_ACK;
  443. if (ospf6_interface->dr == from->router_id)
  444. return DELAYED_ACK;
  445. return NO_ACK;
  446. }
  447. if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) &&
  448. ! CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK))
  449. return DIRECT_ACK;
  450. have = ospf6_lsdb_lookup (newp->header->type, newp->header->id,
  451. newp->header->adv_router,
  452. ospf6_lsa_get_scope (newp->header->type,
  453. from->ospf6_interface));
  454. count = 0;
  455. ospf6->foreach_nei (ospf6, &count, NBS_EXCHANGE, ospf6_count_state);
  456. ospf6->foreach_nei (ospf6, &count, NBS_LOADING, ospf6_count_state);
  457. if (IS_LSA_MAXAGE (newp) && have == NULL && count == 0)
  458. return DIRECT_ACK;
  459. return NO_ACK;
  460. }
  461. static void
  462. ospf6_dbex_flood_linklocal (struct ospf6_lsa *lsa, struct ospf6_interface *o6i,
  463. struct ospf6_neighbor *from)
  464. {
  465. struct ospf6_neighbor *o6n = (struct ospf6_neighbor *) NULL;
  466. int ismore_recent, addretrans = 0;
  467. listnode n;
  468. struct ospf6_lsa *req;
  469. /* (1) for each neighbor */
  470. for (n = listhead (o6i->neighbor_list); n; nextnode (n))
  471. {
  472. o6n = (struct ospf6_neighbor *) getdata (n);
  473. /* (a) */
  474. if (o6n->state < NBS_EXCHANGE)
  475. continue; /* examin next neighbor */
  476. /* (b) */
  477. if (o6n->state == NBS_EXCHANGE
  478. || o6n->state == NBS_LOADING)
  479. {
  480. req = ospf6_lsdb_lookup_lsdb (lsa->header->type,
  481. lsa->header->id,
  482. lsa->header->adv_router,
  483. o6n->request_list);
  484. if (req)
  485. {
  486. ismore_recent = ospf6_lsa_check_recent (lsa, req);
  487. if (ismore_recent > 0)
  488. {
  489. continue; /* examin next neighbor */
  490. }
  491. else if (ismore_recent == 0)
  492. {
  493. ospf6_neighbor_request_remove (req, o6n);
  494. continue; /* examin next neighbor */
  495. }
  496. else /* ismore_recent < 0 (the new LSA is more recent) */
  497. {
  498. ospf6_neighbor_request_remove (req, o6n);
  499. }
  500. }
  501. }
  502. /* (c) */
  503. if (from && from->router_id == o6n->router_id)
  504. continue; /* examin next neighbor */
  505. /* (d) add retranslist */
  506. if (IS_OSPF6_DUMP_DBEX)
  507. zlog_info ("DBEX: schedule flooding [%s:%s]: %s",
  508. o6n->str, o6n->ospf6_interface->interface->name,
  509. lsa->str);
  510. ospf6_neighbor_retrans_add (lsa, o6n);
  511. addretrans++;
  512. if (o6n->send_update == (struct thread *) NULL)
  513. o6n->send_update =
  514. thread_add_timer (master, ospf6_send_lsupdate_rxmt, o6n,
  515. o6n->ospf6_interface->rxmt_interval);
  516. }
  517. /* (2) */
  518. if (addretrans == 0)
  519. return; /* examin next interface */
  520. if (from && from->ospf6_interface == o6i)
  521. {
  522. if (IS_OSPF6_DUMP_DBEX)
  523. zlog_info ("DBEX: flood back %s to %s",
  524. lsa->str, o6i->interface->name);
  525. /* note occurence of floodback */
  526. SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_FLOODBACK);
  527. }
  528. /* (3) */
  529. if (from && from->ospf6_interface == o6i)
  530. {
  531. /* if from DR or BDR, don't need to flood this interface */
  532. if (from->router_id == from->ospf6_interface->dr ||
  533. from->router_id == from->ospf6_interface->bdr)
  534. return; /* examin next interface */
  535. }
  536. /* (4) if I'm BDR, DR will flood this interface */
  537. if (from && from->ospf6_interface == o6i
  538. && o6i->state == IFS_BDR)
  539. return; /* examin next interface */
  540. if (IS_OSPF6_DUMP_DBEX)
  541. zlog_info ("Flood to interface %s", o6i->interface->name);
  542. /* (5) send LinkState Update */
  543. ospf6_send_lsupdate_flood (lsa, o6i);
  544. return;
  545. }
  546. /* RFC2328 section 13.3 */
  547. static void
  548. ospf6_dbex_flood_area (struct ospf6_lsa *lsa, struct ospf6_area *area,
  549. struct ospf6_neighbor *from)
  550. {
  551. listnode n;
  552. struct ospf6_interface *ospf6_interface;
  553. assert (lsa && lsa->lsa_hdr && area);
  554. /* for each eligible ospf_ifs */
  555. for (n = listhead (area->if_list); n; nextnode (n))
  556. {
  557. ospf6_interface = (struct ospf6_interface *) getdata (n);
  558. ospf6_dbex_flood_linklocal (lsa, ospf6_interface, from);
  559. }
  560. }
  561. static void
  562. ospf6_dbex_flood_as (struct ospf6_lsa *lsa, struct ospf6 *ospf6,
  563. struct ospf6_neighbor *from)
  564. {
  565. listnode n;
  566. struct ospf6_area *o6a;
  567. assert (lsa && lsa->lsa_hdr && ospf6);
  568. /* for each attached area */
  569. for (n = listhead (ospf6->area_list); n; nextnode (n))
  570. {
  571. o6a = (struct ospf6_area *) getdata (n);
  572. ospf6_dbex_flood_area (lsa, o6a, from);
  573. }
  574. }
  575. /* flood ospf6_lsa within appropriate scope */
  576. void
  577. ospf6_dbex_flood (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
  578. {
  579. struct ospf6_area *o6a;
  580. struct ospf6_interface *o6i;
  581. struct ospf6 *o6;
  582. struct ospf6_lsa_header *lsa_header;
  583. lsa_header = (struct ospf6_lsa_header *) lsa->lsa_hdr;
  584. if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa_header->type)))
  585. {
  586. o6i = (struct ospf6_interface *) lsa->scope;
  587. assert (o6i);
  588. if (IS_OSPF6_DUMP_DBEX)
  589. zlog_info ("Flood Linklocal: %s", o6i->interface->name);
  590. ospf6_dbex_flood_linklocal (lsa, o6i, from);
  591. }
  592. else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa_header->type)))
  593. {
  594. o6a = (struct ospf6_area *) lsa->scope;
  595. assert (o6a);
  596. if (IS_OSPF6_DUMP_DBEX)
  597. zlog_info ("Flood Area: %s", o6a->str);
  598. ospf6_dbex_flood_area (lsa, o6a, from);
  599. }
  600. else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa_header->type)))
  601. {
  602. o6 = (struct ospf6 *) lsa->scope;
  603. assert (o6);
  604. if (IS_OSPF6_DUMP_DBEX)
  605. zlog_info ("Flood AS");
  606. ospf6_dbex_flood_as (lsa, o6, from);
  607. }
  608. else
  609. {
  610. zlog_warn ("Can't Flood %s: scope unknown", lsa->str);
  611. }
  612. }