Annotation of embedaddon/quagga/ospfd/ospf_flood.c, revision 1.1.1.1
1.1 misho 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:
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 */
75: listnode_add (inbr->oi->ls_ack, ospf_lsa_lock (lsa)); /* delayed LSA Ack */
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:
113: static void
114: ospf_process_self_originated_lsa (struct ospf *ospf,
115: struct ospf_lsa *new, struct ospf_area *area)
116: {
117: struct ospf_interface *oi;
118: struct external_info *ei;
119: struct listnode *node;
120:
121: if (IS_DEBUG_OSPF_EVENT)
122: zlog_debug ("LSA[Type%d:%s]: Process self-originated LSA seq 0x%x",
123: new->data->type, inet_ntoa (new->data->id),
124: ntohl(new->data->ls_seqnum));
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 */
136: if (area->router_lsa_self)
137: area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
138: ospf_router_lsa_update_area (area);
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. */
151: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
152: /* These are sanity check. */
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:
163: #ifdef HAVE_OPAQUE_LSA
164: if (new->data->type == OSPF_OPAQUE_LINK_LSA)
165: {
166: ospf_opaque_lsa_refresh (new);
167: return;
168: }
169: #endif /* HAVE_OPAQUE_LSA */
170:
171: if (oi->network_lsa_self)
172: oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
173: /* Schedule network-LSA origination. */
174: ospf_network_lsa_update (oi);
175: return;
176: }
177: break;
178: case OSPF_SUMMARY_LSA:
179: case OSPF_ASBR_SUMMARY_LSA:
180: ospf_schedule_abr_task (ospf);
181: break;
182: case OSPF_AS_EXTERNAL_LSA :
183: case OSPF_AS_NSSA_LSA:
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: }
190: ei = ospf_external_info_check (new);
191: if (ei)
192: ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE);
193: else
194: ospf_lsa_flush_as (ospf, new);
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
234: ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr,
235: struct ospf_lsa *current, struct ospf_lsa *new)
236: {
237: struct ospf_interface *oi;
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)
244: zlog_debug ("LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]",
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:
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)
264: zlog_debug ("LSA[Flooding]: Got a self-originated LSA, "
265: "while local one is initial instance.");
266: ; /* Accept this LSA for quick LSDB resynchronization. */
267: }
268: else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv),
269: int2tv (OSPF_MIN_LS_ARRIVAL)) < 0)
270: {
271: if (IS_DEBUG_OSPF_EVENT)
272: zlog_debug ("LSA[Flooding]: LSA is received recently.");
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. */
282: lsa_ack_flag = ospf_flood_through (ospf, nbr, new);
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 */
303: ospf_ls_retransmit_delete_nbr_as (ospf, current);
304: break;
305: default:
306: ospf_ls_retransmit_delete_nbr_area (nbr->oi->area, current);
307: break;
308: }
309: }
310:
311: /* Do some internal house keeping that is needed here */
312: SET_FLAG (new->flags, OSPF_LSA_RECEIVED);
313: ospf_lsa_is_self_originated (ospf, new); /* Let it set the flag */
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:
322: if (! (new = ospf_lsa_install (ospf, nbr->oi, new)))
323: return 0; /* unknown LSA type */
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. */
334: if (ospf_lsa_is_self_originated (ospf, new))
335: ospf_process_self_originated_lsa (ospf, new, oi->area);
336: else
337: /* Update statistics value for OSPF-MIB. */
338: ospf->rx_lsa_count++;
339:
340: return 0;
341: }
342:
343: /* OSPF LSA flooding -- RFC2328 Section 13.3. */
344: static int
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)
354: zlog_debug ("ospf_flood_through_interface(): "
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)
377: zlog_debug ("ospf_flood_through_interface(): considering nbr %s (%s)",
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)
396: zlog_debug ("ospf_flood_through_interface(): nbr adj is not Full");
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))
430: zlog_debug ("Skip this neighbor: Not Opaque-capable.");
431: continue;
432: }
433:
434: if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (oi->ospf->opaque)
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))
440: zlog_debug ("Skip this neighbor: Initial flushing done.");
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))
462: zlog_debug ("Skip this neighbor: inbr == onbr");
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))
475: zlog_debug ("Skip this neighbor: lsah->adv_router == onbr");
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: {
507: if (IS_DEBUG_OSPF_NSSA)
508: zlog_debug ("ospf_flood_through_interface(): "
509: "DR/BDR NOT SEND to int %s", IF_NAME (oi));
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: {
521: if (IS_DEBUG_OSPF_NSSA)
522: zlog_debug ("ospf_flood_through_interface(): "
523: "ISM_Backup NOT SEND to int %s", IF_NAME (oi));
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). */
534: /* XXX HASSO: Is this IS_DEBUG_OSPF_NSSA really correct? */
535: if (IS_DEBUG_OSPF_NSSA)
536: zlog_debug ("ospf_flood_through_interface(): "
537: "DR/BDR sending upd to int %s", IF_NAME (oi));
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
562: ospf_flood_through_area (struct ospf_area *area,
563: struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
564: {
565: struct listnode *node, *nnode;
566: struct ospf_interface *oi;
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. */
573: for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
574: {
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))
587: zlog_debug ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", lsa->oi, oi);
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
600: ospf_flood_through_as (struct ospf *ospf, struct ospf_neighbor *inbr,
601: struct ospf_lsa *lsa)
602: {
603: struct listnode *node;
604: struct ospf_area *area;
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:
620: if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7 */
621: if (IS_DEBUG_OSPF_NSSA)
622: zlog_debug ("Flood/AS: NSSA TRANSLATED LSA");
623:
624: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
625: {
626: int continue_flag = 0;
627: struct listnode *if_node;
628: struct ospf_interface *oi;
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 */
637: /* Type-7, flood NSSA area */
638: if (lsa->data->type == OSPF_AS_NSSA_LSA
639: && area == lsa->area)
640: /* We will send it. */
641: continue_flag = 0;
642: else
643: continue_flag = 1; /* Skip this NSSA area for Type-5's et al */
644: break;
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:
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
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:
667: for (ALL_LIST_ELEMENTS_RO (area->oiflist, if_node, oi))
668: {
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
680: ospf_flood_through (struct ospf *ospf,
681: struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
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 */
710: lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa);
711: break;
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)
718: zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7.");
719: break;
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 */
742: lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa);
743: break;
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)
749: zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7.");
750: /* Fallthrough */
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:
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))
773: zlog_debug ("RqstL(%lu)++, NBR(%s), LSA[%s]",
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: {
798: ospf_lsa_unlock (&nbr->ls_req_last);
799: nbr->ls_req_last = NULL;
800: }
801:
802: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */
803: zlog_debug ("RqstL(%lu)--, NBR(%s), LSA[%s]",
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: {
814: ospf_lsa_unlock (&nbr->ls_req_last);
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:
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))
881: zlog_debug ("RXmtL(%lu)++, NBR(%s), LSA[%s]",
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. */
896: zlog_debug ("RXmtL(%lu)--, NBR(%s), LSA[%s]",
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:
923: ospf_lsa_unlock (&nbr->ls_req_last);
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:
934: static void
935: ospf_ls_retransmit_delete_nbr_if (struct ospf_interface *oi,
936: struct ospf_lsa *lsa)
937: {
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);
948:
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: }
953: }
954:
955: void
956: ospf_ls_retransmit_delete_nbr_area (struct ospf_area *area,
957: struct ospf_lsa *lsa)
958: {
959: struct listnode *node, *nnode;
960: struct ospf_interface *oi;
961:
962: for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
963: ospf_ls_retransmit_delete_nbr_if (oi, lsa);
964: }
965:
966: void
967: ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, struct ospf_lsa *lsa)
968: {
969: struct listnode *node, *nnode;
970: struct ospf_interface *oi;
971:
972: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
973: ospf_ls_retransmit_delete_nbr_if (oi, lsa);
974: }
975:
976:
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);
985: ospf_lsa_maxage (area->ospf, lsa);
986: }
987:
988: void
989: ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)
990: {
991: lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
992: ospf_flood_through_as (ospf, NULL, lsa);
993: ospf_lsa_maxage (ospf, lsa);
994: }
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>