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