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