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