]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_flood.c
Merge pull request #9028 from mobash-rasool/ospfv3-asbr-summarisation
[mirror_frr.git] / ospf6d / ospf6_flood.c
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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "thread.h"
25 #include "linklist.h"
26 #include "vty.h"
27 #include "command.h"
28
29 #include "ospf6d.h"
30 #include "ospf6_proto.h"
31 #include "ospf6_lsa.h"
32 #include "ospf6_lsdb.h"
33 #include "ospf6_message.h"
34 #include "ospf6_route.h"
35 #include "ospf6_spf.h"
36
37 #include "ospf6_top.h"
38 #include "ospf6_area.h"
39 #include "ospf6_interface.h"
40 #include "ospf6_neighbor.h"
41
42 #include "ospf6_flood.h"
43 #include "ospf6_nssa.h"
44
45 unsigned char conf_debug_ospf6_flooding;
46
47 struct ospf6_lsdb *ospf6_get_scoped_lsdb(struct ospf6_lsa *lsa)
48 {
49 struct ospf6_lsdb *lsdb = NULL;
50 switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
51 case OSPF6_SCOPE_LINKLOCAL:
52 lsdb = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb;
53 break;
54 case OSPF6_SCOPE_AREA:
55 lsdb = OSPF6_AREA(lsa->lsdb->data)->lsdb;
56 break;
57 case OSPF6_SCOPE_AS:
58 lsdb = OSPF6_PROCESS(lsa->lsdb->data)->lsdb;
59 break;
60 default:
61 assert(0);
62 break;
63 }
64 return lsdb;
65 }
66
67 struct ospf6_lsdb *ospf6_get_scoped_lsdb_self(struct ospf6_lsa *lsa)
68 {
69 struct ospf6_lsdb *lsdb_self = NULL;
70 switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
71 case OSPF6_SCOPE_LINKLOCAL:
72 lsdb_self = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb_self;
73 break;
74 case OSPF6_SCOPE_AREA:
75 lsdb_self = OSPF6_AREA(lsa->lsdb->data)->lsdb_self;
76 break;
77 case OSPF6_SCOPE_AS:
78 lsdb_self = OSPF6_PROCESS(lsa->lsdb->data)->lsdb_self;
79 break;
80 default:
81 assert(0);
82 break;
83 }
84 return lsdb_self;
85 }
86
87 void ospf6_lsa_originate(struct ospf6_lsa *lsa)
88 {
89 struct ospf6_lsa *old;
90 struct ospf6_lsdb *lsdb_self;
91
92 if (lsa->header->adv_router == INADDR_ANY) {
93 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
94 zlog_debug(
95 "Refusing to originate LSA (zero router ID): %s",
96 lsa->name);
97
98 ospf6_lsa_delete(lsa);
99 return;
100 }
101
102 /* find previous LSA */
103 old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
104 lsa->header->adv_router, lsa->lsdb);
105
106 /* if the new LSA does not differ from previous,
107 suppress this update of the LSA */
108 if (old && !OSPF6_LSA_IS_DIFFER(lsa, old)) {
109 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
110 zlog_debug("Suppress updating LSA: %s", lsa->name);
111 ospf6_lsa_delete(lsa);
112 return;
113 }
114
115 /* store it in the LSDB for self-originated LSAs */
116 lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
117 ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self);
118
119 THREAD_OFF(lsa->refresh);
120 thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
121 &lsa->refresh);
122
123 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
124 || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) {
125 zlog_debug("LSA Originate:");
126 ospf6_lsa_header_print(lsa);
127 }
128
129 ospf6_install_lsa(lsa);
130 ospf6_flood(NULL, lsa);
131 }
132
133 void ospf6_lsa_originate_process(struct ospf6_lsa *lsa, struct ospf6 *process)
134 {
135 lsa->lsdb = process->lsdb;
136 ospf6_lsa_originate(lsa);
137 }
138
139 void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
140 {
141 lsa->lsdb = oa->lsdb;
142 ospf6_lsa_originate(lsa);
143 }
144
145 void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa,
146 struct ospf6_interface *oi)
147 {
148 lsa->lsdb = oi->lsdb;
149 ospf6_lsa_originate(lsa);
150 }
151
152 void ospf6_remove_id_from_external_id_table(struct ospf6 *ospf6,
153 uint32_t id)
154 {
155 struct prefix prefix_id;
156 struct route_node *node;
157
158 /* remove binding in external_id_table */
159 prefix_id.family = AF_INET;
160 prefix_id.prefixlen = 32;
161 prefix_id.u.prefix4.s_addr = id;
162 node = route_node_lookup(ospf6->external_id_table, &prefix_id);
163 assert(node);
164 node->info = NULL;
165 route_unlock_node(node); /* to free the lookup lock */
166 route_unlock_node(node); /* to free the original lock */
167
168 }
169
170 void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
171 {
172 ospf6_lsa_purge(lsa);
173
174 ospf6_remove_id_from_external_id_table(ospf6, lsa->header->id);
175 }
176
177 void ospf6_lsa_purge(struct ospf6_lsa *lsa)
178 {
179 struct ospf6_lsa *self;
180 struct ospf6_lsdb *lsdb_self;
181
182 /* remove it from the LSDB for self-originated LSAs */
183 lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
184 self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
185 lsa->header->adv_router, lsdb_self);
186 if (self) {
187 THREAD_OFF(self->expire);
188 THREAD_OFF(self->refresh);
189 ospf6_lsdb_remove(self, lsdb_self);
190 }
191
192 ospf6_lsa_premature_aging(lsa);
193 }
194
195 /* Puring Multi Link-State IDs LSAs:
196 * Same Advertising Router with Multiple Link-State IDs
197 * LSAs, purging require to traverse all Link-State IDs
198 */
199 void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa, struct ospf6_lsa *lsa)
200 {
201 int ls_id = 0;
202 struct ospf6_lsa *lsa_next;
203 uint16_t type;
204
205 type = lsa->header->type;
206
207 ospf6_lsa_purge(lsa);
208
209 lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
210 oa->ospf6->router_id, oa->lsdb);
211 while (lsa_next) {
212 ospf6_lsa_purge(lsa_next);
213 lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
214 oa->ospf6->router_id, oa->lsdb);
215 }
216 }
217
218 void ospf6_increment_retrans_count(struct ospf6_lsa *lsa)
219 {
220 /* The LSA must be the original one (see the description
221 in ospf6_decrement_retrans_count () below) */
222 lsa->retrans_count++;
223 }
224
225 void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa)
226 {
227 struct ospf6_lsdb *lsdb;
228 struct ospf6_lsa *orig;
229
230 /* The LSA must be on the retrans-list of a neighbor. It means
231 the "lsa" is a copied one, and we have to decrement the
232 retransmission count of the original one (instead of this "lsa"'s).
233 In order to find the original LSA, first we have to find
234 appropriate LSDB that have the original LSA. */
235 lsdb = ospf6_get_scoped_lsdb(lsa);
236
237 /* Find the original LSA of which the retrans_count should be
238 * decremented */
239 orig = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
240 lsa->header->adv_router, lsdb);
241 if (orig) {
242 orig->retrans_count--;
243 assert(orig->retrans_count >= 0);
244 }
245 }
246
247 /* RFC2328 section 13.2 Installing LSAs in the database */
248 void ospf6_install_lsa(struct ospf6_lsa *lsa)
249 {
250 struct timeval now;
251 struct ospf6_lsa *old;
252 struct ospf6_area *area = NULL;
253
254 /* Remove the old instance from all neighbors' Link state
255 retransmission list (RFC2328 13.2 last paragraph) */
256 old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
257 lsa->header->adv_router, lsa->lsdb);
258 if (old) {
259 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) {
260 if (IS_OSPF6_DEBUG_NSSA)
261 zlog_debug("%s : old LSA %s", __func__,
262 lsa->name);
263 lsa->external_lsa_id = old->external_lsa_id;
264 }
265 THREAD_OFF(old->expire);
266 THREAD_OFF(old->refresh);
267 ospf6_flood_clear(old);
268 }
269
270 monotime(&now);
271 if (!OSPF6_LSA_IS_MAXAGE(lsa)) {
272 lsa->expire = NULL;
273 thread_add_timer(master, ospf6_lsa_expire, lsa,
274 OSPF_LSA_MAXAGE + lsa->birth.tv_sec
275 - now.tv_sec,
276 &lsa->expire);
277 } else
278 lsa->expire = NULL;
279
280 if (OSPF6_LSA_IS_SEQWRAP(lsa)
281 && !(CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)
282 && lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER))) {
283 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
284 zlog_debug("lsa install wrapping: sequence 0x%x",
285 ntohl(lsa->header->seqnum));
286 SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
287 /* in lieu of premature_aging, since we do not want to recreate
288 * this lsa
289 * and/or mess with timers etc, we just want to wrap the
290 * sequence number
291 * and reflood the lsa before continuing.
292 * NOTE: Flood needs to be called right after this function
293 * call, by the
294 * caller
295 */
296 lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
297 lsa->header->age = htons(OSPF_LSA_MAXAGE);
298 ospf6_lsa_checksum(lsa->header);
299 }
300
301 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
302 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
303 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
304 __func__, lsa->name, ntohs(lsa->header->age),
305 ntohl(lsa->header->seqnum));
306
307 /* actually install */
308 lsa->installed = now;
309 ospf6_lsdb_add(lsa, lsa->lsdb);
310
311 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) {
312 area = OSPF6_AREA(lsa->lsdb->data);
313 ospf6_translated_nssa_refresh(area, lsa, NULL);
314 ospf6_schedule_abr_task(area->ospf6);
315 }
316
317 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) {
318 area = OSPF6_AREA(lsa->lsdb->data);
319 if (old == NULL) {
320 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
321 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
322 zlog_debug("%s: New router LSA %s", __func__,
323 lsa->name);
324 ospf6_abr_nssa_check_status(area->ospf6);
325 }
326 }
327 return;
328 }
329
330 /* RFC2740 section 3.5.2. Sending Link State Update packets */
331 /* RFC2328 section 13.3 Next step in the flooding procedure */
332 void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
333 struct ospf6_interface *oi)
334 {
335 struct listnode *node, *nnode;
336 struct ospf6_neighbor *on;
337 struct ospf6_lsa *req, *old;
338 int retrans_added = 0;
339 int is_debug = 0;
340
341 if (IS_OSPF6_DEBUG_FLOODING
342 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) {
343 is_debug++;
344 zlog_debug("Flooding on %s: %s", oi->interface->name,
345 lsa->name);
346 }
347
348 /* (1) For each neighbor */
349 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
350 if (is_debug)
351 zlog_debug("To neighbor %s", on->name);
352
353 /* (a) if neighbor state < Exchange, examin next */
354 if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
355 if (is_debug)
356 zlog_debug(
357 "Neighbor state less than ExChange, next neighbor");
358 continue;
359 }
360
361 /* (b) if neighbor not yet Full, check request-list */
362 if (on->state != OSPF6_NEIGHBOR_FULL) {
363 if (is_debug)
364 zlog_debug("Neighbor not yet Full");
365
366 req = ospf6_lsdb_lookup(
367 lsa->header->type, lsa->header->id,
368 lsa->header->adv_router, on->request_list);
369 if (req == NULL) {
370 if (is_debug)
371 zlog_debug(
372 "Not on request-list for this neighbor");
373 /* fall through */
374 } else {
375 /* If new LSA less recent, examin next neighbor
376 */
377 if (ospf6_lsa_compare(lsa, req) > 0) {
378 if (is_debug)
379 zlog_debug(
380 "Requesting is older, next neighbor");
381 continue;
382 }
383
384 /* If the same instance, delete from
385 request-list and
386 examin next neighbor */
387 if (ospf6_lsa_compare(lsa, req) == 0) {
388 if (is_debug)
389 zlog_debug(
390 "Requesting the same, remove it, next neighbor");
391 if (req == on->last_ls_req) {
392 /* sanity check refcount */
393 assert(req->lock >= 2);
394 req = ospf6_lsa_unlock(req);
395 on->last_ls_req = NULL;
396 }
397 if (req)
398 ospf6_lsdb_remove(
399 req, on->request_list);
400 ospf6_check_nbr_loading(on);
401 continue;
402 }
403
404 /* If the new LSA is more recent, delete from
405 * request-list */
406 if (ospf6_lsa_compare(lsa, req) < 0) {
407 if (is_debug)
408 zlog_debug(
409 "Received is newer, remove requesting");
410 if (req == on->last_ls_req) {
411 req = ospf6_lsa_unlock(req);
412 on->last_ls_req = NULL;
413 }
414 if (req)
415 ospf6_lsdb_remove(req,
416 on->request_list);
417 ospf6_check_nbr_loading(on);
418 /* fall through */
419 }
420 }
421 }
422
423 /* (c) If the new LSA was received from this neighbor,
424 examin next neighbor */
425 if (from == on) {
426 if (is_debug)
427 zlog_debug(
428 "Received is from the neighbor, next neighbor");
429 continue;
430 }
431
432 if ((oi->area->ospf6->inst_shutdown)
433 || CHECK_FLAG(lsa->flag, OSPF6_LSA_FLUSH)) {
434 if (is_debug)
435 zlog_debug(
436 "%s: Send LSA %s (age %d) update now",
437 __func__, lsa->name,
438 ntohs(lsa->header->age));
439 ospf6_lsupdate_send_neighbor_now(on, lsa);
440 continue;
441 } else {
442 /* (d) add retrans-list, schedule retransmission */
443 if (is_debug)
444 zlog_debug("Add retrans-list of neighbor %s ",
445 on->name);
446
447 /* Do not increment the retrans count if the lsa is
448 * already present in the retrans list.
449 */
450 old = ospf6_lsdb_lookup(
451 lsa->header->type, lsa->header->id,
452 lsa->header->adv_router, on->retrans_list);
453 if (!old) {
454 if (is_debug)
455 zlog_debug(
456 "Increment %s from retrans_list of %s",
457 lsa->name, on->name);
458 ospf6_increment_retrans_count(lsa);
459 ospf6_lsdb_add(ospf6_lsa_copy(lsa),
460 on->retrans_list);
461 thread_add_timer(
462 master, ospf6_lsupdate_send_neighbor,
463 on, on->ospf6_if->rxmt_interval,
464 &on->thread_send_lsupdate);
465 retrans_added++;
466 }
467 }
468 }
469
470 /* (2) examin next interface if not added to retrans-list */
471 if (retrans_added == 0) {
472 if (is_debug)
473 zlog_debug(
474 "No retransmission scheduled, next interface %s",
475 oi->interface->name);
476 return;
477 }
478
479 /* (3) If the new LSA was received on this interface,
480 and it was from DR or BDR, examin next interface */
481 if (from && from->ospf6_if == oi
482 && (from->router_id == oi->drouter
483 || from->router_id == oi->bdrouter)) {
484 if (is_debug)
485 zlog_debug(
486 "Received is from the I/F's DR or BDR, next interface");
487 return;
488 }
489
490 /* (4) If the new LSA was received on this interface,
491 and the interface state is BDR, examin next interface */
492 if (from && from->ospf6_if == oi) {
493 if (oi->state == OSPF6_INTERFACE_BDR) {
494 if (is_debug)
495 zlog_debug(
496 "Received is from the I/F, itself BDR, next interface");
497 return;
498 }
499 SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
500 }
501
502 /* (5) flood the LSA out the interface. */
503 if (is_debug)
504 zlog_debug("Schedule flooding for the interface");
505 if ((oi->type == OSPF_IFTYPE_BROADCAST)
506 || (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
507 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list);
508 thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
509 &oi->thread_send_lsupdate);
510 } else {
511 /* reschedule retransmissions to all neighbors */
512 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
513 THREAD_OFF(on->thread_send_lsupdate);
514 on->thread_send_lsupdate = NULL;
515 thread_add_event(master, ospf6_lsupdate_send_neighbor,
516 on, 0, &on->thread_send_lsupdate);
517 }
518 }
519 }
520
521 void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
522 struct ospf6_area *oa)
523 {
524 struct listnode *node, *nnode;
525 struct ospf6_interface *oi;
526
527 for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
528 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
529 && oi != OSPF6_INTERFACE(lsa->lsdb->data))
530 continue;
531
532 ospf6_flood_interface(from, lsa, oi);
533 }
534 }
535
536 static void ospf6_flood_process(struct ospf6_neighbor *from,
537 struct ospf6_lsa *lsa, struct ospf6 *process)
538 {
539 struct listnode *node, *nnode;
540 struct ospf6_area *oa;
541
542 for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
543
544 /* If unknown LSA and U-bit clear, treat as link local
545 * flooding scope
546 */
547 if (!OSPF6_LSA_IS_KNOWN(lsa->header->type)
548 && !(ntohs(lsa->header->type) & OSPF6_LSTYPE_UBIT_MASK)
549 && (oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)) {
550
551 if (IS_OSPF6_DEBUG_FLOODING)
552 zlog_debug("Unknown LSA, do not flood");
553 continue;
554 }
555
556 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
557 && oa != OSPF6_AREA(lsa->lsdb->data))
558 continue;
559 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
560 && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
561 continue;
562
563 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
564 && (IS_AREA_STUB(oa) || IS_AREA_NSSA(oa)))
565 continue;
566
567 /* Check for NSSA LSA */
568 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
569 && !IS_AREA_NSSA(oa) && !OSPF6_LSA_IS_MAXAGE(lsa))
570 continue;
571
572 ospf6_flood_area(from, lsa, oa);
573 }
574 }
575
576 void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
577 {
578 struct ospf6 *ospf6;
579
580 ospf6 = ospf6_get_by_lsdb(lsa);
581 if (ospf6 == NULL)
582 return;
583
584 ospf6_flood_process(from, lsa, ospf6);
585 }
586
587 static void ospf6_flood_clear_interface(struct ospf6_lsa *lsa,
588 struct ospf6_interface *oi)
589 {
590 struct listnode *node, *nnode;
591 struct ospf6_neighbor *on;
592 struct ospf6_lsa *rem;
593
594 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
595 rem = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
596 lsa->header->adv_router,
597 on->retrans_list);
598 if (rem && !ospf6_lsa_compare(rem, lsa)) {
599 if (IS_OSPF6_DEBUG_FLOODING
600 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
601 zlog_debug("Remove %s from retrans_list of %s",
602 rem->name, on->name);
603 ospf6_decrement_retrans_count(rem);
604 ospf6_lsdb_remove(rem, on->retrans_list);
605 }
606 }
607 }
608
609 void ospf6_flood_clear_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
610 {
611 struct listnode *node, *nnode;
612 struct ospf6_interface *oi;
613
614 for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
615 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
616 && oi != OSPF6_INTERFACE(lsa->lsdb->data))
617 continue;
618
619 ospf6_flood_clear_interface(lsa, oi);
620 }
621 }
622
623 static void ospf6_flood_clear_process(struct ospf6_lsa *lsa,
624 struct ospf6 *process)
625 {
626 struct listnode *node, *nnode;
627 struct ospf6_area *oa;
628
629 for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
630 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
631 && oa != OSPF6_AREA(lsa->lsdb->data))
632 continue;
633 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
634 && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
635 continue;
636
637 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
638 && (IS_AREA_STUB(oa) || (IS_AREA_NSSA(oa))))
639 continue;
640 /* Check for NSSA LSA */
641 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
642 && !IS_AREA_NSSA(oa))
643 continue;
644
645 ospf6_flood_clear_area(lsa, oa);
646 }
647 }
648
649 void ospf6_flood_clear(struct ospf6_lsa *lsa)
650 {
651 struct ospf6 *ospf6;
652
653 ospf6 = ospf6_get_by_lsdb(lsa);
654 if (ospf6 == NULL)
655 return;
656 ospf6_flood_clear_process(lsa, ospf6);
657 }
658
659
660 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
661 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa *lsa,
662 int ismore_recent,
663 struct ospf6_neighbor *from)
664 {
665 struct ospf6_interface *oi;
666 int is_debug = 0;
667
668 if (IS_OSPF6_DEBUG_FLOODING
669 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
670 is_debug++;
671
672 assert(from && from->ospf6_if);
673 oi = from->ospf6_if;
674
675 /* LSA is more recent than database copy, but was not flooded
676 back out receiving interface. Delayed acknowledgement sent
677 if advertisement received from Designated Router,
678 otherwide do nothing. */
679 if (ismore_recent < 0) {
680 if (oi->drouter == from->router_id) {
681 if (is_debug)
682 zlog_debug(
683 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
684 /* Delayed acknowledgement */
685 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
686 thread_add_timer(master, ospf6_lsack_send_interface, oi,
687 3, &oi->thread_send_lsack);
688 } else {
689 if (is_debug)
690 zlog_debug(
691 "No acknowledgement (BDR & MoreRecent & ! from DR)");
692 }
693 return;
694 }
695
696 /* LSA is a duplicate, and was treated as an implied acknowledgement.
697 Delayed acknowledgement sent if advertisement received from
698 Designated Router, otherwise do nothing */
699 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
700 && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
701 if (oi->drouter == from->router_id) {
702 if (is_debug)
703 zlog_debug(
704 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
705 /* Delayed acknowledgement */
706 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
707 thread_add_timer(master, ospf6_lsack_send_interface, oi,
708 3, &oi->thread_send_lsack);
709 } else {
710 if (is_debug)
711 zlog_debug(
712 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
713 }
714 return;
715 }
716
717 /* LSA is a duplicate, and was not treated as an implied
718 acknowledgement.
719 Direct acknowledgement sent */
720 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
721 && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
722 if (is_debug)
723 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
724 ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
725 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
726 &from->thread_send_lsack);
727 return;
728 }
729
730 /* LSA's LS age is equal to Maxage, and there is no current instance
731 of the LSA in the link state database, and none of router's
732 neighbors are in states Exchange or Loading */
733 /* Direct acknowledgement sent, but this case is handled in
734 early of ospf6_receive_lsa () */
735 }
736
737 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa *lsa,
738 int ismore_recent,
739 struct ospf6_neighbor *from)
740 {
741 struct ospf6_interface *oi;
742 int is_debug = 0;
743
744 if (IS_OSPF6_DEBUG_FLOODING
745 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
746 is_debug++;
747
748 assert(from && from->ospf6_if);
749 oi = from->ospf6_if;
750
751 /* LSA has been flood back out receiving interface.
752 No acknowledgement sent. */
753 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK)) {
754 if (is_debug)
755 zlog_debug("No acknowledgement (AllOther & FloodBack)");
756 return;
757 }
758
759 /* LSA is more recent than database copy, but was not flooded
760 back out receiving interface. Delayed acknowledgement sent. */
761 if (ismore_recent < 0) {
762 if (is_debug)
763 zlog_debug(
764 "Delayed acknowledgement (AllOther & MoreRecent)");
765 /* Delayed acknowledgement */
766 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
767 thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
768 &oi->thread_send_lsack);
769 return;
770 }
771
772 /* LSA is a duplicate, and was treated as an implied acknowledgement.
773 No acknowledgement sent. */
774 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
775 && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
776 if (is_debug)
777 zlog_debug(
778 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
779 return;
780 }
781
782 /* LSA is a duplicate, and was not treated as an implied
783 acknowledgement.
784 Direct acknowledgement sent */
785 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
786 && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
787 if (is_debug)
788 zlog_debug(
789 "Direct acknowledgement (AllOther & Duplicate)");
790 ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
791 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
792 &from->thread_send_lsack);
793 return;
794 }
795
796 /* LSA's LS age is equal to Maxage, and there is no current instance
797 of the LSA in the link state database, and none of router's
798 neighbors are in states Exchange or Loading */
799 /* Direct acknowledgement sent, but this case is handled in
800 early of ospf6_receive_lsa () */
801 }
802
803 static void ospf6_acknowledge_lsa(struct ospf6_lsa *lsa, int ismore_recent,
804 struct ospf6_neighbor *from)
805 {
806 struct ospf6_interface *oi;
807
808 assert(from && from->ospf6_if);
809 oi = from->ospf6_if;
810
811 if (oi->state == OSPF6_INTERFACE_BDR)
812 ospf6_acknowledge_lsa_bdrouter(lsa, ismore_recent, from);
813 else
814 ospf6_acknowledge_lsa_allother(lsa, ismore_recent, from);
815 }
816
817 /* RFC2328 section 13 (4):
818 if MaxAge LSA and if we have no instance, and no neighbor
819 is in states Exchange or Loading
820 returns 1 if match this case, else returns 0 */
821 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa,
822 struct ospf6_neighbor *from)
823 {
824 struct ospf6_neighbor *on;
825 struct ospf6_interface *oi;
826 struct ospf6_area *oa;
827 struct ospf6 *process = NULL;
828 struct listnode *i, *j, *k;
829 int count = 0;
830
831 if (!OSPF6_LSA_IS_MAXAGE(lsa))
832 return 0;
833
834 if (ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
835 lsa->header->adv_router, lsa->lsdb))
836 return 0;
837
838 process = from->ospf6_if->area->ospf6;
839
840 for (ALL_LIST_ELEMENTS_RO(process->area_list, i, oa))
841 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
842 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on))
843 if (on->state == OSPF6_NEIGHBOR_EXCHANGE
844 || on->state == OSPF6_NEIGHBOR_LOADING)
845 count++;
846
847 if (count == 0)
848 return 1;
849 return 0;
850 }
851
852 /* RFC2328 section 13 The Flooding Procedure */
853 void ospf6_receive_lsa(struct ospf6_neighbor *from,
854 struct ospf6_lsa_header *lsa_header)
855 {
856 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
857 int ismore_recent;
858 int is_debug = 0;
859 unsigned int time_delta_ms;
860
861 ismore_recent = 1;
862 assert(from);
863
864 /* if we receive a LSA with invalid seqnum drop it */
865 if (ntohl(lsa_header->seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER) {
866 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header->type)) {
867 zlog_debug(
868 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
869 ospf6_lstype_name(lsa_header->type),
870 &lsa_header->id, &lsa_header->adv_router,
871 ntohl(lsa_header->seqnum));
872 }
873 return;
874 }
875
876 /* make lsa structure for received lsa */
877 new = ospf6_lsa_create(lsa_header);
878
879 if (IS_OSPF6_DEBUG_FLOODING
880 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header->type)) {
881 is_debug++;
882 zlog_debug("LSA Receive from %s", from->name);
883 ospf6_lsa_header_print(new);
884 }
885
886 /* (1) LSA Checksum */
887 if (!ospf6_lsa_checksum_valid(new->header)) {
888 if (is_debug)
889 zlog_debug("Wrong LSA Checksum, discard");
890 ospf6_lsa_delete(new);
891 return;
892 }
893
894 /* (2) Examine the LSA's LS type.
895 RFC2470 3.5.1. Receiving Link State Update packets */
896 if (IS_AREA_STUB(from->ospf6_if->area)
897 && OSPF6_LSA_SCOPE(new->header->type) == OSPF6_SCOPE_AS) {
898 if (is_debug)
899 zlog_debug(
900 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
901 ospf6_lsa_delete(new);
902 return;
903 }
904
905 /* (3) LSA which have reserved scope is discarded
906 RFC2470 3.5.1. Receiving Link State Update packets */
907 /* Flooding scope check. LSAs with unknown scope are discarded here.
908 Set appropriate LSDB for the LSA */
909 switch (OSPF6_LSA_SCOPE(new->header->type)) {
910 case OSPF6_SCOPE_LINKLOCAL:
911 new->lsdb = from->ospf6_if->lsdb;
912 break;
913 case OSPF6_SCOPE_AREA:
914 new->lsdb = from->ospf6_if->area->lsdb;
915 break;
916 case OSPF6_SCOPE_AS:
917 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
918 break;
919 default:
920 if (is_debug)
921 zlog_debug("LSA has reserved scope, discard");
922 ospf6_lsa_delete(new);
923 return;
924 }
925
926 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
927 is in states Exchange or Loading */
928 if (ospf6_is_maxage_lsa_drop(new, from)) {
929 /* log */
930 if (is_debug)
931 zlog_debug(
932 "Drop MaxAge LSA with direct acknowledgement.");
933
934 /* a) Acknowledge back to neighbor (Direct acknowledgement,
935 * 13.5) */
936 ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list);
937 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
938 &from->thread_send_lsack);
939
940 /* b) Discard */
941 ospf6_lsa_delete(new);
942 return;
943 }
944
945 /* (5) */
946 /* lookup the same database copy in lsdb */
947 old = ospf6_lsdb_lookup(new->header->type, new->header->id,
948 new->header->adv_router, new->lsdb);
949 if (old) {
950 ismore_recent = ospf6_lsa_compare(new, old);
951 if (ntohl(new->header->seqnum) == ntohl(old->header->seqnum)) {
952 if (is_debug)
953 zlog_debug("Received is duplicated LSA");
954 SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE);
955 }
956 }
957
958 /* if no database copy or received is more recent */
959 if (old == NULL || ismore_recent < 0) {
960 /* in case we have no database copy */
961 ismore_recent = -1;
962
963 /* (a) MinLSArrival check */
964 if (old) {
965 struct timeval now, res;
966 monotime(&now);
967 timersub(&now, &old->installed, &res);
968 time_delta_ms =
969 (res.tv_sec * 1000) + (int)(res.tv_usec / 1000);
970 if (time_delta_ms
971 < from->ospf6_if->area->ospf6->lsa_minarrival) {
972 if (is_debug)
973 zlog_debug(
974 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
975 time_delta_ms,
976 from->ospf6_if->area->ospf6
977 ->lsa_minarrival);
978 ospf6_lsa_delete(new);
979 return; /* examin next lsa */
980 }
981 }
982
983 monotime(&new->received);
984
985 if (is_debug)
986 zlog_debug(
987 "Install, Flood, Possibly acknowledge the received LSA");
988
989 /* Remove older copies of this LSA from retx lists */
990 if (old)
991 ospf6_flood_clear(old);
992
993 /* (b) immediately flood and (c) remove from all retrans-list */
994 /* Prevent self-originated LSA to be flooded. this is to make
995 reoriginated instance of the LSA not to be rejected by other
996 routers
997 due to MinLSArrival. */
998 if (new->header->adv_router
999 != from->ospf6_if->area->ospf6->router_id)
1000 ospf6_flood(from, new);
1001
1002 /* (d), installing lsdb, which may cause routing
1003 table calculation (replacing database copy) */
1004 ospf6_install_lsa(new);
1005
1006 if (OSPF6_LSA_IS_MAXAGE(new))
1007 ospf6_maxage_remove(from->ospf6_if->area->ospf6);
1008
1009 /* (e) possibly acknowledge */
1010 ospf6_acknowledge_lsa(new, ismore_recent, from);
1011
1012 /* (f) Self Originated LSA, section 13.4 */
1013 if (new->header->adv_router
1014 == from->ospf6_if->area->ospf6->router_id) {
1015 /* Self-originated LSA (newer than ours) is received
1016 from
1017 another router. We have to make a new instance of the
1018 LSA
1019 or have to flush this LSA. */
1020 if (is_debug) {
1021 zlog_debug(
1022 "Newer instance of the self-originated LSA");
1023 zlog_debug("Schedule reorigination");
1024 }
1025 new->refresh = NULL;
1026 thread_add_event(master, ospf6_lsa_refresh, new, 0,
1027 &new->refresh);
1028 }
1029
1030 return;
1031 }
1032
1033 /* (6) if there is instance on sending neighbor's request list */
1034 if (ospf6_lsdb_lookup(new->header->type, new->header->id,
1035 new->header->adv_router, from->request_list)) {
1036 /* if no database copy, should go above state (5) */
1037 assert(old);
1038
1039 zlog_warn(
1040 "Received is not newer, on the neighbor %s request-list",
1041 from->name);
1042 zlog_warn(
1043 "BadLSReq, discard the received LSA lsa %s send badLSReq",
1044 new->name);
1045
1046 /* BadLSReq */
1047 thread_add_event(master, bad_lsreq, from, 0, NULL);
1048
1049 ospf6_lsa_delete(new);
1050 return;
1051 }
1052
1053 /* (7) if neither one is more recent */
1054 if (ismore_recent == 0) {
1055 if (is_debug)
1056 zlog_debug(
1057 "The same instance as database copy (neither recent)");
1058
1059 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
1060 */
1061 rem = ospf6_lsdb_lookup(new->header->type, new->header->id,
1062 new->header->adv_router,
1063 from->retrans_list);
1064 if (rem) {
1065 if (is_debug) {
1066 zlog_debug(
1067 "It is on the neighbor's retrans-list.");
1068 zlog_debug(
1069 "Treat as an Implied acknowledgement");
1070 }
1071 SET_FLAG(new->flag, OSPF6_LSA_IMPLIEDACK);
1072 ospf6_decrement_retrans_count(rem);
1073 ospf6_lsdb_remove(rem, from->retrans_list);
1074 }
1075
1076 if (is_debug)
1077 zlog_debug("Possibly acknowledge and then discard");
1078
1079 /* (b) possibly acknowledge */
1080 ospf6_acknowledge_lsa(new, ismore_recent, from);
1081
1082 ospf6_lsa_delete(new);
1083 return;
1084 }
1085
1086 /* (8) previous database copy is more recent */
1087 {
1088 assert(old);
1089
1090 /* If database copy is in 'Seqnumber Wrapping',
1091 simply discard the received LSA */
1092 if (OSPF6_LSA_IS_MAXAGE(old)
1093 && old->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)) {
1094 if (is_debug) {
1095 zlog_debug("The LSA is in Seqnumber Wrapping");
1096 zlog_debug("MaxAge & MaxSeqNum, discard");
1097 }
1098 ospf6_lsa_delete(new);
1099 return;
1100 }
1101
1102 /* Otherwise, Send database copy of this LSA to this neighbor */
1103 {
1104 if (is_debug) {
1105 zlog_debug("Database copy is more recent.");
1106 zlog_debug(
1107 "Send back directly and then discard");
1108 }
1109
1110 /* Neighbor router sent recent age for LSA,
1111 * Router could be restarted while current copy is
1112 * MAXAGEd and not removed.*/
1113 if (OSPF6_LSA_IS_MAXAGE(old)
1114 && !OSPF6_LSA_IS_MAXAGE(new)) {
1115 if (new->header->adv_router
1116 != from->ospf6_if->area->ospf6->router_id) {
1117 if (is_debug)
1118 zlog_debug(
1119 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
1120 __PRETTY_FUNCTION__, old->name);
1121 ospf6_lsa_purge(old);
1122 ospf6_flood(from, new);
1123 ospf6_install_lsa(new);
1124 return;
1125 }
1126 /* For self-originated LSA, only trust
1127 * ourselves. Fall through and send
1128 * LS Update with our current copy.
1129 */
1130 if (is_debug)
1131 zlog_debug(
1132 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
1133 __PRETTY_FUNCTION__, old->name);
1134 }
1135
1136 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
1137
1138 ospf6_lsdb_add(ospf6_lsa_copy(old),
1139 from->lsupdate_list);
1140 thread_add_event(master, ospf6_lsupdate_send_neighbor,
1141 from, 0, &from->thread_send_lsupdate);
1142
1143 ospf6_lsa_delete(new);
1144 return;
1145 }
1146 return;
1147 }
1148 }
1149
1150 DEFUN (debug_ospf6_flooding,
1151 debug_ospf6_flooding_cmd,
1152 "debug ospf6 flooding",
1153 DEBUG_STR
1154 OSPF6_STR
1155 "Debug OSPFv3 flooding function\n"
1156 )
1157 {
1158 OSPF6_DEBUG_FLOODING_ON();
1159 return CMD_SUCCESS;
1160 }
1161
1162 DEFUN (no_debug_ospf6_flooding,
1163 no_debug_ospf6_flooding_cmd,
1164 "no debug ospf6 flooding",
1165 NO_STR
1166 DEBUG_STR
1167 OSPF6_STR
1168 "Debug OSPFv3 flooding function\n"
1169 )
1170 {
1171 OSPF6_DEBUG_FLOODING_OFF();
1172 return CMD_SUCCESS;
1173 }
1174
1175 int config_write_ospf6_debug_flood(struct vty *vty)
1176 {
1177 if (IS_OSPF6_DEBUG_FLOODING)
1178 vty_out(vty, "debug ospf6 flooding\n");
1179 return 0;
1180 }
1181
1182 void install_element_ospf6_debug_flood(void)
1183 {
1184 install_element(ENABLE_NODE, &debug_ospf6_flooding_cmd);
1185 install_element(ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1186 install_element(CONFIG_NODE, &debug_ospf6_flooding_cmd);
1187 install_element(CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1188 }