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 961 : struct ospf6_lsdb *ospf6_get_scoped_lsdb(struct ospf6_lsa *lsa)
50 : {
51 961 : struct ospf6_lsdb *lsdb = NULL;
52 961 : switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
53 56 : case OSPF6_SCOPE_LINKLOCAL:
54 56 : lsdb = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb;
55 56 : break;
56 706 : case OSPF6_SCOPE_AREA:
57 706 : lsdb = OSPF6_AREA(lsa->lsdb->data)->lsdb;
58 706 : break;
59 199 : case OSPF6_SCOPE_AS:
60 199 : lsdb = OSPF6_PROCESS(lsa->lsdb->data)->lsdb;
61 199 : break;
62 : default:
63 0 : assert(0);
64 : break;
65 : }
66 961 : return lsdb;
67 : }
68 :
69 234 : struct ospf6_lsdb *ospf6_get_scoped_lsdb_self(struct ospf6_lsa *lsa)
70 : {
71 234 : struct ospf6_lsdb *lsdb_self = NULL;
72 234 : switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
73 33 : case OSPF6_SCOPE_LINKLOCAL:
74 33 : lsdb_self = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb_self;
75 33 : break;
76 161 : case OSPF6_SCOPE_AREA:
77 161 : lsdb_self = OSPF6_AREA(lsa->lsdb->data)->lsdb_self;
78 161 : break;
79 40 : case OSPF6_SCOPE_AS:
80 40 : lsdb_self = OSPF6_PROCESS(lsa->lsdb->data)->lsdb_self;
81 40 : break;
82 : default:
83 0 : assert(0);
84 : break;
85 : }
86 234 : return lsdb_self;
87 : }
88 :
89 355 : void ospf6_lsa_originate(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
90 : {
91 355 : struct ospf6_lsa *old;
92 355 : struct ospf6_lsdb *lsdb_self;
93 :
94 355 : 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 355 : 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 355 : if (old && !OSPF6_LSA_IS_DIFFER(lsa, old)
111 195 : && !ospf6->gr_info.finishing_restart) {
112 195 : if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
113 0 : zlog_debug("Suppress updating LSA: %s", lsa->name);
114 195 : ospf6_lsa_delete(lsa);
115 195 : return;
116 : }
117 :
118 : /* store it in the LSDB for self-originated LSAs */
119 160 : lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
120 160 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self);
121 :
122 160 : THREAD_OFF(lsa->refresh);
123 160 : thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
124 : &lsa->refresh);
125 :
126 160 : if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
127 160 : || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) {
128 0 : zlog_debug("LSA Originate:");
129 0 : ospf6_lsa_header_print(lsa);
130 : }
131 :
132 160 : ospf6_install_lsa(lsa);
133 160 : ospf6_flood(NULL, lsa);
134 : }
135 :
136 61 : void ospf6_lsa_originate_process(struct ospf6_lsa *lsa, struct ospf6 *process)
137 : {
138 61 : lsa->lsdb = process->lsdb;
139 61 : ospf6_lsa_originate(process, lsa);
140 61 : }
141 :
142 228 : void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
143 : {
144 228 : lsa->lsdb = oa->lsdb;
145 228 : ospf6_lsa_originate(oa->ospf6, lsa);
146 228 : }
147 :
148 66 : void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa,
149 : struct ospf6_interface *oi)
150 : {
151 66 : assert(oi->type != OSPF_IFTYPE_VIRTUALLINK);
152 :
153 66 : lsa->lsdb = oi->lsdb;
154 66 : ospf6_lsa_originate(oi->area->ospf6, lsa);
155 66 : }
156 :
157 20 : void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
158 : {
159 20 : uint32_t id = lsa->header->id;
160 20 : struct ospf6_area *oa;
161 20 : struct listnode *lnode;
162 :
163 20 : ospf6_lsa_purge(lsa);
164 :
165 : /* Delete the corresponding NSSA LSA */
166 67 : for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) {
167 27 : lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), id,
168 : ospf6->router_id, oa->lsdb);
169 27 : 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 20 : }
178 :
179 74 : void ospf6_lsa_purge(struct ospf6_lsa *lsa)
180 : {
181 74 : struct ospf6_lsa *self;
182 74 : struct ospf6_lsdb *lsdb_self;
183 :
184 : /* remove it from the LSDB for self-originated LSAs */
185 74 : lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
186 148 : self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
187 74 : lsa->header->adv_router, lsdb_self);
188 74 : if (self) {
189 64 : THREAD_OFF(self->expire);
190 64 : THREAD_OFF(self->refresh);
191 64 : ospf6_lsdb_remove(self, lsdb_self);
192 : }
193 :
194 74 : ospf6_lsa_premature_aging(lsa);
195 74 : }
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 14 : void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa, struct ospf6_lsa *lsa)
202 : {
203 14 : int ls_id = 0;
204 14 : struct ospf6_lsa *lsa_next;
205 14 : uint16_t type;
206 :
207 14 : type = lsa->header->type;
208 :
209 14 : ospf6_lsa_purge(lsa);
210 :
211 14 : lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
212 14 : oa->ospf6->router_id, oa->lsdb);
213 14 : 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 14 : }
219 :
220 492 : 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 492 : lsa->retrans_count++;
225 492 : }
226 :
227 492 : void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa)
228 : {
229 492 : struct ospf6_lsdb *lsdb;
230 492 : 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 492 : lsdb = ospf6_get_scoped_lsdb(lsa);
238 :
239 : /* Find the original LSA of which the retrans_count should be
240 : * decremented */
241 984 : orig = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
242 492 : lsa->header->adv_router, lsdb);
243 492 : if (orig) {
244 492 : orig->retrans_count--;
245 492 : assert(orig->retrans_count >= 0);
246 : }
247 492 : }
248 :
249 : /* RFC2328 section 13.2 Installing LSAs in the database */
250 615 : void ospf6_install_lsa(struct ospf6_lsa *lsa)
251 : {
252 615 : struct ospf6 *ospf6;
253 615 : struct timeval now;
254 615 : struct ospf6_lsa *old;
255 615 : struct ospf6_area *area = NULL;
256 :
257 615 : ospf6 = ospf6_get_by_lsdb(lsa);
258 615 : assert(ospf6);
259 :
260 : /* Remove the old instance from all neighbors' Link state
261 : retransmission list (RFC2328 13.2 last paragraph) */
262 1230 : old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
263 615 : lsa->header->adv_router, lsa->lsdb);
264 615 : if (old) {
265 287 : 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 287 : THREAD_OFF(old->expire);
272 287 : THREAD_OFF(old->refresh);
273 287 : ospf6_flood_clear(old);
274 : }
275 :
276 615 : monotime(&now);
277 615 : if (!OSPF6_LSA_IS_MAXAGE(lsa)) {
278 451 : 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 164 : lsa->expire = NULL;
284 :
285 615 : 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 615 : if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
307 615 : || 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 615 : lsa->installed = now;
314 :
315 : /* Topo change handling */
316 615 : if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa->header->type))
317 532 : && !CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)) {
318 :
319 : /* check if it is new lsa ? or existing lsa got modified ?*/
320 477 : if (!old || OSPF6_LSA_IS_CHANGED(old, lsa))
321 392 : ospf6_helper_handle_topo_chg(ospf6, lsa);
322 : }
323 :
324 615 : ospf6_lsdb_add(lsa, lsa->lsdb);
325 :
326 615 : 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 615 : if (ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) {
334 168 : area = OSPF6_AREA(lsa->lsdb->data);
335 168 : if (old == NULL) {
336 67 : if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
337 67 : || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
338 0 : zlog_debug("%s: New router LSA %s", __func__,
339 : lsa->name);
340 67 : ospf6_abr_nssa_check_status(area->ospf6);
341 : }
342 : }
343 615 : 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 1186 : void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
349 : struct ospf6_interface *oi)
350 : {
351 1186 : struct listnode *node, *nnode;
352 1186 : struct ospf6_neighbor *on;
353 1186 : struct ospf6_lsa *req, *old;
354 1186 : int retrans_added = 0;
355 1186 : int is_debug = 0;
356 :
357 1186 : if (IS_OSPF6_DEBUG_FLOODING
358 1186 : || 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 3477 : for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
365 1105 : if (is_debug)
366 0 : zlog_debug("To neighbor %s", on->name);
367 :
368 : /* (a) if neighbor state < Exchange, examin next */
369 1105 : if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
370 103 : if (is_debug)
371 0 : zlog_debug(
372 : "Neighbor state less than ExChange, next neighbor");
373 103 : continue;
374 : }
375 :
376 : /* (b) if neighbor not yet Full, check request-list */
377 1002 : if (on->state != OSPF6_NEIGHBOR_FULL) {
378 259 : if (is_debug)
379 0 : zlog_debug("Neighbor not yet Full");
380 :
381 518 : req = ospf6_lsdb_lookup(
382 259 : lsa->header->type, lsa->header->id,
383 259 : lsa->header->adv_router, on->request_list);
384 259 : if (req == NULL) {
385 112 : 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 147 : 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 147 : if (ospf6_lsa_compare(lsa, req) == 0) {
403 145 : if (is_debug)
404 0 : zlog_debug(
405 : "Requesting the same, remove it, next neighbor");
406 145 : if (req == on->last_ls_req) {
407 : /* sanity check refcount */
408 31 : assert(req->lock >= 2);
409 31 : req = ospf6_lsa_unlock(req);
410 31 : on->last_ls_req = NULL;
411 : }
412 145 : if (req)
413 145 : ospf6_lsdb_remove(
414 : req, on->request_list);
415 145 : ospf6_check_nbr_loading(on);
416 145 : continue;
417 : }
418 :
419 : /* If the new LSA is more recent, delete from
420 : * request-list */
421 2 : if (ospf6_lsa_compare(lsa, req) < 0) {
422 2 : if (is_debug)
423 0 : zlog_debug(
424 : "Received is newer, remove requesting");
425 2 : if (req == on->last_ls_req) {
426 1 : req = ospf6_lsa_unlock(req);
427 1 : on->last_ls_req = NULL;
428 : }
429 2 : if (req)
430 2 : ospf6_lsdb_remove(req,
431 : on->request_list);
432 2 : 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 857 : if (from == on) {
441 237 : if (is_debug)
442 0 : zlog_debug(
443 : "Received is from the neighbor, next neighbor");
444 237 : continue;
445 : }
446 :
447 620 : if ((oi->area->ospf6->inst_shutdown)
448 503 : || CHECK_FLAG(lsa->flag, OSPF6_LSA_FLUSH)) {
449 117 : 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 117 : ospf6_lsupdate_send_neighbor_now(on, lsa);
455 117 : continue;
456 : } else {
457 : /* (d) add retrans-list, schedule retransmission */
458 503 : 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 1006 : old = ospf6_lsdb_lookup(
466 503 : lsa->header->type, lsa->header->id,
467 503 : lsa->header->adv_router, on->retrans_list);
468 503 : if (!old) {
469 469 : struct ospf6_lsa *orig;
470 469 : struct ospf6_lsdb *lsdb;
471 :
472 469 : 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 469 : lsdb = ospf6_get_scoped_lsdb(lsa);
483 938 : orig = ospf6_lsdb_lookup(
484 469 : lsa->header->type, lsa->header->id,
485 469 : lsa->header->adv_router, lsdb);
486 469 : if (orig)
487 329 : ospf6_increment_retrans_count(orig);
488 : else
489 140 : ospf6_increment_retrans_count(lsa);
490 :
491 469 : ospf6_lsdb_add(ospf6_lsa_copy(lsa),
492 : on->retrans_list);
493 469 : 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 469 : retrans_added++;
500 : }
501 : }
502 : }
503 :
504 : /* (2) examin next interface if not added to retrans-list */
505 1186 : if (retrans_added == 0) {
506 796 : if (is_debug)
507 0 : zlog_debug(
508 : "No retransmission scheduled, next interface %pOI",
509 : oi);
510 796 : 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 390 : if (from && from->ospf6_if == oi
516 176 : && (from->router_id == oi->drouter
517 114 : || from->router_id == oi->bdrouter)) {
518 90 : if (is_debug)
519 0 : zlog_debug(
520 : "Received is from the I/F's DR or BDR, next interface");
521 90 : 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 156 : if (from && from->ospf6_if == oi) {
527 86 : if (oi->state == OSPF6_INTERFACE_BDR) {
528 19 : if (is_debug)
529 0 : zlog_debug(
530 : "Received is from the I/F, itself BDR, next interface");
531 19 : return;
532 : }
533 67 : SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
534 : }
535 :
536 : /* (5) flood the LSA out the interface. */
537 281 : if (is_debug)
538 0 : zlog_debug("Schedule flooding for the interface");
539 281 : if ((oi->type == OSPF_IFTYPE_BROADCAST)
540 281 : || (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
541 209 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list);
542 209 : thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
543 : &oi->thread_send_lsupdate);
544 : } else {
545 : /* reschedule retransmissions to all neighbors */
546 285 : for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
547 141 : THREAD_OFF(on->thread_send_lsupdate);
548 141 : thread_add_event(master, ospf6_lsupdate_send_neighbor,
549 : on, 0, &on->thread_send_lsupdate);
550 : }
551 : }
552 : }
553 :
554 732 : void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
555 : struct ospf6_area *oa)
556 : {
557 732 : struct listnode *node, *nnode;
558 732 : struct ospf6_interface *oi;
559 :
560 2680 : for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
561 1216 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
562 178 : && oi != OSPF6_INTERFACE(lsa->lsdb->data))
563 71 : continue;
564 1145 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AS
565 298 : && oi->type == OSPF_IFTYPE_VIRTUALLINK)
566 0 : continue;
567 :
568 1145 : ospf6_flood_interface(from, lsa, oi);
569 : }
570 732 : }
571 :
572 696 : static void ospf6_flood_process(struct ospf6_neighbor *from,
573 : struct ospf6_lsa *lsa, struct ospf6 *process)
574 : {
575 696 : struct listnode *node, *nnode;
576 696 : struct ospf6_area *oa;
577 :
578 2293 : 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 901 : 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 901 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
593 594 : && oa != OSPF6_AREA(lsa->lsdb->data))
594 141 : continue;
595 760 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
596 135 : && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
597 28 : continue;
598 :
599 732 : if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
600 172 : && (IS_AREA_STUB(oa) || IS_AREA_NSSA(oa)))
601 0 : continue;
602 :
603 : /* Check for NSSA LSA */
604 732 : 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 732 : ospf6_flood_area(from, lsa, oa);
609 : }
610 696 : }
611 :
612 696 : void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
613 : {
614 696 : struct ospf6 *ospf6;
615 :
616 696 : ospf6 = ospf6_get_by_lsdb(lsa);
617 696 : if (ospf6 == NULL)
618 : return;
619 :
620 696 : ospf6_flood_process(from, lsa, ospf6);
621 : }
622 :
623 853 : static void ospf6_flood_clear_interface(struct ospf6_lsa *lsa,
624 : struct ospf6_interface *oi)
625 : {
626 853 : struct listnode *node, *nnode;
627 853 : struct ospf6_neighbor *on;
628 853 : struct ospf6_lsa *rem;
629 :
630 2528 : for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
631 1644 : rem = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
632 822 : lsa->header->adv_router,
633 : on->retrans_list);
634 822 : if (rem && !ospf6_lsa_compare(rem, lsa)) {
635 79 : if (IS_OSPF6_DEBUG_FLOODING
636 79 : || 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 79 : ospf6_decrement_retrans_count(rem);
640 79 : ospf6_lsdb_remove(rem, on->retrans_list);
641 : }
642 : }
643 853 : }
644 :
645 532 : void ospf6_flood_clear_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
646 : {
647 532 : struct listnode *node, *nnode;
648 532 : struct ospf6_interface *oi;
649 :
650 1937 : for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
651 873 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
652 57 : && oi != OSPF6_INTERFACE(lsa->lsdb->data))
653 20 : continue;
654 853 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AS
655 134 : && oi->type == OSPF_IFTYPE_VIRTUALLINK)
656 0 : continue;
657 :
658 853 : ospf6_flood_clear_interface(lsa, oi);
659 : }
660 532 : }
661 :
662 518 : static void ospf6_flood_clear_process(struct ospf6_lsa *lsa,
663 : struct ospf6 *process)
664 : {
665 518 : struct listnode *node, *nnode;
666 518 : struct ospf6_area *oa;
667 :
668 1707 : for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
669 671 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
670 547 : && oa != OSPF6_AREA(lsa->lsdb->data))
671 130 : continue;
672 541 : if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
673 46 : && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
674 9 : continue;
675 :
676 532 : if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
677 78 : && (IS_AREA_STUB(oa) || (IS_AREA_NSSA(oa))))
678 0 : continue;
679 : /* Check for NSSA LSA */
680 532 : if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
681 0 : && !IS_AREA_NSSA(oa))
682 0 : continue;
683 :
684 532 : ospf6_flood_clear_area(lsa, oa);
685 : }
686 518 : }
687 :
688 518 : void ospf6_flood_clear(struct ospf6_lsa *lsa)
689 : {
690 518 : struct ospf6 *ospf6;
691 :
692 518 : ospf6 = ospf6_get_by_lsdb(lsa);
693 518 : if (ospf6 == NULL)
694 : return;
695 518 : ospf6_flood_clear_process(lsa, ospf6);
696 : }
697 :
698 :
699 : /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
700 306 : static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa *lsa,
701 : int ismore_recent,
702 : struct ospf6_neighbor *from)
703 : {
704 306 : struct ospf6_interface *oi;
705 306 : int is_debug = 0;
706 :
707 306 : if (IS_OSPF6_DEBUG_FLOODING
708 306 : || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
709 : is_debug++;
710 :
711 306 : assert(from && from->ospf6_if);
712 306 : 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 306 : if (ismore_recent < 0) {
719 153 : if (oi->drouter == from->router_id) {
720 134 : if (is_debug)
721 0 : zlog_debug(
722 : "Delayed acknowledgement (BDR & MoreRecent & from DR)");
723 : /* Delayed acknowledgement */
724 134 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
725 134 : thread_add_timer(master, ospf6_lsack_send_interface, oi,
726 : 3, &oi->thread_send_lsack);
727 : } else {
728 19 : if (is_debug)
729 0 : zlog_debug(
730 : "No acknowledgement (BDR & MoreRecent & ! from DR)");
731 : }
732 153 : 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 153 : if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
739 : && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
740 35 : if (oi->drouter == from->router_id) {
741 29 : if (is_debug)
742 0 : zlog_debug(
743 : "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
744 : /* Delayed acknowledgement */
745 29 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
746 29 : thread_add_timer(master, ospf6_lsack_send_interface, oi,
747 : 3, &oi->thread_send_lsack);
748 : } else {
749 6 : if (is_debug)
750 0 : zlog_debug(
751 : "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
752 : }
753 35 : return;
754 : }
755 :
756 : /* LSA is a duplicate, and was not treated as an implied
757 : acknowledgement.
758 : Direct acknowledgement sent */
759 118 : if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
760 : && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
761 118 : if (is_debug)
762 0 : zlog_debug("Direct acknowledgement (BDR & Duplicate)");
763 118 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
764 118 : thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
765 : &from->thread_send_lsack);
766 118 : 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 448 : static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa *lsa,
777 : int ismore_recent,
778 : struct ospf6_neighbor *from)
779 : {
780 448 : struct ospf6_interface *oi;
781 448 : int is_debug = 0;
782 :
783 448 : if (IS_OSPF6_DEBUG_FLOODING
784 448 : || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
785 : is_debug++;
786 :
787 448 : assert(from && from->ospf6_if);
788 448 : oi = from->ospf6_if;
789 :
790 : /* LSA has been flood back out receiving interface.
791 : No acknowledgement sent. */
792 448 : if (CHECK_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK)) {
793 67 : if (is_debug)
794 0 : zlog_debug("No acknowledgement (AllOther & FloodBack)");
795 67 : return;
796 : }
797 :
798 : /* LSA is more recent than database copy, but was not flooded
799 : back out receiving interface. Delayed acknowledgement sent. */
800 381 : if (ismore_recent < 0) {
801 160 : if (is_debug)
802 0 : zlog_debug(
803 : "Delayed acknowledgement (AllOther & MoreRecent)");
804 : /* Delayed acknowledgement */
805 160 : 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 160 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
811 160 : thread_add_timer(master, ospf6_lsack_send_interface, oi,
812 : 3, &oi->thread_send_lsack);
813 : }
814 160 : return;
815 : }
816 :
817 : /* LSA is a duplicate, and was treated as an implied acknowledgement.
818 : No acknowledgement sent. */
819 221 : if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
820 : && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
821 66 : if (is_debug)
822 0 : zlog_debug(
823 : "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
824 66 : return;
825 : }
826 :
827 : /* LSA is a duplicate, and was not treated as an implied
828 : acknowledgement.
829 : Direct acknowledgement sent */
830 155 : if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
831 : && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
832 155 : if (is_debug)
833 0 : zlog_debug(
834 : "Direct acknowledgement (AllOther & Duplicate)");
835 155 : ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
836 155 : thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
837 : &from->thread_send_lsack);
838 155 : 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 754 : static void ospf6_acknowledge_lsa(struct ospf6_lsa *lsa, int ismore_recent,
849 : struct ospf6_neighbor *from)
850 : {
851 754 : struct ospf6_interface *oi;
852 :
853 754 : assert(from && from->ospf6_if);
854 754 : oi = from->ospf6_if;
855 :
856 754 : if (oi->state == OSPF6_INTERFACE_BDR)
857 306 : ospf6_acknowledge_lsa_bdrouter(lsa, ismore_recent, from);
858 : else
859 448 : ospf6_acknowledge_lsa_allother(lsa, ismore_recent, from);
860 754 : }
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 898 : static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa,
867 : struct ospf6_neighbor *from)
868 : {
869 898 : struct ospf6_neighbor *on;
870 898 : struct ospf6_interface *oi;
871 898 : struct ospf6_area *oa;
872 898 : struct ospf6 *process = NULL;
873 898 : struct listnode *i, *j, *k;
874 898 : int count = 0;
875 :
876 898 : if (!OSPF6_LSA_IS_MAXAGE(lsa))
877 : return 0;
878 :
879 189 : if (ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
880 189 : lsa->header->adv_router, lsa->lsdb))
881 : return 0;
882 :
883 25 : process = from->ospf6_if->area->ospf6;
884 :
885 80 : for (ALL_LIST_ELEMENTS_RO(process->area_list, i, oa))
886 112 : for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
887 149 : for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on))
888 45 : if (on->state == OSPF6_NEIGHBOR_EXCHANGE
889 45 : || on->state == OSPF6_NEIGHBOR_LOADING)
890 27 : count++;
891 :
892 25 : if (count == 0)
893 : return 1;
894 : return 0;
895 : }
896 :
897 296 : static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa *lsa,
898 : struct ospf6_neighbor *from)
899 : {
900 296 : struct timeval now, res;
901 296 : unsigned int time_delta_ms;
902 :
903 296 : monotime(&now);
904 296 : timersub(&now, &lsa->installed, &res);
905 296 : time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec / 1000);
906 :
907 296 : if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) {
908 276 : if (IS_OSPF6_DEBUG_FLOODING ||
909 138 : 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 138 : return true;
915 : }
916 : return false;
917 : }
918 :
919 : /* RFC2328 section 13 The Flooding Procedure */
920 898 : void ospf6_receive_lsa(struct ospf6_neighbor *from,
921 : struct ospf6_lsa_header *lsa_header)
922 : {
923 898 : struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
924 898 : int ismore_recent;
925 898 : int is_debug = 0;
926 :
927 898 : ismore_recent = 1;
928 898 : assert(from);
929 :
930 : /* if we receive a LSA with invalid seqnum drop it */
931 898 : 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 898 : new = ospf6_lsa_create(lsa_header);
944 :
945 898 : if (IS_OSPF6_DEBUG_FLOODING
946 898 : || 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 898 : 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 898 : 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 898 : 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 898 : switch (OSPF6_LSA_SCOPE(new->header->type)) {
985 80 : case OSPF6_SCOPE_LINKLOCAL:
986 80 : 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 80 : new->lsdb = from->ospf6_if->lsdb;
993 80 : break;
994 623 : case OSPF6_SCOPE_AREA:
995 623 : new->lsdb = from->ospf6_if->area->lsdb;
996 623 : break;
997 195 : case OSPF6_SCOPE_AS:
998 195 : new->lsdb = from->ospf6_if->area->ospf6->lsdb;
999 195 : 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 898 : if (ospf6_is_maxage_lsa_drop(new, from)) {
1010 : /* log */
1011 4 : 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 4 : ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list);
1018 4 : thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
1019 : &from->thread_send_lsack);
1020 :
1021 : /* b) Discard */
1022 4 : ospf6_lsa_delete(new);
1023 4 : return;
1024 : }
1025 :
1026 : /* (5) */
1027 : /* lookup the same database copy in lsdb */
1028 1788 : old = ospf6_lsdb_lookup(new->header->type, new->header->id,
1029 894 : new->header->adv_router, new->lsdb);
1030 894 : if (old) {
1031 670 : ismore_recent = ospf6_lsa_compare(new, old);
1032 670 : if (ntohl(new->header->seqnum) == ntohl(old->header->seqnum)) {
1033 466 : if (is_debug)
1034 0 : zlog_debug("Received is duplicated LSA");
1035 466 : SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE);
1036 : }
1037 : }
1038 :
1039 : /* if no database copy or received is more recent */
1040 894 : if (old == NULL || ismore_recent < 0) {
1041 507 : bool self_originated;
1042 :
1043 : /* in case we have no database copy */
1044 507 : ismore_recent = -1;
1045 :
1046 : /* (a) MinLSArrival check */
1047 507 : if (old) {
1048 283 : if (ospf6_lsa_check_min_arrival(old, from)) {
1049 127 : ospf6_lsa_delete(new);
1050 127 : return; /* examin next lsa */
1051 : }
1052 : }
1053 :
1054 380 : monotime(&new->received);
1055 :
1056 380 : 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 380 : if (old)
1062 156 : ospf6_flood_clear(old);
1063 :
1064 380 : self_originated = (new->header->adv_router
1065 380 : == from->ospf6_if->area->ospf6->router_id);
1066 :
1067 : /* Received non-self-originated Grace LSA. */
1068 380 : 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 380 : if (!self_originated)
1117 380 : ospf6_flood(from, new);
1118 :
1119 : /* (d), installing lsdb, which may cause routing
1120 : table calculation (replacing database copy) */
1121 380 : ospf6_install_lsa(new);
1122 :
1123 380 : if (OSPF6_LSA_IS_MAXAGE(new))
1124 89 : ospf6_maxage_remove(from->ospf6_if->area->ospf6);
1125 :
1126 : /* (e) possibly acknowledge */
1127 380 : ospf6_acknowledge_lsa(new, ismore_recent, from);
1128 :
1129 : /* (f) Self Originated LSA, section 13.4 */
1130 380 : 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 380 : struct ospf6 *ospf6 = from->ospf6_if->area->ospf6;
1155 380 : struct ospf6_area *area = from->ospf6_if->area;
1156 380 : if (ospf6->gr_info.restart_in_progress)
1157 0 : ospf6_gr_check_lsdb_consistency(ospf6, area);
1158 :
1159 380 : return;
1160 : }
1161 :
1162 : /* (6) if there is instance on sending neighbor's request list */
1163 387 : if (ospf6_lsdb_lookup(new->header->type, new->header->id,
1164 387 : 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 387 : if (ismore_recent == 0) {
1184 374 : 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 748 : rem = ospf6_lsdb_lookup(new->header->type, new->header->id,
1191 374 : new->header->adv_router,
1192 : from->retrans_list);
1193 374 : if (rem) {
1194 101 : 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 101 : SET_FLAG(new->flag, OSPF6_LSA_IMPLIEDACK);
1201 101 : ospf6_decrement_retrans_count(rem);
1202 101 : ospf6_lsdb_remove(rem, from->retrans_list);
1203 : }
1204 :
1205 374 : if (is_debug)
1206 0 : zlog_debug("Possibly acknowledge and then discard");
1207 :
1208 : /* (b) possibly acknowledge */
1209 374 : ospf6_acknowledge_lsa(new, ismore_recent, from);
1210 :
1211 374 : ospf6_lsa_delete(new);
1212 374 : return;
1213 : }
1214 :
1215 : /* (8) previous database copy is more recent */
1216 : {
1217 13 : assert(old);
1218 :
1219 : /* If database copy is in 'Seqnumber Wrapping',
1220 : simply discard the received LSA */
1221 13 : 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 13 : 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 13 : 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 13 : if (ospf6_lsa_check_min_arrival(old, from)) {
1267 11 : ospf6_lsa_delete(new);
1268 11 : return; /* examin next lsa */
1269 : }
1270 :
1271 2 : ospf6_lsdb_add(ospf6_lsa_copy(old),
1272 : from->lsupdate_list);
1273 2 : thread_add_event(master, ospf6_lsupdate_send_neighbor,
1274 : from, 0, &from->thread_send_lsupdate);
1275 :
1276 2 : ospf6_lsa_delete(new);
1277 2 : 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 16 : void install_element_ospf6_debug_flood(void)
1315 : {
1316 16 : install_element(ENABLE_NODE, &debug_ospf6_flooding_cmd);
1317 16 : install_element(ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1318 16 : install_element(CONFIG_NODE, &debug_ospf6_flooding_cmd);
1319 16 : install_element(CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1320 16 : }
|