]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * OSPF Flooding -- RFC2328 Section 13. | |
3 | * Copyright (C) 1999, 2000 Toshiaki Takada | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published | |
9 | * by the Free Software Foundation; either version 2, or (at your | |
10 | * option) any later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the | |
19 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | * Boston, MA 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "linklist.h" | |
26 | #include "prefix.h" | |
27 | #include "if.h" | |
28 | #include "command.h" | |
29 | #include "table.h" | |
30 | #include "thread.h" | |
31 | #include "memory.h" | |
32 | #include "log.h" | |
33 | #include "zclient.h" | |
34 | ||
35 | #include "ospfd/ospfd.h" | |
36 | #include "ospfd/ospf_interface.h" | |
37 | #include "ospfd/ospf_ism.h" | |
38 | #include "ospfd/ospf_asbr.h" | |
39 | #include "ospfd/ospf_lsa.h" | |
40 | #include "ospfd/ospf_lsdb.h" | |
41 | #include "ospfd/ospf_neighbor.h" | |
42 | #include "ospfd/ospf_nsm.h" | |
43 | #include "ospfd/ospf_spf.h" | |
44 | #include "ospfd/ospf_flood.h" | |
45 | #include "ospfd/ospf_packet.h" | |
46 | #include "ospfd/ospf_abr.h" | |
47 | #include "ospfd/ospf_route.h" | |
48 | #include "ospfd/ospf_zebra.h" | |
49 | #include "ospfd/ospf_dump.h" | |
50 | ||
51 | extern struct zclient *zclient; | |
52 | \f | |
53 | /* Do the LSA acking specified in table 19, Section 13.5, row 2 | |
54 | * This get called from ospf_flood_out_interface. Declared inline | |
55 | * for speed. */ | |
56 | static void | |
57 | ospf_flood_delayed_lsa_ack (struct ospf_neighbor *inbr, struct ospf_lsa *lsa) | |
58 | { | |
59 | /* LSA is more recent than database copy, but was not | |
60 | flooded back out receiving interface. Delayed | |
61 | acknowledgment sent. If interface is in Backup state | |
62 | delayed acknowledgment sent only if advertisement | |
63 | received from Designated Router, otherwise do nothing See | |
64 | RFC 2328 Section 13.5 */ | |
65 | ||
66 | /* Whether LSA is more recent or not, and whether this is in | |
67 | response to the LSA being sent out recieving interface has been | |
68 | worked out previously */ | |
69 | ||
70 | /* Deal with router as BDR */ | |
71 | if (inbr->oi->state == ISM_Backup && ! NBR_IS_DR (inbr)) | |
72 | return; | |
73 | ||
74 | /* Schedule a delayed LSA Ack to be sent */ | |
1fe6ed38 | 75 | listnode_add (inbr->oi->ls_ack, ospf_lsa_lock (lsa)); /* delayed LSA Ack */ |
718e3744 | 76 | } |
77 | ||
78 | /* Check LSA is related to external info. */ | |
79 | struct external_info * | |
80 | ospf_external_info_check (struct ospf_lsa *lsa) | |
81 | { | |
82 | struct as_external_lsa *al; | |
83 | struct prefix_ipv4 p; | |
84 | struct route_node *rn; | |
85 | int type; | |
86 | ||
87 | al = (struct as_external_lsa *) lsa->data; | |
88 | ||
89 | p.family = AF_INET; | |
90 | p.prefix = lsa->data->id; | |
91 | p.prefixlen = ip_masklen (al->mask); | |
92 | ||
93 | for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) | |
94 | { | |
95 | int redist_type = is_prefix_default (&p) ? DEFAULT_ROUTE : type; | |
96 | if (ospf_is_type_redistributed (redist_type)) | |
97 | if (EXTERNAL_INFO (type)) | |
98 | { | |
99 | rn = route_node_lookup (EXTERNAL_INFO (type), | |
100 | (struct prefix *) &p); | |
101 | if (rn) | |
102 | { | |
103 | route_unlock_node (rn); | |
104 | if (rn->info != NULL) | |
105 | return (struct external_info *) rn->info; | |
106 | } | |
107 | } | |
108 | } | |
109 | ||
110 | return NULL; | |
111 | } | |
112 | ||
4dadc291 | 113 | static void |
68980084 | 114 | ospf_process_self_originated_lsa (struct ospf *ospf, |
115 | struct ospf_lsa *new, struct ospf_area *area) | |
718e3744 | 116 | { |
117 | struct ospf_interface *oi; | |
118 | struct external_info *ei; | |
52dc7ee6 | 119 | struct listnode *node; |
718e3744 | 120 | |
121 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 122 | zlog_debug ("LSA[Type%d:%s]: Process self-originated LSA seq 0x%x", |
7ddf1d6e | 123 | new->data->type, inet_ntoa (new->data->id), |
0c2be26c | 124 | ntohl(new->data->ls_seqnum)); |
718e3744 | 125 | |
126 | /* If we're here, we installed a self-originated LSA that we received | |
127 | from a neighbor, i.e. it's more recent. We must see whether we want | |
128 | to originate it. | |
129 | If yes, we should use this LSA's sequence number and reoriginate | |
130 | a new instance. | |
131 | if not --- we must flush this LSA from the domain. */ | |
132 | switch (new->data->type) | |
133 | { | |
134 | case OSPF_ROUTER_LSA: | |
135 | /* Originate a new instance and schedule flooding */ | |
bd246242 JT |
136 | if (area->router_lsa_self) |
137 | area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum; | |
c363d386 | 138 | ospf_router_lsa_update_area (area); |
718e3744 | 139 | return; |
140 | case OSPF_NETWORK_LSA: | |
141 | #ifdef HAVE_OPAQUE_LSA | |
142 | case OSPF_OPAQUE_LINK_LSA: | |
143 | #endif /* HAVE_OPAQUE_LSA */ | |
144 | /* We must find the interface the LSA could belong to. | |
145 | If the interface is no more a broadcast type or we are no more | |
146 | the DR, we flush the LSA otherwise -- create the new instance and | |
147 | schedule flooding. */ | |
148 | ||
149 | /* Look through all interfaces, not just area, since interface | |
150 | could be moved from one area to another. */ | |
1eb8ef25 | 151 | for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) |
718e3744 | 152 | /* These are sanity check. */ |
1eb8ef25 | 153 | if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &new->data->id)) |
154 | { | |
155 | if (oi->area != area || | |
156 | oi->type != OSPF_IFTYPE_BROADCAST || | |
157 | !IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) | |
158 | { | |
159 | ospf_schedule_lsa_flush_area (area, new); | |
160 | return; | |
161 | } | |
162 | ||
718e3744 | 163 | #ifdef HAVE_OPAQUE_LSA |
1eb8ef25 | 164 | if (new->data->type == OSPF_OPAQUE_LINK_LSA) |
165 | { | |
166 | ospf_opaque_lsa_refresh (new); | |
167 | return; | |
168 | } | |
718e3744 | 169 | #endif /* HAVE_OPAQUE_LSA */ |
170 | ||
bd246242 JT |
171 | if (oi->network_lsa_self) |
172 | oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum; | |
1eb8ef25 | 173 | /* Schedule network-LSA origination. */ |
c363d386 | 174 | ospf_network_lsa_update (oi); |
1eb8ef25 | 175 | return; |
176 | } | |
718e3744 | 177 | break; |
178 | case OSPF_SUMMARY_LSA: | |
179 | case OSPF_ASBR_SUMMARY_LSA: | |
68980084 | 180 | ospf_schedule_abr_task (ospf); |
718e3744 | 181 | break; |
182 | case OSPF_AS_EXTERNAL_LSA : | |
718e3744 | 183 | case OSPF_AS_NSSA_LSA: |
d4a53d58 | 184 | if ( (new->data->type == OSPF_AS_EXTERNAL_LSA) |
185 | && CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)) | |
186 | { | |
187 | ospf_translated_nssa_refresh (ospf, NULL, new); | |
188 | return; | |
189 | } | |
718e3744 | 190 | ei = ospf_external_info_check (new); |
191 | if (ei) | |
d4a53d58 | 192 | ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE); |
718e3744 | 193 | else |
d4a53d58 | 194 | ospf_lsa_flush_as (ospf, new); |
718e3744 | 195 | break; |
196 | #ifdef HAVE_OPAQUE_LSA | |
197 | case OSPF_OPAQUE_AREA_LSA: | |
198 | ospf_opaque_lsa_refresh (new); | |
199 | break; | |
200 | case OSPF_OPAQUE_AS_LSA: | |
201 | ospf_opaque_lsa_refresh (new); /* Reconsideration may needed. *//* XXX */ | |
202 | break; | |
203 | #endif /* HAVE_OPAQUE_LSA */ | |
204 | default: | |
205 | break; | |
206 | } | |
207 | } | |
208 | ||
209 | /* OSPF LSA flooding -- RFC2328 Section 13.(5). */ | |
210 | ||
211 | /* Now Updated for NSSA operation, as follows: | |
212 | ||
213 | ||
214 | Type-5's have no change. Blocked to STUB or NSSA. | |
215 | ||
216 | Type-7's can be received, and if a DR | |
217 | they will also flood the local NSSA Area as Type-7's | |
218 | ||
219 | If a Self-Originated LSA (now an ASBR), | |
220 | The LSDB will be updated as Type-5's, (for continual re-fresh) | |
221 | ||
222 | If an NSSA-IR it is installed/flooded as Type-7, P-bit on. | |
223 | if an NSSA-ABR it is installed/flooded as Type-7, P-bit off. | |
224 | ||
225 | Later, during the ABR TASK, if the ABR is the Elected NSSA | |
226 | translator, then All Type-7s (with P-bit ON) are Translated to | |
227 | Type-5's and flooded to all non-NSSA/STUB areas. | |
228 | ||
229 | During ASE Calculations, | |
230 | non-ABRs calculate external routes from Type-7's | |
231 | ABRs calculate external routes from Type-5's and non-self Type-7s | |
232 | */ | |
233 | int | |
68980084 | 234 | ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, |
235 | struct ospf_lsa *current, struct ospf_lsa *new) | |
718e3744 | 236 | { |
237 | struct ospf_interface *oi; | |
718e3744 | 238 | int lsa_ack_flag; |
239 | ||
240 | /* Type-7 LSA's will be flooded throughout their native NSSA area, | |
241 | but will also be flooded as Type-5's into ABR capable links. */ | |
242 | ||
243 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 244 | zlog_debug ("LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]", |
718e3744 | 245 | inet_ntoa (nbr->router_id), |
246 | LOOKUP (ospf_nsm_state_msg, nbr->state), | |
247 | current, | |
248 | dump_lsa_key (new)); | |
249 | ||
250 | lsa_ack_flag = 0; | |
251 | oi = nbr->oi; | |
252 | ||
718e3744 | 253 | /* If there is already a database copy, and if the |
254 | database copy was received via flooding and installed less | |
255 | than MinLSArrival seconds ago, discard the new LSA | |
256 | (without acknowledging it). */ | |
257 | if (current != NULL) /* -- endo. */ | |
258 | { | |
259 | if (IS_LSA_SELF (current) | |
260 | && (ntohs (current->data->ls_age) == 0 | |
261 | && ntohl (current->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)) | |
262 | { | |
263 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 264 | zlog_debug ("LSA[Flooding]: Got a self-originated LSA, " |
718e3744 | 265 | "while local one is initial instance."); |
266 | ; /* Accept this LSA for quick LSDB resynchronization. */ | |
267 | } | |
2518efd1 | 268 | else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv), |
718e3744 | 269 | int2tv (OSPF_MIN_LS_ARRIVAL)) < 0) |
270 | { | |
271 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 272 | zlog_debug ("LSA[Flooding]: LSA is received recently."); |
718e3744 | 273 | return -1; |
274 | } | |
275 | } | |
276 | ||
277 | /* Flood the new LSA out some subset of the router's interfaces. | |
278 | In some cases (e.g., the state of the receiving interface is | |
279 | DR and the LSA was received from a router other than the | |
280 | Backup DR) the LSA will be flooded back out the receiving | |
281 | interface. */ | |
68980084 | 282 | lsa_ack_flag = ospf_flood_through (ospf, nbr, new); |
718e3744 | 283 | |
284 | #ifdef HAVE_OPAQUE_LSA | |
285 | /* Remove the current database copy from all neighbors' Link state | |
286 | retransmission lists. AS_EXTERNAL and AS_EXTERNAL_OPAQUE does | |
287 | ^^^^^^^^^^^^^^^^^^^^^^^ | |
288 | not have area ID. | |
289 | All other (even NSSA's) do have area ID. */ | |
290 | #else /* HAVE_OPAQUE_LSA */ | |
291 | /* Remove the current database copy from all neighbors' Link state | |
292 | retransmission lists. Only AS_EXTERNAL does not have area ID. | |
293 | All other (even NSSA's) do have area ID. */ | |
294 | #endif /* HAVE_OPAQUE_LSA */ | |
295 | if (current) | |
296 | { | |
297 | switch (current->data->type) | |
298 | { | |
299 | case OSPF_AS_EXTERNAL_LSA: | |
300 | #ifdef HAVE_OPAQUE_LSA | |
301 | case OSPF_OPAQUE_AS_LSA: | |
302 | #endif /* HAVE_OPAQUE_LSA */ | |
68980084 | 303 | ospf_ls_retransmit_delete_nbr_as (ospf, current); |
718e3744 | 304 | break; |
305 | default: | |
68980084 | 306 | ospf_ls_retransmit_delete_nbr_area (nbr->oi->area, current); |
718e3744 | 307 | break; |
308 | } | |
309 | } | |
310 | ||
311 | /* Do some internal house keeping that is needed here */ | |
312 | SET_FLAG (new->flags, OSPF_LSA_RECEIVED); | |
68980084 | 313 | ospf_lsa_is_self_originated (ospf, new); /* Let it set the flag */ |
718e3744 | 314 | |
315 | /* Install the new LSA in the link state database | |
316 | (replacing the current database copy). This may cause the | |
317 | routing table calculation to be scheduled. In addition, | |
318 | timestamp the new LSA with the current time. The flooding | |
319 | procedure cannot overwrite the newly installed LSA until | |
320 | MinLSArrival seconds have elapsed. */ | |
321 | ||
6b161fc1 | 322 | if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) |
4de148e5 | 323 | return -1; /* unknown LSA type or any other error condition */ |
718e3744 | 324 | |
325 | /* Acknowledge the receipt of the LSA by sending a Link State | |
326 | Acknowledgment packet back out the receiving interface. */ | |
327 | if (lsa_ack_flag) | |
328 | ospf_flood_delayed_lsa_ack (nbr, new); | |
329 | ||
330 | /* If this new LSA indicates that it was originated by the | |
331 | receiving router itself, the router must take special action, | |
332 | either updating the LSA or in some cases flushing it from | |
333 | the routing domain. */ | |
68980084 | 334 | if (ospf_lsa_is_self_originated (ospf, new)) |
335 | ospf_process_self_originated_lsa (ospf, new, oi->area); | |
718e3744 | 336 | else |
337 | /* Update statistics value for OSPF-MIB. */ | |
68980084 | 338 | ospf->rx_lsa_count++; |
718e3744 | 339 | |
340 | return 0; | |
341 | } | |
342 | ||
343 | /* OSPF LSA flooding -- RFC2328 Section 13.3. */ | |
4dadc291 | 344 | static int |
718e3744 | 345 | ospf_flood_through_interface (struct ospf_interface *oi, |
346 | struct ospf_neighbor *inbr, | |
347 | struct ospf_lsa *lsa) | |
348 | { | |
349 | struct ospf_neighbor *onbr; | |
350 | struct route_node *rn; | |
351 | int retx_flag; | |
352 | ||
353 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 354 | zlog_debug ("ospf_flood_through_interface(): " |
718e3744 | 355 | "considering int %s, INBR(%s), LSA[%s]", |
356 | IF_NAME (oi), inbr ? inet_ntoa (inbr->router_id) : "NULL", | |
357 | dump_lsa_key (lsa)); | |
358 | ||
359 | if (!ospf_if_is_enable (oi)) | |
360 | return 0; | |
361 | ||
362 | /* Remember if new LSA is aded to a retransmit list. */ | |
363 | retx_flag = 0; | |
364 | ||
365 | /* Each of the neighbors attached to this interface are examined, | |
366 | to determine whether they must receive the new LSA. The following | |
367 | steps are executed for each neighbor: */ | |
368 | for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) | |
369 | { | |
370 | struct ospf_lsa *ls_req; | |
371 | ||
372 | if (rn->info == NULL) | |
373 | continue; | |
374 | ||
375 | onbr = rn->info; | |
376 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 377 | zlog_debug ("ospf_flood_through_interface(): considering nbr %s (%s)", |
718e3744 | 378 | inet_ntoa (onbr->router_id), |
379 | LOOKUP (ospf_nsm_state_msg, onbr->state)); | |
380 | ||
381 | /* If the neighbor is in a lesser state than Exchange, it | |
382 | does not participate in flooding, and the next neighbor | |
383 | should be examined. */ | |
384 | if (onbr->state < NSM_Exchange) | |
385 | continue; | |
386 | ||
387 | /* If the adjacency is not yet full (neighbor state is | |
388 | Exchange or Loading), examine the Link state request | |
389 | list associated with this adjacency. If there is an | |
390 | instance of the new LSA on the list, it indicates that | |
391 | the neighboring router has an instance of the LSA | |
392 | already. Compare the new LSA to the neighbor's copy: */ | |
393 | if (onbr->state < NSM_Full) | |
394 | { | |
395 | if (IS_DEBUG_OSPF_EVENT) | |
60925303 | 396 | zlog_debug ("ospf_flood_through_interface(): nbr adj is not Full"); |
718e3744 | 397 | ls_req = ospf_ls_request_lookup (onbr, lsa); |
398 | if (ls_req != NULL) | |
399 | { | |
400 | int ret; | |
401 | ||
402 | ret = ospf_lsa_more_recent (ls_req, lsa); | |
403 | /* The new LSA is less recent. */ | |
404 | if (ret > 0) | |
405 | continue; | |
406 | /* The two copies are the same instance, then delete | |
407 | the LSA from the Link state request list. */ | |
408 | else if (ret == 0) | |
409 | { | |
410 | ospf_ls_request_delete (onbr, ls_req); | |
411 | ospf_check_nbr_loading (onbr); | |
412 | continue; | |
413 | } | |
414 | /* The new LSA is more recent. Delete the LSA | |
415 | from the Link state request list. */ | |
416 | else | |
417 | { | |
418 | ospf_ls_request_delete (onbr, ls_req); | |
419 | ospf_check_nbr_loading (onbr); | |
420 | } | |
421 | } | |
422 | } | |
423 | ||
424 | #ifdef HAVE_OPAQUE_LSA | |
425 | if (IS_OPAQUE_LSA (lsa->data->type)) | |
426 | { | |
427 | if (! CHECK_FLAG (onbr->options, OSPF_OPTION_O)) | |
428 | { | |
429 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 430 | zlog_debug ("Skip this neighbor: Not Opaque-capable."); |
718e3744 | 431 | continue; |
432 | } | |
433 | ||
29226d4a | 434 | if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (oi->ospf->opaque) |
718e3744 | 435 | && IS_LSA_SELF (lsa) |
436 | && onbr->state == NSM_Full) | |
437 | { | |
438 | /* Small attempt to reduce unnecessary retransmission. */ | |
439 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 440 | zlog_debug ("Skip this neighbor: Initial flushing done."); |
718e3744 | 441 | continue; |
442 | } | |
443 | } | |
444 | #endif /* HAVE_OPAQUE_LSA */ | |
445 | ||
446 | /* If the new LSA was received from this neighbor, | |
447 | examine the next neighbor. */ | |
448 | #ifdef ORIGINAL_CODING | |
449 | if (inbr) | |
450 | if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id)) | |
451 | continue; | |
452 | #else /* ORIGINAL_CODING */ | |
453 | if (inbr) | |
454 | { | |
455 | /* | |
456 | * Triggered by LSUpd message parser "ospf_ls_upd ()". | |
457 | * E.g., all LSAs handling here is received via network. | |
458 | */ | |
459 | if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id)) | |
460 | { | |
461 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 462 | zlog_debug ("Skip this neighbor: inbr == onbr"); |
718e3744 | 463 | continue; |
464 | } | |
465 | } | |
466 | else | |
467 | { | |
468 | /* | |
469 | * Triggered by MaxAge remover, so far. | |
470 | * NULL "inbr" means flooding starts from this node. | |
471 | */ | |
472 | if (IPV4_ADDR_SAME (&lsa->data->adv_router, &onbr->router_id)) | |
473 | { | |
474 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 475 | zlog_debug ("Skip this neighbor: lsah->adv_router == onbr"); |
718e3744 | 476 | continue; |
477 | } | |
478 | } | |
479 | #endif /* ORIGINAL_CODING */ | |
480 | ||
481 | /* Add the new LSA to the Link state retransmission list | |
482 | for the adjacency. The LSA will be retransmitted | |
483 | at intervals until an acknowledgment is seen from | |
484 | the neighbor. */ | |
485 | ospf_ls_retransmit_add (onbr, lsa); | |
486 | retx_flag = 1; | |
487 | } | |
488 | ||
489 | /* If in the previous step, the LSA was NOT added to any of | |
490 | the Link state retransmission lists, there is no need to | |
491 | flood the LSA out the interface. */ | |
492 | if (retx_flag == 0) | |
493 | { | |
494 | return (inbr && inbr->oi == oi); | |
495 | } | |
496 | ||
497 | /* if we've received the lsa on this interface we need to perform | |
498 | additional checking */ | |
499 | if (inbr && (inbr->oi == oi)) | |
500 | { | |
501 | /* If the new LSA was received on this interface, and it was | |
502 | received from either the Designated Router or the Backup | |
503 | Designated Router, chances are that all the neighbors have | |
504 | received the LSA already. */ | |
505 | if (NBR_IS_DR (inbr) || NBR_IS_BDR (inbr)) | |
506 | { | |
718e3744 | 507 | if (IS_DEBUG_OSPF_NSSA) |
60925303 | 508 | zlog_debug ("ospf_flood_through_interface(): " |
718e3744 | 509 | "DR/BDR NOT SEND to int %s", IF_NAME (oi)); |
718e3744 | 510 | return 1; |
511 | } | |
512 | ||
513 | /* If the new LSA was received on this interface, and the | |
514 | interface state is Backup, examine the next interface. The | |
515 | Designated Router will do the flooding on this interface. | |
516 | However, if the Designated Router fails the router will | |
517 | end up retransmitting the updates. */ | |
518 | ||
519 | if (oi->state == ISM_Backup) | |
520 | { | |
718e3744 | 521 | if (IS_DEBUG_OSPF_NSSA) |
60925303 | 522 | zlog_debug ("ospf_flood_through_interface(): " |
718e3744 | 523 | "ISM_Backup NOT SEND to int %s", IF_NAME (oi)); |
718e3744 | 524 | return 1; |
525 | } | |
526 | } | |
527 | ||
528 | /* The LSA must be flooded out the interface. Send a Link State | |
529 | Update packet (including the new LSA as contents) out the | |
530 | interface. The LSA's LS age must be incremented by InfTransDelay | |
531 | (which must be > 0) when it is copied into the outgoing Link | |
532 | State Update packet (until the LS age field reaches the maximum | |
533 | value of MaxAge). */ | |
beebba75 | 534 | /* XXX HASSO: Is this IS_DEBUG_OSPF_NSSA really correct? */ |
718e3744 | 535 | if (IS_DEBUG_OSPF_NSSA) |
60925303 | 536 | zlog_debug ("ospf_flood_through_interface(): " |
718e3744 | 537 | "DR/BDR sending upd to int %s", IF_NAME (oi)); |
718e3744 | 538 | |
539 | /* RFC2328 Section 13.3 | |
540 | On non-broadcast networks, separate Link State Update | |
541 | packets must be sent, as unicasts, to each adjacent neighbor | |
542 | (i.e., those in state Exchange or greater). The destination | |
543 | IP addresses for these packets are the neighbors' IP | |
544 | addresses. */ | |
545 | if (oi->type == OSPF_IFTYPE_NBMA) | |
546 | { | |
547 | struct route_node *rn; | |
548 | struct ospf_neighbor *nbr; | |
549 | ||
550 | for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) | |
551 | if ((nbr = rn->info) != NULL) | |
552 | if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange) | |
553 | ospf_ls_upd_send_lsa (nbr, lsa, OSPF_SEND_PACKET_DIRECT); | |
554 | } | |
555 | else | |
556 | ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT); | |
557 | ||
558 | return 0; | |
559 | } | |
560 | ||
561 | int | |
68980084 | 562 | ospf_flood_through_area (struct ospf_area *area, |
563 | struct ospf_neighbor *inbr, struct ospf_lsa *lsa) | |
718e3744 | 564 | { |
1eb8ef25 | 565 | struct listnode *node, *nnode; |
566 | struct ospf_interface *oi; | |
718e3744 | 567 | int lsa_ack_flag = 0; |
568 | ||
569 | /* All other types are specific to a single area (Area A). The | |
570 | eligible interfaces are all those interfaces attaching to the | |
571 | Area A. If Area A is the backbone, this includes all the virtual | |
572 | links. */ | |
1eb8ef25 | 573 | for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) |
718e3744 | 574 | { |
718e3744 | 575 | if (area->area_id.s_addr != OSPF_AREA_BACKBONE && |
576 | oi->type == OSPF_IFTYPE_VIRTUALLINK) | |
577 | continue; | |
578 | ||
579 | #ifdef HAVE_OPAQUE_LSA | |
580 | if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) && (lsa->oi != oi)) | |
581 | { | |
582 | /* | |
583 | * Link local scoped Opaque-LSA should only be flooded | |
584 | * for the link on which the LSA has received. | |
585 | */ | |
586 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 587 | zlog_debug ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", lsa->oi, oi); |
718e3744 | 588 | continue; |
589 | } | |
590 | #endif /* HAVE_OPAQUE_LSA */ | |
591 | ||
592 | if (ospf_flood_through_interface (oi, inbr, lsa)) | |
593 | lsa_ack_flag = 1; | |
594 | } | |
595 | ||
596 | return (lsa_ack_flag); | |
597 | } | |
598 | ||
599 | int | |
68980084 | 600 | ospf_flood_through_as (struct ospf *ospf, struct ospf_neighbor *inbr, |
601 | struct ospf_lsa *lsa) | |
718e3744 | 602 | { |
52dc7ee6 | 603 | struct listnode *node; |
1eb8ef25 | 604 | struct ospf_area *area; |
718e3744 | 605 | int lsa_ack_flag; |
606 | ||
607 | lsa_ack_flag = 0; | |
608 | ||
609 | /* The incoming LSA is type 5 or type 7 (AS-EXTERNAL or AS-NSSA ) | |
610 | ||
611 | Divert the Type-5 LSA's to all non-NSSA/STUB areas | |
612 | ||
613 | Divert the Type-7 LSA's to all NSSA areas | |
614 | ||
615 | AS-external-LSAs are flooded throughout the entire AS, with the | |
616 | exception of stub areas (see Section 3.6). The eligible | |
617 | interfaces are all the router's interfaces, excluding virtual | |
618 | links and those interfaces attaching to stub areas. */ | |
619 | ||
718e3744 | 620 | if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7 */ |
621 | if (IS_DEBUG_OSPF_NSSA) | |
60925303 | 622 | zlog_debug ("Flood/AS: NSSA TRANSLATED LSA"); |
718e3744 | 623 | |
1eb8ef25 | 624 | for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) |
718e3744 | 625 | { |
626 | int continue_flag = 0; | |
52dc7ee6 | 627 | struct listnode *if_node; |
1eb8ef25 | 628 | struct ospf_interface *oi; |
718e3744 | 629 | |
630 | switch (area->external_routing) | |
631 | { | |
632 | /* Don't send AS externals into stub areas. Various types | |
633 | of support for partial stub areas can be implemented | |
634 | here. NSSA's will receive Type-7's that have areas | |
635 | matching the originl LSA. */ | |
636 | case OSPF_AREA_NSSA: /* Sending Type 5 or 7 into NSSA area */ | |
718e3744 | 637 | /* Type-7, flood NSSA area */ |
68980084 | 638 | if (lsa->data->type == OSPF_AS_NSSA_LSA |
639 | && area == lsa->area) | |
718e3744 | 640 | /* We will send it. */ |
641 | continue_flag = 0; | |
68980084 | 642 | else |
718e3744 | 643 | continue_flag = 1; /* Skip this NSSA area for Type-5's et al */ |
644 | break; | |
718e3744 | 645 | |
646 | case OSPF_AREA_TYPE_MAX: | |
647 | case OSPF_AREA_STUB: | |
648 | continue_flag = 1; /* Skip this area. */ | |
649 | break; | |
650 | ||
651 | case OSPF_AREA_DEFAULT: | |
652 | default: | |
718e3744 | 653 | /* No Type-7 into normal area */ |
654 | if (lsa->data->type == OSPF_AS_NSSA_LSA) | |
655 | continue_flag = 1; /* skip Type-7 */ | |
656 | else | |
718e3744 | 657 | continue_flag = 0; /* Do this area. */ |
658 | break; | |
659 | } | |
660 | ||
661 | /* Do continue for above switch. Saves a big if then mess */ | |
662 | if (continue_flag) | |
663 | continue; /* main for-loop */ | |
664 | ||
665 | /* send to every interface in this area */ | |
666 | ||
1eb8ef25 | 667 | for (ALL_LIST_ELEMENTS_RO (area->oiflist, if_node, oi)) |
718e3744 | 668 | { |
718e3744 | 669 | /* Skip virtual links */ |
670 | if (oi->type != OSPF_IFTYPE_VIRTUALLINK) | |
671 | if (ospf_flood_through_interface (oi, inbr, lsa)) /* lsa */ | |
672 | lsa_ack_flag = 1; | |
673 | } | |
674 | } /* main area for-loop */ | |
675 | ||
676 | return (lsa_ack_flag); | |
677 | } | |
678 | ||
679 | int | |
68980084 | 680 | ospf_flood_through (struct ospf *ospf, |
681 | struct ospf_neighbor *inbr, struct ospf_lsa *lsa) | |
718e3744 | 682 | { |
683 | int lsa_ack_flag = 0; | |
684 | ||
685 | /* Type-7 LSA's for NSSA are flooded throughout the AS here, and | |
686 | upon return are updated in the LSDB for Type-7's. Later, | |
687 | re-fresh will re-send them (and also, if ABR, packet code will | |
688 | translate to Type-5's) | |
689 | ||
690 | As usual, Type-5 LSA's (if not DISCARDED because we are STUB or | |
691 | NSSA) are flooded throughout the AS, and are updated in the | |
692 | global table. */ | |
693 | #ifdef ORIGINAL_CODING | |
694 | switch (lsa->data->type) | |
695 | { | |
696 | case OSPF_ROUTER_LSA: | |
697 | case OSPF_NETWORK_LSA: | |
698 | case OSPF_SUMMARY_LSA: | |
699 | case OSPF_ASBR_SUMMARY_LSA: | |
700 | #ifdef HAVE_OPAQUE_LSA | |
701 | case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */ | |
702 | case OSPF_OPAQUE_AREA_LSA: | |
703 | #endif /* HAVE_OPAQUE_LSA */ | |
704 | lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); | |
705 | break; | |
706 | case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ | |
707 | #ifdef HAVE_OPAQUE_LSA | |
708 | case OSPF_OPAQUE_AS_LSA: | |
709 | #endif /* HAVE_OPAQUE_LSA */ | |
68980084 | 710 | lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); |
718e3744 | 711 | break; |
718e3744 | 712 | /* Type-7 Only received within NSSA, then flooded */ |
713 | case OSPF_AS_NSSA_LSA: | |
714 | /* Any P-bit was installed with the Type-7. */ | |
715 | lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); | |
716 | ||
717 | if (IS_DEBUG_OSPF_NSSA) | |
60925303 | 718 | zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); |
718e3744 | 719 | break; |
718e3744 | 720 | default: |
721 | break; | |
722 | } | |
723 | #else /* ORIGINAL_CODING */ | |
724 | /* | |
725 | * At the common sub-sub-function "ospf_flood_through_interface()", | |
726 | * a parameter "inbr" will be used to distinguish the called context | |
727 | * whether the given LSA was received from the neighbor, or the | |
728 | * flooding for the LSA starts from this node (e.g. the LSA was self- | |
729 | * originated, or the LSA is going to be flushed from routing domain). | |
730 | * | |
731 | * So, for consistency reasons, this function "ospf_flood_through()" | |
732 | * should also allow the usage that the given "inbr" parameter to be | |
733 | * NULL. If we do so, corresponding AREA parameter should be referred | |
734 | * by "lsa->area", instead of "inbr->oi->area". | |
735 | */ | |
736 | switch (lsa->data->type) | |
737 | { | |
738 | case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ | |
739 | #ifdef HAVE_OPAQUE_LSA | |
740 | case OSPF_OPAQUE_AS_LSA: | |
741 | #endif /* HAVE_OPAQUE_LSA */ | |
68980084 | 742 | lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); |
718e3744 | 743 | break; |
718e3744 | 744 | /* Type-7 Only received within NSSA, then flooded */ |
745 | case OSPF_AS_NSSA_LSA: | |
746 | /* Any P-bit was installed with the Type-7. */ | |
747 | ||
748 | if (IS_DEBUG_OSPF_NSSA) | |
60925303 | 749 | zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); |
718e3744 | 750 | /* Fallthrough */ |
718e3744 | 751 | default: |
752 | lsa_ack_flag = ospf_flood_through_area (lsa->area, inbr, lsa); | |
753 | break; | |
754 | } | |
755 | #endif /* ORIGINAL_CODING */ | |
756 | ||
757 | return (lsa_ack_flag); | |
758 | } | |
759 | ||
760 | \f | |
761 | ||
762 | /* Management functions for neighbor's Link State Request list. */ | |
763 | void | |
764 | ospf_ls_request_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | |
765 | { | |
766 | /* | |
767 | * We cannot make use of the newly introduced callback function | |
768 | * "lsdb->new_lsa_hook" to replace debug output below, just because | |
769 | * it seems no simple and smart way to pass neighbor information to | |
770 | * the common function "ospf_lsdb_add()" -- endo. | |
771 | */ | |
772 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 773 | zlog_debug ("RqstL(%lu)++, NBR(%s), LSA[%s]", |
718e3744 | 774 | ospf_ls_request_count (nbr), |
775 | inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); | |
776 | ||
777 | ospf_lsdb_add (&nbr->ls_req, lsa); | |
778 | } | |
779 | ||
780 | unsigned long | |
781 | ospf_ls_request_count (struct ospf_neighbor *nbr) | |
782 | { | |
783 | return ospf_lsdb_count_all (&nbr->ls_req); | |
784 | } | |
785 | ||
786 | int | |
787 | ospf_ls_request_isempty (struct ospf_neighbor *nbr) | |
788 | { | |
789 | return ospf_lsdb_isempty (&nbr->ls_req); | |
790 | } | |
791 | ||
792 | /* Remove LSA from neighbor's ls-request list. */ | |
793 | void | |
794 | ospf_ls_request_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | |
795 | { | |
796 | if (nbr->ls_req_last == lsa) | |
797 | { | |
1fe6ed38 | 798 | ospf_lsa_unlock (&nbr->ls_req_last); |
718e3744 | 799 | nbr->ls_req_last = NULL; |
800 | } | |
801 | ||
802 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */ | |
60925303 | 803 | zlog_debug ("RqstL(%lu)--, NBR(%s), LSA[%s]", |
718e3744 | 804 | ospf_ls_request_count (nbr), |
805 | inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); | |
806 | ||
807 | ospf_lsdb_delete (&nbr->ls_req, lsa); | |
808 | } | |
809 | ||
810 | /* Remove all LSA from neighbor's ls-requenst list. */ | |
811 | void | |
812 | ospf_ls_request_delete_all (struct ospf_neighbor *nbr) | |
813 | { | |
1fe6ed38 | 814 | ospf_lsa_unlock (&nbr->ls_req_last); |
718e3744 | 815 | nbr->ls_req_last = NULL; |
816 | ospf_lsdb_delete_all (&nbr->ls_req); | |
817 | } | |
818 | ||
819 | /* Lookup LSA from neighbor's ls-request list. */ | |
820 | struct ospf_lsa * | |
821 | ospf_ls_request_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | |
822 | { | |
823 | return ospf_lsdb_lookup (&nbr->ls_req, lsa); | |
824 | } | |
825 | ||
826 | struct ospf_lsa * | |
827 | ospf_ls_request_new (struct lsa_header *lsah) | |
828 | { | |
829 | struct ospf_lsa *new; | |
830 | ||
831 | new = ospf_lsa_new (); | |
832 | new->data = ospf_lsa_data_new (OSPF_LSA_HEADER_SIZE); | |
833 | memcpy (new->data, lsah, OSPF_LSA_HEADER_SIZE); | |
834 | ||
835 | return new; | |
836 | } | |
837 | ||
838 | \f | |
839 | /* Management functions for neighbor's ls-retransmit list. */ | |
840 | unsigned long | |
841 | ospf_ls_retransmit_count (struct ospf_neighbor *nbr) | |
842 | { | |
843 | return ospf_lsdb_count_all (&nbr->ls_rxmt); | |
844 | } | |
845 | ||
846 | unsigned long | |
847 | ospf_ls_retransmit_count_self (struct ospf_neighbor *nbr, int lsa_type) | |
848 | { | |
849 | return ospf_lsdb_count_self (&nbr->ls_rxmt, lsa_type); | |
850 | } | |
851 | ||
852 | int | |
853 | ospf_ls_retransmit_isempty (struct ospf_neighbor *nbr) | |
854 | { | |
855 | return ospf_lsdb_isempty (&nbr->ls_rxmt); | |
856 | } | |
857 | ||
858 | /* Add LSA to be retransmitted to neighbor's ls-retransmit list. */ | |
859 | void | |
860 | ospf_ls_retransmit_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | |
861 | { | |
862 | struct ospf_lsa *old; | |
863 | ||
864 | old = ospf_ls_retransmit_lookup (nbr, lsa); | |
865 | ||
866 | if (ospf_lsa_more_recent (old, lsa) < 0) | |
867 | { | |
868 | if (old) | |
869 | { | |
870 | old->retransmit_counter--; | |
871 | ospf_lsdb_delete (&nbr->ls_rxmt, old); | |
872 | } | |
873 | lsa->retransmit_counter++; | |
874 | /* | |
875 | * We cannot make use of the newly introduced callback function | |
876 | * "lsdb->new_lsa_hook" to replace debug output below, just because | |
877 | * it seems no simple and smart way to pass neighbor information to | |
878 | * the common function "ospf_lsdb_add()" -- endo. | |
879 | */ | |
880 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) | |
60925303 | 881 | zlog_debug ("RXmtL(%lu)++, NBR(%s), LSA[%s]", |
718e3744 | 882 | ospf_ls_retransmit_count (nbr), |
883 | inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); | |
884 | ospf_lsdb_add (&nbr->ls_rxmt, lsa); | |
885 | } | |
886 | } | |
887 | ||
888 | /* Remove LSA from neibghbor's ls-retransmit list. */ | |
889 | void | |
890 | ospf_ls_retransmit_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | |
891 | { | |
892 | if (ospf_ls_retransmit_lookup (nbr, lsa)) | |
893 | { | |
894 | lsa->retransmit_counter--; | |
895 | if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */ | |
60925303 | 896 | zlog_debug ("RXmtL(%lu)--, NBR(%s), LSA[%s]", |
718e3744 | 897 | ospf_ls_retransmit_count (nbr), |
898 | inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); | |
899 | ospf_lsdb_delete (&nbr->ls_rxmt, lsa); | |
900 | } | |
901 | } | |
902 | ||
903 | /* Clear neighbor's ls-retransmit list. */ | |
904 | void | |
905 | ospf_ls_retransmit_clear (struct ospf_neighbor *nbr) | |
906 | { | |
907 | struct ospf_lsdb *lsdb; | |
908 | int i; | |
909 | ||
910 | lsdb = &nbr->ls_rxmt; | |
911 | ||
912 | for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) | |
913 | { | |
914 | struct route_table *table = lsdb->type[i].db; | |
915 | struct route_node *rn; | |
916 | struct ospf_lsa *lsa; | |
917 | ||
918 | for (rn = route_top (table); rn; rn = route_next (rn)) | |
919 | if ((lsa = rn->info) != NULL) | |
920 | ospf_ls_retransmit_delete (nbr, lsa); | |
921 | } | |
922 | ||
1fe6ed38 | 923 | ospf_lsa_unlock (&nbr->ls_req_last); |
718e3744 | 924 | nbr->ls_req_last = NULL; |
925 | } | |
926 | ||
927 | /* Lookup LSA from neighbor's ls-retransmit list. */ | |
928 | struct ospf_lsa * | |
929 | ospf_ls_retransmit_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) | |
930 | { | |
931 | return ospf_lsdb_lookup (&nbr->ls_rxmt, lsa); | |
932 | } | |
933 | ||
4dadc291 | 934 | static void |
68980084 | 935 | ospf_ls_retransmit_delete_nbr_if (struct ospf_interface *oi, |
936 | struct ospf_lsa *lsa) | |
718e3744 | 937 | { |
68980084 | 938 | struct route_node *rn; |
939 | struct ospf_neighbor *nbr; | |
940 | struct ospf_lsa *lsr; | |
941 | ||
942 | if (ospf_if_is_enable (oi)) | |
943 | for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) | |
944 | /* If LSA find in LS-retransmit list, then remove it. */ | |
945 | if ((nbr = rn->info) != NULL) | |
946 | { | |
947 | lsr = ospf_ls_retransmit_lookup (nbr, lsa); | |
718e3744 | 948 | |
68980084 | 949 | /* If LSA find in ls-retransmit list, remove it. */ |
950 | if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum) | |
951 | ospf_ls_retransmit_delete (nbr, lsr); | |
952 | } | |
718e3744 | 953 | } |
954 | ||
718e3744 | 955 | void |
68980084 | 956 | ospf_ls_retransmit_delete_nbr_area (struct ospf_area *area, |
957 | struct ospf_lsa *lsa) | |
718e3744 | 958 | { |
1eb8ef25 | 959 | struct listnode *node, *nnode; |
960 | struct ospf_interface *oi; | |
718e3744 | 961 | |
1eb8ef25 | 962 | for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) |
963 | ospf_ls_retransmit_delete_nbr_if (oi, lsa); | |
68980084 | 964 | } |
718e3744 | 965 | |
68980084 | 966 | void |
967 | ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, struct ospf_lsa *lsa) | |
968 | { | |
1eb8ef25 | 969 | struct listnode *node, *nnode; |
970 | struct ospf_interface *oi; | |
718e3744 | 971 | |
1eb8ef25 | 972 | for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) |
973 | ospf_ls_retransmit_delete_nbr_if (oi, lsa); | |
718e3744 | 974 | } |
975 | ||
976 | \f | |
977 | /* Sets ls_age to MaxAge and floods throu the area. | |
978 | When we implement ASE routing, there will be anothe function | |
979 | flushing an LSA from the whole domain. */ | |
980 | void | |
981 | ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area) | |
982 | { | |
983 | lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); | |
984 | ospf_flood_through_area (area, NULL, lsa); | |
68980084 | 985 | ospf_lsa_maxage (area->ospf, lsa); |
718e3744 | 986 | } |
987 | ||
718e3744 | 988 | void |
68980084 | 989 | ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa) |
718e3744 | 990 | { |
991 | lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); | |
68980084 | 992 | ospf_flood_through_as (ospf, NULL, lsa); |
993 | ospf_lsa_maxage (ospf, lsa); | |
718e3744 | 994 | } |
02d942c9 PJ |
995 | |
996 | void | |
997 | ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa) | |
998 | { | |
999 | lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); | |
1000 | ||
1001 | switch (lsa->data->type) | |
1002 | { | |
1003 | case OSPF_ROUTER_LSA: | |
1004 | case OSPF_NETWORK_LSA: | |
1005 | case OSPF_SUMMARY_LSA: | |
1006 | case OSPF_ASBR_SUMMARY_LSA: | |
1007 | case OSPF_AS_NSSA_LSA: | |
1008 | #ifdef HAVE_OPAQUE_LSA | |
1009 | case OSPF_OPAQUE_LINK_LSA: | |
1010 | case OSPF_OPAQUE_AREA_LSA: | |
1011 | #endif /* HAVE_OPAQUE_LSA */ | |
1012 | ospf_lsa_flush_area (lsa, lsa->area); | |
1013 | break; | |
1014 | case OSPF_AS_EXTERNAL_LSA: | |
1015 | #ifdef HAVE_OPAQUE_LSA | |
1016 | case OSPF_OPAQUE_AS_LSA: | |
1017 | #endif /* HAVE_OPAQUE_LSA */ | |
1018 | ospf_lsa_flush_as (ospf, lsa); | |
1019 | break; | |
1020 | default: | |
1021 | zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type); | |
1022 | break; | |
1023 | } | |
1024 | } |