blob: 708fa1c51d3f9875fadb344ba5f2619ae74cf377 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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
36#include "ospfd/ospfd.h"
37#include "ospfd/ospf_interface.h"
38#include "ospfd/ospf_ism.h"
39#include "ospfd/ospf_asbr.h"
40#include "ospfd/ospf_lsa.h"
41#include "ospfd/ospf_lsdb.h"
42#include "ospfd/ospf_neighbor.h"
43#include "ospfd/ospf_nsm.h"
44#include "ospfd/ospf_flood.h"
45#include "ospfd/ospf_packet.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_dump.h"
48#include "ospfd/ospf_route.h"
49#include "ospfd/ospf_ase.h"
50#include "ospfd/ospf_zebra.h"
51
52
53u_int32_t
54get_metric (u_char *metric)
55{
56 u_int32_t m;
57 m = metric[0];
58 m = (m << 8) + metric[1];
59 m = (m << 8) + metric[2];
60 return m;
61}
62
63
64struct timeval
65tv_adjust (struct timeval a)
66{
67 while (a.tv_usec >= 1000000)
68 {
69 a.tv_usec -= 1000000;
70 a.tv_sec++;
71 }
72
73 while (a.tv_usec < 0)
74 {
75 a.tv_usec += 1000000;
76 a.tv_sec--;
77 }
78
79 return a;
80}
81
82int
83tv_ceil (struct timeval a)
84{
85 a = tv_adjust (a);
86
87 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
88}
89
90int
91tv_floor (struct timeval a)
92{
93 a = tv_adjust (a);
94
95 return a.tv_sec;
96}
97
98struct timeval
99int2tv (int a)
100{
101 struct timeval ret;
102
103 ret.tv_sec = a;
104 ret.tv_usec = 0;
105
106 return ret;
107}
108
109struct timeval
110tv_add (struct timeval a, struct timeval b)
111{
112 struct timeval ret;
113
114 ret.tv_sec = a.tv_sec + b.tv_sec;
115 ret.tv_usec = a.tv_usec + b.tv_usec;
116
117 return tv_adjust (ret);
118}
119
120struct timeval
121tv_sub (struct timeval a, struct timeval b)
122{
123 struct timeval ret;
124
125 ret.tv_sec = a.tv_sec - b.tv_sec;
126 ret.tv_usec = a.tv_usec - b.tv_usec;
127
128 return tv_adjust (ret);
129}
130
131int
132tv_cmp (struct timeval a, struct timeval b)
133{
134 return (a.tv_sec == b.tv_sec ?
135 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
136}
137
138int
139ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
140{
141 struct timeval delta, now;
142 int delay = 0;
143
144 gettimeofday (&now, NULL);
145 delta = tv_sub (now, lsa->tv_orig);
146
147 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
148 {
149 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
150
151 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000152 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000153 lsa->data->type, inet_ntoa (lsa->data->id), delay);
154
155 assert (delay > 0);
156 }
157
158 return delay;
159}
160
161
162int
163get_age (struct ospf_lsa *lsa)
164{
165 int age;
166 struct timeval now;
167
168 gettimeofday (&now, NULL);
169 age = ntohs (lsa->data->ls_age) + tv_floor (tv_sub (now, lsa->tv_recv));
170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
176#define MODX 4102
177#define LSA_CHECKSUM_OFFSET 15
178
179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
182 u_char *sp, *ep, *p, *q;
183 int c0 = 0, c1 = 0;
184 int x, y;
185 u_int16_t length;
186
187 lsa->checksum = 0;
188 length = ntohs (lsa->length) - 2;
hassoc9e52be2004-09-26 16:09:34 +0000189 sp = (u_char *) &lsa->options;
paul718e3742002-12-13 20:15:29 +0000190
191 for (ep = sp + length; sp < ep; sp = q)
192 {
193 q = sp + MODX;
194 if (q > ep)
195 q = ep;
196 for (p = sp; p < q; p++)
197 {
198 c0 += *p;
199 c1 += c0;
200 }
201 c0 %= 255;
202 c1 %= 255;
203 }
204
205 x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
206 if (x <= 0)
207 x += 255;
208 y = 510 - c0 - x;
209 if (y > 255)
210 y -= 255;
211
212 /* take care endian issue. */
213 lsa->checksum = htons ((x << 8) + y);
214
215 return (lsa->checksum);
216}
217
218
219
220/* Create OSPF LSA. */
221struct ospf_lsa *
222ospf_lsa_new ()
223{
224 struct ospf_lsa *new;
225
226 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
227 memset (new, 0, sizeof (struct ospf_lsa));
228
229 new->flags = 0;
230 new->lock = 1;
231 new->retransmit_counter = 0;
232 gettimeofday (&new->tv_recv, NULL);
233 new->tv_orig = new->tv_recv;
234 new->refresh_list = -1;
235
236 return new;
237}
238
239/* Duplicate OSPF LSA. */
240struct ospf_lsa *
241ospf_lsa_dup (struct ospf_lsa *lsa)
242{
243 struct ospf_lsa *new;
244
245 if (lsa == NULL)
246 return NULL;
247
248 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
249
250 memcpy (new, lsa, sizeof (struct ospf_lsa));
251 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
252 new->lock = 1;
253 new->retransmit_counter = 0;
254 new->data = ospf_lsa_data_dup (lsa->data);
255
paulf2c80652002-12-13 21:44:27 +0000256 /* kevinm: Clear the refresh_list, otherwise there are going
257 to be problems when we try to remove the LSA from the
258 queue (which it's not a member of.)
259 XXX: Should we add the LSA to the refresh_list queue? */
260 new->refresh_list = -1;
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000263 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000264
paul718e3742002-12-13 20:15:29 +0000265 return new;
266}
267
268/* Free OSPF LSA. */
269void
270ospf_lsa_free (struct ospf_lsa *lsa)
271{
272 assert (lsa->lock == 0);
273
274 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000275 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000276
277 /* Delete LSA data. */
278 if (lsa->data != NULL)
279 ospf_lsa_data_free (lsa->data);
280
281 assert (lsa->refresh_list < 0);
282
283 memset (lsa, 0, sizeof (struct ospf_lsa));
284 XFREE (MTYPE_OSPF_LSA, lsa);
285}
286
287/* Lock LSA. */
288struct ospf_lsa *
289ospf_lsa_lock (struct ospf_lsa *lsa)
290{
291 lsa->lock++;
292 return lsa;
293}
294
295/* Unlock LSA. */
296void
297ospf_lsa_unlock (struct ospf_lsa *lsa)
298{
299 /* This is sanity check. */
300 if (!lsa)
301 return;
302
303 lsa->lock--;
304
305 assert (lsa->lock >= 0);
306
307 if (lsa->lock == 0)
308 {
309 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD));
310 ospf_lsa_free (lsa);
311 }
312}
313
314/* Check discard flag. */
315void
316ospf_lsa_discard (struct ospf_lsa *lsa)
317{
318 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
319 {
320 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
321 ospf_lsa_unlock (lsa);
322 }
323}
324
325/* Create LSA data. */
326struct lsa_header *
327ospf_lsa_data_new (size_t size)
328{
329 struct lsa_header *new;
330
331 new = (struct lsa_header *) XMALLOC (MTYPE_OSPF_LSA_DATA, size);
332 memset (new, 0, size);
333
334 return new;
335}
336
337/* Duplicate LSA data. */
338struct lsa_header *
339ospf_lsa_data_dup (struct lsa_header *lsah)
340{
341 struct lsa_header *new;
342
343 new = ospf_lsa_data_new (ntohs (lsah->length));
344 memcpy (new, lsah, ntohs (lsah->length));
345
346 return new;
347}
348
349/* Free LSA data. */
350void
351ospf_lsa_data_free (struct lsa_header *lsah)
352{
353 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000354 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000355 lsah->type, inet_ntoa (lsah->id), lsah);
356
357 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
358}
359
360
361/* LSA general functions. */
362
363const char *
364dump_lsa_key (struct ospf_lsa *lsa)
365{
366 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000367 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000368 };
369 struct lsa_header *lsah;
370
371 if (lsa != NULL && (lsah = lsa->data) != NULL)
372 {
373 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
374 strcpy (id, inet_ntoa (lsah->id));
375 strcpy (ar, inet_ntoa (lsah->adv_router));
376
377 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
378 }
379 else
380 strcpy (buf, "NULL");
381
382 return buf;
383}
384
385u_int32_t
386lsa_seqnum_increment (struct ospf_lsa *lsa)
387{
388 u_int32_t seqnum;
389
390 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
391
392 return htonl (seqnum);
393}
394
395void
396lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000397 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000398{
399 struct lsa_header *lsah;
400
401 lsah = (struct lsa_header *) STREAM_DATA (s);
402
403 lsah->ls_age = htons (0);
404 lsah->options = options;
405 lsah->type = type;
406 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000407 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000408 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
409
paul9985f832005-02-09 15:51:56 +0000410 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000411}
412
paul68980082003-03-25 05:07:42 +0000413
paul718e3742002-12-13 20:15:29 +0000414/* router-LSA related functions. */
415/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000416static u_char
paul718e3742002-12-13 20:15:29 +0000417router_lsa_flags (struct ospf_area *area)
418{
419 u_char flags;
420
paul68980082003-03-25 05:07:42 +0000421 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000422
423 /* Set virtual link flag. */
424 if (ospf_full_virtual_nbrs (area))
425 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
426 else
427 /* Just sanity check */
428 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
429
430 /* Set Shortcut ABR behabiour flag. */
431 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000432 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000433 if (!OSPF_IS_AREA_BACKBONE (area))
434 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000435 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000436 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
437 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
438
439 /* ASBR can't exit in stub area. */
440 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000441 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
442 /* If ASBR set External flag */
443 else if (IS_OSPF_ASBR (area->ospf))
444 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
445
446 /* Set ABR dependent flags */
447 if (IS_OSPF_ABR (area->ospf))
448 {
449 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000450 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000451 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000452 */
pauld4a53d52003-07-12 21:30:57 +0000453 if ( (area->external_routing == OSPF_AREA_NSSA)
454 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
455 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000456 }
paul718e3742002-12-13 20:15:29 +0000457 return flags;
458}
459
460/* Lookup neighbor other than myself.
461 And check neighbor count,
462 Point-to-Point link must have only 1 neighbor. */
463struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000464ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000465{
paul718e3742002-12-13 20:15:29 +0000466 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000467 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000468
469 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000470 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
471 if ((nbr = rn->info))
472 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000473 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000474 {
475 route_unlock_node (rn);
476 break;
477 }
paul718e3742002-12-13 20:15:29 +0000478
479 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000480 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000481 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
482
483 return nbr;
484}
485
486/* Set a link information. */
paul4dadc292005-05-06 21:37:42 +0000487static void
paul718e3742002-12-13 20:15:29 +0000488link_info_set (struct stream *s, struct in_addr id,
489 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
490{
491 /* TOS based routing is not supported. */
492 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
493 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
494 stream_putc (s, type); /* Link Type. */
495 stream_putc (s, tos); /* TOS = 0. */
496 stream_putw (s, cost); /* Link Cost. */
497}
498
499/* Describe Point-to-Point link. */
paul4dadc292005-05-06 21:37:42 +0000500static int
paul718e3742002-12-13 20:15:29 +0000501lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
502{
503 int links = 0;
504 struct ospf_neighbor *nbr;
505 struct in_addr id, mask;
506
507 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000508 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000509
paul68980082003-03-25 05:07:42 +0000510 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000511 if (nbr->state == NSM_Full)
512 {
513 /* For unnumbered point-to-point networks, the Link Data field
514 should specify the interface's MIB-II ifIndex value. */
515 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
516 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
517 links++;
518 }
519
hasso3fb9cd62004-10-19 19:44:43 +0000520 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000521 {
522 /* Option 1:
523 link_type = LSA_LINK_TYPE_STUB;
524 link_id = nbr->address.u.prefix4;
525 link_data.s_addr = 0xffffffff;
526 link_cost = o->output_cost; */
527
528 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
529 mask.s_addr = 0xffffffff;
530 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
531 }
532 else
533 {
534 /* Option 2: We need to include link to a stub
535 network regardless of the state of the neighbor */
536 masklen2ip (oi->address->prefixlen, &mask);
537 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
538 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
539 }
540 links++;
541
542 return links;
543}
544
545/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000546static int
paul718e3742002-12-13 20:15:29 +0000547lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
548{
549 struct ospf_neighbor *dr;
550 struct in_addr id, mask;
551
552 /* Describe Type 3 Link. */
553 if (oi->state == ISM_Waiting)
554 {
555 masklen2ip (oi->address->prefixlen, &mask);
556 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
557 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
558 return 1;
559 }
560
561 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
562 /* Describe Type 2 link. */
563 if (dr && (dr->state == NSM_Full ||
564 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000565 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000566 {
567 link_info_set (s, DR (oi), oi->address->u.prefix4,
568 LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);
569 }
570 /* Describe type 3 link. */
571 else
572 {
573 masklen2ip (oi->address->prefixlen, &mask);
574 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
575 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
576 }
577 return 1;
578}
579
paul4dadc292005-05-06 21:37:42 +0000580static int
paul718e3742002-12-13 20:15:29 +0000581lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
582{
583 struct in_addr id, mask;
584
585 /* Describe Type 3 Link. */
586 if (oi->state != ISM_Loopback)
587 return 0;
588
589 mask.s_addr = 0xffffffff;
590 id.s_addr = oi->address->u.prefix4.s_addr;
591 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
592 return 1;
593}
594
595/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000596static int
paul718e3742002-12-13 20:15:29 +0000597lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
598{
599 struct ospf_neighbor *nbr;
600
paul718e3742002-12-13 20:15:29 +0000601 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000602 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000603 if (nbr->state == NSM_Full)
604 {
605 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
606 LSA_LINK_TYPE_VIRTUALLINK, 0, oi->output_cost);
607 return 1;
608 }
609
610 return 0;
611}
612
613#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
614
paul7afa08d2002-12-13 20:59:45 +0000615/* this function add for support point-to-multipoint ,see rfc2328
61612.4.1.4.*/
617/* from "edward rrr" <edward_rrr@hotmail.com>
618 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000619static int
paul68980082003-03-25 05:07:42 +0000620lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000621{
622 int links = 0;
623 struct route_node *rn;
624 struct ospf_neighbor *nbr = NULL;
625 struct in_addr id, mask;
626
627 mask.s_addr = 0xffffffff;
628 id.s_addr = oi->address->u.prefix4.s_addr;
629 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
630 links++;
631
paul1cc8f762003-04-05 19:34:32 +0000632 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000633 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000634
635 /* Search neighbor, */
636 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
637 if ((nbr = rn->info) != NULL)
638 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000639 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000640 if (nbr->state == NSM_Full)
641
642 {
paul7afa08d2002-12-13 20:59:45 +0000643 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
644 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
645 links++;
paul1cc8f762003-04-05 19:34:32 +0000646 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000647 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000648 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000649 }
650
651 return links;
paul7afa08d2002-12-13 20:59:45 +0000652}
653
paul718e3742002-12-13 20:15:29 +0000654/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000655static int
paul718e3742002-12-13 20:15:29 +0000656router_lsa_link_set (struct stream *s, struct ospf_area *area)
657{
hasso52dc7ee2004-09-23 19:18:23 +0000658 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000659 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000660 int links = 0;
661
paul1eb8ef22005-04-07 07:30:20 +0000662 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000663 {
paul718e3742002-12-13 20:15:29 +0000664 struct interface *ifp = oi->ifp;
665
666 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000667 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000668 {
669 if (oi->state != ISM_Down)
670 {
671 /* Describe each link. */
672 switch (oi->type)
673 {
674 case OSPF_IFTYPE_POINTOPOINT:
675 links += lsa_link_ptop_set (s, oi);
676 break;
677 case OSPF_IFTYPE_BROADCAST:
678 links += lsa_link_broadcast_set (s, oi);
679 break;
680 case OSPF_IFTYPE_NBMA:
681 links += lsa_link_nbma_set (s, oi);
682 break;
683 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000684 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000685 break;
686 case OSPF_IFTYPE_VIRTUALLINK:
687 links += lsa_link_virtuallink_set (s, oi);
688 break;
689 case OSPF_IFTYPE_LOOPBACK:
690 links += lsa_link_loopback_set (s, oi);
691 }
692 }
693 }
694 }
695
696 return links;
697}
698
699/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000700static void
paul718e3742002-12-13 20:15:29 +0000701ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
702{
703 unsigned long putp;
704 u_int16_t cnt;
705
706 /* Set flags. */
707 stream_putc (s, router_lsa_flags (area));
708
709 /* Set Zero fields. */
710 stream_putc (s, 0);
711
712 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000713 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000714
715 /* Forward word */
716 stream_putw(s, 0);
717
718 /* Set all link information. */
719 cnt = router_lsa_link_set (s, area);
720
721 /* Set # of links here. */
722 stream_putw_at (s, putp, cnt);
723}
724
725/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000726static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000727ospf_router_lsa_new (struct ospf_area *area)
728{
paul68980082003-03-25 05:07:42 +0000729 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000730 struct stream *s;
731 struct lsa_header *lsah;
732 struct ospf_lsa *new;
733 int length;
734
735 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000736 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000737
738 /* Create a stream for LSA. */
739 s = stream_new (OSPF_MAX_LSA_SIZE);
740 lsah = (struct lsa_header *) STREAM_DATA (s);
741
paul718e3742002-12-13 20:15:29 +0000742 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000743 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000744 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000745
746 /* Set router-LSA body fields. */
747 ospf_router_lsa_body_set (s, area);
748
749 /* Set length. */
750 length = stream_get_endp (s);
751 lsah->length = htons (length);
752
753 /* Now, create OSPF LSA instance. */
754 new = ospf_lsa_new ();
755 new->area = area;
756 SET_FLAG (new->flags, OSPF_LSA_SELF);
757
758 /* Copy LSA data to store, discard stream. */
759 new->data = ospf_lsa_data_new (length);
760 memcpy (new->data, lsah, length);
761 stream_free (s);
762
763 return new;
764}
765
766/* Originate Router-LSA. */
767struct ospf_lsa *
768ospf_router_lsa_originate (struct ospf_area *area)
769{
770 struct ospf_lsa *new;
771
772 /* Create new router-LSA instance. */
773 new = ospf_router_lsa_new (area);
774
775 /* Sanity check. */
776 if (new->data->adv_router.s_addr == 0)
777 {
778 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000779 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000780 ospf_lsa_discard (new);
781 return NULL;
782 }
783
784 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000785 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000786
787 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000788 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000789
790 /* Flooding new LSA through area. */
791 ospf_flood_through_area (area, NULL, new);
792
793 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
794 {
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000796 new->data->type, inet_ntoa (new->data->id), new);
797 ospf_lsa_header_dump (new->data);
798 }
799
800 return new;
801}
802
803/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000804static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000805ospf_router_lsa_refresh (struct ospf_lsa *lsa)
806{
807 struct ospf_area *area = lsa->area;
808 struct ospf_lsa *new;
809
810 /* Sanity check. */
811 assert (lsa->data);
812
813 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000814 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000815
816 /* Create new router-LSA instance. */
817 new = ospf_router_lsa_new (area);
818 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
819
paul68980082003-03-25 05:07:42 +0000820 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000821
822 /* Flood LSA through area. */
823 ospf_flood_through_area (area, NULL, new);
824
825 /* Debug logging. */
826 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
827 {
ajse588f212004-12-08 18:12:06 +0000828 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000829 new->data->type, inet_ntoa (new->data->id));
830 ospf_lsa_header_dump (new->data);
831 }
832
833 return NULL;
834}
835
paul4dadc292005-05-06 21:37:42 +0000836static int
paul718e3742002-12-13 20:15:29 +0000837ospf_router_lsa_timer (struct thread *t)
838{
839 struct ospf_area *area;
840
841 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000842 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000843
844 area = THREAD_ARG (t);
845 area->t_router_lsa_self = NULL;
846
847 /* Now refresh router-LSA. */
848 if (area->router_lsa_self)
849 ospf_router_lsa_refresh (area->router_lsa_self);
850 /* Newly originate router-LSA. */
851 else
852 ospf_router_lsa_originate (area);
853
854 return 0;
855}
856
857void
858ospf_router_lsa_timer_add (struct ospf_area *area)
859{
860 /* Keep area's self-originated router-LSA. */
861 struct ospf_lsa *lsa = area->router_lsa_self;
862
863 /* Cancel previously scheduled router-LSA timer. */
864 if (area->t_router_lsa_self)
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000866 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000867
868 OSPF_TIMER_OFF (area->t_router_lsa_self);
869
870 /* If router-LSA is originated previously, check the interval time. */
871 if (lsa)
872 {
873 int delay;
874 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
875 {
876 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
877 ospf_router_lsa_timer, delay);
878 return;
879 }
880 }
881
882 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000883 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000884
885 /* Immediately refresh router-LSA. */
886 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
887}
888
889int
paul68980082003-03-25 05:07:42 +0000890ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000891{
paul68980082003-03-25 05:07:42 +0000892 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000893 struct listnode *node, *nnode;
894 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000895
896 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000897 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000898
paul68980082003-03-25 05:07:42 +0000899 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000900
paul1eb8ef22005-04-07 07:30:20 +0000901 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000902 {
paul718e3742002-12-13 20:15:29 +0000903 struct ospf_lsa *lsa = area->router_lsa_self;
904 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000905 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000906
907 /* Keep Area ID string. */
908 area_str = AREA_NAME (area);
909
910 /* If LSA not exist in this Area, originate new. */
911 if (lsa == NULL)
912 {
913 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000914 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000915
916 ospf_router_lsa_originate (area);
917 }
918 /* If router-ID is changed, Link ID must change.
919 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000920 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000921 {
922 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000923 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000924 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
925 ospf_lsa_flush_area (lsa, area);
926 ospf_lsa_unlock (area->router_lsa_self);
927 area->router_lsa_self = NULL;
928
929 /* Refresh router-LSA, (not install) and flood through area. */
930 ospf_router_lsa_timer_add (area);
931 }
932 else
933 {
934 rl = (struct router_lsa *) lsa->data;
935 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000936 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +0000937 ospf_router_lsa_timer_add (area);
938 }
939 }
940
941 return 0;
942}
943
944
945/* network-LSA related functions. */
946/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +0000947static void
paul718e3742002-12-13 20:15:29 +0000948ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
949{
950 struct in_addr mask;
951 struct route_node *rn;
952 struct ospf_neighbor *nbr;
953
954 masklen2ip (oi->address->prefixlen, &mask);
955 stream_put_ipv4 (s, mask.s_addr);
956
957 /* The network-LSA lists those routers that are fully adjacent to
958 the Designated Router; each fully adjacent router is identified by
959 its OSPF Router ID. The Designated Router includes itself in this
960 list. RFC2328, Section 12.4.2 */
961
962 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
963 if ((nbr = rn->info) != NULL)
964 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
965 stream_put_ipv4 (s, nbr->router_id.s_addr);
966}
967
paul4dadc292005-05-06 21:37:42 +0000968static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000969ospf_network_lsa_new (struct ospf_interface *oi)
970{
971 struct stream *s;
972 struct ospf_lsa *new;
973 struct lsa_header *lsah;
974 int length;
975
976 /* If there are no neighbours on this network (the net is stub),
977 the router does not originate network-LSA (see RFC 12.4.2) */
978 if (oi->full_nbrs == 0)
979 return NULL;
980
981 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000982 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +0000983
984 /* Create new stream for LSA. */
985 s = stream_new (OSPF_MAX_LSA_SIZE);
986 lsah = (struct lsa_header *) STREAM_DATA (s);
987
988 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +0000989 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000990
991 /* Set network-LSA body fields. */
992 ospf_network_lsa_body_set (s, oi);
993
994 /* Set length. */
995 length = stream_get_endp (s);
996 lsah->length = htons (length);
997
998 /* Create OSPF LSA instance. */
999 new = ospf_lsa_new ();
1000 new->area = oi->area;
1001 SET_FLAG (new->flags, OSPF_LSA_SELF);
1002
1003 /* Copy LSA to store. */
1004 new->data = ospf_lsa_data_new (length);
1005 memcpy (new->data, lsah, length);
1006 stream_free (s);
1007
1008 return new;
1009}
1010
1011/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001012static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001013ospf_network_lsa_originate (struct ospf_interface *oi)
1014{
1015 struct ospf_lsa *new;
1016
1017 /* Create new network-LSA instance. */
1018 new = ospf_network_lsa_new (oi);
1019 if (new == NULL)
1020 return NULL;
1021
1022 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001023 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001024
1025 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001026 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001027
1028 /* Flooding new LSA through area. */
1029 ospf_flood_through_area (oi->area, NULL, new);
1030
1031 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1032 {
ajse588f212004-12-08 18:12:06 +00001033 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001034 new->data->type, inet_ntoa (new->data->id), new);
1035 ospf_lsa_header_dump (new->data);
1036 }
1037
1038 return new;
1039}
1040
1041int
1042ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1043{
1044 struct ospf_area *area = lsa->area;
1045 struct ospf_lsa *new;
1046
1047 assert (lsa->data);
1048
1049 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001050 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001051
1052 /* Create new network-LSA instance. */
1053 new = ospf_network_lsa_new (oi);
1054 if (new == NULL)
1055 return -1;
1056 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1057
paul68980082003-03-25 05:07:42 +00001058 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001059
1060 /* Flood LSA through aera. */
1061 ospf_flood_through_area (area, NULL, new);
1062
1063 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1064 {
ajse588f212004-12-08 18:12:06 +00001065 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001066 new->data->type, inet_ntoa (new->data->id));
1067 ospf_lsa_header_dump (new->data);
1068 }
1069
1070 return 0;
1071}
1072
paul4dadc292005-05-06 21:37:42 +00001073static int
paul718e3742002-12-13 20:15:29 +00001074ospf_network_lsa_refresh_timer (struct thread *t)
1075{
1076 struct ospf_interface *oi;
1077
1078 oi = THREAD_ARG (t);
1079 oi->t_network_lsa_self = NULL;
1080
1081 if (oi->network_lsa_self)
1082 /* Now refresh network-LSA. */
1083 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1084 else
1085 /* Newly create network-LSA. */
1086 ospf_network_lsa_originate (oi);
1087
1088 return 0;
1089}
1090
1091void
1092ospf_network_lsa_timer_add (struct ospf_interface *oi)
1093{
1094 /* Keep interface's self-originated network-LSA. */
1095 struct ospf_lsa *lsa = oi->network_lsa_self;
1096
1097 /* Cancel previously schedules network-LSA timer. */
1098 if (oi->t_network_lsa_self)
1099 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001100 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001101 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1102
1103 /* If network-LSA is originated previously, check the interval time. */
1104 if (lsa)
1105 {
1106 int delay;
1107 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1108 {
1109 oi->t_network_lsa_self =
1110 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1111 oi, delay);
1112 return;
1113 }
1114 }
1115
1116 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001117 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001118
1119 /* Immediately refresh network-LSA. */
1120 oi->t_network_lsa_self =
1121 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1122}
1123
1124
paul4dadc292005-05-06 21:37:42 +00001125static void
paul718e3742002-12-13 20:15:29 +00001126stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1127{
1128 u_int32_t metric;
1129 char *mp;
1130
1131 /* Put 0 metric. TOS metric is not supported. */
1132 metric = htonl (metric_value);
1133 mp = (char *) &metric;
1134 mp++;
1135 stream_put (s, mp, 3);
1136}
1137
1138/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001139static void
paul718e3742002-12-13 20:15:29 +00001140ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1141 u_int32_t metric)
1142{
1143 struct in_addr mask;
1144
1145 masklen2ip (p->prefixlen, &mask);
1146
1147 /* Put Network Mask. */
1148 stream_put_ipv4 (s, mask.s_addr);
1149
1150 /* Set # TOS. */
1151 stream_putc (s, (u_char) 0);
1152
1153 /* Set metric. */
1154 stream_put_ospf_metric (s, metric);
1155}
1156
paul4dadc292005-05-06 21:37:42 +00001157static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001158ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1159 u_int32_t metric, struct in_addr id)
1160{
1161 struct stream *s;
1162 struct ospf_lsa *new;
1163 struct lsa_header *lsah;
1164 int length;
1165
1166 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001167 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001168
1169 /* Create new stream for LSA. */
1170 s = stream_new (OSPF_MAX_LSA_SIZE);
1171 lsah = (struct lsa_header *) STREAM_DATA (s);
1172
paul68980082003-03-25 05:07:42 +00001173 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1174 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001175
1176 /* Set summary-LSA body fields. */
1177 ospf_summary_lsa_body_set (s, p, metric);
1178
1179 /* Set length. */
1180 length = stream_get_endp (s);
1181 lsah->length = htons (length);
1182
1183 /* Create OSPF LSA instance. */
1184 new = ospf_lsa_new ();
1185 new->area = area;
1186 SET_FLAG (new->flags, OSPF_LSA_SELF);
1187
1188 /* Copy LSA to store. */
1189 new->data = ospf_lsa_data_new (length);
1190 memcpy (new->data, lsah, length);
1191 stream_free (s);
1192
1193 return new;
1194}
1195
1196/* Originate Summary-LSA. */
1197struct ospf_lsa *
1198ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1199 struct ospf_area *area)
1200{
1201 struct ospf_lsa *new;
1202 struct in_addr id;
1203
paul68980082003-03-25 05:07:42 +00001204 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001205
1206 /* Create new summary-LSA instance. */
1207 new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id);
1208
1209 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001210 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001211
1212 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001213 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001214
1215 /* Flooding new LSA through area. */
1216 ospf_flood_through_area (area, NULL, new);
1217
1218 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1219 {
ajse588f212004-12-08 18:12:06 +00001220 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001221 new->data->type, inet_ntoa (new->data->id), new);
1222 ospf_lsa_header_dump (new->data);
1223 }
1224
1225 return new;
1226}
1227
1228struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001229ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001230{
1231 struct ospf_lsa *new;
1232 struct summary_lsa *sl;
1233 struct prefix p;
1234
1235 /* Sanity check. */
1236 assert (lsa->data);
1237
1238 sl = (struct summary_lsa *)lsa->data;
1239 p.prefixlen = ip_masklen (sl->mask);
1240 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1241 sl->header.id);
1242
1243 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1244
1245 /* Re-calculate checksum. */
1246 ospf_lsa_checksum (new->data);
1247
paul68980082003-03-25 05:07:42 +00001248 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001249
1250 /* Flood LSA through AS. */
1251 ospf_flood_through_area (new->area, NULL, new);
1252
1253 /* Debug logging. */
1254 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1255 {
ajse588f212004-12-08 18:12:06 +00001256 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001257 new->data->type, inet_ntoa (new->data->id));
1258 ospf_lsa_header_dump (new->data);
1259 }
1260
1261 return new;
1262}
1263
1264
1265/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001266static void
paul718e3742002-12-13 20:15:29 +00001267ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1268 u_int32_t metric)
1269{
1270 struct in_addr mask;
1271
1272 masklen2ip (p->prefixlen, &mask);
1273
1274 /* Put Network Mask. */
1275 stream_put_ipv4 (s, mask.s_addr);
1276
1277 /* Set # TOS. */
1278 stream_putc (s, (u_char) 0);
1279
1280 /* Set metric. */
1281 stream_put_ospf_metric (s, metric);
1282}
1283
paul4dadc292005-05-06 21:37:42 +00001284static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001285ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1286 u_int32_t metric, struct in_addr id)
1287{
1288 struct stream *s;
1289 struct ospf_lsa *new;
1290 struct lsa_header *lsah;
1291 int length;
1292
1293 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001294 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001295
1296 /* Create new stream for LSA. */
1297 s = stream_new (OSPF_MAX_LSA_SIZE);
1298 lsah = (struct lsa_header *) STREAM_DATA (s);
1299
paul68980082003-03-25 05:07:42 +00001300 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1301 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001302
1303 /* Set summary-LSA body fields. */
1304 ospf_summary_asbr_lsa_body_set (s, p, metric);
1305
1306 /* Set length. */
1307 length = stream_get_endp (s);
1308 lsah->length = htons (length);
1309
1310 /* Create OSPF LSA instance. */
1311 new = ospf_lsa_new ();
1312 new->area = area;
1313 SET_FLAG (new->flags, OSPF_LSA_SELF);
1314
1315 /* Copy LSA to store. */
1316 new->data = ospf_lsa_data_new (length);
1317 memcpy (new->data, lsah, length);
1318 stream_free (s);
1319
1320 return new;
1321}
1322
1323/* Originate summary-ASBR-LSA. */
1324struct ospf_lsa *
1325ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1326 struct ospf_area *area)
1327{
1328 struct ospf_lsa *new;
1329 struct in_addr id;
1330
paul68980082003-03-25 05:07:42 +00001331 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001332
1333 /* Create new summary-LSA instance. */
1334 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
1335
1336 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001337 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001338
1339 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001340 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001341
1342 /* Flooding new LSA through area. */
1343 ospf_flood_through_area (area, NULL, new);
1344
1345 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1346 {
ajse588f212004-12-08 18:12:06 +00001347 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001348 new->data->type, inet_ntoa (new->data->id), new);
1349 ospf_lsa_header_dump (new->data);
1350 }
1351
1352 return new;
1353}
1354
1355struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001356ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001357{
1358 struct ospf_lsa *new;
1359 struct summary_lsa *sl;
1360 struct prefix p;
1361
1362 /* Sanity check. */
1363 assert (lsa->data);
1364
1365 sl = (struct summary_lsa *)lsa->data;
1366 p.prefixlen = ip_masklen (sl->mask);
1367 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1368 sl->header.id);
1369
1370 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1371
1372 /* Re-calculate checksum. */
1373 ospf_lsa_checksum (new->data);
1374
paul68980082003-03-25 05:07:42 +00001375 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001376
1377 /* Flood LSA through area. */
1378 ospf_flood_through_area (new->area, NULL, new);
1379
1380 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1381 {
ajse588f212004-12-08 18:12:06 +00001382 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001383 new->data->type, inet_ntoa (new->data->id));
1384 ospf_lsa_header_dump (new->data);
1385 }
1386
1387 return new;
1388}
1389
1390/* AS-external-LSA related functions. */
1391
1392/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1393 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001394static struct in_addr
paul68980082003-03-25 05:07:42 +00001395ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001396{
1397 struct in_addr fwd;
1398 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001399 struct listnode *node;
1400 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001401
1402 fwd.s_addr = 0;
1403
1404 if (!nexthop.s_addr)
1405 return fwd;
1406
1407 /* Check whether nexthop is covered by OSPF network. */
1408 nh.family = AF_INET;
1409 nh.u.prefix4 = nexthop;
1410 nh.prefixlen = IPV4_MAX_BITLEN;
1411
paul1eb8ef22005-04-07 07:30:20 +00001412 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1413 if (if_is_operative (oi->ifp))
1414 if (oi->address->family == AF_INET)
1415 if (prefix_match (oi->address, &nh))
1416 return nexthop;
paul718e3742002-12-13 20:15:29 +00001417
1418 return fwd;
1419}
1420
paul718e3742002-12-13 20:15:29 +00001421/* NSSA-external-LSA related functions. */
1422
1423/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001424
paul718e3742002-12-13 20:15:29 +00001425struct in_addr
1426ospf_get_ip_from_ifp (struct ospf_interface *oi)
1427{
1428 struct in_addr fwd;
1429
1430 fwd.s_addr = 0;
1431
paul2e3b2e42002-12-13 21:03:13 +00001432 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001433 return oi->address->u.prefix4;
1434
1435 return fwd;
1436}
1437
1438/* Get 1st IP connection for Forward Addr */
1439struct in_addr
paulf2c80652002-12-13 21:44:27 +00001440ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001441{
1442 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001443 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001444 struct listnode *node;
1445 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001446
1447 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001448 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001449
paul1eb8ef22005-04-07 07:30:20 +00001450 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001451 {
paul2e3b2e42002-12-13 21:03:13 +00001452 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001453 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001454 if (oi->address && oi->address->family == AF_INET)
1455 {
1456 if (best_default.s_addr == 0)
1457 best_default = oi->address->u.prefix4;
1458 if (oi->area == area)
1459 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001460 }
paul718e3742002-12-13 20:15:29 +00001461 }
paulf2c80652002-12-13 21:44:27 +00001462 if (best_default.s_addr != 0)
1463 return best_default;
paul718e3742002-12-13 20:15:29 +00001464
paul68980082003-03-25 05:07:42 +00001465 if (best_default.s_addr != 0)
1466 return best_default;
1467
paul718e3742002-12-13 20:15:29 +00001468 return fwd;
1469}
hassobeebba72004-06-20 21:00:27 +00001470
paul718e3742002-12-13 20:15:29 +00001471#define DEFAULT_DEFAULT_METRIC 20
1472#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1473#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1474
1475#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1476
1477int
paul68980082003-03-25 05:07:42 +00001478metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001479{
paul68980082003-03-25 05:07:42 +00001480 return (ospf->dmetric[src].type < 0 ?
1481 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001482}
1483
1484int
paul68980082003-03-25 05:07:42 +00001485metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001486{
paul68980082003-03-25 05:07:42 +00001487 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001488 {
1489 if (src == DEFAULT_ROUTE)
1490 {
paul68980082003-03-25 05:07:42 +00001491 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001492 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1493 else
1494 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1495 }
paul68980082003-03-25 05:07:42 +00001496 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001497 return DEFAULT_DEFAULT_METRIC;
1498 else
paul68980082003-03-25 05:07:42 +00001499 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001500 }
1501
paul68980082003-03-25 05:07:42 +00001502 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001503}
1504
1505/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001506static void
paul68980082003-03-25 05:07:42 +00001507ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1508 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001509{
1510 struct prefix_ipv4 *p = &ei->p;
1511 struct in_addr mask, fwd_addr;
1512 u_int32_t mvalue;
1513 int mtype;
1514 int type;
1515
1516 /* Put Network Mask. */
1517 masklen2ip (p->prefixlen, &mask);
1518 stream_put_ipv4 (s, mask.s_addr);
1519
1520 /* If prefix is default, specify DEFAULT_ROUTE. */
1521 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1522
1523 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001524 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001525
1526 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001527 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001528
1529 /* Put type of external metric. */
1530 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1531
1532 /* Put 0 metric. TOS metric is not supported. */
1533 stream_put_ospf_metric (s, mvalue);
1534
1535 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001536 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001537
1538 /* Put forwarding address. */
1539 stream_put_ipv4 (s, fwd_addr.s_addr);
1540
1541 /* Put route tag -- This value should be introduced from configuration. */
1542 stream_putl (s, 0);
1543}
1544
1545/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001546static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001547ospf_external_lsa_new (struct ospf *ospf,
1548 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001549{
1550 struct stream *s;
1551 struct lsa_header *lsah;
1552 struct ospf_lsa *new;
1553 struct in_addr id;
1554 int length;
1555
1556 if (ei == NULL)
1557 {
1558 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001559 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001560 return NULL;
1561 }
1562
1563 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001564 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001565
1566 /* If old Link State ID is specified, refresh LSA with same ID. */
1567 if (old_id)
1568 id = *old_id;
1569 /* Get Link State with unique ID. */
1570 else
1571 {
paul68980082003-03-25 05:07:42 +00001572 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001573 if (id.s_addr == 0xffffffff)
1574 {
1575 /* Maybe Link State ID not available. */
1576 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001577 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001578 return NULL;
1579 }
1580 }
1581
1582 /* Create new stream for LSA. */
1583 s = stream_new (OSPF_MAX_LSA_SIZE);
1584 lsah = (struct lsa_header *) STREAM_DATA (s);
1585
1586 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001587 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1588 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001589
1590 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001591 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001592
1593 /* Set length. */
1594 length = stream_get_endp (s);
1595 lsah->length = htons (length);
1596
1597 /* Now, create OSPF LSA instance. */
1598 new = ospf_lsa_new ();
1599 new->area = NULL;
1600 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1601
1602 /* Copy LSA data to store, discard stream. */
1603 new->data = ospf_lsa_data_new (length);
1604 memcpy (new->data, lsah, length);
1605 stream_free (s);
1606
1607 return new;
1608}
1609
paul718e3742002-12-13 20:15:29 +00001610/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001611static void
paul68980082003-03-25 05:07:42 +00001612ospf_install_flood_nssa (struct ospf *ospf,
1613 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001614{
pauld4a53d52003-07-12 21:30:57 +00001615 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001616 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001617 struct ospf_area *area;
1618 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001619
pauld4a53d52003-07-12 21:30:57 +00001620 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1621 * which originated from an NSSA area. In which case it should not be
1622 * flooded back to NSSA areas.
1623 */
1624 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1625 return;
1626
paul718e3742002-12-13 20:15:29 +00001627 /* NSSA Originate or Refresh (If anyNSSA)
1628
1629 LSA is self-originated. And just installed as Type-5.
1630 Additionally, install as Type-7 LSDB for every attached NSSA.
1631
1632 P-Bit controls which ABR performs translation to outside world; If
1633 we are an ABR....do not set the P-bit, because we send the Type-5,
1634 not as the ABR Translator, but as the ASBR owner within the AS!
1635
1636 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1637 elected ABR Translator will see the P-bit, Translate, and re-flood.
1638
1639 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1640 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1641
paul1eb8ef22005-04-07 07:30:20 +00001642 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001643 {
hasso0c14ad82003-07-03 08:36:02 +00001644 /* Don't install Type-7 LSA's into nonNSSA area */
1645 if (area->external_routing != OSPF_AREA_NSSA)
1646 continue;
paul718e3742002-12-13 20:15:29 +00001647
paul68980082003-03-25 05:07:42 +00001648 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001649 new = ospf_lsa_dup (lsa);
1650 new->area = area;
1651 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001652
paul68980082003-03-25 05:07:42 +00001653 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001654 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001655 {
pauld4a53d52003-07-12 21:30:57 +00001656 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001657
1658 /* set non-zero FWD ADDR
1659
1660 draft-ietf-ospf-nssa-update-09.txt
1661
1662 if the network between the NSSA AS boundary router and the
1663 adjacent AS is advertised into OSPF as an internal OSPF route,
1664 the forwarding address should be the next op address as is cu
1665 currently done with type-5 LSAs. If the intervening network is
1666 not adversited into OSPF as an internal OSPF route and the
1667 type-7 LSA's P-bit is set a forwarding address should be
1668 selected from one of the router's active OSPF inteface addresses
1669 which belong to the NSSA. If no such addresses exist, then
1670 no type-7 LSA's with the P-bit set should originate from this
1671 router. */
1672
pauld4a53d52003-07-12 21:30:57 +00001673 /* kevinm: not updating lsa anymore, just new */
1674 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001675
1676 if (extlsa->e[0].fwd_addr.s_addr == 0)
1677 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001678
pauld7480322003-05-16 17:31:51 +00001679 if (extlsa->e[0].fwd_addr.s_addr == 0)
1680 {
1681 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001682 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
pauld4a53d52003-07-12 21:30:57 +00001683 ospf_lsa_discard(new);
pauld7480322003-05-16 17:31:51 +00001684 return;
1685 }
paulf2c80652002-12-13 21:44:27 +00001686 }
paul68980082003-03-25 05:07:42 +00001687 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001688 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001689
paul68980082003-03-25 05:07:42 +00001690 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001691 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001692
1693 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001694 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001695 }
paul718e3742002-12-13 20:15:29 +00001696}
pauld4a53d52003-07-12 21:30:57 +00001697
paul4dadc292005-05-06 21:37:42 +00001698static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001699ospf_lsa_translated_nssa_new (struct ospf *ospf,
1700 struct ospf_lsa *type7)
1701{
1702
1703 struct ospf_lsa *new;
1704 struct as_external_lsa *ext, *extnew;
1705 struct external_info ei;
1706
1707 ext = (struct as_external_lsa *)(type7->data);
1708
1709 /* need external_info struct, fill in bare minimum */
1710 ei.p.family = AF_INET;
1711 ei.p.prefix = type7->data->id;
1712 ei.p.prefixlen = ip_masklen (ext->mask);
1713 ei.type = ZEBRA_ROUTE_OSPF;
1714 ei.nexthop = ext->header.adv_router;
1715 ei.route_map_set.metric = -1;
1716 ei.route_map_set.metric_type = -1;
1717 ei.tag = 0;
1718
1719 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1720 {
1721 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001722 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001723 "Translated Type-5 for %s",
1724 inet_ntoa (ei.p.prefix));
1725 return NULL;
1726 }
1727
1728 extnew = (struct as_external_lsa *)(new->data);
1729
1730 /* copy over Type-7 data to new */
1731 extnew->e[0].tos = ext->e[0].tos;
1732 extnew->e[0].route_tag = ext->e[0].route_tag;
1733 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1734 new->data->ls_seqnum = type7->data->ls_seqnum;
1735
1736 /* add translated flag, checksum and lock new lsa */
1737 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1738 ospf_lsa_checksum (new->data);
1739 new = ospf_lsa_lock (new);
1740
1741 return new;
1742}
1743
1744/* compare type-5 to type-7
1745 * -1: err, 0: same, 1: different
1746 */
paul4dadc292005-05-06 21:37:42 +00001747static int
pauld4a53d52003-07-12 21:30:57 +00001748ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1749{
1750
1751 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1752 *e7 = (struct as_external_lsa *)t7;
1753
1754
1755 /* sanity checks */
1756 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1757 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1758 return -1;
1759
1760 if (t5->data->id.s_addr != t7->data->id.s_addr)
1761 return -1;
1762
1763 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1764 return LSA_REFRESH_FORCE;
1765
1766 if (e5->mask.s_addr != e7->mask.s_addr)
1767 return LSA_REFRESH_FORCE;
1768
1769 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1770 return LSA_REFRESH_FORCE;
1771
1772 if (e5->e[0].route_tag != e7->e[0].route_tag)
1773 return LSA_REFRESH_FORCE;
1774
1775 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1776 return LSA_REFRESH_FORCE;
1777
1778 return LSA_REFRESH_IF_CHANGED;
1779}
1780
1781/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1782struct ospf_lsa *
1783ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1784{
1785 struct ospf_lsa *new;
1786 struct as_external_lsa *extnew;
1787
1788 /* we cant use ospf_external_lsa_originate() as we need to set
1789 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1790 */
1791
1792 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1793 {
1794 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001795 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001796 "Type-7, Id %s, to Type-5",
1797 inet_ntoa (type7->data->id));
1798 return NULL;
1799 }
1800
1801 extnew = (struct as_external_lsa *)new;
1802
1803 if (IS_DEBUG_OSPF_NSSA)
1804 {
ajse588f212004-12-08 18:12:06 +00001805 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001806 "translated Type 7, installed:");
1807 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001808 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1809 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001810 }
1811
1812 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1813 {
1814 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001815 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001816 "Could not install LSA "
1817 "id %s", inet_ntoa (type7->data->id));
1818 return NULL;
1819 }
1820
1821 ospf->lsa_originate_count++;
1822 ospf_flood_through_as (ospf, NULL, new);
1823
1824 return new;
1825}
1826
1827/* Refresh Translated from NSSA AS-external-LSA. */
1828struct ospf_lsa *
1829ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1830 struct ospf_lsa *type5)
1831{
1832 struct ospf_lsa *new = NULL;
1833
1834 /* Sanity checks. */
1835 assert (type7 || type5);
1836 if (type7)
1837 assert (type7->data);
1838 if (type5)
1839 assert (type5->data);
1840 assert (ospf->anyNSSA);
1841
1842 /* get required data according to what has been given */
1843 if (type7 && type5 == NULL)
1844 {
1845 /* find the translated Type-5 for this Type-7 */
1846 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1847 struct prefix_ipv4 p =
1848 {
1849 .prefix = type7->data->id,
1850 .prefixlen = ip_masklen (ext->mask),
1851 .family = AF_INET,
1852 };
1853
1854 type5 = ospf_external_info_find_lsa (ospf, &p);
1855 }
1856 else if (type5 && type7 == NULL)
1857 {
1858 /* find the type-7 from which supplied type-5 was translated,
1859 * ie find first type-7 with same LSA Id.
1860 */
paul1eb8ef22005-04-07 07:30:20 +00001861 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001862 struct route_node *rn;
1863 struct ospf_lsa *lsa;
1864 struct ospf_area *area;
1865
paul1eb8ef22005-04-07 07:30:20 +00001866 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001867 {
1868 if (area->external_routing != OSPF_AREA_NSSA
1869 && !type7)
1870 continue;
1871
1872 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1873 {
1874 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1875 {
1876 type7 = lsa;
1877 break;
1878 }
1879 }
1880 }
1881 }
1882
1883 /* do we have type7? */
1884 if (!type7)
1885 {
1886 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001887 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001888 "Type-5 LSA Id %s",
1889 inet_ntoa (type7->data->id));
1890 return NULL;
1891 }
1892
1893 /* do we have valid translated type5? */
1894 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1895 {
1896 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001897 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001898 "found for Type-7 with Id %s",
1899 inet_ntoa (type7->data->id));
1900 return NULL;
1901 }
1902
1903 /* Delete LSA from neighbor retransmit-list. */
1904 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1905
1906 /* create new translated LSA */
1907 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1908 {
1909 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001910 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001911 "Type-7 for %s to Type-5",
1912 inet_ntoa (type7->data->id));
1913 return NULL;
1914 }
1915
1916 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1917 {
1918 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001919 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001920 "translated LSA, Id %s",
1921 inet_ntoa (new->data->id));
1922 return NULL;
1923 }
1924
1925 /* Flood LSA through area. */
1926 ospf_flood_through_as (ospf, NULL, new);
1927
1928 return new;
1929}
paul718e3742002-12-13 20:15:29 +00001930
1931int
1932is_prefix_default (struct prefix_ipv4 *p)
1933{
1934 struct prefix_ipv4 q;
1935
1936 q.family = AF_INET;
1937 q.prefix.s_addr = 0;
1938 q.prefixlen = 0;
1939
1940 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1941}
1942
1943/* Originate an AS-external-LSA, install and flood. */
1944struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001945ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001946{
1947 struct ospf_lsa *new;
1948
1949 /* Added for NSSA project....
1950
1951 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1952 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1953 every area. The Type-7's are flooded to every IR and every ABR; We
1954 install the Type-5 LSDB so that the normal "refresh" code operates
1955 as usual, and flag them as not used during ASE calculations. The
1956 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1957 Address of non-zero.
1958
1959 If an ABR is the elected NSSA translator, following SPF and during
1960 the ABR task it will translate all the scanned Type-7's, with P-bit
1961 ON and not-self generated, and translate to Type-5's throughout the
1962 non-NSSA/STUB AS.
1963
1964 A difference in operation depends whether this ASBR is an ABR
1965 or not. If not an ABR, the P-bit is ON, to indicate that any
1966 elected NSSA-ABR can perform its translation.
1967
1968 If an ABR, the P-bit is OFF; No ABR will perform translation and
1969 this ASBR will flood the Type-5 LSA as usual.
1970
1971 For the case where this ASBR is not an ABR, the ASE calculations
1972 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
1973 demonstrate to the user that there are LSA's that belong to any
1974 attached NSSA.
1975
1976 Finally, it just so happens that when the ABR is translating every
1977 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
1978 approved Type-5 (translated from Type-7); at the end of translation
1979 if any Translated Type-5's remain unapproved, then they must be
1980 flushed from the AS.
1981
1982 */
1983
1984 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00001985 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00001986 return NULL;
1987
1988 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00001989 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00001990 {
1991 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00001992 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00001993 inet_ntoa (ei->p.prefix));
1994 return NULL;
1995 }
1996
1997 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00001998 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001999
2000 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002001 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002002
2003 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002004 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002005
paul718e3742002-12-13 20:15:29 +00002006 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002007 if (ospf->anyNSSA &&
2008 /* stay away from translated LSAs! */
2009 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002010 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002011
2012 /* Debug logging. */
2013 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2014 {
ajse588f212004-12-08 18:12:06 +00002015 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002016 new->data->type, inet_ntoa (new->data->id), new);
2017 ospf_lsa_header_dump (new->data);
2018 }
2019
2020 return new;
2021}
2022
2023/* Originate AS-external-LSA from external info with initial flag. */
2024int
paul68980082003-03-25 05:07:42 +00002025ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002026{
paul68980082003-03-25 05:07:42 +00002027 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002028 struct route_node *rn;
2029 struct external_info *ei;
2030 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002031 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002032
paul68980082003-03-25 05:07:42 +00002033 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002034
2035 /* Originate As-external-LSA from all type of distribute source. */
2036 if ((rt = EXTERNAL_INFO (type)))
2037 for (rn = route_top (rt); rn; rn = route_next (rn))
2038 if ((ei = rn->info) != NULL)
2039 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002040 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002041 zlog_warn ("LSA: AS-external-LSA was not originated.");
2042
2043 return 0;
2044}
2045
paul4dadc292005-05-06 21:37:42 +00002046static struct external_info *
paul020709f2003-04-04 02:44:16 +00002047ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002048{
2049 int type;
2050 struct route_node *rn;
2051 struct prefix_ipv4 p;
2052
2053 p.family = AF_INET;
2054 p.prefix.s_addr = 0;
2055 p.prefixlen = 0;
2056
2057 /* First, lookup redistributed default route. */
2058 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2059 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2060 {
2061 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2062 if (rn != NULL)
2063 {
2064 route_unlock_node (rn);
2065 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002066 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002067 return rn->info;
2068 }
2069 }
2070
2071 return NULL;
2072}
2073
2074int
paul68980082003-03-25 05:07:42 +00002075ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002076{
2077 int *origin;
2078 struct prefix_ipv4 p;
2079 struct in_addr nexthop;
2080 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002081 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002082
paul020709f2003-04-04 02:44:16 +00002083 ospf = ospf_lookup ();
2084
paul718e3742002-12-13 20:15:29 +00002085 /* Get originate flags. */
paul68980082003-03-25 05:07:42 +00002086 origin = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002087
2088 p.family = AF_INET;
2089 p.prefix.s_addr = 0;
2090 p.prefixlen = 0;
2091
2092 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
2093 {
2094 /* If there is no default route via redistribute,
2095 then originate AS-external-LSA with nexthop 0 (self). */
2096 nexthop.s_addr = 0;
2097 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2098 }
2099
paul020709f2003-04-04 02:44:16 +00002100 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002101 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002102
2103 return 0;
2104}
2105
paul645878f2003-04-13 21:42:11 +00002106/* Flush any NSSA LSAs for given prefix */
2107void
2108ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2109{
paul1eb8ef22005-04-07 07:30:20 +00002110 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002111 struct ospf_lsa *lsa;
2112 struct ospf_area *area;
2113
paul1eb8ef22005-04-07 07:30:20 +00002114 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002115 {
paul1eb8ef22005-04-07 07:30:20 +00002116 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002117 {
2118 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2119 ospf->router_id)))
2120 {
2121 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002122 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002123 inet_ntoa (p->prefix), p->prefixlen);
2124 continue;
2125 }
2126 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2127 if (!IS_LSA_MAXAGE (lsa))
2128 {
2129 ospf_refresher_unregister_lsa (ospf, lsa);
2130 ospf_lsa_flush_area (lsa, area);
2131 }
2132 }
paul645878f2003-04-13 21:42:11 +00002133 }
2134}
paul645878f2003-04-13 21:42:11 +00002135
paul718e3742002-12-13 20:15:29 +00002136/* Flush an AS-external-LSA from LSDB and routing domain. */
2137void
paul68980082003-03-25 05:07:42 +00002138ospf_external_lsa_flush (struct ospf *ospf,
2139 u_char type, struct prefix_ipv4 *p,
paul718e3742002-12-13 20:15:29 +00002140 unsigned int ifindex, struct in_addr nexthop)
2141{
2142 struct ospf_lsa *lsa;
2143
2144 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002145 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002146 inet_ntoa (p->prefix), p->prefixlen);
2147
2148 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002149 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002150 {
2151 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002152 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002153 inet_ntoa (p->prefix), p->prefixlen);
2154 return;
2155 }
hassobeebba72004-06-20 21:00:27 +00002156
pauld4a53d52003-07-12 21:30:57 +00002157 /* If LSA is selforiginated, not a translated LSA, and there is
2158 * NSSA area, flush Type-7 LSA's at first.
2159 */
2160 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2161 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002162 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002163
2164 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002165 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002166
2167 /* There must be no self-originated LSA in rtrs_external. */
2168#if 0
2169 /* Remove External route from Zebra. */
2170 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2171#endif
2172
2173 if (!IS_LSA_MAXAGE (lsa))
2174 {
2175 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002176 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002177
2178 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002179 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002180 }
2181
2182 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002183 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002184}
2185
2186void
paul68980082003-03-25 05:07:42 +00002187ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002188{
2189 struct prefix_ipv4 p;
2190 struct external_info *ei;
2191 struct ospf_lsa *lsa;
2192
2193 p.family = AF_INET;
2194 p.prefixlen = 0;
2195 p.prefix.s_addr = 0;
2196
paul020709f2003-04-04 02:44:16 +00002197 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002198 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002199
2200 if (ei)
2201 {
2202 if (lsa)
2203 {
2204 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002205 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002206 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002207 }
2208 else
2209 {
2210 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002211 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002212 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002213 }
2214 }
2215 else
2216 {
2217 if (lsa)
2218 {
2219 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002220 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002221 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002222 }
2223 }
2224}
2225
2226void
paul68980082003-03-25 05:07:42 +00002227ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002228{
2229 struct route_node *rn;
2230 struct external_info *ei;
2231
2232 if (type != DEFAULT_ROUTE)
2233 if (EXTERNAL_INFO(type))
2234 /* Refresh each redistributed AS-external-LSAs. */
2235 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2236 if ((ei = rn->info))
2237 if (!is_prefix_default (&ei->p))
2238 {
2239 struct ospf_lsa *lsa;
2240
paul68980082003-03-25 05:07:42 +00002241 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2242 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002243 else
paul68980082003-03-25 05:07:42 +00002244 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002245 }
2246}
2247
2248/* Refresh AS-external-LSA. */
2249void
paul68980082003-03-25 05:07:42 +00002250ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002251 struct external_info *ei, int force)
2252{
2253 struct ospf_lsa *new;
2254 int changed;
2255
2256 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002257 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002258 {
pauld4a53d52003-07-12 21:30:57 +00002259 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002260 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002261 "redist check fail",
2262 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002263 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
2264 ei->ifindex, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00002265 return;
2266 }
2267
2268 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002269 {
2270 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002271 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002272 lsa->data->type, inet_ntoa (lsa->data->id));
2273 return;
2274 }
paul718e3742002-12-13 20:15:29 +00002275
2276 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002277 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002278
2279 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002280 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002281
paul68980082003-03-25 05:07:42 +00002282 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002283
2284 if (new == NULL)
2285 {
2286 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002287 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002288 inet_ntoa (lsa->data->id));
2289 return;
2290 }
2291
2292 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2293
2294 /* Record timestamp. */
2295 gettimeofday (&new->tv_orig, NULL);
2296
2297 /* Re-calculate checksum. */
2298 ospf_lsa_checksum (new->data);
2299
paul68980082003-03-25 05:07:42 +00002300 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002301
2302 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002303 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002304
paul718e3742002-12-13 20:15:29 +00002305 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002306 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002307 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002308
pauld4a53d52003-07-12 21:30:57 +00002309 /* Register self-originated LSA to refresh queue.
2310 * Translated LSAs should not be registered, but refreshed upon
2311 * refresh of the Type-7
2312 */
2313 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2314 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002315
2316 /* Debug logging. */
2317 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2318 {
ajse588f212004-12-08 18:12:06 +00002319 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002320 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002321 ospf_lsa_header_dump (new->data);
2322 }
2323
2324 return;
2325}
2326
2327
2328/* LSA installation functions. */
2329
2330/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002331static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002332ospf_router_lsa_install (struct ospf *ospf,
2333 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002334{
2335 struct ospf_area *area = new->area;
2336
2337 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2338 The entire routing table must be recalculated, starting with
2339 the shortest path calculations for each area (not just the
2340 area whose link-state database has changed).
2341 */
2342 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002343 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002344
2345 if (IS_LSA_SELF (new))
2346 {
2347 /* Set router-LSA refresh timer. */
2348 OSPF_TIMER_OFF (area->t_router_lsa_self);
2349 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002350 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002351
2352 /* Set self-originated router-LSA. */
2353 ospf_lsa_unlock (area->router_lsa_self);
2354 area->router_lsa_self = ospf_lsa_lock (new);
2355
2356 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002357 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002358 new->data->type, inet_ntoa (new->data->id),
2359 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002360 }
2361
2362 return new;
2363}
2364
2365#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2366 if (!(T)) \
2367 (T) = thread_add_timer (master, (F), oi, (V))
2368
2369/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002370static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002371ospf_network_lsa_install (struct ospf *ospf,
2372 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002373 struct ospf_lsa *new,
2374 int rt_recalc)
2375{
2376
2377 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2378 The entire routing table must be recalculated, starting with
2379 the shortest path calculations for each area (not just the
2380 area whose link-state database has changed).
2381 */
2382 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002383 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002384
2385 /* We supposed that when LSA is originated by us, we pass the int
2386 for which it was originated. If LSA was received by flooding,
2387 the RECEIVED flag is set, so we do not link the LSA to the int. */
2388 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2389 {
2390 /* Set LSRefresh timer. */
2391 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2392
2393 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2394 ospf_network_lsa_refresh_timer,
2395 OSPF_LS_REFRESH_TIME);
2396
2397 ospf_lsa_unlock (oi->network_lsa_self);
2398 oi->network_lsa_self = ospf_lsa_lock (new);
2399 }
2400
2401 return new;
2402}
2403
2404/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002405static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002406ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2407 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002408{
paul718e3742002-12-13 20:15:29 +00002409 if (rt_recalc && !IS_LSA_SELF (new))
2410 {
2411 /* RFC 2328 Section 13.2 Summary-LSAs
2412 The best route to the destination described by the summary-
2413 LSA must be recalculated (see Section 16.5). If this
2414 destination is an AS boundary router, it may also be
2415 necessary to re-examine all the AS-external-LSAs.
2416 */
2417
2418#if 0
2419 /* This doesn't exist yet... */
2420 ospf_summary_incremental_update(new); */
2421#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002422 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002423#endif /* #if 0 */
2424
2425 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002426 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002427 }
2428
2429 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002430 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002431
2432 return new;
2433}
2434
2435/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002436static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002437ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2438 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002439{
2440 if (rt_recalc && !IS_LSA_SELF (new))
2441 {
2442 /* RFC 2328 Section 13.2 Summary-LSAs
2443 The best route to the destination described by the summary-
2444 LSA must be recalculated (see Section 16.5). If this
2445 destination is an AS boundary router, it may also be
2446 necessary to re-examine all the AS-external-LSAs.
2447 */
2448#if 0
2449 /* These don't exist yet... */
2450 ospf_summary_incremental_update(new);
2451 /* Isn't this done by the above call?
2452 - RFC 2328 Section 16.5 implies it should be */
2453 /* ospf_ase_calculate_schedule(); */
2454#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002455 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002456#endif /* #if 0 */
2457 }
2458
2459 /* register LSA to refresh-list. */
2460 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002461 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002462
2463 return new;
2464}
2465
2466/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002467static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002468ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2469 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002470{
paul68980082003-03-25 05:07:42 +00002471 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002472 /* If LSA is not self-originated, calculate an external route. */
2473 if (rt_recalc)
2474 {
2475 /* RFC 2328 Section 13.2 AS-external-LSAs
2476 The best route to the destination described by the AS-
2477 external-LSA must be recalculated (see Section 16.6).
2478 */
2479
2480 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002481 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002482 }
2483
pauld4a53d52003-07-12 21:30:57 +00002484 if (new->data->type == OSPF_AS_NSSA_LSA)
2485 {
2486 /* There is no point to register selforiginate Type-7 LSA for
2487 * refreshing. We rely on refreshing Type-5 LSA's
2488 */
2489 if (IS_LSA_SELF (new))
2490 return new;
2491 else
2492 {
2493 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2494 * New translations will be taken care of by the abr_task.
2495 */
2496 ospf_translated_nssa_refresh (ospf, new, NULL);
2497 }
2498 }
pauld7480322003-05-16 17:31:51 +00002499
pauld4a53d52003-07-12 21:30:57 +00002500 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002501 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002502 */
hassobeebba72004-06-20 21:00:27 +00002503 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002504 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002505
2506 return new;
2507}
2508
2509void
paul68980082003-03-25 05:07:42 +00002510ospf_discard_from_db (struct ospf *ospf,
2511 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002512{
2513 struct ospf_lsa *old;
2514
2515 old = ospf_lsdb_lookup (lsdb, lsa);
2516
2517 if (!old)
2518 return;
2519
2520 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002521 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002522
2523 switch (old->data->type)
2524 {
2525 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002526 ospf_ase_unregister_external_lsa (old, ospf);
2527 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2528 break;
paul718e3742002-12-13 20:15:29 +00002529#ifdef HAVE_OPAQUE_LSA
2530 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002531 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002532 break;
paul69310a62005-05-11 18:09:59 +00002533#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002534 case OSPF_AS_NSSA_LSA:
2535 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2536 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002537 break;
paul718e3742002-12-13 20:15:29 +00002538 default:
paul68980082003-03-25 05:07:42 +00002539 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002540 break;
2541 }
2542
paul68980082003-03-25 05:07:42 +00002543 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002544 ospf_lsa_discard (old);
2545}
2546
paul718e3742002-12-13 20:15:29 +00002547struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002548ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2549 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002550{
2551 struct ospf_lsa *new = NULL;
2552 struct ospf_lsa *old = NULL;
2553 struct ospf_lsdb *lsdb = NULL;
2554 int rt_recalc;
2555
2556 /* Set LSDB. */
2557 switch (lsa->data->type)
2558 {
paulf2c80652002-12-13 21:44:27 +00002559 /* kevinm */
2560 case OSPF_AS_NSSA_LSA:
2561 if (lsa->area)
2562 lsdb = lsa->area->lsdb;
2563 else
paul68980082003-03-25 05:07:42 +00002564 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002565 break;
paul718e3742002-12-13 20:15:29 +00002566 case OSPF_AS_EXTERNAL_LSA:
2567#ifdef HAVE_OPAQUE_LSA
2568 case OSPF_OPAQUE_AS_LSA:
2569#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002570 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002571 break;
2572 default:
2573 lsdb = lsa->area->lsdb;
2574 break;
2575 }
2576
paul718e3742002-12-13 20:15:29 +00002577 assert (lsdb);
2578
2579 /* RFC 2328 13.2. Installing LSAs in the database
2580
2581 Installing a new LSA in the database, either as the result of
2582 flooding or a newly self-originated LSA, may cause the OSPF
2583 routing table structure to be recalculated. The contents of the
2584 new LSA should be compared to the old instance, if present. If
2585 there is no difference, there is no need to recalculate the
2586 routing table. When comparing an LSA to its previous instance,
2587 the following are all considered to be differences in contents:
2588
2589 o The LSA's Options field has changed.
2590
2591 o One of the LSA instances has LS age set to MaxAge, and
2592 the other does not.
2593
2594 o The length field in the LSA header has changed.
2595
2596 o The body of the LSA (i.e., anything outside the 20-byte
2597 LSA header) has changed. Note that this excludes changes
2598 in LS Sequence Number and LS Checksum.
2599
2600 */
2601 /* Look up old LSA and determine if any SPF calculation or incremental
2602 update is needed */
2603 old = ospf_lsdb_lookup (lsdb, lsa);
2604
2605 /* Do comparision and record if recalc needed. */
2606 rt_recalc = 0;
2607 if ( old == NULL || ospf_lsa_different(old, lsa))
2608 rt_recalc = 1;
2609
paul7ddf1d62003-10-13 09:06:46 +00002610 /*
2611 Sequence number check (Section 14.1 of rfc 2328)
2612 "Premature aging is used when it is time for a self-originated
2613 LSA's sequence number field to wrap. At this point, the current
2614 LSA instance (having LS sequence number MaxSequenceNumber) must
2615 be prematurely aged and flushed from the routing domain before a
2616 new instance with sequence number equal to InitialSequenceNumber
2617 can be originated. "
2618 */
2619
paul553ff112004-06-06 09:41:00 +00002620 if (ntohl(lsa->data->ls_seqnum) - 1 == htonl(OSPF_MAX_SEQUENCE_NUMBER))
paul7ddf1d62003-10-13 09:06:46 +00002621 {
2622 if (ospf_lsa_is_self_originated(ospf, lsa))
2623 {
paul0c2be262004-05-31 14:16:54 +00002624 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2625
2626 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002627 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2628 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2629
2630 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2631 {
ajse588f212004-12-08 18:12:06 +00002632 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002633 "lsa 0x%lx", (u_long)lsa);
2634 ospf_lsa_header_dump (lsa->data);
2635 }
2636 }
2637 else
2638 {
2639 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2640 {
ajse588f212004-12-08 18:12:06 +00002641 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002642 "that was not self originated. Ignoring\n");
2643 ospf_lsa_header_dump (lsa->data);
2644 }
2645 return old;
2646 }
2647 }
2648
paul718e3742002-12-13 20:15:29 +00002649 /* discard old LSA from LSDB */
2650 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002651 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002652
paul718e3742002-12-13 20:15:29 +00002653 /* Calculate Checksum if self-originated?. */
2654 if (IS_LSA_SELF (lsa))
2655 ospf_lsa_checksum (lsa->data);
2656
hassofe71a972004-12-22 16:16:02 +00002657 /* Insert LSA to LSDB. */
2658 ospf_lsdb_add (lsdb, lsa);
2659 lsa->lsdb = lsdb;
2660
paul718e3742002-12-13 20:15:29 +00002661 /* Do LSA specific installation process. */
2662 switch (lsa->data->type)
2663 {
2664 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002665 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002666 break;
2667 case OSPF_NETWORK_LSA:
2668 assert (oi);
paul68980082003-03-25 05:07:42 +00002669 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002670 break;
2671 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002672 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002673 break;
2674 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002675 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002676 break;
2677 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002678 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002679 break;
2680#ifdef HAVE_OPAQUE_LSA
2681 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002682 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002683 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002684 else
paul68980082003-03-25 05:07:42 +00002685 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002686 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002687 case OSPF_OPAQUE_AREA_LSA:
2688 case OSPF_OPAQUE_AS_LSA:
2689 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2690 break;
2691#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002692 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002693 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002694 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002695 break;
2696 }
2697
2698 if (new == NULL)
2699 return new; /* Installation failed, cannot proceed further -- endo. */
2700
2701 /* Debug logs. */
2702 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2703 {
2704 char area_str[INET_ADDRSTRLEN];
2705
2706 switch (lsa->data->type)
2707 {
2708 case OSPF_AS_EXTERNAL_LSA:
2709#ifdef HAVE_OPAQUE_LSA
2710 case OSPF_OPAQUE_AS_LSA:
2711#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002712 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002713 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002714 dump_lsa_key (new),
2715 LOOKUP (ospf_lsa_type_msg, new->data->type));
2716 break;
2717 default:
2718 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002719 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002720 dump_lsa_key (new),
2721 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2722 break;
2723 }
2724 }
2725
paul7ddf1d62003-10-13 09:06:46 +00002726 /*
2727 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2728 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2729 */
2730 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2731 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002732 {
paul7ddf1d62003-10-13 09:06:46 +00002733 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002734 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002735 new->data->type,
2736 inet_ntoa (new->data->id),
2737 lsa);
paul68980082003-03-25 05:07:42 +00002738 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002739 }
2740
2741 return new;
2742}
2743
2744
paul4dadc292005-05-06 21:37:42 +00002745static int
paul68980082003-03-25 05:07:42 +00002746ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002747{
paul1eb8ef22005-04-07 07:30:20 +00002748 struct listnode *node, *nnode;
2749 struct ospf_interface *oi;
2750
2751 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002752 {
paul718e3742002-12-13 20:15:29 +00002753 struct route_node *rn;
2754 struct ospf_neighbor *nbr;
2755
2756 if (ospf_if_is_enable (oi))
2757 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2758 if ((nbr = rn->info) != NULL)
2759 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2760 {
2761 route_unlock_node (rn);
2762 return 0;
2763 }
2764 }
2765
2766 return 1;
2767}
2768
2769
2770#ifdef ORIGINAL_CODING
2771/* This function flood the maxaged LSA to DR. */
2772void
2773ospf_maxage_flood (struct ospf_lsa *lsa)
2774{
2775 switch (lsa->data->type)
2776 {
2777 case OSPF_ROUTER_LSA:
2778 case OSPF_NETWORK_LSA:
2779 case OSPF_SUMMARY_LSA:
2780 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002781 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002782#ifdef HAVE_OPAQUE_LSA
2783 case OSPF_OPAQUE_LINK_LSA:
2784 case OSPF_OPAQUE_AREA_LSA:
2785#endif /* HAVE_OPAQUE_LSA */
2786 ospf_flood_through_area (lsa->area, NULL, lsa);
2787 break;
2788 case OSPF_AS_EXTERNAL_LSA:
2789#ifdef HAVE_OPAQUE_LSA
2790 case OSPF_OPAQUE_AS_LSA:
2791#endif /* HAVE_OPAQUE_LSA */
2792 ospf_flood_through_as (NULL, lsa);
2793 break;
2794 default:
2795 break;
2796 }
2797}
2798#endif /* ORIGINAL_CODING */
2799
paul4dadc292005-05-06 21:37:42 +00002800static int
paul718e3742002-12-13 20:15:29 +00002801ospf_maxage_lsa_remover (struct thread *thread)
2802{
paul68980082003-03-25 05:07:42 +00002803 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002804 struct ospf_lsa *lsa;
2805 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002806 int reschedule = 0;
2807
paul68980082003-03-25 05:07:42 +00002808 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002809
2810 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002811 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002812
paul68980082003-03-25 05:07:42 +00002813 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002814
2815 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002816 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002817 {
paul718e3742002-12-13 20:15:29 +00002818 if (lsa->retransmit_counter > 0)
2819 {
2820 reschedule = 1;
2821 continue;
2822 }
2823
2824 /* Remove LSA from the LSDB */
2825 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2826 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002827 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002828 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002829
2830 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002831 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002832 lsa->data->type, inet_ntoa (lsa->data->id));
2833
2834 /* Flood max age LSA. */
2835#ifdef ORIGINAL_CODING
2836 ospf_maxage_flood (lsa);
2837#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002838 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002839#endif /* ORIGINAL_CODING */
2840
paul7ddf1d62003-10-13 09:06:46 +00002841 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2842 {
2843 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002844 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002845 (u_long)lsa);
2846 ospf_router_lsa_originate(lsa->area);
2847 }
2848
paul718e3742002-12-13 20:15:29 +00002849 /* Remove from lsdb. */
paul68980082003-03-25 05:07:42 +00002850 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002851 ospf_lsdb_delete (lsa->lsdb, lsa);
2852 }
2853
2854 /* A MaxAge LSA must be removed immediately from the router's link
2855 state database as soon as both a) it is no longer contained on any
2856 neighbor Link state retransmission lists and b) none of the router's
2857 neighbors are in states Exchange or Loading. */
2858 if (reschedule)
paul68980082003-03-25 05:07:42 +00002859 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002860
2861 return 0;
2862}
2863
paul4dadc292005-05-06 21:37:42 +00002864static int
paul68980082003-03-25 05:07:42 +00002865ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002866{
hasso52dc7ee2004-09-23 19:18:23 +00002867 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00002868 struct ospf_lsa *lsa;
2869
2870 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
2871 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00002872 return 1;
2873
2874 return 0;
2875}
2876
2877void
paul68980082003-03-25 05:07:42 +00002878ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002879{
hasso52dc7ee2004-09-23 19:18:23 +00002880 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002881
paul68980082003-03-25 05:07:42 +00002882 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002883 {
paul68980082003-03-25 05:07:42 +00002884 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00002885 ospf_lsa_unlock (lsa);
2886 }
2887}
2888
2889void
paul68980082003-03-25 05:07:42 +00002890ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002891{
2892 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2893 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00002894 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002895 {
2896 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002897 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002898 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2899 return;
2900 }
2901
paul68980082003-03-25 05:07:42 +00002902 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00002903
2904 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002905 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002906
paul68980082003-03-25 05:07:42 +00002907 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002908}
2909
paul4dadc292005-05-06 21:37:42 +00002910static int
paul68980082003-03-25 05:07:42 +00002911ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002912{
paul718e3742002-12-13 20:15:29 +00002913 /* Stay away from any Local Translated Type-7 LSAs */
2914 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2915 return 0;
paul718e3742002-12-13 20:15:29 +00002916
2917 if (IS_LSA_MAXAGE (lsa))
2918 /* Self-originated LSAs should NOT time-out instead,
2919 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002920 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002921 {
2922 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002923 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002924
2925 switch (lsa->data->type)
2926 {
paul718e3742002-12-13 20:15:29 +00002927#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002928 case OSPF_OPAQUE_LINK_LSA:
2929 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002930 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002931 /*
2932 * As a general rule, whenever network topology has changed
2933 * (due to an LSA removal in this case), routing recalculation
2934 * should be triggered. However, this is not true for opaque
2935 * LSAs. Even if an opaque LSA instance is going to be removed
2936 * from the routing domain, it does not mean a change in network
2937 * topology, and thus, routing recalculation is not needed here.
2938 */
2939 break;
paul718e3742002-12-13 20:15:29 +00002940#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002941 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002942 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002943 ospf_ase_incremental_update (ospf, lsa);
2944 break;
paul718e3742002-12-13 20:15:29 +00002945 default:
paul68980082003-03-25 05:07:42 +00002946 ospf_spf_calculate_schedule (ospf);
2947 break;
paul718e3742002-12-13 20:15:29 +00002948 }
paul68980082003-03-25 05:07:42 +00002949 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002950 }
2951
2952 return 0;
2953}
2954
2955/* Periodical check of MaxAge LSA. */
2956int
paul68980082003-03-25 05:07:42 +00002957ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002958{
paul68980082003-03-25 05:07:42 +00002959 struct ospf *ospf = THREAD_ARG (thread);
2960 struct route_node *rn;
2961 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00002962 struct ospf_area *area;
2963 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002964
paul68980082003-03-25 05:07:42 +00002965 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002966
paul1eb8ef22005-04-07 07:30:20 +00002967 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00002968 {
paul68980082003-03-25 05:07:42 +00002969 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2970 ospf_lsa_maxage_walker_remover (ospf, lsa);
2971 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2972 ospf_lsa_maxage_walker_remover (ospf, lsa);
2973 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2974 ospf_lsa_maxage_walker_remover (ospf, lsa);
2975 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2976 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002977#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002978 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2979 ospf_lsa_maxage_walker_remover (ospf, lsa);
2980 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2981 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002982#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00002983 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
2984 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002985 }
2986
paul4fb949e2003-05-10 20:06:51 +00002987 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00002988 if (ospf->lsdb)
2989 {
2990 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2991 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002992#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002993 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
2994 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002995#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002996 }
paul718e3742002-12-13 20:15:29 +00002997
paul68980082003-03-25 05:07:42 +00002998 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
2999 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003000 return 0;
3001}
3002
paul68980082003-03-25 05:07:42 +00003003struct ospf_lsa *
3004ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3005 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003006{
paul68980082003-03-25 05:07:42 +00003007 struct ospf_lsa *lsa;
3008 struct in_addr mask, id;
3009 struct lsa_header_mask
3010 {
3011 struct lsa_header header;
3012 struct in_addr mask;
3013 } *hmask;
paul718e3742002-12-13 20:15:29 +00003014
paul68980082003-03-25 05:07:42 +00003015 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3016 if (lsa == NULL)
3017 return NULL;
paul718e3742002-12-13 20:15:29 +00003018
paul68980082003-03-25 05:07:42 +00003019 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003020
paul68980082003-03-25 05:07:42 +00003021 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003022
paul68980082003-03-25 05:07:42 +00003023 if (mask.s_addr != hmask->mask.s_addr)
3024 {
3025 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3026 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3027 if (!lsa)
3028 return NULL;
3029 }
paul718e3742002-12-13 20:15:29 +00003030
paul68980082003-03-25 05:07:42 +00003031 return lsa;
paul718e3742002-12-13 20:15:29 +00003032}
3033
3034struct ospf_lsa *
3035ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3036 struct in_addr id, struct in_addr adv_router)
3037{
paule05fba42003-04-13 20:20:53 +00003038 struct ospf *ospf = ospf_lookup();
3039 assert(ospf);
3040
paul718e3742002-12-13 20:15:29 +00003041 switch (type)
3042 {
3043 case OSPF_ROUTER_LSA:
3044 case OSPF_NETWORK_LSA:
3045 case OSPF_SUMMARY_LSA:
3046 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003047 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003048#ifdef HAVE_OPAQUE_LSA
3049 case OSPF_OPAQUE_LINK_LSA:
3050 case OSPF_OPAQUE_AREA_LSA:
3051#endif /* HAVE_OPAQUE_LSA */
3052 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
3053 break;
3054 case OSPF_AS_EXTERNAL_LSA:
3055#ifdef HAVE_OPAQUE_LSA
3056 case OSPF_OPAQUE_AS_LSA:
3057#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003058 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003059 break;
3060 default:
3061 break;
3062 }
3063
3064 return NULL;
3065}
3066
3067struct ospf_lsa *
3068ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3069 struct in_addr id)
3070{
3071 struct ospf_lsa *lsa;
3072 struct route_node *rn;
3073
3074 switch (type)
3075 {
3076 case OSPF_ROUTER_LSA:
3077 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3078 break;
3079 case OSPF_NETWORK_LSA:
3080 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3081 if ((lsa = rn->info))
3082 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3083 {
3084 route_unlock_node (rn);
3085 return lsa;
3086 }
3087 break;
3088 case OSPF_SUMMARY_LSA:
3089 case OSPF_ASBR_SUMMARY_LSA:
3090 /* Currently not used. */
3091 assert (1);
3092 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3093 break;
3094 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003095 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003096#ifdef HAVE_OPAQUE_LSA
3097 case OSPF_OPAQUE_LINK_LSA:
3098 case OSPF_OPAQUE_AREA_LSA:
3099 case OSPF_OPAQUE_AS_LSA:
3100 /* Currently not used. */
3101 break;
3102#endif /* HAVE_OPAQUE_LSA */
3103 default:
3104 break;
3105 }
3106
3107 return NULL;
3108}
3109
3110struct ospf_lsa *
3111ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3112{
3113 struct ospf_lsa *match;
3114
3115#ifdef HAVE_OPAQUE_LSA
3116 /*
3117 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3118 * is redefined to have two subfields; opaque-type and opaque-id.
3119 * However, it is harmless to treat the two sub fields together, as if
3120 * they two were forming a unique LSA-ID.
3121 */
3122#endif /* HAVE_OPAQUE_LSA */
3123
3124 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3125
3126 if (match == NULL)
3127 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003128 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003129 lsah->type, inet_ntoa (lsah->id));
3130
3131 return match;
3132}
3133
3134/* return +n, l1 is more recent.
3135 return -n, l2 is more recent.
3136 return 0, l1 and l2 is identical. */
3137int
3138ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3139{
3140 int r;
3141 int x, y;
3142
3143 if (l1 == NULL && l2 == NULL)
3144 return 0;
3145 if (l1 == NULL)
3146 return -1;
3147 if (l2 == NULL)
3148 return 1;
3149
3150 /* compare LS sequence number. */
3151 x = (int) ntohl (l1->data->ls_seqnum);
3152 y = (int) ntohl (l2->data->ls_seqnum);
3153 if (x > y)
3154 return 1;
3155 if (x < y)
3156 return -1;
3157
3158 /* compare LS checksum. */
3159 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3160 if (r)
3161 return r;
3162
3163 /* compare LS age. */
3164 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3165 return 1;
3166 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3167 return -1;
3168
3169 /* compare LS age with MaxAgeDiff. */
3170 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3171 return -1;
3172 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3173 return 1;
3174
3175 /* LSAs are identical. */
3176 return 0;
3177}
3178
3179/* If two LSAs are different, return 1, otherwise return 0. */
3180int
3181ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3182{
3183 char *p1, *p2;
3184 assert (l1);
3185 assert (l2);
3186 assert (l1->data);
3187 assert (l2->data);
3188
3189 if (l1->data->options != l2->data->options)
3190 return 1;
3191
3192 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3193 return 1;
3194
3195 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3196 return 1;
3197
3198 if (l1->data->length != l2->data->length)
3199 return 1;
3200
3201 if (l1->data->length == 0)
3202 return 1;
3203
pauld1825832003-04-03 01:27:01 +00003204 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003205
3206 p1 = (char *) l1->data;
3207 p2 = (char *) l2->data;
3208
3209 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3210 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3211 return 1;
3212
3213 return 0;
3214}
3215
3216#ifdef ORIGINAL_CODING
3217void
3218ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3219 struct ospf_lsa *self,
3220 struct ospf_lsa *new)
3221{
3222 u_int32_t seqnum;
3223
3224 /* Adjust LS Sequence Number. */
3225 seqnum = ntohl (new->data->ls_seqnum) + 1;
3226 self->data->ls_seqnum = htonl (seqnum);
3227
3228 /* Recalculate LSA checksum. */
3229 ospf_lsa_checksum (self->data);
3230
3231 /* Reflooding LSA. */
3232 /* RFC2328 Section 13.3
3233 On non-broadcast networks, separate Link State Update
3234 packets must be sent, as unicasts, to each adjacent neighbor
3235 (i.e., those in state Exchange or greater). The destination
3236 IP addresses for these packets are the neighbors' IP
3237 addresses. */
3238 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3239 {
3240 struct route_node *rn;
3241 struct ospf_neighbor *onbr;
3242
3243 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3244 if ((onbr = rn->info) != NULL)
3245 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3246 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3247 }
3248 else
3249 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3250
3251 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003252 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003253 self->data->type, inet_ntoa (self->data->id));
3254}
3255#else /* ORIGINAL_CODING */
3256static int
paul68980082003-03-25 05:07:42 +00003257ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003258{
3259 if (lsa == NULL || !IS_LSA_SELF (lsa))
3260 return 0;
3261
3262 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003263 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003264
3265 /* Force given lsa's age to MaxAge. */
3266 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3267
3268 switch (lsa->data->type)
3269 {
3270#ifdef HAVE_OPAQUE_LSA
3271 case OSPF_OPAQUE_LINK_LSA:
3272 case OSPF_OPAQUE_AREA_LSA:
3273 case OSPF_OPAQUE_AS_LSA:
3274 ospf_opaque_lsa_refresh (lsa);
3275 break;
3276#endif /* HAVE_OPAQUE_LSA */
3277 default:
paul68980082003-03-25 05:07:42 +00003278 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003279 break;
3280 }
3281
3282 return 0;
3283}
3284
3285void
paul68980082003-03-25 05:07:42 +00003286ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003287{
paul1eb8ef22005-04-07 07:30:20 +00003288 struct listnode *node, *nnode;
3289 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003290 struct ospf_area *area;
3291 struct ospf_interface *oi;
3292 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003293 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003294 int need_to_flush_ase = 0;
3295
paul1eb8ef22005-04-07 07:30:20 +00003296 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003297 {
paul718e3742002-12-13 20:15:29 +00003298 if ((lsa = area->router_lsa_self) != NULL)
3299 {
3300 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003301 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003302
3303 ospf_lsa_flush_area (lsa, area);
3304 ospf_lsa_unlock (area->router_lsa_self);
3305 area->router_lsa_self = NULL;
3306 OSPF_TIMER_OFF (area->t_router_lsa_self);
3307 }
3308
paul1eb8ef22005-04-07 07:30:20 +00003309 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003310 {
paul718e3742002-12-13 20:15:29 +00003311 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003312 && oi->state == ISM_DR
3313 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003314 {
3315 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003316 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003317
3318 ospf_lsa_flush_area (oi->network_lsa_self, area);
3319 ospf_lsa_unlock (oi->network_lsa_self);
3320 oi->network_lsa_self = NULL;
3321 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3322 }
3323
3324 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3325 && area->external_routing == OSPF_AREA_DEFAULT)
3326 need_to_flush_ase = 1;
3327 }
3328
paul68980082003-03-25 05:07:42 +00003329 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3330 ospf_lsa_flush_schedule (ospf, lsa);
3331 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3332 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003333#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003334 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3335 ospf_lsa_flush_schedule (ospf, lsa);
3336 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3337 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003338#endif /* HAVE_OPAQUE_LSA */
3339 }
3340
3341 if (need_to_flush_ase)
3342 {
paul68980082003-03-25 05:07:42 +00003343 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3344 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003345#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003346 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3347 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003348#endif /* HAVE_OPAQUE_LSA */
3349 }
3350
3351 /*
3352 * Make sure that the MaxAge LSA remover is executed immediately,
3353 * without conflicting to other threads.
3354 */
paul68980082003-03-25 05:07:42 +00003355 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003356 {
paul68980082003-03-25 05:07:42 +00003357 OSPF_TIMER_OFF (ospf->t_maxage);
3358 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003359 }
3360
3361 return;
3362}
3363#endif /* ORIGINAL_CODING */
3364
3365/* If there is self-originated LSA, then return 1, otherwise return 0. */
3366/* An interface-independent version of ospf_lsa_is_self_originated */
3367int
paul68980082003-03-25 05:07:42 +00003368ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003369{
hasso52dc7ee2004-09-23 19:18:23 +00003370 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003371 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003372
3373 /* This LSA is already checked. */
3374 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3375 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3376
3377 /* Make sure LSA is self-checked. */
3378 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3379
3380 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003381 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003382 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3383
3384 /* LSA is router-LSA. */
3385 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003386 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003387 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3388
3389 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3390 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003391 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003392 {
paul718e3742002-12-13 20:15:29 +00003393 /* Ignore virtual link. */
3394 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3395 if (oi->address->family == AF_INET)
3396 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3397 {
3398 /* to make it easier later */
3399 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3400 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3401 }
3402 }
3403
3404 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3405}
3406
3407/* Get unique Link State ID. */
3408struct in_addr
paul68980082003-03-25 05:07:42 +00003409ospf_lsa_unique_id (struct ospf *ospf,
3410 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003411{
3412 struct ospf_lsa *lsa;
3413 struct in_addr mask, id;
3414
3415 id = p->prefix;
3416
3417 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003418 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003419 if (lsa)
3420 {
3421 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3422 if (ip_masklen (al->mask) == p->prefixlen)
3423 {
3424 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003425 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003426 "Can't get Link State ID for %s/%d",
3427 inet_ntoa (p->prefix), p->prefixlen);
3428 /* id.s_addr = 0; */
3429 id.s_addr = 0xffffffff;
3430 return id;
3431 }
3432 /* Masklen differs, then apply wildcard mask to Link State ID. */
3433 else
3434 {
3435 masklen2ip (p->prefixlen, &mask);
3436
3437 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003438 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3439 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003440 if (lsa)
3441 {
3442 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003443 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003444 "Can't get Link State ID for %s/%d",
3445 inet_ntoa (p->prefix), p->prefixlen);
3446 /* id.s_addr = 0; */
3447 id.s_addr = 0xffffffff;
3448 return id;
3449 }
3450 }
3451 }
3452
3453 return id;
3454}
3455
3456
3457#define LSA_ACTION_ORIGN_RTR 1
3458#define LSA_ACTION_ORIGN_NET 2
3459#define LSA_ACTION_FLOOD_AREA 3
3460#define LSA_ACTION_FLOOD_AS 4
3461#define LSA_ACTION_FLUSH_AREA 5
3462#define LSA_ACTION_FLUSH_AS 6
3463
3464struct lsa_action
3465{
3466 u_char action;
3467 struct ospf_area *area;
3468 struct ospf_interface *oi;
3469 struct ospf_lsa *lsa;
3470};
3471
paul4dadc292005-05-06 21:37:42 +00003472static int
paul718e3742002-12-13 20:15:29 +00003473ospf_lsa_action (struct thread *t)
3474{
3475 struct lsa_action *data;
paul020709f2003-04-04 02:44:16 +00003476 struct ospf *ospf;
3477
3478 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00003479
3480 data = THREAD_ARG (t);
3481
3482 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003483 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003484 data->action);
3485
3486 switch (data->action)
3487 {
3488 case LSA_ACTION_ORIGN_RTR:
3489 ospf_router_lsa_refresh (data->area->router_lsa_self);
3490 break;
3491 case LSA_ACTION_ORIGN_NET:
3492 ospf_network_lsa_originate (data->oi);
3493 break;
3494 case LSA_ACTION_FLOOD_AREA:
3495 ospf_flood_through_area (data->area, NULL, data->lsa);
3496 break;
3497 case LSA_ACTION_FLOOD_AS:
paul68980082003-03-25 05:07:42 +00003498 ospf_flood_through_as (ospf, NULL, data->lsa);
paul718e3742002-12-13 20:15:29 +00003499 break;
3500 case LSA_ACTION_FLUSH_AREA:
3501 ospf_lsa_flush_area (data->lsa, data->area);
3502 break;
3503 case LSA_ACTION_FLUSH_AS:
paul68980082003-03-25 05:07:42 +00003504 ospf_lsa_flush_as (ospf, data->lsa);
paul718e3742002-12-13 20:15:29 +00003505 break;
3506 }
3507
3508 ospf_lsa_unlock (data->lsa);
3509 XFREE (MTYPE_OSPF_MESSAGE, data);
3510 return 0;
3511}
3512
3513void
3514ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3515{
3516 struct lsa_action *data;
3517
3518 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3519 memset (data, 0, sizeof (struct lsa_action));
3520
3521 data->action = LSA_ACTION_FLOOD_AREA;
3522 data->area = area;
3523 data->lsa = ospf_lsa_lock (lsa);
3524
3525 thread_add_event (master, ospf_lsa_action, data, 0);
3526}
3527
3528void
3529ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3530{
3531 struct lsa_action *data;
3532
3533 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3534 memset (data, 0, sizeof (struct lsa_action));
3535
3536 data->action = LSA_ACTION_FLUSH_AREA;
3537 data->area = area;
3538 data->lsa = ospf_lsa_lock (lsa);
3539
3540 thread_add_event (master, ospf_lsa_action, data, 0);
3541}
3542
3543
3544/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003545static void
paul68980082003-03-25 05:07:42 +00003546ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003547{
3548 struct external_info *ei;
3549 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3550
3551 switch (lsa->data->type)
3552 {
3553 /* Router and Network LSAs are processed differently. */
3554 case OSPF_ROUTER_LSA:
3555 case OSPF_NETWORK_LSA:
3556 break;
3557 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003558 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003559 break;
3560 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003561 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003562 break;
3563 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003564 /* Translated from NSSA Type-5s are refreshed when
3565 * from refresh of Type-7 - do not refresh these directly.
3566 */
3567 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3568 break;
paul718e3742002-12-13 20:15:29 +00003569 ei = ospf_external_info_check (lsa);
3570 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003571 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003572 else
pauld4a53d52003-07-12 21:30:57 +00003573 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003574 break;
3575#ifdef HAVE_OPAQUE_LSA
3576 case OSPF_OPAQUE_LINK_LSA:
3577 case OSPF_OPAQUE_AREA_LSA:
3578 case OSPF_OPAQUE_AS_LSA:
3579 ospf_opaque_lsa_refresh (lsa);
3580 break;
pauld7480322003-05-16 17:31:51 +00003581#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003582 default:
3583 break;
paul718e3742002-12-13 20:15:29 +00003584 }
3585}
3586
3587void
paul68980082003-03-25 05:07:42 +00003588ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003589{
3590 u_int16_t index, current_index;
3591
3592 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3593
3594 if (lsa->refresh_list < 0)
3595 {
3596 int delay;
3597
3598 if (LS_AGE (lsa) == 0 &&
3599 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3600 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3601 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3602 else
3603 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3604 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3605 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3606
3607 if (delay < 0)
3608 delay = 0;
3609
paul68980082003-03-25 05:07:42 +00003610 current_index = ospf->lsa_refresh_queue.index +
3611 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003612
3613 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3614 % (OSPF_LSA_REFRESHER_SLOTS);
3615
3616 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003617 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003618 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003619 if (!ospf->lsa_refresh_queue.qs[index])
3620 ospf->lsa_refresh_queue.qs[index] = list_new ();
3621 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003622 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003623 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003624 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003625 "setting refresh_list on lsa %p (slod %d)",
3626 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003627 }
3628}
3629
3630void
paul68980082003-03-25 05:07:42 +00003631ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003632{
3633 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3634 if (lsa->refresh_list >= 0)
3635 {
hasso52dc7ee2004-09-23 19:18:23 +00003636 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003637 listnode_delete (refresh_list, lsa);
3638 if (!listcount (refresh_list))
3639 {
3640 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003641 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003642 }
3643 ospf_lsa_unlock (lsa);
3644 lsa->refresh_list = -1;
3645 }
3646}
3647
3648int
3649ospf_lsa_refresh_walker (struct thread *t)
3650{
hasso52dc7ee2004-09-23 19:18:23 +00003651 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003652 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003653 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003654 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003655 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003656 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003657
3658 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003659 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003660
3661
paul68980082003-03-25 05:07:42 +00003662 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003663
ajs9dbc7972005-03-13 19:27:22 +00003664 /* Note: if clock has jumped backwards, then time change could be negative,
3665 so we are careful to cast the expression to unsigned before taking
3666 modulus. */
paul68980082003-03-25 05:07:42 +00003667 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003668 ((unsigned long)(ospf->lsa_refresh_queue.index +
3669 (time (NULL) - ospf->lsa_refresher_started) /
3670 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003671
3672 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003673 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003674 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003675
paul68980082003-03-25 05:07:42 +00003676 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003677 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3678 {
3679 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003680 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003681 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003682
paul68980082003-03-25 05:07:42 +00003683 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003684
paul68980082003-03-25 05:07:42 +00003685 ospf->lsa_refresh_queue.qs [i] = NULL;
3686
paul718e3742002-12-13 20:15:29 +00003687 if (refresh_list)
3688 {
paul1eb8ef22005-04-07 07:30:20 +00003689 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003690 {
paul718e3742002-12-13 20:15:29 +00003691 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003692 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003693 "refresh lsa %p (slot %d)",
3694 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003695
3696 list_delete_node (refresh_list, node);
3697 ospf_lsa_unlock (lsa);
3698 lsa->refresh_list = -1;
3699 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003700 }
3701 list_free (refresh_list);
3702 }
3703 }
3704
paul68980082003-03-25 05:07:42 +00003705 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3706 ospf, ospf->lsa_refresh_interval);
3707 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003708
paul1eb8ef22005-04-07 07:30:20 +00003709 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3710 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003711
3712 list_delete (lsa_to_refresh);
3713
3714 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003715 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003716
3717 return 0;
3718}
3719