Annotation of embedaddon/quagga/ospfd/ospf_lsa.c, revision 1.1.1.3
1.1 misho 1: /*
2: * OSPF Link State Advertisement
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 it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2, or (at your option) any
10: * 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 Free
19: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20: * 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "linklist.h"
26: #include "prefix.h"
27: #include "if.h"
28: #include "table.h"
29: #include "memory.h"
30: #include "stream.h"
31: #include "log.h"
32: #include "thread.h"
33: #include "hash.h"
34: #include "sockunion.h" /* for inet_aton() */
35: #include "checksum.h"
36:
37: #include "ospfd/ospfd.h"
38: #include "ospfd/ospf_interface.h"
39: #include "ospfd/ospf_ism.h"
40: #include "ospfd/ospf_asbr.h"
41: #include "ospfd/ospf_lsa.h"
42: #include "ospfd/ospf_lsdb.h"
43: #include "ospfd/ospf_neighbor.h"
44: #include "ospfd/ospf_nsm.h"
45: #include "ospfd/ospf_flood.h"
46: #include "ospfd/ospf_packet.h"
47: #include "ospfd/ospf_spf.h"
48: #include "ospfd/ospf_dump.h"
49: #include "ospfd/ospf_route.h"
50: #include "ospfd/ospf_ase.h"
51: #include "ospfd/ospf_zebra.h"
52:
53:
54: u_int32_t
55: get_metric (u_char *metric)
56: {
57: u_int32_t m;
58: m = metric[0];
59: m = (m << 8) + metric[1];
60: m = (m << 8) + metric[2];
61: return m;
62: }
63:
64:
65: struct timeval
66: tv_adjust (struct timeval a)
67: {
68: while (a.tv_usec >= 1000000)
69: {
70: a.tv_usec -= 1000000;
71: a.tv_sec++;
72: }
73:
74: while (a.tv_usec < 0)
75: {
76: a.tv_usec += 1000000;
77: a.tv_sec--;
78: }
79:
80: return a;
81: }
82:
83: int
84: tv_ceil (struct timeval a)
85: {
86: a = tv_adjust (a);
87:
88: return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89: }
90:
91: int
92: tv_floor (struct timeval a)
93: {
94: a = tv_adjust (a);
95:
96: return a.tv_sec;
97: }
98:
99: struct timeval
100: int2tv (int a)
101: {
102: struct timeval ret;
103:
104: ret.tv_sec = a;
105: ret.tv_usec = 0;
106:
107: return ret;
108: }
109:
110: struct timeval
111: tv_add (struct timeval a, struct timeval b)
112: {
113: struct timeval ret;
114:
115: ret.tv_sec = a.tv_sec + b.tv_sec;
116: ret.tv_usec = a.tv_usec + b.tv_usec;
117:
118: return tv_adjust (ret);
119: }
120:
121: struct timeval
122: tv_sub (struct timeval a, struct timeval b)
123: {
124: struct timeval ret;
125:
126: ret.tv_sec = a.tv_sec - b.tv_sec;
127: ret.tv_usec = a.tv_usec - b.tv_usec;
128:
129: return tv_adjust (ret);
130: }
131:
132: int
133: tv_cmp (struct timeval a, struct timeval b)
134: {
135: return (a.tv_sec == b.tv_sec ?
136: a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137: }
138:
139: int
140: ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141: {
142: struct timeval delta, now;
143: int delay = 0;
144:
145: quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
146: delta = tv_sub (now, lsa->tv_orig);
147:
148: if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149: {
150: delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151:
152: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
153: zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
154: lsa->data->type, inet_ntoa (lsa->data->id), delay);
155:
156: assert (delay > 0);
157: }
158:
159: return delay;
160: }
161:
162:
163: int
164: get_age (struct ospf_lsa *lsa)
165: {
166: int age;
167:
168: age = ntohs (lsa->data->ls_age)
169: + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
170:
171: return age;
172: }
173:
174:
175: /* Fletcher Checksum -- Refer to RFC1008. */
176:
177: /* All the offsets are zero-based. The offsets in the RFC1008 are
178: one-based. */
179: u_int16_t
180: ospf_lsa_checksum (struct lsa_header *lsa)
181: {
182: u_char *buffer = (u_char *) &lsa->options;
183: int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
184:
185: /* Skip the AGE field */
186: u_int16_t len = ntohs(lsa->length) - options_offset;
187:
188: /* Checksum offset starts from "options" field, not the beginning of the
189: lsa_header struct. The offset is 14, rather than 16. */
190: int checksum_offset = (u_char *) &lsa->checksum - buffer;
191:
192: return fletcher_checksum(buffer, len, checksum_offset);
193: }
194:
1.1.1.3 ! misho 195: int
! 196: ospf_lsa_checksum_valid (struct lsa_header *lsa)
! 197: {
! 198: u_char *buffer = (u_char *) &lsa->options;
! 199: int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
! 200:
! 201: /* Skip the AGE field */
! 202: u_int16_t len = ntohs(lsa->length) - options_offset;
! 203:
! 204: return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
! 205: }
! 206:
1.1 misho 207:
208:
209: /* Create OSPF LSA. */
210: struct ospf_lsa *
211: ospf_lsa_new ()
212: {
213: struct ospf_lsa *new;
214:
215: new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
216:
217: new->flags = 0;
218: new->lock = 1;
219: new->retransmit_counter = 0;
220: new->tv_recv = recent_relative_time ();
221: new->tv_orig = new->tv_recv;
222: new->refresh_list = -1;
223:
224: return new;
225: }
226:
227: /* Duplicate OSPF LSA. */
228: struct ospf_lsa *
229: ospf_lsa_dup (struct ospf_lsa *lsa)
230: {
231: struct ospf_lsa *new;
232:
233: if (lsa == NULL)
234: return NULL;
235:
236: new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
237:
238: memcpy (new, lsa, sizeof (struct ospf_lsa));
239: UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
240: new->lock = 1;
241: new->retransmit_counter = 0;
242: new->data = ospf_lsa_data_dup (lsa->data);
243:
244: /* kevinm: Clear the refresh_list, otherwise there are going
245: to be problems when we try to remove the LSA from the
246: queue (which it's not a member of.)
247: XXX: Should we add the LSA to the refresh_list queue? */
248: new->refresh_list = -1;
249:
250: if (IS_DEBUG_OSPF (lsa, LSA))
251: zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
252:
253: return new;
254: }
255:
256: /* Free OSPF LSA. */
257: void
258: ospf_lsa_free (struct ospf_lsa *lsa)
259: {
260: assert (lsa->lock == 0);
261:
262: if (IS_DEBUG_OSPF (lsa, LSA))
263: zlog_debug ("LSA: freed %p", lsa);
264:
265: /* Delete LSA data. */
266: if (lsa->data != NULL)
267: ospf_lsa_data_free (lsa->data);
268:
269: assert (lsa->refresh_list < 0);
270:
271: memset (lsa, 0, sizeof (struct ospf_lsa));
272: XFREE (MTYPE_OSPF_LSA, lsa);
273: }
274:
275: /* Lock LSA. */
276: struct ospf_lsa *
277: ospf_lsa_lock (struct ospf_lsa *lsa)
278: {
279: lsa->lock++;
280: return lsa;
281: }
282:
283: /* Unlock LSA. */
284: void
285: ospf_lsa_unlock (struct ospf_lsa **lsa)
286: {
287: /* This is sanity check. */
288: if (!lsa || !*lsa)
289: return;
290:
291: (*lsa)->lock--;
292:
293: assert ((*lsa)->lock >= 0);
294:
295: if ((*lsa)->lock == 0)
296: {
297: assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
298: ospf_lsa_free (*lsa);
299: *lsa = NULL;
300: }
301: }
302:
303: /* Check discard flag. */
304: void
305: ospf_lsa_discard (struct ospf_lsa *lsa)
306: {
307: if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
308: {
309: SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
310: ospf_lsa_unlock (&lsa);
311: }
312: }
313:
314: /* Create LSA data. */
315: struct lsa_header *
316: ospf_lsa_data_new (size_t size)
317: {
318: return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
319: }
320:
321: /* Duplicate LSA data. */
322: struct lsa_header *
323: ospf_lsa_data_dup (struct lsa_header *lsah)
324: {
325: struct lsa_header *new;
326:
327: new = ospf_lsa_data_new (ntohs (lsah->length));
328: memcpy (new, lsah, ntohs (lsah->length));
329:
330: return new;
331: }
332:
333: /* Free LSA data. */
334: void
335: ospf_lsa_data_free (struct lsa_header *lsah)
336: {
337: if (IS_DEBUG_OSPF (lsa, LSA))
338: zlog_debug ("LSA[Type%d:%s]: data freed %p",
339: lsah->type, inet_ntoa (lsah->id), lsah);
340:
341: XFREE (MTYPE_OSPF_LSA_DATA, lsah);
342: }
343:
344:
345: /* LSA general functions. */
346:
347: const char *
348: dump_lsa_key (struct ospf_lsa *lsa)
349: {
350: static char buf[] = {
351: "Type255,id(255.255.255.255),ar(255.255.255.255)"
352: };
353: struct lsa_header *lsah;
354:
355: if (lsa != NULL && (lsah = lsa->data) != NULL)
356: {
357: char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
358: strcpy (id, inet_ntoa (lsah->id));
359: strcpy (ar, inet_ntoa (lsah->adv_router));
360:
361: sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
362: }
363: else
364: strcpy (buf, "NULL");
365:
366: return buf;
367: }
368:
369: u_int32_t
370: lsa_seqnum_increment (struct ospf_lsa *lsa)
371: {
372: u_int32_t seqnum;
373:
374: seqnum = ntohl (lsa->data->ls_seqnum) + 1;
375:
376: return htonl (seqnum);
377: }
378:
379: void
380: lsa_header_set (struct stream *s, u_char options,
381: u_char type, struct in_addr id, struct in_addr router_id)
382: {
383: struct lsa_header *lsah;
384:
385: lsah = (struct lsa_header *) STREAM_DATA (s);
386:
387: lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
388: lsah->options = options;
389: lsah->type = type;
390: lsah->id = id;
391: lsah->adv_router = router_id;
392: lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
393:
394: stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
395: }
396:
397:
398: /* router-LSA related functions. */
399: /* Get router-LSA flags. */
400: static u_char
401: router_lsa_flags (struct ospf_area *area)
402: {
403: u_char flags;
404:
405: flags = area->ospf->flags;
406:
407: /* Set virtual link flag. */
408: if (ospf_full_virtual_nbrs (area))
409: SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
410: else
411: /* Just sanity check */
412: UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
413:
414: /* Set Shortcut ABR behabiour flag. */
415: UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
416: if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
417: if (!OSPF_IS_AREA_BACKBONE (area))
418: if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
419: area->ospf->backbone == NULL) ||
420: area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
421: SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
422:
423: /* ASBR can't exit in stub area. */
424: if (area->external_routing == OSPF_AREA_STUB)
425: UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
426: /* If ASBR set External flag */
427: else if (IS_OSPF_ASBR (area->ospf))
428: SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
429:
430: /* Set ABR dependent flags */
431: if (IS_OSPF_ABR (area->ospf))
432: {
433: SET_FLAG (flags, ROUTER_LSA_BORDER);
434: /* If Area is NSSA and we are both ABR and unconditional translator,
435: * set Nt bit to inform other routers.
436: */
437: if ( (area->external_routing == OSPF_AREA_NSSA)
438: && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
439: SET_FLAG (flags, ROUTER_LSA_NT);
440: }
441: return flags;
442: }
443:
444: /* Lookup neighbor other than myself.
445: And check neighbor count,
446: Point-to-Point link must have only 1 neighbor. */
447: struct ospf_neighbor *
448: ospf_nbr_lookup_ptop (struct ospf_interface *oi)
449: {
450: struct ospf_neighbor *nbr = NULL;
451: struct route_node *rn;
452:
453: /* Search neighbor, there must be one of two nbrs. */
454: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
455: if ((nbr = rn->info))
456: if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
457: if (nbr->state == NSM_Full)
458: {
459: route_unlock_node (rn);
460: break;
461: }
462:
463: /* PtoP link must have only 1 neighbor. */
464: if (ospf_nbr_count (oi, 0) > 1)
465: zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
466:
467: return nbr;
468: }
469:
470: /* Determine cost of link, taking RFC3137 stub-router support into
471: * consideration
472: */
473: static u_int16_t
474: ospf_link_cost (struct ospf_interface *oi)
475: {
476: /* RFC3137 stub router support */
477: if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
478: return oi->output_cost;
479: else
480: return OSPF_OUTPUT_COST_INFINITE;
481: }
482:
483: /* Set a link information. */
484: static char
485: link_info_set (struct stream *s, struct in_addr id,
486: struct in_addr data, u_char type, u_char tos, u_int16_t cost)
487: {
488: /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
489: * vast majority of cases. Some rare routers with lots of links need more.
490: * we try accomodate those here.
491: */
492: if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
493: {
494: size_t ret = OSPF_MAX_LSA_SIZE;
495:
496: /* Can we enlarge the stream still? */
497: if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
498: {
499: /* we futz the size here for simplicity, really we need to account
500: * for just:
501: * IP Header - (sizeof (struct ip))
502: * OSPF Header - OSPF_HEADER_SIZE
503: * LSA Header - OSPF_LSA_HEADER_SIZE
504: * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
505: *
506: * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
507: */
508: ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
509: }
510:
511: if (ret == OSPF_MAX_LSA_SIZE)
512: {
513: zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
514: __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
515: return 0;
516: }
517: }
518:
519: /* TOS based routing is not supported. */
520: stream_put_ipv4 (s, id.s_addr); /* Link ID. */
521: stream_put_ipv4 (s, data.s_addr); /* Link Data. */
522: stream_putc (s, type); /* Link Type. */
523: stream_putc (s, tos); /* TOS = 0. */
524: stream_putw (s, cost); /* Link Cost. */
525:
526: return 1;
527: }
528:
529: /* Describe Point-to-Point link (Section 12.4.1.1). */
530: static int
531: lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
532: {
533: int links = 0;
534: struct ospf_neighbor *nbr;
535: struct in_addr id, mask;
536: u_int16_t cost = ospf_link_cost (oi);
537:
538: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
539: zlog_debug ("LSA[Type1]: Set link Point-to-Point");
540:
541: if ((nbr = ospf_nbr_lookup_ptop (oi)))
542: if (nbr->state == NSM_Full)
543: {
544: /* For unnumbered point-to-point networks, the Link Data field
545: should specify the interface's MIB-II ifIndex value. */
546: links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
547: LSA_LINK_TYPE_POINTOPOINT, 0, cost);
548: }
549:
550: /* Regardless of the state of the neighboring router, we must
551: add a Type 3 link (stub network).
552: N.B. Options 1 & 2 share basically the same logic. */
553: masklen2ip (oi->address->prefixlen, &mask);
554: id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
555: links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
556: oi->output_cost);
557: return links;
558: }
559:
560: /* Describe Broadcast Link. */
561: static int
562: lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
563: {
564: struct ospf_neighbor *dr;
565: struct in_addr id, mask;
566: u_int16_t cost = ospf_link_cost (oi);
567:
568: /* Describe Type 3 Link. */
569: if (oi->state == ISM_Waiting)
570: {
571: masklen2ip (oi->address->prefixlen, &mask);
572: id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
573: return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
574: oi->output_cost);
575: }
576:
577: dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
578: /* Describe Type 2 link. */
579: if (dr && (dr->state == NSM_Full ||
580: IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
581: ospf_nbr_count (oi, NSM_Full) > 0)
582: {
583: return link_info_set (s, DR (oi), oi->address->u.prefix4,
584: LSA_LINK_TYPE_TRANSIT, 0, cost);
585: }
586: /* Describe type 3 link. */
587: else
588: {
589: masklen2ip (oi->address->prefixlen, &mask);
590: id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
591: return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
592: oi->output_cost);
593: }
594: }
595:
596: static int
597: lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
598: {
599: struct in_addr id, mask;
600:
601: /* Describe Type 3 Link. */
602: if (oi->state != ISM_Loopback)
603: return 0;
604:
605: mask.s_addr = 0xffffffff;
606: id.s_addr = oi->address->u.prefix4.s_addr;
607: return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
608: }
609:
610: /* Describe Virtual Link. */
611: static int
612: lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
613: {
614: struct ospf_neighbor *nbr;
615: u_int16_t cost = ospf_link_cost (oi);
616:
617: if (oi->state == ISM_PointToPoint)
618: if ((nbr = ospf_nbr_lookup_ptop (oi)))
619: if (nbr->state == NSM_Full)
620: {
621: return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
622: LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
623: }
624:
625: return 0;
626: }
627:
628: #define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
629:
630: /* this function add for support point-to-multipoint ,see rfc2328
631: 12.4.1.4.*/
632: /* from "edward rrr" <edward_rrr@hotmail.com>
633: http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
634: static int
635: lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
636: {
637: int links = 0;
638: struct route_node *rn;
639: struct ospf_neighbor *nbr = NULL;
640: struct in_addr id, mask;
641: u_int16_t cost = ospf_link_cost (oi);
642:
643: mask.s_addr = 0xffffffff;
644: id.s_addr = oi->address->u.prefix4.s_addr;
645: links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
646:
647: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
648: zlog_debug ("PointToMultipoint: running ptomultip_set");
649:
650: /* Search neighbor, */
651: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
652: if ((nbr = rn->info) != NULL)
653: /* Ignore myself. */
654: if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
655: if (nbr->state == NSM_Full)
656:
657: {
658: links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
659: LSA_LINK_TYPE_POINTOPOINT, 0, cost);
660: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
661: zlog_debug ("PointToMultipoint: set link to %s",
662: inet_ntoa(oi->address->u.prefix4));
663: }
664:
665: return links;
666: }
667:
668: /* Set router-LSA link information. */
669: static int
670: router_lsa_link_set (struct stream *s, struct ospf_area *area)
671: {
672: struct listnode *node;
673: struct ospf_interface *oi;
674: int links = 0;
675:
676: for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
677: {
678: struct interface *ifp = oi->ifp;
679:
680: /* Check interface is up, OSPF is enable. */
681: if (if_is_operative (ifp))
682: {
683: if (oi->state != ISM_Down)
684: {
1.1.1.3 ! misho 685: oi->lsa_pos_beg = links;
1.1 misho 686: /* Describe each link. */
687: switch (oi->type)
688: {
689: case OSPF_IFTYPE_POINTOPOINT:
690: links += lsa_link_ptop_set (s, oi);
691: break;
692: case OSPF_IFTYPE_BROADCAST:
693: links += lsa_link_broadcast_set (s, oi);
694: break;
695: case OSPF_IFTYPE_NBMA:
696: links += lsa_link_nbma_set (s, oi);
697: break;
698: case OSPF_IFTYPE_POINTOMULTIPOINT:
699: links += lsa_link_ptomp_set (s, oi);
700: break;
701: case OSPF_IFTYPE_VIRTUALLINK:
702: links += lsa_link_virtuallink_set (s, oi);
703: break;
704: case OSPF_IFTYPE_LOOPBACK:
705: links += lsa_link_loopback_set (s, oi);
706: }
1.1.1.3 ! misho 707: oi->lsa_pos_end = links;
1.1 misho 708: }
709: }
710: }
711:
712: return links;
713: }
714:
715: /* Set router-LSA body. */
716: static void
717: ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
718: {
719: unsigned long putp;
720: u_int16_t cnt;
721:
722: /* Set flags. */
723: stream_putc (s, router_lsa_flags (area));
724:
725: /* Set Zero fields. */
726: stream_putc (s, 0);
727:
728: /* Keep pointer to # links. */
729: putp = stream_get_endp(s);
730:
731: /* Forward word */
732: stream_putw(s, 0);
733:
734: /* Set all link information. */
735: cnt = router_lsa_link_set (s, area);
736:
737: /* Set # of links here. */
738: stream_putw_at (s, putp, cnt);
739: }
740:
741: static int
742: ospf_stub_router_timer (struct thread *t)
743: {
744: struct ospf_area *area = THREAD_ARG (t);
745:
746: area->t_stub_router = NULL;
747:
748: SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
749:
750: /* clear stub route state and generate router-lsa refresh, don't
751: * clobber an administratively set stub-router state though.
752: */
753: if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
754: return 0;
755:
756: UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
757:
758: ospf_router_lsa_update_area (area);
759:
760: return 0;
761: }
762:
1.1.1.2 misho 763: static void
1.1 misho 764: ospf_stub_router_check (struct ospf_area *area)
765: {
766: /* area must either be administratively configured to be stub
767: * or startup-time stub-router must be configured and we must in a pre-stub
768: * state.
769: */
770: if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
771: {
772: SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
773: return;
774: }
775:
776: /* not admin-stubbed, check whether startup stubbing is configured and
777: * whether it's not been done yet
778: */
779: if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
780: return;
781:
782: if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
783: {
784: /* stub-router is hence done forever for this area, even if someone
785: * tries configure it (take effect next restart).
786: */
787: SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
788: return;
789: }
790:
791: /* startup stub-router configured and not yet done */
792: SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
793:
794: OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
795: area->ospf->stub_router_startup_time);
796: }
797:
798: /* Create new router-LSA. */
799: static struct ospf_lsa *
800: ospf_router_lsa_new (struct ospf_area *area)
801: {
802: struct ospf *ospf = area->ospf;
803: struct stream *s;
804: struct lsa_header *lsah;
805: struct ospf_lsa *new;
806: int length;
807:
808: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
809: zlog_debug ("LSA[Type1]: Create router-LSA instance");
810:
811: /* check whether stub-router is desired, and if this is the first
812: * router LSA.
813: */
814: ospf_stub_router_check (area);
815:
816: /* Create a stream for LSA. */
817: s = stream_new (OSPF_MAX_LSA_SIZE);
818: /* Set LSA common header fields. */
819: lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
820: OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
821:
822: /* Set router-LSA body fields. */
823: ospf_router_lsa_body_set (s, area);
824:
825: /* Set length. */
826: length = stream_get_endp (s);
827: lsah = (struct lsa_header *) STREAM_DATA (s);
828: lsah->length = htons (length);
829:
830: /* Now, create OSPF LSA instance. */
831: if ( (new = ospf_lsa_new ()) == NULL)
832: {
833: zlog_err ("%s: Unable to create new lsa", __func__);
834: return NULL;
835: }
836:
837: new->area = area;
838: SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
839:
840: /* Copy LSA data to store, discard stream. */
841: new->data = ospf_lsa_data_new (length);
842: memcpy (new->data, lsah, length);
843: stream_free (s);
844:
845: return new;
846: }
847:
848: /* Originate Router-LSA. */
849: static struct ospf_lsa *
850: ospf_router_lsa_originate (struct ospf_area *area)
851: {
852: struct ospf_lsa *new;
853:
854: /* Create new router-LSA instance. */
855: if ( (new = ospf_router_lsa_new (area)) == NULL)
856: {
857: zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
858: return NULL;
859: }
860:
861: /* Sanity check. */
862: if (new->data->adv_router.s_addr == 0)
863: {
864: if (IS_DEBUG_OSPF_EVENT)
865: zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
866: ospf_lsa_discard (new);
867: return NULL;
868: }
869:
870: /* Install LSA to LSDB. */
871: new = ospf_lsa_install (area->ospf, NULL, new);
872:
873: /* Update LSA origination count. */
874: area->ospf->lsa_originate_count++;
875:
876: /* Flooding new LSA through area. */
877: ospf_flood_through_area (area, NULL, new);
878:
879: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
880: {
881: zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
882: new->data->type, inet_ntoa (new->data->id), new);
883: ospf_lsa_header_dump (new->data);
884: }
885:
886: return new;
887: }
888:
889: /* Refresh router-LSA. */
890: static struct ospf_lsa *
891: ospf_router_lsa_refresh (struct ospf_lsa *lsa)
892: {
893: struct ospf_area *area = lsa->area;
894: struct ospf_lsa *new;
895:
896: /* Sanity check. */
897: assert (lsa->data);
898:
899: /* Delete LSA from neighbor retransmit-list. */
900: ospf_ls_retransmit_delete_nbr_area (area, lsa);
901:
902: /* Unregister LSA from refresh-list */
903: ospf_refresher_unregister_lsa (area->ospf, lsa);
904:
905: /* Create new router-LSA instance. */
906: if ( (new = ospf_router_lsa_new (area)) == NULL)
907: {
908: zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
909: return NULL;
910: }
911:
912: new->data->ls_seqnum = lsa_seqnum_increment (lsa);
913:
914: ospf_lsa_install (area->ospf, NULL, new);
915:
916: /* Flood LSA through area. */
917: ospf_flood_through_area (area, NULL, new);
918:
919: /* Debug logging. */
920: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
921: {
922: zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
923: new->data->type, inet_ntoa (new->data->id));
924: ospf_lsa_header_dump (new->data);
925: }
926:
927: return NULL;
928: }
929:
930: int
931: ospf_router_lsa_update_area (struct ospf_area *area)
932: {
933: if (IS_DEBUG_OSPF_EVENT)
934: zlog_debug ("[router-LSA]: (router-LSA area update)");
935:
936: /* Now refresh router-LSA. */
937: if (area->router_lsa_self)
938: ospf_lsa_refresh (area->ospf, area->router_lsa_self);
939: /* Newly originate router-LSA. */
940: else
941: ospf_router_lsa_originate (area);
942:
943: return 0;
944: }
945:
946: int
947: ospf_router_lsa_update (struct ospf *ospf)
948: {
949: struct listnode *node, *nnode;
950: struct ospf_area *area;
951:
952: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
953: zlog_debug ("Timer[router-LSA Update]: (timer expire)");
954:
955: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
956: {
957: struct ospf_lsa *lsa = area->router_lsa_self;
958: struct router_lsa *rl;
959: const char *area_str;
960:
961: /* Keep Area ID string. */
962: area_str = AREA_NAME (area);
963:
964: /* If LSA not exist in this Area, originate new. */
965: if (lsa == NULL)
966: {
967: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
968: zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
969:
970: ospf_router_lsa_originate (area);
971: }
972: /* If router-ID is changed, Link ID must change.
973: First flush old LSA, then originate new. */
974: else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
975: {
976: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
977: zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
978: lsa->data->type, inet_ntoa (lsa->data->id), area_str);
979: ospf_refresher_unregister_lsa (ospf, lsa);
980: ospf_lsa_flush_area (lsa, area);
981: ospf_lsa_unlock (&area->router_lsa_self);
982: area->router_lsa_self = NULL;
983:
984: /* Refresh router-LSA, (not install) and flood through area. */
985: ospf_router_lsa_update_area (area);
986: }
987: else
988: {
989: rl = (struct router_lsa *) lsa->data;
990: /* Refresh router-LSA, (not install) and flood through area. */
991: if (rl->flags != ospf->flags)
992: ospf_router_lsa_update_area (area);
993: }
994: }
995:
996: return 0;
997: }
998:
999:
1000: /* network-LSA related functions. */
1001: /* Originate Network-LSA. */
1002: static void
1003: ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1004: {
1005: struct in_addr mask;
1006: struct route_node *rn;
1007: struct ospf_neighbor *nbr;
1008:
1009: masklen2ip (oi->address->prefixlen, &mask);
1010: stream_put_ipv4 (s, mask.s_addr);
1011:
1012: /* The network-LSA lists those routers that are fully adjacent to
1013: the Designated Router; each fully adjacent router is identified by
1014: its OSPF Router ID. The Designated Router includes itself in this
1015: list. RFC2328, Section 12.4.2 */
1016:
1017: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1018: if ((nbr = rn->info) != NULL)
1019: if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1020: stream_put_ipv4 (s, nbr->router_id.s_addr);
1021: }
1022:
1023: static struct ospf_lsa *
1024: ospf_network_lsa_new (struct ospf_interface *oi)
1025: {
1026: struct stream *s;
1027: struct ospf_lsa *new;
1028: struct lsa_header *lsah;
1029: struct ospf_if_params *oip;
1030: int length;
1031:
1032: /* If there are no neighbours on this network (the net is stub),
1033: the router does not originate network-LSA (see RFC 12.4.2) */
1034: if (oi->full_nbrs == 0)
1035: return NULL;
1036:
1037: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1038: zlog_debug ("LSA[Type2]: Create network-LSA instance");
1039:
1040: /* Create new stream for LSA. */
1041: s = stream_new (OSPF_MAX_LSA_SIZE);
1042: lsah = (struct lsa_header *) STREAM_DATA (s);
1043:
1044: lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
1045: OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
1046:
1047: /* Set network-LSA body fields. */
1048: ospf_network_lsa_body_set (s, oi);
1049:
1050: /* Set length. */
1051: length = stream_get_endp (s);
1052: lsah->length = htons (length);
1053:
1054: /* Create OSPF LSA instance. */
1055: if ( (new = ospf_lsa_new ()) == NULL)
1056: {
1057: zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1058: return NULL;
1059: }
1060:
1061: new->area = oi->area;
1062: SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
1063:
1064: /* Copy LSA to store. */
1065: new->data = ospf_lsa_data_new (length);
1066: memcpy (new->data, lsah, length);
1067: stream_free (s);
1068:
1069: /* Remember prior network LSA sequence numbers, even if we stop
1070: * originating one for this oi, to try avoid re-originating LSAs with a
1071: * prior sequence number, and thus speed up adjency forming & convergence.
1072: */
1073: if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1074: {
1075: new->data->ls_seqnum = oip->network_lsa_seqnum;
1076: new->data->ls_seqnum = lsa_seqnum_increment (new);
1077: }
1078: else
1079: {
1080: oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1081: ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1082: }
1083: oip->network_lsa_seqnum = new->data->ls_seqnum;
1084:
1085: return new;
1086: }
1087:
1088: /* Originate network-LSA. */
1089: void
1090: ospf_network_lsa_update (struct ospf_interface *oi)
1091: {
1092: struct ospf_lsa *new;
1093:
1094: if (oi->network_lsa_self != NULL)
1095: {
1096: ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1097: return;
1098: }
1099:
1100: /* Create new network-LSA instance. */
1101: new = ospf_network_lsa_new (oi);
1102: if (new == NULL)
1103: return;
1104:
1105: /* Install LSA to LSDB. */
1106: new = ospf_lsa_install (oi->ospf, oi, new);
1107:
1108: /* Update LSA origination count. */
1109: oi->ospf->lsa_originate_count++;
1110:
1111: /* Flooding new LSA through area. */
1112: ospf_flood_through_area (oi->area, NULL, new);
1113:
1114: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1115: {
1116: zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
1117: new->data->type, inet_ntoa (new->data->id), new);
1118: ospf_lsa_header_dump (new->data);
1119: }
1120:
1121: return;
1122: }
1123:
1124: static struct ospf_lsa *
1125: ospf_network_lsa_refresh (struct ospf_lsa *lsa)
1126: {
1127: struct ospf_area *area = lsa->area;
1128: struct ospf_lsa *new, *new2;
1129: struct ospf_if_params *oip;
1130: struct ospf_interface *oi;
1131:
1132: assert (lsa->data);
1133:
1134: /* Retrieve the oi for the network LSA */
1135: oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1136: if (oi == NULL)
1137: {
1138: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1139: {
1140: zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1141: "no oi found, ick, ignoring.",
1142: lsa->data->type, inet_ntoa (lsa->data->id));
1143: ospf_lsa_header_dump (lsa->data);
1144: }
1145: return NULL;
1146: }
1147: /* Delete LSA from neighbor retransmit-list. */
1148: ospf_ls_retransmit_delete_nbr_area (area, lsa);
1149:
1150: /* Unregister LSA from refresh-list */
1151: ospf_refresher_unregister_lsa (area->ospf, lsa);
1152:
1153: /* Create new network-LSA instance. */
1154: new = ospf_network_lsa_new (oi);
1155: if (new == NULL)
1156: return NULL;
1157:
1158: oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1159: assert (oip != NULL);
1160: oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1161:
1162: new2 = ospf_lsa_install (area->ospf, oi, new);
1163:
1164: assert (new2 == new);
1165:
1166: /* Flood LSA through aera. */
1167: ospf_flood_through_area (area, NULL, new);
1168:
1169: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1170: {
1171: zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
1172: new->data->type, inet_ntoa (new->data->id));
1173: ospf_lsa_header_dump (new->data);
1174: }
1175:
1176: return new;
1177: }
1178:
1179: static void
1180: stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1181: {
1182: u_int32_t metric;
1183: char *mp;
1184:
1185: /* Put 0 metric. TOS metric is not supported. */
1186: metric = htonl (metric_value);
1187: mp = (char *) &metric;
1188: mp++;
1189: stream_put (s, mp, 3);
1190: }
1191:
1192: /* summary-LSA related functions. */
1193: static void
1194: ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1195: u_int32_t metric)
1196: {
1197: struct in_addr mask;
1198:
1199: masklen2ip (p->prefixlen, &mask);
1200:
1201: /* Put Network Mask. */
1202: stream_put_ipv4 (s, mask.s_addr);
1203:
1204: /* Set # TOS. */
1205: stream_putc (s, (u_char) 0);
1206:
1207: /* Set metric. */
1208: stream_put_ospf_metric (s, metric);
1209: }
1210:
1211: static struct ospf_lsa *
1212: ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1213: u_int32_t metric, struct in_addr id)
1214: {
1215: struct stream *s;
1216: struct ospf_lsa *new;
1217: struct lsa_header *lsah;
1218: int length;
1219:
1220: if (id.s_addr == 0xffffffff)
1221: {
1222: /* Maybe Link State ID not available. */
1223: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1224: zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1225: OSPF_SUMMARY_LSA);
1226: return NULL;
1227: }
1228:
1229: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1230: zlog_debug ("LSA[Type3]: Create summary-LSA instance");
1231:
1232: /* Create new stream for LSA. */
1233: s = stream_new (OSPF_MAX_LSA_SIZE);
1234: lsah = (struct lsa_header *) STREAM_DATA (s);
1235:
1236: lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1237: id, area->ospf->router_id);
1238:
1239: /* Set summary-LSA body fields. */
1240: ospf_summary_lsa_body_set (s, p, metric);
1241:
1242: /* Set length. */
1243: length = stream_get_endp (s);
1244: lsah->length = htons (length);
1245:
1246: /* Create OSPF LSA instance. */
1247: new = ospf_lsa_new ();
1248: new->area = area;
1249: SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
1250:
1251: /* Copy LSA to store. */
1252: new->data = ospf_lsa_data_new (length);
1253: memcpy (new->data, lsah, length);
1254: stream_free (s);
1255:
1256: return new;
1257: }
1258:
1259: /* Originate Summary-LSA. */
1260: struct ospf_lsa *
1261: ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1262: struct ospf_area *area)
1263: {
1264: struct ospf_lsa *new;
1265: struct in_addr id;
1266:
1267: id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
1268:
1269: if (id.s_addr == 0xffffffff)
1270: {
1271: /* Maybe Link State ID not available. */
1272: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1273: zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1274: OSPF_SUMMARY_LSA);
1275: return NULL;
1276: }
1277:
1278: /* Create new summary-LSA instance. */
1279: if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1280: return NULL;
1281:
1282: /* Instlal LSA to LSDB. */
1283: new = ospf_lsa_install (area->ospf, NULL, new);
1284:
1285: /* Update LSA origination count. */
1286: area->ospf->lsa_originate_count++;
1287:
1288: /* Flooding new LSA through area. */
1289: ospf_flood_through_area (area, NULL, new);
1290:
1291: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1292: {
1293: zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
1294: new->data->type, inet_ntoa (new->data->id), new);
1295: ospf_lsa_header_dump (new->data);
1296: }
1297:
1298: return new;
1299: }
1300:
1301: static struct ospf_lsa*
1302: ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
1303: {
1304: struct ospf_lsa *new;
1305: struct summary_lsa *sl;
1306: struct prefix p;
1307:
1308: /* Sanity check. */
1309: assert (lsa->data);
1310:
1311: sl = (struct summary_lsa *)lsa->data;
1312: p.prefixlen = ip_masklen (sl->mask);
1313: new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1314: sl->header.id);
1315:
1316: if (!new)
1317: return NULL;
1318:
1319: new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1320:
1321: ospf_lsa_install (ospf, NULL, new);
1322:
1323: /* Flood LSA through AS. */
1324: ospf_flood_through_area (new->area, NULL, new);
1325:
1326: /* Debug logging. */
1327: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1328: {
1329: zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
1330: new->data->type, inet_ntoa (new->data->id));
1331: ospf_lsa_header_dump (new->data);
1332: }
1333:
1334: return new;
1335: }
1336:
1337:
1338: /* summary-ASBR-LSA related functions. */
1339: static void
1340: ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1341: u_int32_t metric)
1342: {
1343: /* Put Network Mask. */
1.1.1.3 ! misho 1344: stream_put_ipv4 (s, (u_int32_t) 0);
1.1 misho 1345:
1346: /* Set # TOS. */
1347: stream_putc (s, (u_char) 0);
1348:
1349: /* Set metric. */
1350: stream_put_ospf_metric (s, metric);
1351: }
1352:
1353: static struct ospf_lsa *
1354: ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1355: u_int32_t metric, struct in_addr id)
1356: {
1357: struct stream *s;
1358: struct ospf_lsa *new;
1359: struct lsa_header *lsah;
1360: int length;
1361:
1362: if (id.s_addr == 0xffffffff)
1363: {
1364: /* Maybe Link State ID not available. */
1365: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1366: zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1367: OSPF_ASBR_SUMMARY_LSA);
1368: return NULL;
1369: }
1370:
1371: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1372: zlog_debug ("LSA[Type3]: Create summary-LSA instance");
1373:
1374: /* Create new stream for LSA. */
1375: s = stream_new (OSPF_MAX_LSA_SIZE);
1376: lsah = (struct lsa_header *) STREAM_DATA (s);
1377:
1378: lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1379: id, area->ospf->router_id);
1380:
1381: /* Set summary-LSA body fields. */
1382: ospf_summary_asbr_lsa_body_set (s, p, metric);
1383:
1384: /* Set length. */
1385: length = stream_get_endp (s);
1386: lsah->length = htons (length);
1387:
1388: /* Create OSPF LSA instance. */
1389: new = ospf_lsa_new ();
1390: new->area = area;
1391: SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
1392:
1393: /* Copy LSA to store. */
1394: new->data = ospf_lsa_data_new (length);
1395: memcpy (new->data, lsah, length);
1396: stream_free (s);
1397:
1398: return new;
1399: }
1400:
1401: /* Originate summary-ASBR-LSA. */
1402: struct ospf_lsa *
1403: ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1404: struct ospf_area *area)
1405: {
1406: struct ospf_lsa *new;
1407: struct in_addr id;
1408:
1409: id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
1410:
1411: if (id.s_addr == 0xffffffff)
1412: {
1413: /* Maybe Link State ID not available. */
1414: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1415: zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1416: OSPF_ASBR_SUMMARY_LSA);
1417: return NULL;
1418: }
1419:
1420: /* Create new summary-LSA instance. */
1421: new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
1422: if (!new)
1423: return NULL;
1424:
1425: /* Install LSA to LSDB. */
1426: new = ospf_lsa_install (area->ospf, NULL, new);
1427:
1428: /* Update LSA origination count. */
1429: area->ospf->lsa_originate_count++;
1430:
1431: /* Flooding new LSA through area. */
1432: ospf_flood_through_area (area, NULL, new);
1433:
1434: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1435: {
1436: zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
1437: new->data->type, inet_ntoa (new->data->id), new);
1438: ospf_lsa_header_dump (new->data);
1439: }
1440:
1441: return new;
1442: }
1443:
1444: static struct ospf_lsa*
1445: ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
1446: {
1447: struct ospf_lsa *new;
1448: struct summary_lsa *sl;
1449: struct prefix p;
1450:
1451: /* Sanity check. */
1452: assert (lsa->data);
1453:
1454: sl = (struct summary_lsa *)lsa->data;
1455: p.prefixlen = ip_masklen (sl->mask);
1456: new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1457: sl->header.id);
1458: if (!new)
1459: return NULL;
1460:
1461: new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1462:
1463: ospf_lsa_install (ospf, NULL, new);
1464:
1465: /* Flood LSA through area. */
1466: ospf_flood_through_area (new->area, NULL, new);
1467:
1468: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1469: {
1470: zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
1471: new->data->type, inet_ntoa (new->data->id));
1472: ospf_lsa_header_dump (new->data);
1473: }
1474:
1475: return new;
1476: }
1477:
1478: /* AS-external-LSA related functions. */
1479:
1480: /* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1481: is connected, else 0*/
1482: static struct in_addr
1483: ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
1484: {
1485: struct in_addr fwd;
1486: struct prefix nh;
1487: struct listnode *node;
1488: struct ospf_interface *oi;
1489:
1490: fwd.s_addr = 0;
1491:
1492: if (!nexthop.s_addr)
1493: return fwd;
1494:
1495: /* Check whether nexthop is covered by OSPF network. */
1496: nh.family = AF_INET;
1497: nh.u.prefix4 = nexthop;
1498: nh.prefixlen = IPV4_MAX_BITLEN;
1499:
1500: /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1501: * better to make use of the per-ifp table of ois.
1502: */
1503: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1504: if (if_is_operative (oi->ifp))
1505: if (oi->address->family == AF_INET)
1506: if (prefix_match (oi->address, &nh))
1507: return nexthop;
1508:
1509: return fwd;
1510: }
1511:
1512: /* NSSA-external-LSA related functions. */
1513:
1514: /* Get 1st IP connection for Forward Addr */
1515:
1516: struct in_addr
1517: ospf_get_ip_from_ifp (struct ospf_interface *oi)
1518: {
1519: struct in_addr fwd;
1520:
1521: fwd.s_addr = 0;
1522:
1523: if (if_is_operative (oi->ifp))
1524: return oi->address->u.prefix4;
1525:
1526: return fwd;
1527: }
1528:
1529: /* Get 1st IP connection for Forward Addr */
1530: struct in_addr
1531: ospf_get_nssa_ip (struct ospf_area *area)
1532: {
1533: struct in_addr fwd;
1534: struct in_addr best_default;
1535: struct listnode *node;
1536: struct ospf_interface *oi;
1537:
1538: fwd.s_addr = 0;
1539: best_default.s_addr = 0;
1540:
1541: for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
1542: {
1543: if (if_is_operative (oi->ifp))
1544: if (oi->area->external_routing == OSPF_AREA_NSSA)
1545: if (oi->address && oi->address->family == AF_INET)
1546: {
1547: if (best_default.s_addr == 0)
1548: best_default = oi->address->u.prefix4;
1549: if (oi->area == area)
1550: return oi->address->u.prefix4;
1551: }
1552: }
1553: if (best_default.s_addr != 0)
1554: return best_default;
1555:
1556: if (best_default.s_addr != 0)
1557: return best_default;
1558:
1559: return fwd;
1560: }
1561:
1562: #define DEFAULT_DEFAULT_METRIC 20
1563: #define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1564: #define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1565:
1566: #define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1567:
1568: int
1569: metric_type (struct ospf *ospf, u_char src)
1570: {
1571: return (ospf->dmetric[src].type < 0 ?
1572: DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
1573: }
1574:
1575: int
1576: metric_value (struct ospf *ospf, u_char src)
1577: {
1578: if (ospf->dmetric[src].value < 0)
1579: {
1580: if (src == DEFAULT_ROUTE)
1581: {
1582: if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
1583: return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1584: else
1585: return DEFAULT_DEFAULT_ALWAYS_METRIC;
1586: }
1587: else if (ospf->default_metric < 0)
1588: return DEFAULT_DEFAULT_METRIC;
1589: else
1590: return ospf->default_metric;
1591: }
1592:
1593: return ospf->dmetric[src].value;
1594: }
1595:
1596: /* Set AS-external-LSA body. */
1597: static void
1598: ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1599: struct ospf *ospf)
1600: {
1601: struct prefix_ipv4 *p = &ei->p;
1602: struct in_addr mask, fwd_addr;
1603: u_int32_t mvalue;
1604: int mtype;
1605: int type;
1606:
1607: /* Put Network Mask. */
1608: masklen2ip (p->prefixlen, &mask);
1609: stream_put_ipv4 (s, mask.s_addr);
1610:
1611: /* If prefix is default, specify DEFAULT_ROUTE. */
1612: type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1613:
1614: mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
1615: ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
1616:
1617: mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
1618: ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
1619:
1620: /* Put type of external metric. */
1621: stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1622:
1623: /* Put 0 metric. TOS metric is not supported. */
1624: stream_put_ospf_metric (s, mvalue);
1625:
1626: /* Get forwarding address to nexthop if on the Connection List, else 0. */
1627: fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
1628:
1629: /* Put forwarding address. */
1630: stream_put_ipv4 (s, fwd_addr.s_addr);
1631:
1632: /* Put route tag -- This value should be introduced from configuration. */
1633: stream_putl (s, 0);
1634: }
1635:
1636: /* Create new external-LSA. */
1637: static struct ospf_lsa *
1638: ospf_external_lsa_new (struct ospf *ospf,
1639: struct external_info *ei, struct in_addr *old_id)
1640: {
1641: struct stream *s;
1642: struct lsa_header *lsah;
1643: struct ospf_lsa *new;
1644: struct in_addr id;
1645: int length;
1646:
1647: if (ei == NULL)
1648: {
1649: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1.1.1.2 misho 1650: zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
1.1 misho 1651: return NULL;
1652: }
1653:
1654: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1655: zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
1656:
1657: /* If old Link State ID is specified, refresh LSA with same ID. */
1658: if (old_id)
1659: id = *old_id;
1660: /* Get Link State with unique ID. */
1661: else
1662: {
1663: id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
1664: if (id.s_addr == 0xffffffff)
1665: {
1666: /* Maybe Link State ID not available. */
1667: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1668: zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
1669: return NULL;
1670: }
1671: }
1672:
1673: /* Create new stream for LSA. */
1674: s = stream_new (OSPF_MAX_LSA_SIZE);
1675: lsah = (struct lsa_header *) STREAM_DATA (s);
1676:
1677: /* Set LSA common header fields. */
1678: lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1679: id, ospf->router_id);
1680:
1681: /* Set AS-external-LSA body fields. */
1682: ospf_external_lsa_body_set (s, ei, ospf);
1683:
1684: /* Set length. */
1685: length = stream_get_endp (s);
1686: lsah->length = htons (length);
1687:
1688: /* Now, create OSPF LSA instance. */
1689: new = ospf_lsa_new ();
1690: new->area = NULL;
1691: SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
1692:
1693: /* Copy LSA data to store, discard stream. */
1694: new->data = ospf_lsa_data_new (length);
1695: memcpy (new->data, lsah, length);
1696: stream_free (s);
1697:
1698: return new;
1699: }
1700:
1701: /* As Type-7 */
1702: static void
1703: ospf_install_flood_nssa (struct ospf *ospf,
1704: struct ospf_lsa *lsa, struct external_info *ei)
1705: {
1706: struct ospf_lsa *new;
1707: struct as_external_lsa *extlsa;
1708: struct ospf_area *area;
1709: struct listnode *node, *nnode;
1710:
1711: /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1712: * which originated from an NSSA area. In which case it should not be
1713: * flooded back to NSSA areas.
1714: */
1715: if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1716: return;
1717:
1718: /* NSSA Originate or Refresh (If anyNSSA)
1719:
1720: LSA is self-originated. And just installed as Type-5.
1721: Additionally, install as Type-7 LSDB for every attached NSSA.
1722:
1723: P-Bit controls which ABR performs translation to outside world; If
1724: we are an ABR....do not set the P-bit, because we send the Type-5,
1725: not as the ABR Translator, but as the ASBR owner within the AS!
1726:
1727: If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1728: elected ABR Translator will see the P-bit, Translate, and re-flood.
1729:
1730: Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1731: Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1732:
1733: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
1734: {
1735: /* Don't install Type-7 LSA's into nonNSSA area */
1736: if (area->external_routing != OSPF_AREA_NSSA)
1737: continue;
1738:
1739: /* make lsa duplicate, lock=1 */
1740: new = ospf_lsa_dup (lsa);
1741: new->area = area;
1742: new->data->type = OSPF_AS_NSSA_LSA;
1743:
1744: /* set P-bit if not ABR */
1745: if (! IS_OSPF_ABR (ospf))
1746: {
1747: SET_FLAG(new->data->options, OSPF_OPTION_NP);
1748:
1749: /* set non-zero FWD ADDR
1750:
1751: draft-ietf-ospf-nssa-update-09.txt
1752:
1753: if the network between the NSSA AS boundary router and the
1754: adjacent AS is advertised into OSPF as an internal OSPF route,
1755: the forwarding address should be the next op address as is cu
1756: currently done with type-5 LSAs. If the intervening network is
1757: not adversited into OSPF as an internal OSPF route and the
1758: type-7 LSA's P-bit is set a forwarding address should be
1759: selected from one of the router's active OSPF inteface addresses
1760: which belong to the NSSA. If no such addresses exist, then
1761: no type-7 LSA's with the P-bit set should originate from this
1762: router. */
1763:
1764: /* kevinm: not updating lsa anymore, just new */
1765: extlsa = (struct as_external_lsa *)(new->data);
1766:
1767: if (extlsa->e[0].fwd_addr.s_addr == 0)
1768: extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
1769:
1770: if (extlsa->e[0].fwd_addr.s_addr == 0)
1771: {
1772: if (IS_DEBUG_OSPF_NSSA)
1773: zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
1774: ospf_lsa_discard (new);
1775: return;
1776: }
1777: }
1778:
1779: /* install also as Type-7 */
1780: ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
1781:
1782: /* will send each copy, lock=2+n */
1783: ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
1784: }
1785: }
1786:
1787: static struct ospf_lsa *
1788: ospf_lsa_translated_nssa_new (struct ospf *ospf,
1789: struct ospf_lsa *type7)
1790: {
1791:
1792: struct ospf_lsa *new;
1793: struct as_external_lsa *ext, *extnew;
1794: struct external_info ei;
1795:
1796: ext = (struct as_external_lsa *)(type7->data);
1797:
1798: /* need external_info struct, fill in bare minimum */
1799: ei.p.family = AF_INET;
1800: ei.p.prefix = type7->data->id;
1801: ei.p.prefixlen = ip_masklen (ext->mask);
1802: ei.type = ZEBRA_ROUTE_OSPF;
1803: ei.nexthop = ext->header.adv_router;
1804: ei.route_map_set.metric = -1;
1805: ei.route_map_set.metric_type = -1;
1806: ei.tag = 0;
1807:
1808: if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1809: {
1810: if (IS_DEBUG_OSPF_NSSA)
1811: zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
1812: "Translated Type-5 for %s",
1813: inet_ntoa (ei.p.prefix));
1814: return NULL;
1815: }
1816:
1817: extnew = (struct as_external_lsa *)(new->data);
1818:
1819: /* copy over Type-7 data to new */
1820: extnew->e[0].tos = ext->e[0].tos;
1821: extnew->e[0].route_tag = ext->e[0].route_tag;
1822: extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1823: new->data->ls_seqnum = type7->data->ls_seqnum;
1824:
1825: /* add translated flag, checksum and lock new lsa */
1826: SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1827: new = ospf_lsa_lock (new);
1828:
1829: return new;
1830: }
1831:
1832: /* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1833: struct ospf_lsa *
1834: ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1835: {
1836: struct ospf_lsa *new;
1837: struct as_external_lsa *extnew;
1838:
1839: /* we cant use ospf_external_lsa_originate() as we need to set
1840: * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1841: */
1842:
1843: if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1844: {
1845: if (IS_DEBUG_OSPF_NSSA)
1846: zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
1847: "Type-7, Id %s, to Type-5",
1848: inet_ntoa (type7->data->id));
1849: return NULL;
1850: }
1851:
1852: extnew = (struct as_external_lsa *)new;
1853:
1854: if (IS_DEBUG_OSPF_NSSA)
1855: {
1856: zlog_debug ("ospf_translated_nssa_originate(): "
1857: "translated Type 7, installed:");
1858: ospf_lsa_header_dump (new->data);
1859: zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1860: zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
1861: }
1862:
1863: if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1864: {
1.1.1.3 ! misho 1865: if (IS_DEBUG_OSPF_NSSA)
1.1 misho 1866: zlog_debug ("ospf_lsa_translated_nssa_originate(): "
1867: "Could not install LSA "
1868: "id %s", inet_ntoa (type7->data->id));
1869: return NULL;
1870: }
1871:
1872: ospf->lsa_originate_count++;
1873: ospf_flood_through_as (ospf, NULL, new);
1874:
1875: return new;
1876: }
1877:
1878: /* Refresh Translated from NSSA AS-external-LSA. */
1879: struct ospf_lsa *
1880: ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1881: struct ospf_lsa *type5)
1882: {
1883: struct ospf_lsa *new = NULL;
1884:
1885: /* Sanity checks. */
1886: assert (type7 || type5);
1887: if (!(type7 || type5))
1888: return NULL;
1889: if (type7)
1890: assert (type7->data);
1891: if (type5)
1892: assert (type5->data);
1893: assert (ospf->anyNSSA);
1894:
1895: /* get required data according to what has been given */
1896: if (type7 && type5 == NULL)
1897: {
1898: /* find the translated Type-5 for this Type-7 */
1899: struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1900: struct prefix_ipv4 p =
1901: {
1902: .prefix = type7->data->id,
1903: .prefixlen = ip_masklen (ext->mask),
1904: .family = AF_INET,
1905: };
1906:
1907: type5 = ospf_external_info_find_lsa (ospf, &p);
1908: }
1909: else if (type5 && type7 == NULL)
1910: {
1911: /* find the type-7 from which supplied type-5 was translated,
1912: * ie find first type-7 with same LSA Id.
1913: */
1914: struct listnode *ln, *lnn;
1915: struct route_node *rn;
1916: struct ospf_lsa *lsa;
1917: struct ospf_area *area;
1918:
1919: for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
1920: {
1921: if (area->external_routing != OSPF_AREA_NSSA
1922: && !type7)
1923: continue;
1924:
1925: LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1926: {
1927: if (lsa->data->id.s_addr == type5->data->id.s_addr)
1928: {
1929: type7 = lsa;
1930: break;
1931: }
1932: }
1933: }
1934: }
1935:
1936: /* do we have type7? */
1937: if (!type7)
1938: {
1939: if (IS_DEBUG_OSPF_NSSA)
1940: zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
1941: "Type-5 LSA Id %s",
1942: inet_ntoa (type5->data->id));
1943: return NULL;
1944: }
1945:
1946: /* do we have valid translated type5? */
1947: if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1948: {
1949: if (IS_DEBUG_OSPF_NSSA)
1950: zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
1951: "found for Type-7 with Id %s",
1952: inet_ntoa (type7->data->id));
1953: return NULL;
1954: }
1955:
1956: /* Delete LSA from neighbor retransmit-list. */
1957: ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1958:
1959: /* create new translated LSA */
1960: if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1961: {
1962: if (IS_DEBUG_OSPF_NSSA)
1963: zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
1964: "Type-7 for %s to Type-5",
1965: inet_ntoa (type7->data->id));
1966: return NULL;
1967: }
1968:
1969: if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1970: {
1971: if (IS_DEBUG_OSPF_NSSA)
1972: zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
1973: "translated LSA, Id %s",
1974: inet_ntoa (type7->data->id));
1975: return NULL;
1976: }
1977:
1978: /* Flood LSA through area. */
1979: ospf_flood_through_as (ospf, NULL, new);
1980:
1981: return new;
1982: }
1983:
1984: int
1985: is_prefix_default (struct prefix_ipv4 *p)
1986: {
1987: struct prefix_ipv4 q;
1988:
1989: q.family = AF_INET;
1990: q.prefix.s_addr = 0;
1991: q.prefixlen = 0;
1992:
1993: return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1994: }
1995:
1996: /* Originate an AS-external-LSA, install and flood. */
1997: struct ospf_lsa *
1998: ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
1999: {
2000: struct ospf_lsa *new;
2001:
2002: /* Added for NSSA project....
2003:
2004: External LSAs are originated in ASBRs as usual, but for NSSA systems.
2005: there is the global Type-5 LSDB and a Type-7 LSDB installed for
2006: every area. The Type-7's are flooded to every IR and every ABR; We
2007: install the Type-5 LSDB so that the normal "refresh" code operates
2008: as usual, and flag them as not used during ASE calculations. The
2009: Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2010: Address of non-zero.
2011:
2012: If an ABR is the elected NSSA translator, following SPF and during
2013: the ABR task it will translate all the scanned Type-7's, with P-bit
2014: ON and not-self generated, and translate to Type-5's throughout the
2015: non-NSSA/STUB AS.
2016:
2017: A difference in operation depends whether this ASBR is an ABR
2018: or not. If not an ABR, the P-bit is ON, to indicate that any
2019: elected NSSA-ABR can perform its translation.
2020:
2021: If an ABR, the P-bit is OFF; No ABR will perform translation and
2022: this ASBR will flood the Type-5 LSA as usual.
2023:
2024: For the case where this ASBR is not an ABR, the ASE calculations
2025: are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2026: demonstrate to the user that there are LSA's that belong to any
2027: attached NSSA.
2028:
2029: Finally, it just so happens that when the ABR is translating every
2030: Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2031: approved Type-5 (translated from Type-7); at the end of translation
2032: if any Translated Type-5's remain unapproved, then they must be
2033: flushed from the AS.
2034:
2035: */
2036:
2037: /* Check the AS-external-LSA should be originated. */
2038: if (!ospf_redistribute_check (ospf, ei, NULL))
2039: return NULL;
2040:
2041: /* Create new AS-external-LSA instance. */
2042: if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
2043: {
2044: if (IS_DEBUG_OSPF_EVENT)
2045: zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
2046: inet_ntoa (ei->p.prefix));
2047: return NULL;
2048: }
2049:
2050: /* Install newly created LSA into Type-5 LSDB, lock = 1. */
2051: ospf_lsa_install (ospf, NULL, new);
2052:
2053: /* Update LSA origination count. */
2054: ospf->lsa_originate_count++;
2055:
2056: /* Flooding new LSA. only to AS (non-NSSA/STUB) */
2057: ospf_flood_through_as (ospf, NULL, new);
2058:
2059: /* If there is any attached NSSA, do special handling */
2060: if (ospf->anyNSSA &&
2061: /* stay away from translated LSAs! */
2062: !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
2063: ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
2064:
2065: /* Debug logging. */
2066: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2067: {
2068: zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
2069: new->data->type, inet_ntoa (new->data->id), new);
2070: ospf_lsa_header_dump (new->data);
2071: }
2072:
2073: return new;
2074: }
2075:
2076: /* Originate AS-external-LSA from external info with initial flag. */
2077: int
2078: ospf_external_lsa_originate_timer (struct thread *thread)
2079: {
2080: struct ospf *ospf = THREAD_ARG (thread);
2081: struct route_node *rn;
2082: struct external_info *ei;
2083: struct route_table *rt;
2084: int type = THREAD_VAL (thread);
2085:
2086: ospf->t_external_lsa = NULL;
2087:
2088: /* Originate As-external-LSA from all type of distribute source. */
2089: if ((rt = EXTERNAL_INFO (type)))
2090: for (rn = route_top (rt); rn; rn = route_next (rn))
2091: if ((ei = rn->info) != NULL)
2092: if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
2093: if (!ospf_external_lsa_originate (ospf, ei))
2094: zlog_warn ("LSA: AS-external-LSA was not originated.");
2095:
2096: return 0;
2097: }
2098:
2099: static struct external_info *
2100: ospf_default_external_info (struct ospf *ospf)
2101: {
2102: int type;
2103: struct route_node *rn;
2104: struct prefix_ipv4 p;
2105:
2106: p.family = AF_INET;
2107: p.prefix.s_addr = 0;
2108: p.prefixlen = 0;
2109:
2110: /* First, lookup redistributed default route. */
2111: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2112: if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2113: {
2114: rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2115: if (rn != NULL)
2116: {
2117: route_unlock_node (rn);
2118: assert (rn->info);
2119: if (ospf_redistribute_check (ospf, rn->info, NULL))
2120: return rn->info;
2121: }
2122: }
2123:
2124: return NULL;
2125: }
2126:
2127: int
2128: ospf_default_originate_timer (struct thread *thread)
2129: {
2130: struct prefix_ipv4 p;
2131: struct in_addr nexthop;
2132: struct external_info *ei;
2133: struct ospf *ospf;
2134:
2135: ospf = THREAD_ARG (thread);
2136:
2137: p.family = AF_INET;
2138: p.prefix.s_addr = 0;
2139: p.prefixlen = 0;
2140:
2141: if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
2142: {
2143: /* If there is no default route via redistribute,
2144: then originate AS-external-LSA with nexthop 0 (self). */
2145: nexthop.s_addr = 0;
2146: ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2147: }
2148:
2149: if ((ei = ospf_default_external_info (ospf)))
2150: ospf_external_lsa_originate (ospf, ei);
2151:
2152: return 0;
2153: }
2154:
2155: /* Flush any NSSA LSAs for given prefix */
2156: void
2157: ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2158: {
2159: struct listnode *node, *nnode;
2160: struct ospf_lsa *lsa;
2161: struct ospf_area *area;
2162:
2163: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
2164: {
2165: if (area->external_routing == OSPF_AREA_NSSA)
2166: {
2167: if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2168: ospf->router_id)))
2169: {
2170: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2171: zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
2172: inet_ntoa (p->prefix), p->prefixlen);
2173: continue;
2174: }
2175: ospf_ls_retransmit_delete_nbr_area (area, lsa);
2176: if (!IS_LSA_MAXAGE (lsa))
2177: {
2178: ospf_refresher_unregister_lsa (ospf, lsa);
2179: ospf_lsa_flush_area (lsa, area);
2180: }
2181: }
2182: }
2183: }
2184:
2185: /* Flush an AS-external-LSA from LSDB and routing domain. */
2186: void
2187: ospf_external_lsa_flush (struct ospf *ospf,
2188: u_char type, struct prefix_ipv4 *p,
2189: unsigned int ifindex /*, struct in_addr nexthop */)
2190: {
2191: struct ospf_lsa *lsa;
2192:
2193: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2194: zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
2195: inet_ntoa (p->prefix), p->prefixlen);
2196:
2197: /* First lookup LSA from LSDB. */
2198: if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
2199: {
2200: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2201: zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
2202: inet_ntoa (p->prefix), p->prefixlen);
2203: return;
2204: }
2205:
2206: /* If LSA is selforiginated, not a translated LSA, and there is
2207: * NSSA area, flush Type-7 LSA's at first.
2208: */
2209: if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2210: && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
2211: ospf_nssa_lsa_flush (ospf, p);
2212:
2213: /* Sweep LSA from Link State Retransmit List. */
2214: ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
2215:
2216: /* There must be no self-originated LSA in rtrs_external. */
2217: #if 0
2218: /* Remove External route from Zebra. */
2219: ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2220: #endif
2221:
2222: if (!IS_LSA_MAXAGE (lsa))
2223: {
2224: /* Unregister LSA from Refresh queue. */
2225: ospf_refresher_unregister_lsa (ospf, lsa);
2226:
2227: /* Flush AS-external-LSA through AS. */
2228: ospf_lsa_flush_as (ospf, lsa);
2229: }
2230:
2231: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2232: zlog_debug ("ospf_external_lsa_flush(): stop");
2233: }
2234:
2235: void
2236: ospf_external_lsa_refresh_default (struct ospf *ospf)
2237: {
2238: struct prefix_ipv4 p;
2239: struct external_info *ei;
2240: struct ospf_lsa *lsa;
2241:
2242: p.family = AF_INET;
2243: p.prefixlen = 0;
2244: p.prefix.s_addr = 0;
2245:
2246: ei = ospf_default_external_info (ospf);
2247: lsa = ospf_external_info_find_lsa (ospf, &p);
2248:
2249: if (ei)
2250: {
2251: if (lsa)
2252: {
2253: if (IS_DEBUG_OSPF_EVENT)
2254: zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
2255: ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
2256: }
2257: else
2258: {
2259: if (IS_DEBUG_OSPF_EVENT)
2260: zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
2261: ospf_external_lsa_originate (ospf, ei);
2262: }
2263: }
2264: else
2265: {
2266: if (lsa)
2267: {
2268: if (IS_DEBUG_OSPF_EVENT)
2269: zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
2270: ospf_refresher_unregister_lsa (ospf, lsa);
2271: ospf_lsa_flush_as (ospf, lsa);
2272: }
2273: }
2274: }
2275:
2276: void
2277: ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
2278: {
2279: struct route_node *rn;
2280: struct external_info *ei;
2281:
2282: if (type != DEFAULT_ROUTE)
2283: if (EXTERNAL_INFO(type))
2284: /* Refresh each redistributed AS-external-LSAs. */
2285: for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2286: if ((ei = rn->info))
2287: if (!is_prefix_default (&ei->p))
2288: {
2289: struct ospf_lsa *lsa;
2290:
2291: if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2292: ospf_external_lsa_refresh (ospf, lsa, ei, force);
2293: else
2294: ospf_external_lsa_originate (ospf, ei);
2295: }
2296: }
2297:
2298: /* Refresh AS-external-LSA. */
2299: struct ospf_lsa *
2300: ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
2301: struct external_info *ei, int force)
2302: {
2303: struct ospf_lsa *new;
2304: int changed;
2305:
2306: /* Check the AS-external-LSA should be originated. */
2307: if (!ospf_redistribute_check (ospf, ei, &changed))
2308: {
2309: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2310: zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
2311: "redist check fail",
2312: lsa->data->type, inet_ntoa (lsa->data->id));
2313: ospf_external_lsa_flush (ospf, ei->type, &ei->p,
2314: ei->ifindex /*, ei->nexthop */);
2315: return NULL;
2316: }
2317:
2318: if (!changed && !force)
2319: {
2320: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2321: zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
2322: lsa->data->type, inet_ntoa (lsa->data->id));
2323: return NULL;
2324: }
2325:
2326: /* Delete LSA from neighbor retransmit-list. */
2327: ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
2328:
2329: /* Unregister AS-external-LSA from refresh-list. */
2330: ospf_refresher_unregister_lsa (ospf, lsa);
2331:
2332: new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
2333:
2334: if (new == NULL)
2335: {
2336: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2337: zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
2338: inet_ntoa (lsa->data->id));
2339: return NULL;
2340: }
2341:
2342: new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2343:
2344: ospf_lsa_install (ospf, NULL, new); /* As type-5. */
2345:
2346: /* Flood LSA through AS. */
2347: ospf_flood_through_as (ospf, NULL, new);
2348:
2349: /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
2350: if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
2351: ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
2352:
2353: /* Register self-originated LSA to refresh queue.
2354: * Translated LSAs should not be registered, but refreshed upon
2355: * refresh of the Type-7
2356: */
2357: if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2358: ospf_refresher_register_lsa (ospf, new);
2359:
2360: /* Debug logging. */
2361: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2362: {
2363: zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
2364: new->data->type, inet_ntoa (new->data->id));
2365: ospf_lsa_header_dump (new->data);
2366: }
2367:
2368: return new;
2369: }
2370:
2371:
2372: /* LSA installation functions. */
2373:
2374: /* Install router-LSA to an area. */
2375: static struct ospf_lsa *
2376: ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2377: int rt_recalc)
2378: {
2379: struct ospf_area *area = new->area;
2380:
2381: /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2382: The entire routing table must be recalculated, starting with
2383: the shortest path calculations for each area (not just the
2384: area whose link-state database has changed).
2385: */
2386:
2387: if (IS_LSA_SELF (new))
2388: {
2389:
2390: /* Only install LSA if it is originated/refreshed by us.
2391: * If LSA was received by flooding, the RECEIVED flag is set so do
2392: * not link the LSA */
2393: if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2394: return new; /* ignore stale LSA */
2395:
2396: /* Set self-originated router-LSA. */
2397: ospf_lsa_unlock (&area->router_lsa_self);
2398: area->router_lsa_self = ospf_lsa_lock (new);
2399:
2400: ospf_refresher_register_lsa (ospf, new);
2401: }
2402: if (rt_recalc)
2403: ospf_spf_calculate_schedule (ospf);
2404:
2405: return new;
2406: }
2407:
2408: #define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2409: if (!(T)) \
2410: (T) = thread_add_timer (master, (F), oi, (V))
2411:
2412: /* Install network-LSA to an area. */
2413: static struct ospf_lsa *
2414: ospf_network_lsa_install (struct ospf *ospf,
2415: struct ospf_interface *oi,
2416: struct ospf_lsa *new,
2417: int rt_recalc)
2418: {
2419:
2420: /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2421: The entire routing table must be recalculated, starting with
2422: the shortest path calculations for each area (not just the
2423: area whose link-state database has changed).
2424: */
2425: if (IS_LSA_SELF (new))
2426: {
2427: /* We supposed that when LSA is originated by us, we pass the int
2428: for which it was originated. If LSA was received by flooding,
2429: the RECEIVED flag is set, so we do not link the LSA to the int. */
2430: if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2431: return new; /* ignore stale LSA */
2432:
2433: ospf_lsa_unlock (&oi->network_lsa_self);
2434: oi->network_lsa_self = ospf_lsa_lock (new);
2435: ospf_refresher_register_lsa (ospf, new);
2436: }
2437: if (rt_recalc)
2438: ospf_spf_calculate_schedule (ospf);
2439:
2440: return new;
2441: }
2442:
2443: /* Install summary-LSA to an area. */
2444: static struct ospf_lsa *
2445: ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2446: int rt_recalc)
2447: {
2448: if (rt_recalc && !IS_LSA_SELF (new))
2449: {
2450: /* RFC 2328 Section 13.2 Summary-LSAs
2451: The best route to the destination described by the summary-
2452: LSA must be recalculated (see Section 16.5). If this
2453: destination is an AS boundary router, it may also be
2454: necessary to re-examine all the AS-external-LSAs.
2455: */
2456:
2457: #if 0
2458: /* This doesn't exist yet... */
2459: ospf_summary_incremental_update(new); */
2460: #else /* #if 0 */
2461: ospf_spf_calculate_schedule (ospf);
2462: #endif /* #if 0 */
2463:
2464: if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2465: zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
2466: }
2467:
2468: if (IS_LSA_SELF (new))
2469: ospf_refresher_register_lsa (ospf, new);
2470:
2471: return new;
2472: }
2473:
2474: /* Install ASBR-summary-LSA to an area. */
2475: static struct ospf_lsa *
2476: ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2477: int rt_recalc)
2478: {
2479: if (rt_recalc && !IS_LSA_SELF (new))
2480: {
2481: /* RFC 2328 Section 13.2 Summary-LSAs
2482: The best route to the destination described by the summary-
2483: LSA must be recalculated (see Section 16.5). If this
2484: destination is an AS boundary router, it may also be
2485: necessary to re-examine all the AS-external-LSAs.
2486: */
2487: #if 0
2488: /* These don't exist yet... */
2489: ospf_summary_incremental_update(new);
2490: /* Isn't this done by the above call?
2491: - RFC 2328 Section 16.5 implies it should be */
2492: /* ospf_ase_calculate_schedule(); */
2493: #else /* #if 0 */
2494: ospf_spf_calculate_schedule (ospf);
2495: #endif /* #if 0 */
2496: }
2497:
2498: /* register LSA to refresh-list. */
2499: if (IS_LSA_SELF (new))
2500: ospf_refresher_register_lsa (ospf, new);
2501:
2502: return new;
2503: }
2504:
2505: /* Install AS-external-LSA. */
2506: static struct ospf_lsa *
2507: ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2508: int rt_recalc)
2509: {
2510: ospf_ase_register_external_lsa (new, ospf);
2511: /* If LSA is not self-originated, calculate an external route. */
2512: if (rt_recalc)
2513: {
2514: /* RFC 2328 Section 13.2 AS-external-LSAs
2515: The best route to the destination described by the AS-
2516: external-LSA must be recalculated (see Section 16.6).
2517: */
2518:
2519: if (!IS_LSA_SELF (new))
2520: ospf_ase_incremental_update (ospf, new);
2521: }
2522:
2523: if (new->data->type == OSPF_AS_NSSA_LSA)
2524: {
2525: /* There is no point to register selforiginate Type-7 LSA for
2526: * refreshing. We rely on refreshing Type-5 LSA's
2527: */
2528: if (IS_LSA_SELF (new))
2529: return new;
2530: else
2531: {
2532: /* Try refresh type-5 translated LSA for this LSA, if one exists.
2533: * New translations will be taken care of by the abr_task.
2534: */
2535: ospf_translated_nssa_refresh (ospf, new, NULL);
2536: }
2537: }
2538:
2539: /* Register self-originated LSA to refresh queue.
2540: * Leave Translated LSAs alone if NSSA is enabled
2541: */
2542: if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
2543: ospf_refresher_register_lsa (ospf, new);
2544:
2545: return new;
2546: }
2547:
2548: void
2549: ospf_discard_from_db (struct ospf *ospf,
2550: struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
2551: {
2552: struct ospf_lsa *old;
2553:
2554: if (!lsdb)
2555: {
2556: zlog_warn ("%s: Called with NULL lsdb!", __func__);
2557: if (!lsa)
2558: zlog_warn ("%s: and NULL LSA!", __func__);
2559: else
2560: zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2561: lsa->data->type, inet_ntoa (lsa->data->id));
2562: return;
2563: }
2564:
2565: old = ospf_lsdb_lookup (lsdb, lsa);
2566:
2567: if (!old)
2568: return;
2569:
2570: if (old->refresh_list >= 0)
2571: ospf_refresher_unregister_lsa (ospf, old);
2572:
2573: switch (old->data->type)
2574: {
2575: case OSPF_AS_EXTERNAL_LSA:
2576: ospf_ase_unregister_external_lsa (old, ospf);
2577: ospf_ls_retransmit_delete_nbr_as (ospf, old);
2578: break;
2579: #ifdef HAVE_OPAQUE_LSA
2580: case OSPF_OPAQUE_AS_LSA:
2581: ospf_ls_retransmit_delete_nbr_as (ospf, old);
2582: break;
2583: #endif /* HAVE_OPAQUE_LSA */
2584: case OSPF_AS_NSSA_LSA:
2585: ospf_ls_retransmit_delete_nbr_area (old->area, old);
2586: ospf_ase_unregister_external_lsa (old, ospf);
2587: break;
2588: default:
2589: ospf_ls_retransmit_delete_nbr_area (old->area, old);
2590: break;
2591: }
2592:
2593: ospf_lsa_maxage_delete (ospf, old);
2594: ospf_lsa_discard (old);
2595: }
2596:
2597: struct ospf_lsa *
2598: ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2599: struct ospf_lsa *lsa)
2600: {
2601: struct ospf_lsa *new = NULL;
2602: struct ospf_lsa *old = NULL;
2603: struct ospf_lsdb *lsdb = NULL;
2604: int rt_recalc;
2605:
2606: /* Set LSDB. */
2607: switch (lsa->data->type)
2608: {
2609: /* kevinm */
2610: case OSPF_AS_NSSA_LSA:
2611: if (lsa->area)
2612: lsdb = lsa->area->lsdb;
2613: else
2614: lsdb = ospf->lsdb;
2615: break;
2616: case OSPF_AS_EXTERNAL_LSA:
2617: #ifdef HAVE_OPAQUE_LSA
2618: case OSPF_OPAQUE_AS_LSA:
2619: #endif /* HAVE_OPAQUE_LSA */
2620: lsdb = ospf->lsdb;
2621: break;
2622: default:
2623: lsdb = lsa->area->lsdb;
2624: break;
2625: }
2626:
2627: assert (lsdb);
2628:
2629: /* RFC 2328 13.2. Installing LSAs in the database
2630:
2631: Installing a new LSA in the database, either as the result of
2632: flooding or a newly self-originated LSA, may cause the OSPF
2633: routing table structure to be recalculated. The contents of the
2634: new LSA should be compared to the old instance, if present. If
2635: there is no difference, there is no need to recalculate the
2636: routing table. When comparing an LSA to its previous instance,
2637: the following are all considered to be differences in contents:
2638:
2639: o The LSA's Options field has changed.
2640:
2641: o One of the LSA instances has LS age set to MaxAge, and
2642: the other does not.
2643:
2644: o The length field in the LSA header has changed.
2645:
2646: o The body of the LSA (i.e., anything outside the 20-byte
2647: LSA header) has changed. Note that this excludes changes
2648: in LS Sequence Number and LS Checksum.
2649:
2650: */
2651: /* Look up old LSA and determine if any SPF calculation or incremental
2652: update is needed */
2653: old = ospf_lsdb_lookup (lsdb, lsa);
2654:
2655: /* Do comparision and record if recalc needed. */
2656: rt_recalc = 0;
2657: if ( old == NULL || ospf_lsa_different(old, lsa))
2658: rt_recalc = 1;
2659:
2660: /*
2661: Sequence number check (Section 14.1 of rfc 2328)
2662: "Premature aging is used when it is time for a self-originated
2663: LSA's sequence number field to wrap. At this point, the current
2664: LSA instance (having LS sequence number MaxSequenceNumber) must
2665: be prematurely aged and flushed from the routing domain before a
2666: new instance with sequence number equal to InitialSequenceNumber
2667: can be originated. "
2668: */
2669:
2670: if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
2671: {
2672: if (ospf_lsa_is_self_originated(ospf, lsa))
2673: {
2674: lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2675:
2676: if (!IS_LSA_MAXAGE(lsa))
2677: lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2678: lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2679:
2680: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2681: {
2682: zlog_debug ("ospf_lsa_install() Premature Aging "
2683: "lsa 0x%p, seqnum 0x%x",
2684: lsa, ntohl(lsa->data->ls_seqnum));
2685: ospf_lsa_header_dump (lsa->data);
2686: }
2687: }
2688: else
2689: {
2690: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2691: {
2692: zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
2693: "that was not self originated. Ignoring\n");
2694: ospf_lsa_header_dump (lsa->data);
2695: }
2696: return old;
2697: }
2698: }
2699:
2700: /* discard old LSA from LSDB */
2701: if (old != NULL)
2702: ospf_discard_from_db (ospf, lsdb, lsa);
2703:
2704: /* Calculate Checksum if self-originated?. */
2705: if (IS_LSA_SELF (lsa))
2706: ospf_lsa_checksum (lsa->data);
2707:
2708: /* Insert LSA to LSDB. */
2709: ospf_lsdb_add (lsdb, lsa);
2710: lsa->lsdb = lsdb;
2711:
2712: /* Do LSA specific installation process. */
2713: switch (lsa->data->type)
2714: {
2715: case OSPF_ROUTER_LSA:
2716: new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
2717: break;
2718: case OSPF_NETWORK_LSA:
2719: assert (oi);
2720: new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
2721: break;
2722: case OSPF_SUMMARY_LSA:
2723: new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
2724: break;
2725: case OSPF_ASBR_SUMMARY_LSA:
2726: new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
2727: break;
2728: case OSPF_AS_EXTERNAL_LSA:
2729: new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
2730: break;
2731: #ifdef HAVE_OPAQUE_LSA
2732: case OSPF_OPAQUE_LINK_LSA:
2733: if (IS_LSA_SELF (lsa))
2734: lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
2735: else
1.1.1.3 ! misho 2736: {
! 2737: /* Incoming "oi" for this LSA has set at LSUpd reception. */
! 2738: }
1.1 misho 2739: /* Fallthrough */
2740: case OSPF_OPAQUE_AREA_LSA:
2741: case OSPF_OPAQUE_AS_LSA:
2742: new = ospf_opaque_lsa_install (lsa, rt_recalc);
2743: break;
2744: #endif /* HAVE_OPAQUE_LSA */
2745: case OSPF_AS_NSSA_LSA:
2746: new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
2747: default: /* type-6,8,9....nothing special */
2748: break;
2749: }
2750:
2751: if (new == NULL)
2752: return new; /* Installation failed, cannot proceed further -- endo. */
2753:
2754: /* Debug logs. */
2755: if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2756: {
2757: char area_str[INET_ADDRSTRLEN];
2758:
2759: switch (lsa->data->type)
2760: {
2761: case OSPF_AS_EXTERNAL_LSA:
2762: #ifdef HAVE_OPAQUE_LSA
2763: case OSPF_OPAQUE_AS_LSA:
2764: #endif /* HAVE_OPAQUE_LSA */
2765: case OSPF_AS_NSSA_LSA:
2766: zlog_debug ("LSA[%s]: Install %s",
2767: dump_lsa_key (new),
2768: LOOKUP (ospf_lsa_type_msg, new->data->type));
2769: break;
2770: default:
2771: strcpy (area_str, inet_ntoa (new->area->area_id));
2772: zlog_debug ("LSA[%s]: Install %s to Area %s",
2773: dump_lsa_key (new),
2774: LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2775: break;
2776: }
2777: }
2778:
2779: /*
2780: If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2781: (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2782: */
1.1.1.3 ! misho 2783: if (IS_LSA_MAXAGE (new))
1.1 misho 2784: {
2785: if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2786: zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
2787: new->data->type,
2788: inet_ntoa (new->data->id),
2789: lsa);
1.1.1.3 ! misho 2790: ospf_lsa_maxage (ospf, lsa);
1.1 misho 2791: }
2792:
2793: return new;
2794: }
2795:
2796:
2797: static int
2798: ospf_check_nbr_status (struct ospf *ospf)
2799: {
2800: struct listnode *node, *nnode;
2801: struct ospf_interface *oi;
2802:
2803: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
2804: {
2805: struct route_node *rn;
2806: struct ospf_neighbor *nbr;
2807:
2808: if (ospf_if_is_enable (oi))
2809: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2810: if ((nbr = rn->info) != NULL)
2811: if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2812: {
2813: route_unlock_node (rn);
2814: return 0;
2815: }
2816: }
2817:
2818: return 1;
2819: }
2820:
2821:
2822:
2823: static int
2824: ospf_maxage_lsa_remover (struct thread *thread)
2825: {
2826: struct ospf *ospf = THREAD_ARG (thread);
2827: struct ospf_lsa *lsa;
1.1.1.3 ! misho 2828: struct route_node *rn;
1.1 misho 2829: int reschedule = 0;
2830:
2831: ospf->t_maxage = NULL;
2832:
2833: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2834: zlog_debug ("LSA[MaxAge]: remover Start");
2835:
2836: reschedule = !ospf_check_nbr_status (ospf);
2837:
2838: if (!reschedule)
1.1.1.3 ! misho 2839: for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
1.1 misho 2840: {
1.1.1.3 ! misho 2841: if ((lsa = rn->info) == NULL)
! 2842: {
! 2843: continue;
! 2844: }
! 2845:
1.1 misho 2846: if (lsa->retransmit_counter > 0)
2847: {
2848: reschedule = 1;
2849: continue;
2850: }
2851:
2852: /* TODO: maybe convert this function to a work-queue */
2853: if (thread_should_yield (thread))
2854: OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2855:
2856: /* Remove LSA from the LSDB */
1.1.1.2 misho 2857: if (IS_LSA_SELF (lsa))
1.1 misho 2858: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1.1.1.2 misho 2859: zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
1.1 misho 2860: lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
2861:
2862: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2863: zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2864: lsa->data->type, inet_ntoa (lsa->data->id));
2865:
2866: if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
2867: {
2868: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2869: zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2870: ospf_lsa_refresh (ospf, lsa);
2871: }
2872:
2873: /* Remove from lsdb. */
2874: if (lsa->lsdb)
2875: {
2876: ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2877: ospf_lsdb_delete (lsa->lsdb, lsa);
2878: }
2879: else
2880: zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2881: lsa->data->type, inet_ntoa (lsa->data->id));
2882: }
2883:
2884: /* A MaxAge LSA must be removed immediately from the router's link
2885: state database as soon as both a) it is no longer contained on any
2886: neighbor Link state retransmission lists and b) none of the router's
2887: neighbors are in states Exchange or Loading. */
2888: if (reschedule)
2889: OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2890: ospf->maxage_delay);
2891:
2892: return 0;
2893: }
2894:
2895: void
2896: ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
2897: {
1.1.1.3 ! misho 2898: struct route_node *rn;
! 2899: struct prefix_ls lsa_prefix;
1.1 misho 2900:
1.1.1.3 ! misho 2901: ls_prefix_set (&lsa_prefix, lsa);
! 2902:
! 2903: if ((rn = route_node_lookup(ospf->maxage_lsa,
! 2904: (struct prefix *)&lsa_prefix)))
1.1 misho 2905: {
1.1.1.3 ! misho 2906: if (rn->info == lsa)
! 2907: {
! 2908: UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
! 2909: ospf_lsa_unlock (&lsa); /* maxage_lsa */
! 2910: rn->info = NULL;
! 2911: route_unlock_node (rn); /* route_node_lookup */
! 2912: }
! 2913: route_unlock_node (rn); /* route_node_lookup */
1.1 misho 2914: }
2915: }
2916:
2917: /* Add LSA onto the MaxAge list, and schedule for removal.
2918: * This does *not* lead to the LSA being flooded, that must be taken
2919: * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2920: * function).
2921: */
2922: void
2923: ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
2924: {
1.1.1.3 ! misho 2925: struct prefix_ls lsa_prefix;
! 2926: struct route_node *rn;
! 2927:
1.1 misho 2928: /* When we saw a MaxAge LSA flooded to us, we put it on the list
2929: and schedule the MaxAge LSA remover. */
2930: if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
2931: {
2932: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2933: zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2934: lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2935: return;
2936: }
2937:
1.1.1.3 ! misho 2938: ls_prefix_set (&lsa_prefix, lsa);
! 2939: if ((rn = route_node_get (ospf->maxage_lsa,
! 2940: (struct prefix *)&lsa_prefix)) != NULL)
! 2941: {
! 2942: if (rn->info != NULL)
! 2943: {
! 2944: route_unlock_node (rn);
! 2945: }
! 2946: else
! 2947: {
! 2948: rn->info = ospf_lsa_lock(lsa);
! 2949: SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
! 2950: }
! 2951: }
! 2952: else
! 2953: {
! 2954: zlog_err("Unable to allocate memory for maxage lsa\n");
! 2955: assert(0);
! 2956: }
1.1 misho 2957:
2958: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2959: zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
2960:
2961: OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2962: ospf->maxage_delay);
2963: }
2964:
2965: static int
2966: ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
2967: {
2968: /* Stay away from any Local Translated Type-7 LSAs */
2969: if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2970: return 0;
2971:
2972: if (IS_LSA_MAXAGE (lsa))
2973: /* Self-originated LSAs should NOT time-out instead,
2974: they're flushed and submitted to the max_age list explicitly. */
2975: if (!ospf_lsa_is_self_originated (ospf, lsa))
2976: {
2977: if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2978: zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
2979:
2980: switch (lsa->data->type)
2981: {
2982: #ifdef HAVE_OPAQUE_LSA
2983: case OSPF_OPAQUE_LINK_LSA:
2984: case OSPF_OPAQUE_AREA_LSA:
2985: case OSPF_OPAQUE_AS_LSA:
2986: /*
2987: * As a general rule, whenever network topology has changed
2988: * (due to an LSA removal in this case), routing recalculation
2989: * should be triggered. However, this is not true for opaque
2990: * LSAs. Even if an opaque LSA instance is going to be removed
2991: * from the routing domain, it does not mean a change in network
2992: * topology, and thus, routing recalculation is not needed here.
2993: */
2994: break;
2995: #endif /* HAVE_OPAQUE_LSA */
2996: case OSPF_AS_EXTERNAL_LSA:
2997: case OSPF_AS_NSSA_LSA:
2998: ospf_ase_incremental_update (ospf, lsa);
2999: break;
3000: default:
3001: ospf_spf_calculate_schedule (ospf);
3002: break;
3003: }
3004: ospf_lsa_maxage (ospf, lsa);
3005: }
3006:
3007: if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3008: if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3009: printf ("Eek! Shouldn't happen!\n");
3010:
3011: return 0;
3012: }
3013:
3014: /* Periodical check of MaxAge LSA. */
3015: int
3016: ospf_lsa_maxage_walker (struct thread *thread)
3017: {
3018: struct ospf *ospf = THREAD_ARG (thread);
3019: struct route_node *rn;
3020: struct ospf_lsa *lsa;
3021: struct ospf_area *area;
3022: struct listnode *node, *nnode;
3023:
3024: ospf->t_maxage_walker = NULL;
3025:
3026: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
3027: {
3028: LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3029: ospf_lsa_maxage_walker_remover (ospf, lsa);
3030: LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3031: ospf_lsa_maxage_walker_remover (ospf, lsa);
3032: LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3033: ospf_lsa_maxage_walker_remover (ospf, lsa);
3034: LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3035: ospf_lsa_maxage_walker_remover (ospf, lsa);
3036: #ifdef HAVE_OPAQUE_LSA
3037: LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3038: ospf_lsa_maxage_walker_remover (ospf, lsa);
3039: LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3040: ospf_lsa_maxage_walker_remover (ospf, lsa);
3041: #endif /* HAVE_OPAQUE_LSA */
3042: LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3043: ospf_lsa_maxage_walker_remover (ospf, lsa);
3044: }
3045:
3046: /* for AS-external-LSAs. */
3047: if (ospf->lsdb)
3048: {
3049: LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3050: ospf_lsa_maxage_walker_remover (ospf, lsa);
3051: #ifdef HAVE_OPAQUE_LSA
3052: LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3053: ospf_lsa_maxage_walker_remover (ospf, lsa);
3054: #endif /* HAVE_OPAQUE_LSA */
3055: }
3056:
3057: OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3058: OSPF_LSA_MAXAGE_CHECK_INTERVAL);
3059: return 0;
3060: }
3061:
3062: struct ospf_lsa *
3063: ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3064: struct prefix_ipv4 *p, struct in_addr router_id)
3065: {
3066: struct ospf_lsa *lsa;
3067: struct in_addr mask, id;
3068: struct lsa_header_mask
3069: {
3070: struct lsa_header header;
3071: struct in_addr mask;
3072: } *hmask;
3073:
3074: lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3075: if (lsa == NULL)
3076: return NULL;
3077:
3078: masklen2ip (p->prefixlen, &mask);
3079:
3080: hmask = (struct lsa_header_mask *) lsa->data;
3081:
3082: if (mask.s_addr != hmask->mask.s_addr)
3083: {
3084: id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3085: lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3086: if (!lsa)
3087: return NULL;
3088: }
3089:
3090: return lsa;
3091: }
3092:
3093: struct ospf_lsa *
3094: ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3095: struct in_addr id, struct in_addr adv_router)
3096: {
3097: struct ospf *ospf = ospf_lookup();
3098: assert(ospf);
3099:
3100: switch (type)
3101: {
3102: case OSPF_ROUTER_LSA:
3103: case OSPF_NETWORK_LSA:
3104: case OSPF_SUMMARY_LSA:
3105: case OSPF_ASBR_SUMMARY_LSA:
3106: case OSPF_AS_NSSA_LSA:
3107: #ifdef HAVE_OPAQUE_LSA
3108: case OSPF_OPAQUE_LINK_LSA:
3109: case OSPF_OPAQUE_AREA_LSA:
3110: #endif /* HAVE_OPAQUE_LSA */
3111: return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
3112: case OSPF_AS_EXTERNAL_LSA:
3113: #ifdef HAVE_OPAQUE_LSA
3114: case OSPF_OPAQUE_AS_LSA:
3115: #endif /* HAVE_OPAQUE_LSA */
3116: return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
3117: default:
3118: break;
3119: }
3120:
3121: return NULL;
3122: }
3123:
3124: struct ospf_lsa *
3125: ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3126: struct in_addr id)
3127: {
3128: struct ospf_lsa *lsa;
3129: struct route_node *rn;
3130:
3131: switch (type)
3132: {
3133: case OSPF_ROUTER_LSA:
3134: return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3135: case OSPF_NETWORK_LSA:
3136: for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3137: if ((lsa = rn->info))
3138: if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3139: {
3140: route_unlock_node (rn);
3141: return lsa;
3142: }
3143: break;
3144: case OSPF_SUMMARY_LSA:
3145: case OSPF_ASBR_SUMMARY_LSA:
3146: /* Currently not used. */
3147: assert (1);
3148: return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3149: case OSPF_AS_EXTERNAL_LSA:
3150: case OSPF_AS_NSSA_LSA:
3151: #ifdef HAVE_OPAQUE_LSA
3152: case OSPF_OPAQUE_LINK_LSA:
3153: case OSPF_OPAQUE_AREA_LSA:
3154: case OSPF_OPAQUE_AS_LSA:
3155: /* Currently not used. */
3156: break;
3157: #endif /* HAVE_OPAQUE_LSA */
3158: default:
3159: break;
3160: }
3161:
3162: return NULL;
3163: }
3164:
3165: struct ospf_lsa *
3166: ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3167: {
3168: struct ospf_lsa *match;
3169:
3170: #ifdef HAVE_OPAQUE_LSA
3171: /*
3172: * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3173: * is redefined to have two subfields; opaque-type and opaque-id.
3174: * However, it is harmless to treat the two sub fields together, as if
3175: * they two were forming a unique LSA-ID.
3176: */
3177: #endif /* HAVE_OPAQUE_LSA */
3178:
3179: match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3180:
3181: if (match == NULL)
3182: if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3183: zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
3184: lsah->type, inet_ntoa (lsah->id));
3185:
3186: return match;
3187: }
3188:
3189: /* return +n, l1 is more recent.
3190: return -n, l2 is more recent.
3191: return 0, l1 and l2 is identical. */
3192: int
3193: ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3194: {
3195: int r;
3196: int x, y;
3197:
3198: if (l1 == NULL && l2 == NULL)
3199: return 0;
3200: if (l1 == NULL)
3201: return -1;
3202: if (l2 == NULL)
3203: return 1;
3204:
3205: /* compare LS sequence number. */
3206: x = (int) ntohl (l1->data->ls_seqnum);
3207: y = (int) ntohl (l2->data->ls_seqnum);
3208: if (x > y)
3209: return 1;
3210: if (x < y)
3211: return -1;
3212:
3213: /* compare LS checksum. */
3214: r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3215: if (r)
3216: return r;
3217:
3218: /* compare LS age. */
3219: if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3220: return 1;
3221: else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3222: return -1;
3223:
3224: /* compare LS age with MaxAgeDiff. */
3225: if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3226: return -1;
3227: else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3228: return 1;
3229:
3230: /* LSAs are identical. */
3231: return 0;
3232: }
3233:
3234: /* If two LSAs are different, return 1, otherwise return 0. */
3235: int
3236: ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3237: {
3238: char *p1, *p2;
3239: assert (l1);
3240: assert (l2);
3241: assert (l1->data);
3242: assert (l2->data);
3243:
3244: if (l1->data->options != l2->data->options)
3245: return 1;
3246:
3247: if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3248: return 1;
3249:
3250: if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3251: return 1;
3252:
3253: if (l1->data->length != l2->data->length)
3254: return 1;
3255:
3256: if (l1->data->length == 0)
3257: return 1;
3258:
3259: if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3260: return 1; /* May be a stale LSA in the LSBD */
3261:
3262: assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
3263:
3264: p1 = (char *) l1->data;
3265: p2 = (char *) l2->data;
3266:
3267: if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3268: ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3269: return 1;
3270:
3271: return 0;
3272: }
3273:
3274: #ifdef ORIGINAL_CODING
3275: void
3276: ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3277: struct ospf_lsa *self,
3278: struct ospf_lsa *new)
3279: {
3280: u_int32_t seqnum;
3281:
3282: /* Adjust LS Sequence Number. */
3283: seqnum = ntohl (new->data->ls_seqnum) + 1;
3284: self->data->ls_seqnum = htonl (seqnum);
3285:
3286: /* Recalculate LSA checksum. */
3287: ospf_lsa_checksum (self->data);
3288:
3289: /* Reflooding LSA. */
3290: /* RFC2328 Section 13.3
3291: On non-broadcast networks, separate Link State Update
3292: packets must be sent, as unicasts, to each adjacent neighbor
3293: (i.e., those in state Exchange or greater). The destination
3294: IP addresses for these packets are the neighbors' IP
3295: addresses. */
3296: if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3297: {
3298: struct route_node *rn;
3299: struct ospf_neighbor *onbr;
3300:
3301: for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3302: if ((onbr = rn->info) != NULL)
3303: if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3304: ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3305: }
3306: else
3307: ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3308:
3309: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3310: zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
3311: self->data->type, inet_ntoa (self->data->id));
3312: }
3313: #else /* ORIGINAL_CODING */
3314: static int
3315: ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
3316: {
3317: if (lsa == NULL || !IS_LSA_SELF (lsa))
3318: return 0;
3319:
3320: if (IS_DEBUG_OSPF_EVENT)
3321: zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3322:
3323: /* Force given lsa's age to MaxAge. */
3324: lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3325:
3326: switch (lsa->data->type)
3327: {
3328: #ifdef HAVE_OPAQUE_LSA
3329: /* Opaque wants to be notified of flushes */
3330: case OSPF_OPAQUE_LINK_LSA:
3331: case OSPF_OPAQUE_AREA_LSA:
3332: case OSPF_OPAQUE_AS_LSA:
3333: ospf_opaque_lsa_refresh (lsa);
3334: break;
3335: #endif /* HAVE_OPAQUE_LSA */
3336: default:
3337: ospf_refresher_unregister_lsa (ospf, lsa);
3338: ospf_lsa_flush (ospf, lsa);
3339: break;
3340: }
3341:
3342: return 0;
3343: }
3344:
3345: void
3346: ospf_flush_self_originated_lsas_now (struct ospf *ospf)
3347: {
3348: struct listnode *node, *nnode;
3349: struct listnode *node2, *nnode2;
3350: struct ospf_area *area;
3351: struct ospf_interface *oi;
3352: struct ospf_lsa *lsa;
3353: struct route_node *rn;
3354: int need_to_flush_ase = 0;
3355:
3356: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
3357: {
3358: if ((lsa = area->router_lsa_self) != NULL)
3359: {
3360: if (IS_DEBUG_OSPF_EVENT)
3361: zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3362: lsa->data->type, inet_ntoa (lsa->data->id));
3363:
3364: ospf_refresher_unregister_lsa (ospf, lsa);
3365: ospf_lsa_flush_area (lsa, area);
3366: ospf_lsa_unlock (&area->router_lsa_self);
3367: area->router_lsa_self = NULL;
3368: }
3369:
3370: for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
3371: {
3372: if ((lsa = oi->network_lsa_self) != NULL
3373: && oi->state == ISM_DR
3374: && oi->full_nbrs > 0)
3375: {
3376: if (IS_DEBUG_OSPF_EVENT)
3377: zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3378: lsa->data->type, inet_ntoa (lsa->data->id));
3379:
3380: ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
3381: ospf_lsa_flush_area (oi->network_lsa_self, area);
3382: ospf_lsa_unlock (&oi->network_lsa_self);
3383: oi->network_lsa_self = NULL;
3384: }
3385:
3386: if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3387: && area->external_routing == OSPF_AREA_DEFAULT)
3388: need_to_flush_ase = 1;
3389: }
3390:
3391: LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3392: ospf_lsa_flush_schedule (ospf, lsa);
3393: LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3394: ospf_lsa_flush_schedule (ospf, lsa);
3395: #ifdef HAVE_OPAQUE_LSA
3396: LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3397: ospf_lsa_flush_schedule (ospf, lsa);
3398: LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3399: ospf_lsa_flush_schedule (ospf, lsa);
3400: #endif /* HAVE_OPAQUE_LSA */
3401: }
3402:
3403: if (need_to_flush_ase)
3404: {
3405: LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3406: ospf_lsa_flush_schedule (ospf, lsa);
3407: #ifdef HAVE_OPAQUE_LSA
3408: LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3409: ospf_lsa_flush_schedule (ospf, lsa);
3410: #endif /* HAVE_OPAQUE_LSA */
3411: }
3412:
3413: /*
3414: * Make sure that the MaxAge LSA remover is executed immediately,
3415: * without conflicting to other threads.
3416: */
3417: if (ospf->t_maxage != NULL)
3418: {
3419: OSPF_TIMER_OFF (ospf->t_maxage);
3420: thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
3421: }
3422:
3423: return;
3424: }
3425: #endif /* ORIGINAL_CODING */
3426:
3427: /* If there is self-originated LSA, then return 1, otherwise return 0. */
3428: /* An interface-independent version of ospf_lsa_is_self_originated */
3429: int
3430: ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
3431: {
3432: struct listnode *node;
3433: struct ospf_interface *oi;
3434:
3435: /* This LSA is already checked. */
3436: if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
1.1.1.2 misho 3437: return IS_LSA_SELF (lsa);
1.1 misho 3438:
3439: /* Make sure LSA is self-checked. */
3440: SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3441:
3442: /* AdvRouter and Router ID is the same. */
3443: if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
3444: SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3445:
3446: /* LSA is router-LSA. */
3447: else if (lsa->data->type == OSPF_ROUTER_LSA &&
3448: IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
3449: SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3450:
3451: /* LSA is network-LSA. Compare Link ID with all interfaces. */
3452: else if (lsa->data->type == OSPF_NETWORK_LSA)
3453: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
3454: {
3455: /* Ignore virtual link. */
3456: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3457: if (oi->address->family == AF_INET)
3458: if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3459: {
3460: /* to make it easier later */
3461: SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1.1.1.2 misho 3462: return IS_LSA_SELF (lsa);
1.1 misho 3463: }
3464: }
3465:
1.1.1.2 misho 3466: return IS_LSA_SELF (lsa);
1.1 misho 3467: }
3468:
3469: /* Get unique Link State ID. */
3470: struct in_addr
3471: ospf_lsa_unique_id (struct ospf *ospf,
3472: struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
3473: {
3474: struct ospf_lsa *lsa;
3475: struct in_addr mask, id;
3476:
3477: id = p->prefix;
3478:
3479: /* Check existence of LSA instance. */
3480: lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
3481: if (lsa)
3482: {
3483: struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3484: if (ip_masklen (al->mask) == p->prefixlen)
3485: {
3486: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3487: zlog_debug ("ospf_lsa_unique_id(): "
3488: "Can't get Link State ID for %s/%d",
3489: inet_ntoa (p->prefix), p->prefixlen);
3490: /* id.s_addr = 0; */
3491: id.s_addr = 0xffffffff;
3492: return id;
3493: }
3494: /* Masklen differs, then apply wildcard mask to Link State ID. */
3495: else
3496: {
3497: masklen2ip (p->prefixlen, &mask);
3498:
3499: id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3500: lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3501: id, ospf->router_id);
3502: if (lsa)
3503: {
3504: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3505: zlog_debug ("ospf_lsa_unique_id(): "
3506: "Can't get Link State ID for %s/%d",
3507: inet_ntoa (p->prefix), p->prefixlen);
3508: /* id.s_addr = 0; */
3509: id.s_addr = 0xffffffff;
3510: return id;
3511: }
3512: }
3513: }
3514:
3515: return id;
3516: }
3517:
3518:
3519: #define LSA_ACTION_FLOOD_AREA 1
3520: #define LSA_ACTION_FLUSH_AREA 2
3521:
3522: struct lsa_action
3523: {
3524: u_char action;
3525: struct ospf_area *area;
3526: struct ospf_lsa *lsa;
3527: };
3528:
3529: static int
3530: ospf_lsa_action (struct thread *t)
3531: {
3532: struct lsa_action *data;
3533:
3534: data = THREAD_ARG (t);
3535:
3536: if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3537: zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
3538: data->action);
3539:
3540: switch (data->action)
3541: {
3542: case LSA_ACTION_FLOOD_AREA:
3543: ospf_flood_through_area (data->area, NULL, data->lsa);
3544: break;
3545: case LSA_ACTION_FLUSH_AREA:
3546: ospf_lsa_flush_area (data->lsa, data->area);
3547: break;
3548: }
3549:
3550: ospf_lsa_unlock (&data->lsa); /* Message */
3551: XFREE (MTYPE_OSPF_MESSAGE, data);
3552: return 0;
3553: }
3554:
3555: void
3556: ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3557: {
3558: struct lsa_action *data;
3559:
3560: data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3561: data->action = LSA_ACTION_FLOOD_AREA;
3562: data->area = area;
3563: data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
3564:
3565: thread_add_event (master, ospf_lsa_action, data, 0);
3566: }
3567:
3568: void
3569: ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3570: {
3571: struct lsa_action *data;
3572:
3573: data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3574: data->action = LSA_ACTION_FLUSH_AREA;
3575: data->area = area;
3576: data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
3577:
3578: thread_add_event (master, ospf_lsa_action, data, 0);
3579: }
3580:
3581:
3582: /* LSA Refreshment functions. */
3583: struct ospf_lsa *
3584: ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
3585: {
3586: struct external_info *ei;
3587: struct ospf_lsa *new = NULL;
3588: assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
1.1.1.2 misho 3589: assert (IS_LSA_SELF (lsa));
1.1 misho 3590: assert (lsa->lock > 0);
3591:
3592: switch (lsa->data->type)
3593: {
3594: /* Router and Network LSAs are processed differently. */
3595: case OSPF_ROUTER_LSA:
3596: new = ospf_router_lsa_refresh (lsa);
3597: break;
3598: case OSPF_NETWORK_LSA:
3599: new = ospf_network_lsa_refresh (lsa);
3600: break;
3601: case OSPF_SUMMARY_LSA:
3602: new = ospf_summary_lsa_refresh (ospf, lsa);
3603: break;
3604: case OSPF_ASBR_SUMMARY_LSA:
3605: new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
3606: break;
3607: case OSPF_AS_EXTERNAL_LSA:
3608: /* Translated from NSSA Type-5s are refreshed when
3609: * from refresh of Type-7 - do not refresh these directly.
3610: */
3611: if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3612: break;
3613: ei = ospf_external_info_check (lsa);
3614: if (ei)
3615: new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
3616: else
3617: ospf_lsa_flush_as (ospf, lsa);
3618: break;
3619: #ifdef HAVE_OPAQUE_LSA
3620: case OSPF_OPAQUE_LINK_LSA:
3621: case OSPF_OPAQUE_AREA_LSA:
3622: case OSPF_OPAQUE_AS_LSA:
3623: new = ospf_opaque_lsa_refresh (lsa);
3624: break;
3625: #endif /* HAVE_OPAQUE_LSA */
3626: default:
3627: break;
3628: }
3629: return new;
3630: }
3631:
3632: void
3633: ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
3634: {
3635: u_int16_t index, current_index;
3636:
3637: assert (lsa->lock > 0);
1.1.1.2 misho 3638: assert (IS_LSA_SELF (lsa));
1.1 misho 3639:
3640: if (lsa->refresh_list < 0)
3641: {
3642: int delay;
3643:
3644: if (LS_AGE (lsa) == 0 &&
3645: ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3646: /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3647: delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3648: else
3649: /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3650: delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3651: + (random () % (2*OSPF_LS_REFRESH_JITTER));
3652:
3653: if (delay < 0)
3654: delay = 0;
3655:
3656: current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3657: - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
3658:
3659: index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3660: % (OSPF_LSA_REFRESHER_SLOTS);
3661:
3662: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3663: zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
3664: inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
3665: if (!ospf->lsa_refresh_queue.qs[index])
3666: ospf->lsa_refresh_queue.qs[index] = list_new ();
3667: listnode_add (ospf->lsa_refresh_queue.qs[index],
3668: ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
3669: lsa->refresh_list = index;
3670: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3671: zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
3672: "setting refresh_list on lsa %p (slod %d)",
3673: inet_ntoa (lsa->data->id), lsa, index);
3674: }
3675: }
3676:
3677: void
3678: ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
3679: {
3680: assert (lsa->lock > 0);
1.1.1.2 misho 3681: assert (IS_LSA_SELF (lsa));
1.1 misho 3682: if (lsa->refresh_list >= 0)
3683: {
3684: struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
3685: listnode_delete (refresh_list, lsa);
3686: if (!listcount (refresh_list))
3687: {
3688: list_free (refresh_list);
3689: ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
3690: }
3691: ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
3692: lsa->refresh_list = -1;
3693: }
3694: }
3695:
3696: int
3697: ospf_lsa_refresh_walker (struct thread *t)
3698: {
3699: struct list *refresh_list;
3700: struct listnode *node, *nnode;
3701: struct ospf *ospf = THREAD_ARG (t);
3702: struct ospf_lsa *lsa;
3703: int i;
3704: struct list *lsa_to_refresh = list_new ();
3705:
3706: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3707: zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3708:
3709:
3710: i = ospf->lsa_refresh_queue.index;
3711:
3712: /* Note: if clock has jumped backwards, then time change could be negative,
3713: so we are careful to cast the expression to unsigned before taking
3714: modulus. */
3715: ospf->lsa_refresh_queue.index =
3716: ((unsigned long)(ospf->lsa_refresh_queue.index +
3717: (quagga_time (NULL) - ospf->lsa_refresher_started)
3718: / OSPF_LSA_REFRESHER_GRANULARITY))
3719: % OSPF_LSA_REFRESHER_SLOTS;
3720:
3721: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3722: zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
3723: ospf->lsa_refresh_queue.index);
3724:
3725: for (;i != ospf->lsa_refresh_queue.index;
3726: i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3727: {
3728: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3729: zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
3730: "refresh index %d", i);
3731:
3732: refresh_list = ospf->lsa_refresh_queue.qs [i];
3733:
3734: assert (i >= 0);
3735:
3736: ospf->lsa_refresh_queue.qs [i] = NULL;
3737:
3738: if (refresh_list)
3739: {
3740: for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
3741: {
3742: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3743: zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
3744: "refresh lsa %p (slot %d)",
3745: inet_ntoa (lsa->data->id), lsa, i);
3746:
3747: assert (lsa->lock > 0);
3748: list_delete_node (refresh_list, node);
3749: lsa->refresh_list = -1;
3750: listnode_add (lsa_to_refresh, lsa);
3751: }
3752: list_free (refresh_list);
3753: }
3754: }
3755:
3756: ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3757: ospf, ospf->lsa_refresh_interval);
3758: ospf->lsa_refresher_started = quagga_time (NULL);
3759:
3760: for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3761: {
3762: ospf_lsa_refresh (ospf, lsa);
3763: assert (lsa->lock > 0);
3764: ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3765: }
3766:
3767: list_delete (lsa_to_refresh);
3768:
3769: if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3770: zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
3771:
3772: return 0;
3773: }
3774:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>