/src/frr/ospfd/ospf_flood.c
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * OSPF Flooding -- RFC2328 Section 13. |
4 | | * Copyright (C) 1999, 2000 Toshiaki Takada |
5 | | */ |
6 | | |
7 | | #include <zebra.h> |
8 | | |
9 | | #include "monotime.h" |
10 | | #include "linklist.h" |
11 | | #include "prefix.h" |
12 | | #include "if.h" |
13 | | #include "command.h" |
14 | | #include "table.h" |
15 | | #include "frrevent.h" |
16 | | #include "memory.h" |
17 | | #include "log.h" |
18 | | #include "zclient.h" |
19 | | |
20 | | #include "ospfd/ospfd.h" |
21 | | #include "ospfd/ospf_interface.h" |
22 | | #include "ospfd/ospf_ism.h" |
23 | | #include "ospfd/ospf_asbr.h" |
24 | | #include "ospfd/ospf_lsa.h" |
25 | | #include "ospfd/ospf_lsdb.h" |
26 | | #include "ospfd/ospf_neighbor.h" |
27 | | #include "ospfd/ospf_nsm.h" |
28 | | #include "ospfd/ospf_spf.h" |
29 | | #include "ospfd/ospf_flood.h" |
30 | | #include "ospfd/ospf_packet.h" |
31 | | #include "ospfd/ospf_abr.h" |
32 | | #include "ospfd/ospf_route.h" |
33 | | #include "ospfd/ospf_zebra.h" |
34 | | #include "ospfd/ospf_dump.h" |
35 | | |
36 | | extern struct zclient *zclient; |
37 | | |
38 | | /** @brief Function to refresh type-5 and type-7 DNA |
39 | | * LSAs when we receive an indication LSA. |
40 | | * @param Ospf instance. |
41 | | * @return Void. |
42 | | */ |
43 | | void ospf_refresh_dna_type5_and_type7_lsas(struct ospf *ospf) |
44 | 182 | { |
45 | 182 | struct route_node *rn; |
46 | 182 | struct ospf_lsa *lsa = NULL; |
47 | | |
48 | 34.2k | LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) |
49 | 17.0k | if (IS_LSA_SELF(lsa) && |
50 | 17.0k | CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE)) |
51 | 0 | ospf_lsa_refresh(ospf, lsa); |
52 | | |
53 | 182 | LSDB_LOOP (NSSA_LSDB(ospf), rn, lsa) |
54 | 0 | if (IS_LSA_SELF(lsa) && |
55 | 0 | CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE)) |
56 | 0 | ospf_lsa_refresh(ospf, lsa); |
57 | 182 | } |
58 | | |
59 | | /** @brief Function to update area flood reduction states. |
60 | | * @param area pointer. |
61 | | * @return Void. |
62 | | */ |
63 | | void ospf_area_update_fr_state(struct ospf_area *area) |
64 | 0 | { |
65 | 0 | unsigned int count_router_lsas = 0; |
66 | |
|
67 | 0 | if (area == NULL) |
68 | 0 | return; |
69 | | |
70 | 0 | count_router_lsas = |
71 | 0 | (unsigned int)(ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA) - |
72 | 0 | ospf_lsdb_count_self(area->lsdb, |
73 | 0 | OSPF_ROUTER_LSA)); |
74 | |
|
75 | 0 | if (count_router_lsas > |
76 | 0 | (unsigned int)area->fr_info.router_lsas_recv_dc_bit) { |
77 | 0 | area->fr_info.enabled = false; |
78 | 0 | area->fr_info.area_dc_clear = true; |
79 | 0 | return; |
80 | 0 | } else if (count_router_lsas < |
81 | 0 | (unsigned int)area->fr_info.router_lsas_recv_dc_bit) { |
82 | | /* This can never happen, total number of router lsas received |
83 | | * can never be less than router lsas received with dc bit set |
84 | | */ |
85 | 0 | OSPF_LOG_ERR("%s: Counter mismatch for area %pI4", __func__, |
86 | 0 | &area->area_id); |
87 | 0 | OSPF_LOG_ERR( |
88 | 0 | "%s: router LSAs in lsdb %d router LSAs recvd with dc bit set %d", |
89 | 0 | __func__, count_router_lsas, |
90 | 0 | area->fr_info.router_lsas_recv_dc_bit); |
91 | 0 | return; |
92 | 0 | } |
93 | | |
94 | 0 | area->fr_info.area_dc_clear = false; |
95 | |
|
96 | 0 | if (OSPF_FR_CONFIG(area->ospf, area)) { |
97 | 0 | if (!area->fr_info.enabled) { |
98 | 0 | area->fr_info.enabled = true; |
99 | 0 | area->fr_info.state_changed = true; |
100 | 0 | } |
101 | 0 | } else { |
102 | 0 | area->fr_info.enabled = false; |
103 | 0 | area->fr_info.area_dc_clear = true; |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | /* Do the LSA acking specified in table 19, Section 13.5, row 2 |
108 | | * This get called from ospf_flood_out_interface. Declared inline |
109 | | * for speed. */ |
110 | | static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr, |
111 | | struct ospf_lsa *lsa) |
112 | 0 | { |
113 | | /* LSA is more recent than database copy, but was not |
114 | | flooded back out receiving interface. Delayed |
115 | | acknowledgment sent. If interface is in Backup state |
116 | | delayed acknowledgment sent only if advertisement |
117 | | received from Designated Router, otherwise do nothing See |
118 | | RFC 2328 Section 13.5 */ |
119 | | |
120 | | /* Whether LSA is more recent or not, and whether this is in |
121 | | response to the LSA being sent out recieving interface has been |
122 | | worked out previously */ |
123 | | |
124 | | /* Deal with router as BDR */ |
125 | 0 | if (inbr->oi->state == ISM_Backup && !NBR_IS_DR(inbr)) |
126 | 0 | return; |
127 | | |
128 | | /* Schedule a delayed LSA Ack to be sent */ |
129 | 0 | listnode_add(inbr->oi->ls_ack, |
130 | 0 | ospf_lsa_lock(lsa)); /* delayed LSA Ack */ |
131 | 0 | } |
132 | | |
133 | | /* Check LSA is related to external info. */ |
134 | | struct external_info *ospf_external_info_check(struct ospf *ospf, |
135 | | struct ospf_lsa *lsa) |
136 | 103 | { |
137 | 103 | struct as_external_lsa *al; |
138 | 103 | struct prefix_ipv4 p; |
139 | 103 | struct route_node *rn; |
140 | 103 | struct list *ext_list; |
141 | 103 | struct listnode *node; |
142 | 103 | struct ospf_external *ext; |
143 | 103 | int type; |
144 | | |
145 | 103 | al = (struct as_external_lsa *)lsa->data; |
146 | | |
147 | 103 | p.family = AF_INET; |
148 | 103 | p.prefix = lsa->data->id; |
149 | 103 | p.prefixlen = ip_masklen(al->mask); |
150 | | |
151 | 3.29k | for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { |
152 | 3.19k | int redist_on = 0; |
153 | | |
154 | 3.19k | redist_on = |
155 | 3.19k | is_default_prefix4(&p) |
156 | 3.19k | ? vrf_bitmap_check( |
157 | 31 | zclient->default_information[AFI_IP], |
158 | 31 | ospf->vrf_id) |
159 | 3.19k | : (zclient->mi_redist[AFI_IP][type].enabled |
160 | 3.16k | || vrf_bitmap_check( |
161 | 3.06k | zclient->redist[AFI_IP][type], |
162 | 3.06k | ospf->vrf_id)); |
163 | | // Pending: check for MI above. |
164 | 3.19k | if (redist_on) { |
165 | 102 | ext_list = ospf->external[type]; |
166 | 102 | if (!ext_list) |
167 | 102 | continue; |
168 | | |
169 | 0 | for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { |
170 | 0 | rn = NULL; |
171 | 0 | if (ext->external_info) |
172 | 0 | rn = route_node_lookup( |
173 | 0 | ext->external_info, |
174 | 0 | (struct prefix *)&p); |
175 | 0 | if (rn) { |
176 | 0 | route_unlock_node(rn); |
177 | 0 | if (rn->info != NULL) |
178 | 0 | return (struct external_info *) |
179 | 0 | rn->info; |
180 | 0 | } |
181 | 0 | } |
182 | 0 | } |
183 | 3.19k | } |
184 | | |
185 | 103 | if (is_default_prefix4(&p) && ospf->external[DEFAULT_ROUTE]) { |
186 | 0 | ext_list = ospf->external[DEFAULT_ROUTE]; |
187 | |
|
188 | 0 | for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { |
189 | 0 | if (!ext->external_info) |
190 | 0 | continue; |
191 | | |
192 | 0 | rn = route_node_lookup(ext->external_info, |
193 | 0 | (struct prefix *)&p); |
194 | 0 | if (!rn) |
195 | 0 | continue; |
196 | 0 | route_unlock_node(rn); |
197 | 0 | if (rn->info != NULL) |
198 | 0 | return (struct external_info *)rn->info; |
199 | 0 | } |
200 | 0 | } |
201 | 103 | return NULL; |
202 | 103 | } |
203 | | |
204 | | static void ospf_process_self_originated_lsa(struct ospf *ospf, |
205 | | struct ospf_lsa *new, |
206 | | struct ospf_area *area) |
207 | 372 | { |
208 | 372 | struct ospf_interface *oi; |
209 | 372 | struct external_info *ei; |
210 | 372 | struct listnode *node; |
211 | 372 | struct as_external_lsa *al; |
212 | 372 | struct prefix_ipv4 p; |
213 | 372 | struct ospf_external_aggr_rt *aggr; |
214 | | |
215 | 372 | if (IS_DEBUG_OSPF_EVENT) |
216 | 0 | zlog_debug( |
217 | 372 | "%s:LSA[Type%d:%pI4]: Process self-originated LSA seq 0x%x", |
218 | 372 | ospf_get_name(ospf), new->data->type, |
219 | 372 | &new->data->id, ntohl(new->data->ls_seqnum)); |
220 | | |
221 | | /* If we're here, we installed a self-originated LSA that we received |
222 | | from a neighbor, i.e. it's more recent. We must see whether we want |
223 | | to originate it. |
224 | | If yes, we should use this LSA's sequence number and reoriginate |
225 | | a new instance. |
226 | | if not --- we must flush this LSA from the domain. */ |
227 | 372 | switch (new->data->type) { |
228 | 1 | case OSPF_ROUTER_LSA: |
229 | | /* Originate a new instance and schedule flooding */ |
230 | 1 | if (area->router_lsa_self) |
231 | 0 | area->router_lsa_self->data->ls_seqnum = |
232 | 0 | new->data->ls_seqnum; |
233 | 1 | ospf_router_lsa_update_area(area); |
234 | 1 | return; |
235 | 195 | case OSPF_NETWORK_LSA: |
236 | 195 | case OSPF_OPAQUE_LINK_LSA: |
237 | | /* We must find the interface the LSA could belong to. |
238 | | If the interface is no more a broadcast type or we are no |
239 | | more |
240 | | the DR, we flush the LSA otherwise -- create the new instance |
241 | | and |
242 | | schedule flooding. */ |
243 | | |
244 | | /* Look through all interfaces, not just area, since interface |
245 | | could be moved from one area to another. */ |
246 | 195 | for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) |
247 | | /* These are sanity check. */ |
248 | 195 | if (IPV4_ADDR_SAME(&oi->address->u.prefix4, |
249 | 195 | &new->data->id)) { |
250 | 146 | if (oi->area != area |
251 | 146 | || oi->type != OSPF_IFTYPE_BROADCAST |
252 | 146 | || !IPV4_ADDR_SAME(&oi->address->u.prefix4, |
253 | 146 | &DR(oi))) { |
254 | 146 | ospf_schedule_lsa_flush_area(area, new); |
255 | 146 | return; |
256 | 146 | } |
257 | | |
258 | 0 | if (new->data->type == OSPF_OPAQUE_LINK_LSA) { |
259 | 0 | ospf_opaque_lsa_refresh(new); |
260 | 0 | return; |
261 | 0 | } |
262 | | |
263 | 0 | if (oi->network_lsa_self) |
264 | 0 | oi->network_lsa_self->data->ls_seqnum = |
265 | 0 | new->data->ls_seqnum; |
266 | | /* Schedule network-LSA origination. */ |
267 | 0 | ospf_network_lsa_update(oi); |
268 | 0 | return; |
269 | 0 | } |
270 | 49 | break; |
271 | 49 | case OSPF_SUMMARY_LSA: |
272 | 73 | case OSPF_ASBR_SUMMARY_LSA: |
273 | 73 | ospf_schedule_abr_task(ospf); |
274 | 73 | break; |
275 | 103 | case OSPF_AS_EXTERNAL_LSA: |
276 | 103 | case OSPF_AS_NSSA_LSA: |
277 | 103 | if ((new->data->type == OSPF_AS_EXTERNAL_LSA) |
278 | 103 | && CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)) { |
279 | 0 | ospf_translated_nssa_refresh(ospf, NULL, new); |
280 | 0 | return; |
281 | 0 | } |
282 | | |
283 | 103 | al = (struct as_external_lsa *)new->data; |
284 | 103 | p.family = AF_INET; |
285 | 103 | p.prefixlen = ip_masklen(al->mask); |
286 | 103 | p.prefix = new->data->id; |
287 | | |
288 | 103 | ei = ospf_external_info_check(ospf, new); |
289 | 103 | if (ei) { |
290 | 0 | if (ospf_external_aggr_match(ospf, &ei->p)) { |
291 | 0 | if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) |
292 | 0 | zlog_debug( |
293 | 0 | "%s, Matching external aggregate route found for %pI4, so don't refresh it.", |
294 | 0 | __func__, |
295 | 0 | &ei->p.prefix); |
296 | | |
297 | | /* Aggregated external route shouldn't |
298 | | * be in LSDB. |
299 | | */ |
300 | 0 | if (!IS_LSA_MAXAGE(new)) |
301 | 0 | ospf_lsa_flush_as(ospf, new); |
302 | |
|
303 | 0 | return; |
304 | 0 | } |
305 | | |
306 | 0 | ospf_external_lsa_refresh(ospf, new, ei, |
307 | 0 | LSA_REFRESH_FORCE, false); |
308 | 103 | } else { |
309 | 103 | aggr = (struct ospf_external_aggr_rt *) |
310 | 103 | ospf_extrenal_aggregator_lookup(ospf, &p); |
311 | 103 | if (aggr) { |
312 | 0 | struct external_info ei_aggr; |
313 | |
|
314 | 0 | memset(&ei_aggr, 0, |
315 | 0 | sizeof(struct external_info)); |
316 | 0 | ei_aggr.p = aggr->p; |
317 | 0 | ei_aggr.tag = aggr->tag; |
318 | 0 | ei_aggr.instance = ospf->instance; |
319 | 0 | ei_aggr.route_map_set.metric = -1; |
320 | 0 | ei_aggr.route_map_set.metric_type = -1; |
321 | |
|
322 | 0 | ospf_external_lsa_refresh(ospf, new, &ei_aggr, |
323 | 0 | LSA_REFRESH_FORCE, true); |
324 | 0 | SET_FLAG(aggr->flags, |
325 | 0 | OSPF_EXTERNAL_AGGRT_ORIGINATED); |
326 | 0 | } else |
327 | 103 | ospf_lsa_flush_as(ospf, new); |
328 | 103 | } |
329 | 103 | break; |
330 | 103 | case OSPF_OPAQUE_AREA_LSA: |
331 | 0 | ospf_opaque_lsa_refresh(new); |
332 | 0 | break; |
333 | 0 | case OSPF_OPAQUE_AS_LSA: |
334 | 0 | ospf_opaque_lsa_refresh(new); |
335 | | /* Reconsideration may needed. */ /* XXX */ |
336 | 0 | break; |
337 | 0 | default: |
338 | 0 | break; |
339 | 372 | } |
340 | 372 | } |
341 | | |
342 | | /* OSPF LSA flooding -- RFC2328 Section 13.(5). */ |
343 | | |
344 | | /* Now Updated for NSSA operation, as follows: |
345 | | |
346 | | |
347 | | Type-5's have no change. Blocked to STUB or NSSA. |
348 | | |
349 | | Type-7's can be received, and if a DR |
350 | | they will also flood the local NSSA Area as Type-7's |
351 | | |
352 | | If a Self-Originated LSA (now an ASBR), |
353 | | The LSDB will be updated as Type-5's, (for continual re-fresh) |
354 | | |
355 | | If an NSSA-IR it is installed/flooded as Type-7, P-bit on. |
356 | | if an NSSA-ABR it is installed/flooded as Type-7, P-bit off. |
357 | | |
358 | | Later, during the ABR TASK, if the ABR is the Elected NSSA |
359 | | translator, then All Type-7s (with P-bit ON) are Translated to |
360 | | Type-5's and flooded to all non-NSSA/STUB areas. |
361 | | |
362 | | During ASE Calculations, |
363 | | non-ABRs calculate external routes from Type-7's |
364 | | ABRs calculate external routes from Type-5's and non-self Type-7s |
365 | | */ |
366 | | int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr, |
367 | | struct ospf_lsa *current, struct ospf_lsa *new) |
368 | 8.37k | { |
369 | 8.37k | struct ospf_interface *oi; |
370 | 8.37k | int lsa_ack_flag; |
371 | | |
372 | | /* Type-7 LSA's will be flooded throughout their native NSSA area, |
373 | | but will also be flooded as Type-5's into ABR capable links. */ |
374 | | |
375 | 8.37k | if (IS_DEBUG_OSPF_EVENT) |
376 | 0 | zlog_debug( |
377 | 8.37k | "%s:LSA[Flooding]: start, NBR %pI4 (%s), cur(%p), New-LSA[%s]", |
378 | 8.37k | ospf_get_name(ospf), &nbr->router_id, |
379 | 8.37k | lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), |
380 | 8.37k | (void *)current, dump_lsa_key(new)); |
381 | | |
382 | 8.37k | oi = nbr->oi; |
383 | | |
384 | | /* If there is already a database copy, and if the |
385 | | database copy was received via flooding and installed less |
386 | | than MinLSArrival seconds ago, discard the new LSA |
387 | | (without acknowledging it). */ |
388 | 8.37k | if (current != NULL) /* -- endo. */ |
389 | 6.58k | { |
390 | 6.58k | if (IS_LSA_SELF(current) |
391 | 6.58k | && (ntohs(current->data->ls_age) == 0 |
392 | 3.71k | && ntohl(current->data->ls_seqnum) |
393 | 52 | == OSPF_INITIAL_SEQUENCE_NUMBER)) { |
394 | 0 | if (IS_DEBUG_OSPF_EVENT) |
395 | 0 | zlog_debug( |
396 | 0 | "%s:LSA[Flooding]: Got a self-originated LSA, while local one is initial instance.", |
397 | 0 | ospf_get_name(ospf)); |
398 | 0 | ; /* Accept this LSA for quick LSDB resynchronization. |
399 | | */ |
400 | 6.58k | } else if (monotime_since(¤t->tv_recv, NULL) |
401 | 6.58k | < ospf->min_ls_arrival * 1000LL) { |
402 | 6.58k | if (IS_DEBUG_OSPF_EVENT) |
403 | 0 | zlog_debug( |
404 | 6.58k | "%s:LSA[Flooding]: LSA is received recently.", |
405 | 6.58k | ospf_get_name(ospf)); |
406 | 6.58k | return -1; |
407 | 6.58k | } |
408 | 6.58k | } |
409 | | |
410 | | /* Flood the new LSA out some subset of the router's interfaces. |
411 | | In some cases (e.g., the state of the receiving interface is |
412 | | DR and the LSA was received from a router other than the |
413 | | Backup DR) the LSA will be flooded back out the receiving |
414 | | interface. */ |
415 | 1.79k | lsa_ack_flag = ospf_flood_through(ospf, nbr, new); |
416 | | |
417 | | /* Remove the current database copy from all neighbors' Link state |
418 | | retransmission lists. AS_EXTERNAL and AS_EXTERNAL_OPAQUE does |
419 | | ^^^^^^^^^^^^^^^^^^^^^^^ |
420 | | not have area ID. |
421 | | All other (even NSSA's) do have area ID. */ |
422 | 1.79k | if (current) { |
423 | 0 | switch (current->data->type) { |
424 | 0 | case OSPF_AS_EXTERNAL_LSA: |
425 | 0 | case OSPF_OPAQUE_AS_LSA: |
426 | 0 | ospf_ls_retransmit_delete_nbr_as(ospf, current); |
427 | 0 | break; |
428 | 0 | default: |
429 | 0 | ospf_ls_retransmit_delete_nbr_area(oi->area, current); |
430 | 0 | break; |
431 | 0 | } |
432 | 0 | } |
433 | | |
434 | | /* Do some internal house keeping that is needed here */ |
435 | 1.79k | SET_FLAG(new->flags, OSPF_LSA_RECEIVED); |
436 | 1.79k | (void)ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */ |
437 | | |
438 | | /* Received non-self-originated Grace LSA */ |
439 | 1.79k | if (IS_GRACE_LSA(new) && !IS_LSA_SELF(new)) { |
440 | | |
441 | 493 | if (IS_LSA_MAXAGE(new)) { |
442 | | |
443 | | /* Handling Max age grace LSA.*/ |
444 | 0 | if (IS_DEBUG_OSPF_GR) |
445 | 0 | zlog_debug( |
446 | 0 | "%s, Received a maxage GRACE-LSA from router %pI4", |
447 | 0 | __func__, &new->data->adv_router); |
448 | |
|
449 | 0 | if (current) { |
450 | 0 | ospf_process_maxage_grace_lsa(ospf, new, nbr); |
451 | 0 | } else { |
452 | 0 | if (IS_DEBUG_OSPF_GR) |
453 | 0 | zlog_debug( |
454 | 0 | "%s, Grace LSA doesn't exist in lsdb, so discarding grace lsa", |
455 | 0 | __func__); |
456 | 0 | return -1; |
457 | 0 | } |
458 | 493 | } else { |
459 | 493 | if (IS_DEBUG_OSPF_GR) |
460 | 0 | zlog_debug( |
461 | 493 | "%s, Received a GRACE-LSA from router %pI4", |
462 | 493 | __func__, &new->data->adv_router); |
463 | | |
464 | 493 | if (ospf_process_grace_lsa(ospf, new, nbr) |
465 | 493 | == OSPF_GR_NOT_HELPER) { |
466 | 493 | if (IS_DEBUG_OSPF_GR) |
467 | 0 | zlog_debug( |
468 | 493 | "%s, Not moving to HELPER role, So discarding grace LSA", |
469 | 493 | __func__); |
470 | 493 | return -1; |
471 | 493 | } |
472 | 493 | } |
473 | 493 | } |
474 | | |
475 | | /* Install the new LSA in the link state database |
476 | | (replacing the current database copy). This may cause the |
477 | | routing table calculation to be scheduled. In addition, |
478 | | timestamp the new LSA with the current time. The flooding |
479 | | procedure cannot overwrite the newly installed LSA until |
480 | | MinLSArrival seconds have elapsed. */ |
481 | | |
482 | 1.30k | if (!(new = ospf_lsa_install(ospf, oi, new))) |
483 | 180 | return -1; /* unknown LSA type or any other error condition */ |
484 | | |
485 | | /* check if the installed LSA is an indication LSA */ |
486 | 1.12k | if (ospf_check_indication_lsa(new) && !IS_LSA_SELF(new) && |
487 | 1.12k | !IS_LSA_MAXAGE(new)) { |
488 | 182 | new->area->fr_info.area_ind_lsa_recvd = true; |
489 | | /* check if there are already type 5 LSAs originated |
490 | | * with DNA bit set, if yes reoriginate those LSAs. |
491 | | */ |
492 | 182 | ospf_refresh_dna_type5_and_type7_lsas(ospf); |
493 | 182 | } |
494 | | |
495 | | /* Check if we recived an indication LSA flush on backbone |
496 | | * network. |
497 | | */ |
498 | 1.12k | ospf_recv_indication_lsa_flush(new); |
499 | | |
500 | 1.12k | if (new->area && OSPF_FR_CONFIG(ospf, new->area)) { |
501 | 0 | struct lsa_header const *lsah = new->data; |
502 | |
|
503 | 0 | if (!CHECK_FLAG(lsah->options, OSPF_OPTION_DC) && |
504 | 0 | !ospf_check_indication_lsa(new)) { |
505 | |
|
506 | 0 | new->area->fr_info.area_dc_clear = true; |
507 | | /* check of previously area supported flood reduction */ |
508 | 0 | if (new->area->fr_info.enabled) { |
509 | 0 | new->area->fr_info.enabled = false; |
510 | 0 | OSPF_LOG_DEBUG( |
511 | 0 | IS_DEBUG_OSPF_EVENT, |
512 | 0 | "Flood Reduction STATE on -> off by %s LSA", |
513 | 0 | dump_lsa_key(new)); |
514 | | /* if yes update all the lsa to the area the |
515 | | * new LSAs will have DNA bit set to 0. |
516 | | */ |
517 | 0 | ospf_refresh_area_self_lsas(new->area); |
518 | 0 | } |
519 | 0 | } else if (!new->area->fr_info.enabled) { |
520 | | /* check again after installing new LSA that area |
521 | | * supports flood reduction. |
522 | | */ |
523 | 0 | ospf_area_update_fr_state(new->area); |
524 | 0 | if (new->area->fr_info.enabled) { |
525 | 0 | OSPF_LOG_DEBUG( |
526 | 0 | IS_DEBUG_OSPF_EVENT, |
527 | 0 | "Flood Reduction STATE off -> on by %s LSA", |
528 | 0 | dump_lsa_key(new)); |
529 | 0 | ospf_refresh_area_self_lsas(new->area); |
530 | 0 | } |
531 | 0 | } |
532 | 0 | } |
533 | | |
534 | | /* Acknowledge the receipt of the LSA by sending a Link State |
535 | | Acknowledgment packet back out the receiving interface. */ |
536 | 1.12k | if (lsa_ack_flag) |
537 | 0 | ospf_flood_delayed_lsa_ack(nbr, new); |
538 | | |
539 | | /* If this new LSA indicates that it was originated by the |
540 | | receiving router itself, the router must take special action, |
541 | | either updating the LSA or in some cases flushing it from |
542 | | the routing domain. */ |
543 | 1.12k | if (ospf_lsa_is_self_originated(ospf, new)) |
544 | 372 | ospf_process_self_originated_lsa(ospf, new, oi->area); |
545 | 748 | else |
546 | | /* Update statistics value for OSPF-MIB. */ |
547 | 748 | ospf->rx_lsa_count++; |
548 | | |
549 | 1.12k | return 0; |
550 | 1.30k | } |
551 | | |
552 | | /* OSPF LSA flooding -- RFC2328 Section 13.3. */ |
553 | | int ospf_flood_through_interface(struct ospf_interface *oi, |
554 | | struct ospf_neighbor *inbr, |
555 | | struct ospf_lsa *lsa) |
556 | 1.63k | { |
557 | 1.63k | struct ospf_neighbor *onbr; |
558 | 1.63k | struct route_node *rn; |
559 | 1.63k | int retx_flag; |
560 | | |
561 | 1.63k | if (IS_DEBUG_OSPF_EVENT) |
562 | 0 | zlog_debug( |
563 | 1.63k | "%s: considering int %s (%s), INBR(%pI4), LSA[%s] AGE %u", |
564 | 1.63k | __func__, IF_NAME(oi), ospf_get_name(oi->ospf), |
565 | 1.63k | inbr ? &inbr->router_id : NULL, dump_lsa_key(lsa), |
566 | 1.63k | ntohs(lsa->data->ls_age)); |
567 | | |
568 | 1.63k | if (!ospf_if_is_enable(oi)) |
569 | 1.63k | return 0; |
570 | | |
571 | | /* If flood reduction is configured, set the DC bit on the lsa. */ |
572 | 0 | if (IS_LSA_SELF(lsa)) { |
573 | 0 | if (OSPF_FR_CONFIG(oi->area->ospf, oi->area)) { |
574 | 0 | if (!ospf_check_indication_lsa(lsa)) { |
575 | 0 | SET_FLAG(lsa->data->options, OSPF_OPTION_DC); |
576 | 0 | ospf_lsa_checksum(lsa->data); |
577 | 0 | } |
578 | 0 | } else if (CHECK_FLAG(lsa->data->options, OSPF_OPTION_DC)) { |
579 | 0 | UNSET_FLAG(lsa->data->options, OSPF_OPTION_DC); |
580 | 0 | ospf_lsa_checksum(lsa->data); |
581 | 0 | } |
582 | | |
583 | | /* If flood reduction is enabled then set DNA bit on the |
584 | | * self lsas. |
585 | | */ |
586 | 0 | if (oi->area->fr_info.enabled) |
587 | 0 | SET_FLAG(lsa->data->ls_age, DO_NOT_AGE); |
588 | 0 | } |
589 | | |
590 | | /* Remember if new LSA is added to a retransmit list. */ |
591 | 0 | retx_flag = 0; |
592 | | |
593 | | /* Each of the neighbors attached to this interface are examined, |
594 | | to determine whether they must receive the new LSA. The following |
595 | | steps are executed for each neighbor: */ |
596 | 0 | for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { |
597 | 0 | struct ospf_lsa *ls_req; |
598 | |
|
599 | 0 | if (rn->info == NULL) |
600 | 0 | continue; |
601 | | |
602 | 0 | onbr = rn->info; |
603 | 0 | if (IS_DEBUG_OSPF_EVENT) |
604 | 0 | zlog_debug( |
605 | 0 | "%s: considering nbr %pI4 via %s (%s), state: %s", |
606 | 0 | __func__, &onbr->router_id, IF_NAME(oi), |
607 | 0 | ospf_get_name(oi->ospf), |
608 | 0 | lookup_msg(ospf_nsm_state_msg, onbr->state, |
609 | 0 | NULL)); |
610 | | |
611 | | /* If the neighbor is in a lesser state than Exchange, it |
612 | | does not participate in flooding, and the next neighbor |
613 | | should be examined. */ |
614 | 0 | if (onbr->state < NSM_Exchange) |
615 | 0 | continue; |
616 | | |
617 | | /* If the adjacency is not yet full (neighbor state is |
618 | | Exchange or Loading), examine the Link state request |
619 | | list associated with this adjacency. If there is an |
620 | | instance of the new LSA on the list, it indicates that |
621 | | the neighboring router has an instance of the LSA |
622 | | already. Compare the new LSA to the neighbor's copy: */ |
623 | 0 | if (onbr->state < NSM_Full) { |
624 | 0 | if (IS_DEBUG_OSPF_EVENT) |
625 | 0 | zlog_debug( |
626 | 0 | "%s: adj to onbr %pI4 is not Full (%s)", |
627 | 0 | __func__, &onbr->router_id, |
628 | 0 | lookup_msg(ospf_nsm_state_msg, |
629 | 0 | onbr->state, NULL)); |
630 | 0 | ls_req = ospf_ls_request_lookup(onbr, lsa); |
631 | 0 | if (ls_req != NULL) { |
632 | 0 | int ret; |
633 | |
|
634 | 0 | ret = ospf_lsa_more_recent(ls_req, lsa); |
635 | | /* The new LSA is less recent. */ |
636 | 0 | if (ret > 0) |
637 | 0 | continue; |
638 | | /* The two copies are the same instance, then |
639 | | delete |
640 | | the LSA from the Link state request list. */ |
641 | 0 | else if (ret == 0) { |
642 | 0 | ospf_ls_request_delete(onbr, ls_req); |
643 | 0 | ospf_check_nbr_loading(onbr); |
644 | 0 | continue; |
645 | 0 | } |
646 | | /* The new LSA is more recent. Delete the LSA |
647 | | from the Link state request list. */ |
648 | 0 | else { |
649 | 0 | ospf_ls_request_delete(onbr, ls_req); |
650 | 0 | ospf_check_nbr_loading(onbr); |
651 | 0 | } |
652 | 0 | } |
653 | 0 | } |
654 | | |
655 | 0 | if (IS_OPAQUE_LSA(lsa->data->type)) { |
656 | 0 | if (!CHECK_FLAG(onbr->options, OSPF_OPTION_O)) { |
657 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
658 | 0 | zlog_debug( |
659 | 0 | "%s: Skipping neighbor %s via %pI4 -- Not Opaque-capable.", |
660 | 0 | __func__, IF_NAME(oi), |
661 | 0 | &onbr->router_id); |
662 | 0 | continue; |
663 | 0 | } |
664 | 0 | } |
665 | | |
666 | | /* If the new LSA was received from this neighbor, |
667 | | examine the next neighbor. */ |
668 | 0 | if (inbr) { |
669 | | /* |
670 | | * Triggered by LSUpd message parser "ospf_ls_upd ()". |
671 | | * E.g., all LSAs handling here is received via network. |
672 | | */ |
673 | 0 | if (IPV4_ADDR_SAME(&inbr->router_id, |
674 | 0 | &onbr->router_id)) { |
675 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
676 | 0 | zlog_debug( |
677 | 0 | "%s: Skipping neighbor %s via %pI4 -- inbr == onbr.", |
678 | 0 | __func__, IF_NAME(oi), |
679 | 0 | &inbr->router_id); |
680 | 0 | continue; |
681 | 0 | } |
682 | 0 | } else { |
683 | | /* |
684 | | * Triggered by MaxAge remover, so far. |
685 | | * NULL "inbr" means flooding starts from this node. |
686 | | */ |
687 | 0 | if (IPV4_ADDR_SAME(&lsa->data->adv_router, |
688 | 0 | &onbr->router_id)) { |
689 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
690 | 0 | zlog_debug( |
691 | 0 | "%s: Skipping neighbor %s via %pI4 -- lsah->adv_router == onbr.", |
692 | 0 | __func__, IF_NAME(oi), |
693 | 0 | &onbr->router_id); |
694 | 0 | continue; |
695 | 0 | } |
696 | 0 | } |
697 | | |
698 | | /* Add the new LSA to the Link state retransmission list |
699 | | for the adjacency. The LSA will be retransmitted |
700 | | at intervals until an acknowledgment is seen from |
701 | | the neighbor. */ |
702 | 0 | ospf_ls_retransmit_add(onbr, lsa); |
703 | 0 | retx_flag = 1; |
704 | 0 | } |
705 | | |
706 | | /* If in the previous step, the LSA was NOT added to any of |
707 | | the Link state retransmission lists, there is no need to |
708 | | flood the LSA out the interface. */ |
709 | 0 | if (retx_flag == 0) { |
710 | 0 | return (inbr && inbr->oi == oi); |
711 | 0 | } |
712 | | |
713 | | /* if we've received the lsa on this interface we need to perform |
714 | | additional checking */ |
715 | 0 | if (inbr && (inbr->oi == oi)) { |
716 | | /* If the new LSA was received on this interface, and it was |
717 | | received from either the Designated Router or the Backup |
718 | | Designated Router, chances are that all the neighbors have |
719 | | received the LSA already. */ |
720 | 0 | if (NBR_IS_DR(inbr) || NBR_IS_BDR(inbr)) { |
721 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
722 | 0 | zlog_debug("%s: DR/BDR NOT SEND to int %s (%s)", |
723 | 0 | __func__, IF_NAME(oi), |
724 | 0 | ospf_get_name(oi->ospf)); |
725 | 0 | return 1; |
726 | 0 | } |
727 | | |
728 | | /* If the new LSA was received on this interface, and the |
729 | | interface state is Backup, examine the next interface. The |
730 | | Designated Router will do the flooding on this interface. |
731 | | However, if the Designated Router fails the router will |
732 | | end up retransmitting the updates. */ |
733 | | |
734 | 0 | if (oi->state == ISM_Backup) { |
735 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
736 | 0 | zlog_debug( |
737 | 0 | "%s: ISM_Backup NOT SEND to int %s (%s)", |
738 | 0 | __func__, IF_NAME(oi), |
739 | 0 | ospf_get_name(oi->ospf)); |
740 | 0 | return 1; |
741 | 0 | } |
742 | 0 | } |
743 | | |
744 | | /* The LSA must be flooded out the interface. Send a Link State |
745 | | Update packet (including the new LSA as contents) out the |
746 | | interface. The LSA's LS age must be incremented by InfTransDelay |
747 | | (which must be > 0) when it is copied into the outgoing Link |
748 | | State Update packet (until the LS age field reaches the maximum |
749 | | value of MaxAge). */ |
750 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
751 | 0 | zlog_debug("%s: DR/BDR sending upd to int %s (%s)", __func__, |
752 | 0 | IF_NAME(oi), ospf_get_name(oi->ospf)); |
753 | | |
754 | | /* RFC2328 Section 13.3 |
755 | | On non-broadcast networks, separate Link State Update |
756 | | packets must be sent, as unicasts, to each adjacent neighbor |
757 | | (i.e., those in state Exchange or greater). The destination |
758 | | IP addresses for these packets are the neighbors' IP |
759 | | addresses. */ |
760 | 0 | if (oi->type == OSPF_IFTYPE_NBMA) { |
761 | 0 | struct ospf_neighbor *nbr; |
762 | |
|
763 | 0 | for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { |
764 | 0 | nbr = rn->info; |
765 | |
|
766 | 0 | if (!nbr) |
767 | 0 | continue; |
768 | 0 | if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange) |
769 | 0 | ospf_ls_upd_send_lsa(nbr, lsa, |
770 | 0 | OSPF_SEND_PACKET_DIRECT); |
771 | 0 | } |
772 | 0 | } else |
773 | | /* If P2MP delayed reflooding is configured and the LSA was |
774 | | received from a neighbor on the P2MP interface, do not flood |
775 | | if back out on the interface. The LSA will be retransmitted |
776 | | upon expiration of each neighbor's retransmission timer. This |
777 | | will allow time to receive a multicast multicast link state |
778 | | acknoweldgement and remove the LSA from each neighbor's link |
779 | | state retransmission list. */ |
780 | 0 | if (oi->p2mp_delay_reflood && |
781 | 0 | (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) && |
782 | 0 | (inbr != NULL) && (oi == inbr->oi)) { |
783 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
784 | 0 | zlog_debug( |
785 | 0 | "Delay reflooding for LSA[%s] from NBR %pI4 on interface %s", |
786 | 0 | dump_lsa_key(lsa), |
787 | 0 | inbr ? &(inbr->router_id) |
788 | 0 | : &(oi->ospf->router_id), |
789 | 0 | IF_NAME(oi)); |
790 | 0 | } else |
791 | 0 | ospf_ls_upd_send_lsa(oi->nbr_self, lsa, |
792 | 0 | OSPF_SEND_PACKET_INDIRECT); |
793 | |
|
794 | 0 | return 0; |
795 | 0 | } |
796 | | |
797 | | int ospf_flood_through_area(struct ospf_area *area, struct ospf_neighbor *inbr, |
798 | | struct ospf_lsa *lsa) |
799 | 1.63k | { |
800 | 1.63k | struct listnode *node, *nnode; |
801 | 1.63k | struct ospf_interface *oi; |
802 | 1.63k | int lsa_ack_flag = 0; |
803 | | |
804 | 1.63k | assert(area); |
805 | | /* All other types are specific to a single area (Area A). The |
806 | | eligible interfaces are all those interfaces attaching to the |
807 | | Area A. If Area A is the backbone, this includes all the virtual |
808 | | links. */ |
809 | 1.63k | for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) { |
810 | 1.63k | if (area->area_id.s_addr != OSPF_AREA_BACKBONE |
811 | 1.63k | && oi->type == OSPF_IFTYPE_VIRTUALLINK) |
812 | 0 | continue; |
813 | | |
814 | 1.63k | if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) |
815 | 1.63k | && (lsa->oi != oi)) { |
816 | | /* |
817 | | * Link local scoped Opaque-LSA should only be flooded |
818 | | * for the link on which the LSA has received. |
819 | | */ |
820 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
821 | 0 | zlog_debug( |
822 | 0 | "Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", |
823 | 0 | (void *)lsa->oi, (void *)oi); |
824 | 0 | continue; |
825 | 0 | } |
826 | | |
827 | 1.63k | if (ospf_flood_through_interface(oi, inbr, lsa)) |
828 | 0 | lsa_ack_flag = 1; |
829 | 1.63k | } |
830 | | |
831 | 0 | return (lsa_ack_flag); |
832 | 1.63k | } |
833 | | |
834 | | int ospf_flood_through_as(struct ospf *ospf, struct ospf_neighbor *inbr, |
835 | | struct ospf_lsa *lsa) |
836 | 276 | { |
837 | 276 | struct listnode *node; |
838 | 276 | struct ospf_area *area; |
839 | 276 | int lsa_ack_flag; |
840 | | |
841 | 276 | lsa_ack_flag = 0; |
842 | | |
843 | | /* The incoming LSA is type 5 or type 7 (AS-EXTERNAL or AS-NSSA ) |
844 | | |
845 | | Divert the Type-5 LSA's to all non-NSSA/STUB areas |
846 | | |
847 | | Divert the Type-7 LSA's to all NSSA areas |
848 | | |
849 | | AS-external-LSAs are flooded throughout the entire AS, with the |
850 | | exception of stub areas (see Section 3.6). The eligible |
851 | | interfaces are all the router's interfaces, excluding virtual |
852 | | links and those interfaces attaching to stub areas. */ |
853 | | |
854 | 276 | if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7 */ |
855 | 0 | if (IS_DEBUG_OSPF_NSSA) |
856 | 0 | zlog_debug("Flood/AS: NSSA TRANSLATED LSA"); |
857 | | |
858 | 276 | for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { |
859 | 0 | int continue_flag = 0; |
860 | 0 | struct listnode *if_node; |
861 | 0 | struct ospf_interface *oi; |
862 | |
|
863 | 0 | switch (area->external_routing) { |
864 | | /* Don't send AS externals into stub areas. Various types |
865 | | of support for partial stub areas can be implemented |
866 | | here. NSSA's will receive Type-7's that have areas |
867 | | matching the originl LSA. */ |
868 | 0 | case OSPF_AREA_NSSA: /* Sending Type 5 or 7 into NSSA area */ |
869 | | /* Type-7, flood NSSA area */ |
870 | 0 | if (lsa->data->type == OSPF_AS_NSSA_LSA |
871 | 0 | && area == lsa->area) |
872 | | /* We will send it. */ |
873 | 0 | continue_flag = 0; |
874 | 0 | else |
875 | 0 | continue_flag = 1; /* Skip this NSSA area for |
876 | | Type-5's et al */ |
877 | 0 | break; |
878 | | |
879 | 0 | case OSPF_AREA_TYPE_MAX: |
880 | 0 | case OSPF_AREA_STUB: |
881 | 0 | continue_flag = 1; /* Skip this area. */ |
882 | 0 | break; |
883 | | |
884 | 0 | case OSPF_AREA_DEFAULT: |
885 | 0 | default: |
886 | | /* No Type-7 into normal area */ |
887 | 0 | if (lsa->data->type == OSPF_AS_NSSA_LSA) |
888 | 0 | continue_flag = 1; /* skip Type-7 */ |
889 | 0 | else |
890 | 0 | continue_flag = 0; /* Do this area. */ |
891 | 0 | break; |
892 | 0 | } |
893 | | |
894 | | /* Do continue for above switch. Saves a big if then mess */ |
895 | 0 | if (continue_flag) |
896 | 0 | continue; /* main for-loop */ |
897 | | |
898 | | /* send to every interface in this area */ |
899 | | |
900 | 0 | for (ALL_LIST_ELEMENTS_RO(area->oiflist, if_node, oi)) { |
901 | | /* Skip virtual links */ |
902 | 0 | if (oi->type != OSPF_IFTYPE_VIRTUALLINK) |
903 | 0 | if (ospf_flood_through_interface(oi, inbr, |
904 | 0 | lsa)) /* lsa */ |
905 | 0 | lsa_ack_flag = 1; |
906 | 0 | } |
907 | 0 | } /* main area for-loop */ |
908 | | |
909 | 276 | return (lsa_ack_flag); |
910 | 276 | } |
911 | | |
912 | | int ospf_flood_through(struct ospf *ospf, struct ospf_neighbor *inbr, |
913 | | struct ospf_lsa *lsa) |
914 | 1.79k | { |
915 | 1.79k | int lsa_ack_flag = 0; |
916 | | |
917 | | /* Type-7 LSA's for NSSA are flooded throughout the AS here, and |
918 | | upon return are updated in the LSDB for Type-7's. Later, |
919 | | re-fresh will re-send them (and also, if ABR, packet code will |
920 | | translate to Type-5's) |
921 | | |
922 | | As usual, Type-5 LSA's (if not DISCARDED because we are STUB or |
923 | | NSSA) are flooded throughout the AS, and are updated in the |
924 | | global table. */ |
925 | | /* |
926 | | * At the common sub-sub-function "ospf_flood_through_interface()", |
927 | | * a parameter "inbr" will be used to distinguish the called context |
928 | | * whether the given LSA was received from the neighbor, or the |
929 | | * flooding for the LSA starts from this node (e.g. the LSA was self- |
930 | | * originated, or the LSA is going to be flushed from routing domain). |
931 | | * |
932 | | * So, for consistency reasons, this function "ospf_flood_through()" |
933 | | * should also allow the usage that the given "inbr" parameter to be |
934 | | * NULL. If we do so, corresponding AREA parameter should be referred |
935 | | * by "lsa->area", instead of "inbr->oi->area". |
936 | | */ |
937 | 1.79k | switch (lsa->data->type) { |
938 | 169 | case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ |
939 | 171 | case OSPF_OPAQUE_AS_LSA: |
940 | 171 | lsa_ack_flag = ospf_flood_through_as(ospf, inbr, lsa); |
941 | 171 | break; |
942 | | /* Type-7 Only received within NSSA, then flooded */ |
943 | 0 | case OSPF_AS_NSSA_LSA: |
944 | | /* Any P-bit was installed with the Type-7. */ |
945 | |
|
946 | 0 | if (IS_DEBUG_OSPF_NSSA) |
947 | 0 | zlog_debug("%s: LOCAL NSSA FLOOD of Type-7.", __func__); |
948 | | /* Fallthrough */ |
949 | 1.62k | default: |
950 | 1.62k | lsa_ack_flag = ospf_flood_through_area(lsa->area, inbr, lsa); |
951 | 1.62k | break; |
952 | 1.79k | } |
953 | | |
954 | | /* always need to send ack when incoming intf is PTP or P2MP */ |
955 | 1.79k | if (inbr != NULL && (inbr->oi->type == OSPF_IFTYPE_POINTOMULTIPOINT || |
956 | 1.79k | inbr->oi->type == OSPF_IFTYPE_POINTOPOINT)) |
957 | 0 | lsa_ack_flag = 1; |
958 | | |
959 | 1.79k | return (lsa_ack_flag); |
960 | 1.79k | } |
961 | | |
962 | | |
963 | | /* Management functions for neighbor's Link State Request list. */ |
964 | | void ospf_ls_request_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) |
965 | 7.22k | { |
966 | | /* |
967 | | * We cannot make use of the newly introduced callback function |
968 | | * "lsdb->new_lsa_hook" to replace debug output below, just because |
969 | | * it seems no simple and smart way to pass neighbor information to |
970 | | * the common function "ospf_lsdb_add()" -- endo. |
971 | | */ |
972 | 7.22k | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
973 | 0 | zlog_debug("RqstL(%lu)++, NBR(%pI4(%s)), LSA[%s]", |
974 | 7.22k | ospf_ls_request_count(nbr), |
975 | 7.22k | &nbr->router_id, |
976 | 7.22k | ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); |
977 | | |
978 | 7.22k | ospf_lsdb_add(&nbr->ls_req, lsa); |
979 | 7.22k | } |
980 | | |
981 | | unsigned long ospf_ls_request_count(struct ospf_neighbor *nbr) |
982 | 0 | { |
983 | 0 | return ospf_lsdb_count_all(&nbr->ls_req); |
984 | 0 | } |
985 | | |
986 | | int ospf_ls_request_isempty(struct ospf_neighbor *nbr) |
987 | 0 | { |
988 | 0 | return ospf_lsdb_isempty(&nbr->ls_req); |
989 | 0 | } |
990 | | |
991 | | /* Remove LSA from neighbor's ls-request list. */ |
992 | | void ospf_ls_request_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) |
993 | 0 | { |
994 | 0 | if (nbr->ls_req_last == lsa) { |
995 | 0 | ospf_lsa_unlock(&nbr->ls_req_last); |
996 | 0 | nbr->ls_req_last = NULL; |
997 | 0 | } |
998 | |
|
999 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ |
1000 | 0 | zlog_debug("RqstL(%lu)--, NBR(%pI4(%s)), LSA[%s]", |
1001 | 0 | ospf_ls_request_count(nbr), |
1002 | 0 | &nbr->router_id, |
1003 | 0 | ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); |
1004 | |
|
1005 | 0 | ospf_lsdb_delete(&nbr->ls_req, lsa); |
1006 | 0 | } |
1007 | | |
1008 | | /* Remove all LSA from neighbor's ls-requenst list. */ |
1009 | | void ospf_ls_request_delete_all(struct ospf_neighbor *nbr) |
1010 | 0 | { |
1011 | 0 | ospf_lsa_unlock(&nbr->ls_req_last); |
1012 | 0 | nbr->ls_req_last = NULL; |
1013 | 0 | ospf_lsdb_delete_all(&nbr->ls_req); |
1014 | 0 | } |
1015 | | |
1016 | | /* Lookup LSA from neighbor's ls-request list. */ |
1017 | | struct ospf_lsa *ospf_ls_request_lookup(struct ospf_neighbor *nbr, |
1018 | | struct ospf_lsa *lsa) |
1019 | 9.58k | { |
1020 | 9.58k | return ospf_lsdb_lookup(&nbr->ls_req, lsa); |
1021 | 9.58k | } |
1022 | | |
1023 | | struct ospf_lsa *ospf_ls_request_new(struct lsa_header *lsah) |
1024 | 7.53k | { |
1025 | 7.53k | struct ospf_lsa *new; |
1026 | | |
1027 | 7.53k | new = ospf_lsa_new_and_data(OSPF_LSA_HEADER_SIZE); |
1028 | 7.53k | memcpy(new->data, lsah, OSPF_LSA_HEADER_SIZE); |
1029 | | |
1030 | 7.53k | return new; |
1031 | 7.53k | } |
1032 | | |
1033 | | |
1034 | | /* Management functions for neighbor's ls-retransmit list. */ |
1035 | | unsigned long ospf_ls_retransmit_count(struct ospf_neighbor *nbr) |
1036 | 0 | { |
1037 | 0 | return ospf_lsdb_count_all(&nbr->ls_rxmt); |
1038 | 0 | } |
1039 | | |
1040 | | unsigned long ospf_ls_retransmit_count_self(struct ospf_neighbor *nbr, |
1041 | | int lsa_type) |
1042 | 0 | { |
1043 | 0 | return ospf_lsdb_count_self(&nbr->ls_rxmt, lsa_type); |
1044 | 0 | } |
1045 | | |
1046 | | int ospf_ls_retransmit_isempty(struct ospf_neighbor *nbr) |
1047 | 0 | { |
1048 | 0 | return ospf_lsdb_isempty(&nbr->ls_rxmt); |
1049 | 0 | } |
1050 | | |
1051 | | /* Add LSA to be retransmitted to neighbor's ls-retransmit list. */ |
1052 | | void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) |
1053 | 0 | { |
1054 | 0 | struct ospf_lsa *old; |
1055 | |
|
1056 | 0 | old = ospf_ls_retransmit_lookup(nbr, lsa); |
1057 | |
|
1058 | 0 | if (ospf_lsa_more_recent(old, lsa) < 0) { |
1059 | 0 | if (old) { |
1060 | 0 | old->retransmit_counter--; |
1061 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
1062 | 0 | zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]", |
1063 | 0 | ospf_ls_retransmit_count(nbr), |
1064 | 0 | &nbr->router_id, |
1065 | 0 | ospf_get_name(nbr->oi->ospf), |
1066 | 0 | dump_lsa_key(old)); |
1067 | 0 | ospf_lsdb_delete(&nbr->ls_rxmt, old); |
1068 | 0 | } |
1069 | 0 | lsa->retransmit_counter++; |
1070 | | /* |
1071 | | * We cannot make use of the newly introduced callback function |
1072 | | * "lsdb->new_lsa_hook" to replace debug output below, just |
1073 | | * because |
1074 | | * it seems no simple and smart way to pass neighbor information |
1075 | | * to |
1076 | | * the common function "ospf_lsdb_add()" -- endo. |
1077 | | */ |
1078 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) |
1079 | 0 | zlog_debug("RXmtL(%lu)++, NBR(%pI4(%s)), LSA[%s]", |
1080 | 0 | ospf_ls_retransmit_count(nbr), |
1081 | 0 | &nbr->router_id, |
1082 | 0 | ospf_get_name(nbr->oi->ospf), |
1083 | 0 | dump_lsa_key(lsa)); |
1084 | 0 | ospf_lsdb_add(&nbr->ls_rxmt, lsa); |
1085 | 0 | } |
1086 | 0 | } |
1087 | | |
1088 | | /* Remove LSA from neibghbor's ls-retransmit list. */ |
1089 | | void ospf_ls_retransmit_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) |
1090 | 0 | { |
1091 | 0 | if (ospf_ls_retransmit_lookup(nbr, lsa)) { |
1092 | 0 | lsa->retransmit_counter--; |
1093 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ |
1094 | 0 | zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]", |
1095 | 0 | ospf_ls_retransmit_count(nbr), |
1096 | 0 | &nbr->router_id, |
1097 | 0 | ospf_get_name(nbr->oi->ospf), |
1098 | 0 | dump_lsa_key(lsa)); |
1099 | 0 | ospf_lsdb_delete(&nbr->ls_rxmt, lsa); |
1100 | 0 | } |
1101 | 0 | } |
1102 | | |
1103 | | /* Clear neighbor's ls-retransmit list. */ |
1104 | | void ospf_ls_retransmit_clear(struct ospf_neighbor *nbr) |
1105 | 0 | { |
1106 | 0 | struct ospf_lsdb *lsdb; |
1107 | 0 | int i; |
1108 | |
|
1109 | 0 | lsdb = &nbr->ls_rxmt; |
1110 | |
|
1111 | 0 | for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { |
1112 | 0 | struct route_table *table = lsdb->type[i].db; |
1113 | 0 | struct route_node *rn; |
1114 | 0 | struct ospf_lsa *lsa; |
1115 | |
|
1116 | 0 | for (rn = route_top(table); rn; rn = route_next(rn)) |
1117 | 0 | if ((lsa = rn->info) != NULL) |
1118 | 0 | ospf_ls_retransmit_delete(nbr, lsa); |
1119 | 0 | } |
1120 | |
|
1121 | 0 | ospf_lsa_unlock(&nbr->ls_req_last); |
1122 | 0 | nbr->ls_req_last = NULL; |
1123 | 0 | } |
1124 | | |
1125 | | /* Lookup LSA from neighbor's ls-retransmit list. */ |
1126 | | struct ospf_lsa *ospf_ls_retransmit_lookup(struct ospf_neighbor *nbr, |
1127 | | struct ospf_lsa *lsa) |
1128 | 3.48k | { |
1129 | 3.48k | return ospf_lsdb_lookup(&nbr->ls_rxmt, lsa); |
1130 | 3.48k | } |
1131 | | |
1132 | | static void ospf_ls_retransmit_delete_nbr_if(struct ospf_interface *oi, |
1133 | | struct ospf_lsa *lsa) |
1134 | 0 | { |
1135 | 0 | struct route_node *rn; |
1136 | 0 | struct ospf_neighbor *nbr; |
1137 | 0 | struct ospf_lsa *lsr; |
1138 | |
|
1139 | 0 | if (ospf_if_is_enable(oi)) |
1140 | 0 | for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { |
1141 | | /* If LSA find in LS-retransmit list, then remove it. */ |
1142 | 0 | nbr = rn->info; |
1143 | |
|
1144 | 0 | if (!nbr) |
1145 | 0 | continue; |
1146 | | |
1147 | 0 | lsr = ospf_ls_retransmit_lookup(nbr, lsa); |
1148 | | |
1149 | | /* If LSA find in ls-retransmit list, remove it. */ |
1150 | 0 | if (lsr != NULL && |
1151 | 0 | lsr->data->ls_seqnum == lsa->data->ls_seqnum) |
1152 | 0 | ospf_ls_retransmit_delete(nbr, lsr); |
1153 | 0 | } |
1154 | 0 | } |
1155 | | |
1156 | | void ospf_ls_retransmit_delete_nbr_area(struct ospf_area *area, |
1157 | | struct ospf_lsa *lsa) |
1158 | 0 | { |
1159 | 0 | struct listnode *node, *nnode; |
1160 | 0 | struct ospf_interface *oi; |
1161 | |
|
1162 | 0 | for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) |
1163 | 0 | ospf_ls_retransmit_delete_nbr_if(oi, lsa); |
1164 | 0 | } |
1165 | | |
1166 | | void ospf_ls_retransmit_delete_nbr_as(struct ospf *ospf, struct ospf_lsa *lsa) |
1167 | 0 | { |
1168 | 0 | struct listnode *node, *nnode; |
1169 | 0 | struct ospf_interface *oi; |
1170 | |
|
1171 | 0 | for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) |
1172 | 0 | ospf_ls_retransmit_delete_nbr_if(oi, lsa); |
1173 | 0 | } |
1174 | | |
1175 | | |
1176 | | /* Sets ls_age to MaxAge and floods throu the area. |
1177 | | When we implement ASE routing, there will be another function |
1178 | | flushing an LSA from the whole domain. */ |
1179 | | void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area) |
1180 | 0 | { |
1181 | 0 | struct ospf *ospf = area->ospf; |
1182 | |
|
1183 | 0 | if (ospf_lsa_is_self_originated(ospf, lsa) |
1184 | 0 | && ospf->gr_info.restart_in_progress) { |
1185 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) |
1186 | 0 | zlog_debug( |
1187 | 0 | "%s:LSA[Type%d:%pI4]: Graceful Restart in progress -- not flushing self-originated LSA", |
1188 | 0 | ospf_get_name(ospf), lsa->data->type, |
1189 | 0 | &lsa->data->id); |
1190 | 0 | return; |
1191 | 0 | } |
1192 | | |
1193 | | /* Reset the lsa origination time such that it gives |
1194 | | more time for the ACK to be received and avoid |
1195 | | retransmissions */ |
1196 | 0 | lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); |
1197 | 0 | if (IS_DEBUG_OSPF_EVENT) |
1198 | 0 | zlog_debug("%s: MaxAge set to LSA[%s]", __func__, |
1199 | 0 | dump_lsa_key(lsa)); |
1200 | 0 | monotime(&lsa->tv_recv); |
1201 | 0 | lsa->tv_orig = lsa->tv_recv; |
1202 | 0 | ospf_flood_through_area(area, NULL, lsa); |
1203 | 0 | ospf_lsa_maxage(ospf, lsa); |
1204 | 0 | } |
1205 | | |
1206 | | void ospf_lsa_flush_as(struct ospf *ospf, struct ospf_lsa *lsa) |
1207 | 103 | { |
1208 | 103 | if (ospf_lsa_is_self_originated(ospf, lsa) |
1209 | 103 | && ospf->gr_info.restart_in_progress) { |
1210 | 0 | if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) |
1211 | 0 | zlog_debug( |
1212 | 0 | "%s:LSA[Type%d:%pI4]: Graceful Restart in progress -- not flushing self-originated LSA", |
1213 | 0 | ospf_get_name(ospf), lsa->data->type, |
1214 | 0 | &lsa->data->id); |
1215 | 0 | return; |
1216 | 0 | } |
1217 | | |
1218 | | /* Reset the lsa origination time such that it gives |
1219 | | more time for the ACK to be received and avoid |
1220 | | retransmissions */ |
1221 | 103 | lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); |
1222 | 103 | if (IS_DEBUG_OSPF_EVENT) |
1223 | 0 | zlog_debug("%s: MaxAge set to LSA[%s]", __func__, |
1224 | 103 | dump_lsa_key(lsa)); |
1225 | 103 | monotime(&lsa->tv_recv); |
1226 | 103 | lsa->tv_orig = lsa->tv_recv; |
1227 | 103 | ospf_flood_through_as(ospf, NULL, lsa); |
1228 | 103 | ospf_lsa_maxage(ospf, lsa); |
1229 | 103 | } |
1230 | | |
1231 | | void ospf_lsa_flush(struct ospf *ospf, struct ospf_lsa *lsa) |
1232 | 0 | { |
1233 | 0 | lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); |
1234 | |
|
1235 | 0 | switch (lsa->data->type) { |
1236 | 0 | case OSPF_ROUTER_LSA: |
1237 | 0 | case OSPF_NETWORK_LSA: |
1238 | 0 | case OSPF_SUMMARY_LSA: |
1239 | 0 | case OSPF_ASBR_SUMMARY_LSA: |
1240 | 0 | case OSPF_AS_NSSA_LSA: |
1241 | 0 | case OSPF_OPAQUE_LINK_LSA: |
1242 | 0 | case OSPF_OPAQUE_AREA_LSA: |
1243 | 0 | ospf_lsa_flush_area(lsa, lsa->area); |
1244 | 0 | break; |
1245 | 0 | case OSPF_AS_EXTERNAL_LSA: |
1246 | 0 | case OSPF_OPAQUE_AS_LSA: |
1247 | 0 | ospf_lsa_flush_as(ospf, lsa); |
1248 | 0 | break; |
1249 | 0 | default: |
1250 | 0 | zlog_info("%s: Unknown LSA type %u", __func__, lsa->data->type); |
1251 | 0 | break; |
1252 | 0 | } |
1253 | 0 | } |