blob: ff018fd4c9523ef61a0853ed6c1fc701b812764f [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
paul88d6cf32005-10-29 12:50:09 +0000486/* Determine cost of link, taking RFC3137 stub-router support into
487 * consideration
488 */
489static u_int16_t
490ospf_link_cost (struct ospf_interface *oi)
491{
492 /* RFC3137 stub router support */
493 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
494 return oi->output_cost;
495 else
496 return OSPF_OUTPUT_COST_INFINITE;
497}
498
paul718e3742002-12-13 20:15:29 +0000499/* Set a link information. */
paul4dadc292005-05-06 21:37:42 +0000500static void
paul718e3742002-12-13 20:15:29 +0000501link_info_set (struct stream *s, struct in_addr id,
502 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
503{
504 /* TOS based routing is not supported. */
505 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
506 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
507 stream_putc (s, type); /* Link Type. */
508 stream_putc (s, tos); /* TOS = 0. */
509 stream_putw (s, cost); /* Link Cost. */
510}
511
512/* Describe Point-to-Point link. */
paul4dadc292005-05-06 21:37:42 +0000513static int
paul718e3742002-12-13 20:15:29 +0000514lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
515{
516 int links = 0;
517 struct ospf_neighbor *nbr;
518 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000519 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000520
521 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000522 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000523
paul68980082003-03-25 05:07:42 +0000524 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000525 if (nbr->state == NSM_Full)
526 {
527 /* For unnumbered point-to-point networks, the Link Data field
528 should specify the interface's MIB-II ifIndex value. */
529 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
paul88d6cf32005-10-29 12:50:09 +0000530 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000531 links++;
532 }
533
hasso3fb9cd62004-10-19 19:44:43 +0000534 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000535 {
536 /* Option 1:
537 link_type = LSA_LINK_TYPE_STUB;
538 link_id = nbr->address.u.prefix4;
539 link_data.s_addr = 0xffffffff;
540 link_cost = o->output_cost; */
541
542 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
543 mask.s_addr = 0xffffffff;
544 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
545 }
546 else
547 {
548 /* Option 2: We need to include link to a stub
549 network regardless of the state of the neighbor */
550 masklen2ip (oi->address->prefixlen, &mask);
551 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
552 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
553 }
554 links++;
555
556 return links;
557}
558
559/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000560static int
paul718e3742002-12-13 20:15:29 +0000561lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
562{
563 struct ospf_neighbor *dr;
564 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000565 u_int16_t cost = ospf_link_cost (oi);
566
paul718e3742002-12-13 20:15:29 +0000567 /* Describe Type 3 Link. */
568 if (oi->state == ISM_Waiting)
569 {
570 masklen2ip (oi->address->prefixlen, &mask);
571 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
572 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
573 return 1;
574 }
575
576 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
577 /* Describe Type 2 link. */
578 if (dr && (dr->state == NSM_Full ||
579 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000580 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000581 {
582 link_info_set (s, DR (oi), oi->address->u.prefix4,
paul88d6cf32005-10-29 12:50:09 +0000583 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000584 }
585 /* Describe type 3 link. */
586 else
587 {
588 masklen2ip (oi->address->prefixlen, &mask);
589 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
590 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
591 }
592 return 1;
593}
594
paul4dadc292005-05-06 21:37:42 +0000595static int
paul718e3742002-12-13 20:15:29 +0000596lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
597{
598 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000599
paul718e3742002-12-13 20:15:29 +0000600 /* Describe Type 3 Link. */
601 if (oi->state != ISM_Loopback)
602 return 0;
603
604 mask.s_addr = 0xffffffff;
605 id.s_addr = oi->address->u.prefix4.s_addr;
606 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
607 return 1;
608}
609
610/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000611static int
paul718e3742002-12-13 20:15:29 +0000612lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
613{
614 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000615 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000616
paul718e3742002-12-13 20:15:29 +0000617 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000618 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000619 if (nbr->state == NSM_Full)
620 {
621 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
paul88d6cf32005-10-29 12:50:09 +0000622 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000623 return 1;
624 }
625
626 return 0;
627}
628
629#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
630
paul7afa08d2002-12-13 20:59:45 +0000631/* this function add for support point-to-multipoint ,see rfc2328
63212.4.1.4.*/
633/* from "edward rrr" <edward_rrr@hotmail.com>
634 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000635static int
paul68980082003-03-25 05:07:42 +0000636lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000637{
638 int links = 0;
639 struct route_node *rn;
640 struct ospf_neighbor *nbr = NULL;
641 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000642 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000643
644 mask.s_addr = 0xffffffff;
645 id.s_addr = oi->address->u.prefix4.s_addr;
646 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
647 links++;
648
paul1cc8f762003-04-05 19:34:32 +0000649 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000650 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000651
652 /* Search neighbor, */
653 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
654 if ((nbr = rn->info) != NULL)
655 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000656 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000657 if (nbr->state == NSM_Full)
658
659 {
paul7afa08d2002-12-13 20:59:45 +0000660 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
paul88d6cf32005-10-29 12:50:09 +0000661 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul7afa08d2002-12-13 20:59:45 +0000662 links++;
paul1cc8f762003-04-05 19:34:32 +0000663 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000664 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000665 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000666 }
667
668 return links;
paul7afa08d2002-12-13 20:59:45 +0000669}
670
paul718e3742002-12-13 20:15:29 +0000671/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000672static int
paul718e3742002-12-13 20:15:29 +0000673router_lsa_link_set (struct stream *s, struct ospf_area *area)
674{
hasso52dc7ee2004-09-23 19:18:23 +0000675 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000676 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000677 int links = 0;
678
paul1eb8ef22005-04-07 07:30:20 +0000679 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000680 {
paul718e3742002-12-13 20:15:29 +0000681 struct interface *ifp = oi->ifp;
682
683 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000684 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000685 {
686 if (oi->state != ISM_Down)
687 {
688 /* Describe each link. */
689 switch (oi->type)
690 {
691 case OSPF_IFTYPE_POINTOPOINT:
692 links += lsa_link_ptop_set (s, oi);
693 break;
694 case OSPF_IFTYPE_BROADCAST:
695 links += lsa_link_broadcast_set (s, oi);
696 break;
697 case OSPF_IFTYPE_NBMA:
698 links += lsa_link_nbma_set (s, oi);
699 break;
700 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000701 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000702 break;
703 case OSPF_IFTYPE_VIRTUALLINK:
704 links += lsa_link_virtuallink_set (s, oi);
705 break;
706 case OSPF_IFTYPE_LOOPBACK:
707 links += lsa_link_loopback_set (s, oi);
708 }
709 }
710 }
711 }
712
713 return links;
714}
715
716/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000717static void
paul718e3742002-12-13 20:15:29 +0000718ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
719{
720 unsigned long putp;
721 u_int16_t cnt;
722
723 /* Set flags. */
724 stream_putc (s, router_lsa_flags (area));
725
726 /* Set Zero fields. */
727 stream_putc (s, 0);
728
729 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000730 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000731
732 /* Forward word */
733 stream_putw(s, 0);
734
735 /* Set all link information. */
736 cnt = router_lsa_link_set (s, area);
737
738 /* Set # of links here. */
739 stream_putw_at (s, putp, cnt);
740}
paul88d6cf32005-10-29 12:50:09 +0000741
742static int
743ospf_stub_router_timer (struct thread *t)
744{
745 struct ospf_area *area = THREAD_ARG (t);
746
747 area->t_stub_router = NULL;
748
749 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
750
751 /* clear stub route state and generate router-lsa refresh, don't
752 * clobber an administratively set stub-router state though.
753 */
754 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
755 return 0;
756
757 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
758
759 ospf_router_lsa_timer_add (area);
760
761 return 0;
762}
paul718e3742002-12-13 20:15:29 +0000763
paul88d6cf32005-10-29 12:50:09 +0000764inline static void
765ospf_stub_router_check (struct ospf_area *area)
766{
767 /* area must either be administratively configured to be stub
768 * or startup-time stub-router must be configured and we must in a pre-stub
769 * state.
770 */
771 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
772 {
773 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
774 return;
775 }
776
777 /* not admin-stubbed, check whether startup stubbing is configured and
778 * whether it's not been done yet
779 */
780 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
781 return;
782
783 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
784 {
785 /* stub-router is hence done forever for this area, even if someone
786 * tries configure it (take effect next restart).
787 */
788 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
789 return;
790 }
791
792 /* startup stub-router configured and not yet done */
793 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
794
795 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
796 area->ospf->stub_router_startup_time);
797}
798
paul718e3742002-12-13 20:15:29 +0000799/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000800static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000801ospf_router_lsa_new (struct ospf_area *area)
802{
paul68980082003-03-25 05:07:42 +0000803 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000804 struct stream *s;
805 struct lsa_header *lsah;
806 struct ospf_lsa *new;
807 int length;
808
809 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000810 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000811
paul88d6cf32005-10-29 12:50:09 +0000812 /* check whether stub-router is desired, and if this is the first
813 * router LSA.
814 */
815 ospf_stub_router_check (area);
816
paul718e3742002-12-13 20:15:29 +0000817 /* Create a stream for LSA. */
818 s = stream_new (OSPF_MAX_LSA_SIZE);
819 lsah = (struct lsa_header *) STREAM_DATA (s);
820
paul718e3742002-12-13 20:15:29 +0000821 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000822 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000823 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000824
825 /* Set router-LSA body fields. */
826 ospf_router_lsa_body_set (s, area);
827
828 /* Set length. */
829 length = stream_get_endp (s);
830 lsah->length = htons (length);
831
832 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000833 if ( (new = ospf_lsa_new ()) == NULL)
834 {
835 zlog_err ("%s: Unable to create new lsa", __func__);
836 return NULL;
837 }
838
paul718e3742002-12-13 20:15:29 +0000839 new->area = area;
840 SET_FLAG (new->flags, OSPF_LSA_SELF);
841
842 /* Copy LSA data to store, discard stream. */
843 new->data = ospf_lsa_data_new (length);
844 memcpy (new->data, lsah, length);
845 stream_free (s);
846
847 return new;
848}
849
850/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000851static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000852ospf_router_lsa_originate (struct ospf_area *area)
853{
854 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000855
paul718e3742002-12-13 20:15:29 +0000856 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000857 if ( (new = ospf_router_lsa_new (area)) == NULL)
858 {
859 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
860 return NULL;
861 }
paul718e3742002-12-13 20:15:29 +0000862
863 /* Sanity check. */
864 if (new->data->adv_router.s_addr == 0)
865 {
866 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000867 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000868 ospf_lsa_discard (new);
869 return NULL;
870 }
871
872 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000873 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000874
875 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000876 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000877
878 /* Flooding new LSA through area. */
879 ospf_flood_through_area (area, NULL, new);
880
881 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
882 {
ajse588f212004-12-08 18:12:06 +0000883 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000884 new->data->type, inet_ntoa (new->data->id), new);
885 ospf_lsa_header_dump (new->data);
886 }
887
888 return new;
889}
890
891/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000892static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000893ospf_router_lsa_refresh (struct ospf_lsa *lsa)
894{
895 struct ospf_area *area = lsa->area;
896 struct ospf_lsa *new;
897
898 /* Sanity check. */
899 assert (lsa->data);
900
901 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000902 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000903
904 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000905 if ( (new = ospf_router_lsa_new (area)) == NULL)
906 {
907 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
908 return NULL;
909 }
910
paul718e3742002-12-13 20:15:29 +0000911 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
912
paul68980082003-03-25 05:07:42 +0000913 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000914
915 /* Flood LSA through area. */
916 ospf_flood_through_area (area, NULL, new);
917
918 /* Debug logging. */
919 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
920 {
ajse588f212004-12-08 18:12:06 +0000921 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000922 new->data->type, inet_ntoa (new->data->id));
923 ospf_lsa_header_dump (new->data);
924 }
925
926 return NULL;
927}
928
paul4dadc292005-05-06 21:37:42 +0000929static int
paul718e3742002-12-13 20:15:29 +0000930ospf_router_lsa_timer (struct thread *t)
931{
932 struct ospf_area *area;
933
934 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000935 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000936
937 area = THREAD_ARG (t);
938 area->t_router_lsa_self = NULL;
939
940 /* Now refresh router-LSA. */
941 if (area->router_lsa_self)
942 ospf_router_lsa_refresh (area->router_lsa_self);
943 /* Newly originate router-LSA. */
944 else
945 ospf_router_lsa_originate (area);
946
947 return 0;
948}
949
950void
951ospf_router_lsa_timer_add (struct ospf_area *area)
952{
953 /* Keep area's self-originated router-LSA. */
954 struct ospf_lsa *lsa = area->router_lsa_self;
955
956 /* Cancel previously scheduled router-LSA timer. */
957 if (area->t_router_lsa_self)
958 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000959 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000960
961 OSPF_TIMER_OFF (area->t_router_lsa_self);
962
963 /* If router-LSA is originated previously, check the interval time. */
964 if (lsa)
965 {
966 int delay;
967 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
968 {
969 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
970 ospf_router_lsa_timer, delay);
971 return;
972 }
973 }
974
975 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000976 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000977
978 /* Immediately refresh router-LSA. */
979 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
980}
981
982int
paul68980082003-03-25 05:07:42 +0000983ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000984{
paul68980082003-03-25 05:07:42 +0000985 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000986 struct listnode *node, *nnode;
987 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000988
989 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000990 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000991
paul68980082003-03-25 05:07:42 +0000992 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000993
paul1eb8ef22005-04-07 07:30:20 +0000994 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000995 {
paul718e3742002-12-13 20:15:29 +0000996 struct ospf_lsa *lsa = area->router_lsa_self;
997 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000998 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000999
1000 /* Keep Area ID string. */
1001 area_str = AREA_NAME (area);
1002
1003 /* If LSA not exist in this Area, originate new. */
1004 if (lsa == NULL)
1005 {
1006 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001007 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001008
1009 ospf_router_lsa_originate (area);
1010 }
1011 /* If router-ID is changed, Link ID must change.
1012 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001013 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001014 {
1015 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001016 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001017 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1018 ospf_lsa_flush_area (lsa, area);
1019 ospf_lsa_unlock (area->router_lsa_self);
1020 area->router_lsa_self = NULL;
1021
1022 /* Refresh router-LSA, (not install) and flood through area. */
1023 ospf_router_lsa_timer_add (area);
1024 }
1025 else
1026 {
1027 rl = (struct router_lsa *) lsa->data;
1028 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001029 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001030 ospf_router_lsa_timer_add (area);
1031 }
1032 }
1033
1034 return 0;
1035}
1036
1037
1038/* network-LSA related functions. */
1039/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001040static void
paul718e3742002-12-13 20:15:29 +00001041ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1042{
1043 struct in_addr mask;
1044 struct route_node *rn;
1045 struct ospf_neighbor *nbr;
1046
1047 masklen2ip (oi->address->prefixlen, &mask);
1048 stream_put_ipv4 (s, mask.s_addr);
1049
1050 /* The network-LSA lists those routers that are fully adjacent to
1051 the Designated Router; each fully adjacent router is identified by
1052 its OSPF Router ID. The Designated Router includes itself in this
1053 list. RFC2328, Section 12.4.2 */
1054
1055 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1056 if ((nbr = rn->info) != NULL)
1057 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1058 stream_put_ipv4 (s, nbr->router_id.s_addr);
1059}
1060
paul4dadc292005-05-06 21:37:42 +00001061static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001062ospf_network_lsa_new (struct ospf_interface *oi)
1063{
1064 struct stream *s;
1065 struct ospf_lsa *new;
1066 struct lsa_header *lsah;
1067 int length;
1068
1069 /* If there are no neighbours on this network (the net is stub),
1070 the router does not originate network-LSA (see RFC 12.4.2) */
1071 if (oi->full_nbrs == 0)
1072 return NULL;
1073
1074 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001075 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001076
1077 /* Create new stream for LSA. */
1078 s = stream_new (OSPF_MAX_LSA_SIZE);
1079 lsah = (struct lsa_header *) STREAM_DATA (s);
1080
1081 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001082 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001083
1084 /* Set network-LSA body fields. */
1085 ospf_network_lsa_body_set (s, oi);
1086
1087 /* Set length. */
1088 length = stream_get_endp (s);
1089 lsah->length = htons (length);
1090
1091 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001092 if ( (new = ospf_lsa_new ()) == NULL)
1093 {
1094 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1095 return NULL;
1096 }
1097
paul718e3742002-12-13 20:15:29 +00001098 new->area = oi->area;
1099 SET_FLAG (new->flags, OSPF_LSA_SELF);
1100
1101 /* Copy LSA to store. */
1102 new->data = ospf_lsa_data_new (length);
1103 memcpy (new->data, lsah, length);
1104 stream_free (s);
1105
1106 return new;
1107}
1108
1109/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001110static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001111ospf_network_lsa_originate (struct ospf_interface *oi)
1112{
1113 struct ospf_lsa *new;
1114
1115 /* Create new network-LSA instance. */
1116 new = ospf_network_lsa_new (oi);
1117 if (new == NULL)
1118 return NULL;
1119
1120 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001121 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001122
1123 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001124 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001125
1126 /* Flooding new LSA through area. */
1127 ospf_flood_through_area (oi->area, NULL, new);
1128
1129 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1130 {
ajse588f212004-12-08 18:12:06 +00001131 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001132 new->data->type, inet_ntoa (new->data->id), new);
1133 ospf_lsa_header_dump (new->data);
1134 }
1135
1136 return new;
1137}
1138
1139int
1140ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1141{
1142 struct ospf_area *area = lsa->area;
1143 struct ospf_lsa *new;
1144
1145 assert (lsa->data);
1146
1147 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001148 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001149
1150 /* Create new network-LSA instance. */
1151 new = ospf_network_lsa_new (oi);
1152 if (new == NULL)
1153 return -1;
1154 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1155
paul68980082003-03-25 05:07:42 +00001156 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001157
1158 /* Flood LSA through aera. */
1159 ospf_flood_through_area (area, NULL, new);
1160
1161 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1162 {
ajse588f212004-12-08 18:12:06 +00001163 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001164 new->data->type, inet_ntoa (new->data->id));
1165 ospf_lsa_header_dump (new->data);
1166 }
1167
1168 return 0;
1169}
1170
paul4dadc292005-05-06 21:37:42 +00001171static int
paul718e3742002-12-13 20:15:29 +00001172ospf_network_lsa_refresh_timer (struct thread *t)
1173{
1174 struct ospf_interface *oi;
1175
1176 oi = THREAD_ARG (t);
1177 oi->t_network_lsa_self = NULL;
1178
1179 if (oi->network_lsa_self)
1180 /* Now refresh network-LSA. */
1181 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1182 else
1183 /* Newly create network-LSA. */
1184 ospf_network_lsa_originate (oi);
1185
1186 return 0;
1187}
1188
1189void
1190ospf_network_lsa_timer_add (struct ospf_interface *oi)
1191{
1192 /* Keep interface's self-originated network-LSA. */
1193 struct ospf_lsa *lsa = oi->network_lsa_self;
1194
1195 /* Cancel previously schedules network-LSA timer. */
1196 if (oi->t_network_lsa_self)
1197 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001198 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001199 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1200
1201 /* If network-LSA is originated previously, check the interval time. */
1202 if (lsa)
1203 {
1204 int delay;
1205 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1206 {
1207 oi->t_network_lsa_self =
1208 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1209 oi, delay);
1210 return;
1211 }
1212 }
1213
1214 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001215 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001216
1217 /* Immediately refresh network-LSA. */
1218 oi->t_network_lsa_self =
1219 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1220}
1221
1222
paul4dadc292005-05-06 21:37:42 +00001223static void
paul718e3742002-12-13 20:15:29 +00001224stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1225{
1226 u_int32_t metric;
1227 char *mp;
1228
1229 /* Put 0 metric. TOS metric is not supported. */
1230 metric = htonl (metric_value);
1231 mp = (char *) &metric;
1232 mp++;
1233 stream_put (s, mp, 3);
1234}
1235
1236/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001237static void
paul718e3742002-12-13 20:15:29 +00001238ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1239 u_int32_t metric)
1240{
1241 struct in_addr mask;
1242
1243 masklen2ip (p->prefixlen, &mask);
1244
1245 /* Put Network Mask. */
1246 stream_put_ipv4 (s, mask.s_addr);
1247
1248 /* Set # TOS. */
1249 stream_putc (s, (u_char) 0);
1250
1251 /* Set metric. */
1252 stream_put_ospf_metric (s, metric);
1253}
1254
paul4dadc292005-05-06 21:37:42 +00001255static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001256ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1257 u_int32_t metric, struct in_addr id)
1258{
1259 struct stream *s;
1260 struct ospf_lsa *new;
1261 struct lsa_header *lsah;
1262 int length;
1263
paulc24d6022005-11-20 14:54:12 +00001264 if (id.s_addr == 0xffffffff)
1265 {
1266 /* Maybe Link State ID not available. */
1267 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1268 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1269 OSPF_SUMMARY_LSA);
1270 return NULL;
1271 }
1272
paul718e3742002-12-13 20:15:29 +00001273 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001274 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001275
1276 /* Create new stream for LSA. */
1277 s = stream_new (OSPF_MAX_LSA_SIZE);
1278 lsah = (struct lsa_header *) STREAM_DATA (s);
1279
paul68980082003-03-25 05:07:42 +00001280 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1281 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001282
1283 /* Set summary-LSA body fields. */
1284 ospf_summary_lsa_body_set (s, p, metric);
1285
1286 /* Set length. */
1287 length = stream_get_endp (s);
1288 lsah->length = htons (length);
1289
1290 /* Create OSPF LSA instance. */
1291 new = ospf_lsa_new ();
1292 new->area = area;
1293 SET_FLAG (new->flags, OSPF_LSA_SELF);
1294
1295 /* Copy LSA to store. */
1296 new->data = ospf_lsa_data_new (length);
1297 memcpy (new->data, lsah, length);
1298 stream_free (s);
1299
1300 return new;
1301}
1302
1303/* Originate Summary-LSA. */
1304struct ospf_lsa *
1305ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1306 struct ospf_area *area)
1307{
1308 struct ospf_lsa *new;
1309 struct in_addr id;
1310
paul68980082003-03-25 05:07:42 +00001311 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001312
paulc24d6022005-11-20 14:54:12 +00001313 if (id.s_addr == 0xffffffff)
1314 {
1315 /* Maybe Link State ID not available. */
1316 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1317 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1318 OSPF_SUMMARY_LSA);
1319 return NULL;
1320 }
1321
paul718e3742002-12-13 20:15:29 +00001322 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001323 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1324 return NULL;
paul718e3742002-12-13 20:15:29 +00001325
1326 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001327 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001328
1329 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001330 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001331
1332 /* Flooding new LSA through area. */
1333 ospf_flood_through_area (area, NULL, new);
1334
1335 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1336 {
ajse588f212004-12-08 18:12:06 +00001337 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001338 new->data->type, inet_ntoa (new->data->id), new);
1339 ospf_lsa_header_dump (new->data);
1340 }
1341
1342 return new;
1343}
1344
1345struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001346ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001347{
1348 struct ospf_lsa *new;
1349 struct summary_lsa *sl;
1350 struct prefix p;
1351
1352 /* Sanity check. */
1353 assert (lsa->data);
1354
1355 sl = (struct summary_lsa *)lsa->data;
1356 p.prefixlen = ip_masklen (sl->mask);
1357 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1358 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001359
1360 if (!new)
1361 return NULL;
1362
paul718e3742002-12-13 20:15:29 +00001363 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1364
1365 /* Re-calculate checksum. */
1366 ospf_lsa_checksum (new->data);
1367
paul68980082003-03-25 05:07:42 +00001368 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001369
1370 /* Flood LSA through AS. */
1371 ospf_flood_through_area (new->area, NULL, new);
1372
1373 /* Debug logging. */
1374 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1375 {
ajse588f212004-12-08 18:12:06 +00001376 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001377 new->data->type, inet_ntoa (new->data->id));
1378 ospf_lsa_header_dump (new->data);
1379 }
1380
1381 return new;
1382}
1383
1384
1385/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001386static void
paul718e3742002-12-13 20:15:29 +00001387ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1388 u_int32_t metric)
1389{
1390 struct in_addr mask;
1391
1392 masklen2ip (p->prefixlen, &mask);
1393
1394 /* Put Network Mask. */
1395 stream_put_ipv4 (s, mask.s_addr);
1396
1397 /* Set # TOS. */
1398 stream_putc (s, (u_char) 0);
1399
1400 /* Set metric. */
1401 stream_put_ospf_metric (s, metric);
1402}
1403
paul4dadc292005-05-06 21:37:42 +00001404static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001405ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1406 u_int32_t metric, struct in_addr id)
1407{
1408 struct stream *s;
1409 struct ospf_lsa *new;
1410 struct lsa_header *lsah;
1411 int length;
1412
paulc24d6022005-11-20 14:54:12 +00001413 if (id.s_addr == 0xffffffff)
1414 {
1415 /* Maybe Link State ID not available. */
1416 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1417 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1418 OSPF_ASBR_SUMMARY_LSA);
1419 return NULL;
1420 }
1421
paul718e3742002-12-13 20:15:29 +00001422 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001423 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001424
1425 /* Create new stream for LSA. */
1426 s = stream_new (OSPF_MAX_LSA_SIZE);
1427 lsah = (struct lsa_header *) STREAM_DATA (s);
1428
paul68980082003-03-25 05:07:42 +00001429 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1430 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001431
1432 /* Set summary-LSA body fields. */
1433 ospf_summary_asbr_lsa_body_set (s, p, metric);
1434
1435 /* Set length. */
1436 length = stream_get_endp (s);
1437 lsah->length = htons (length);
1438
1439 /* Create OSPF LSA instance. */
1440 new = ospf_lsa_new ();
1441 new->area = area;
1442 SET_FLAG (new->flags, OSPF_LSA_SELF);
1443
1444 /* Copy LSA to store. */
1445 new->data = ospf_lsa_data_new (length);
1446 memcpy (new->data, lsah, length);
1447 stream_free (s);
1448
1449 return new;
1450}
1451
1452/* Originate summary-ASBR-LSA. */
1453struct ospf_lsa *
1454ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1455 struct ospf_area *area)
1456{
1457 struct ospf_lsa *new;
1458 struct in_addr id;
1459
paul68980082003-03-25 05:07:42 +00001460 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001461
paulc24d6022005-11-20 14:54:12 +00001462 if (id.s_addr == 0xffffffff)
1463 {
1464 /* Maybe Link State ID not available. */
1465 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1466 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1467 OSPF_ASBR_SUMMARY_LSA);
1468 return NULL;
1469 }
1470
paul718e3742002-12-13 20:15:29 +00001471 /* Create new summary-LSA instance. */
1472 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001473 if (!new)
1474 return NULL;
paul718e3742002-12-13 20:15:29 +00001475
1476 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001477 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001478
1479 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001480 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001481
1482 /* Flooding new LSA through area. */
1483 ospf_flood_through_area (area, NULL, new);
1484
1485 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1486 {
ajse588f212004-12-08 18:12:06 +00001487 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001488 new->data->type, inet_ntoa (new->data->id), new);
1489 ospf_lsa_header_dump (new->data);
1490 }
1491
1492 return new;
1493}
1494
1495struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001496ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001497{
1498 struct ospf_lsa *new;
1499 struct summary_lsa *sl;
1500 struct prefix p;
1501
1502 /* Sanity check. */
1503 assert (lsa->data);
1504
1505 sl = (struct summary_lsa *)lsa->data;
1506 p.prefixlen = ip_masklen (sl->mask);
1507 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1508 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001509 if (!new)
1510 return NULL;
paul718e3742002-12-13 20:15:29 +00001511
1512 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1513
1514 /* Re-calculate checksum. */
1515 ospf_lsa_checksum (new->data);
1516
paul68980082003-03-25 05:07:42 +00001517 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001518
1519 /* Flood LSA through area. */
1520 ospf_flood_through_area (new->area, NULL, new);
1521
1522 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1523 {
ajse588f212004-12-08 18:12:06 +00001524 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001525 new->data->type, inet_ntoa (new->data->id));
1526 ospf_lsa_header_dump (new->data);
1527 }
1528
1529 return new;
1530}
1531
1532/* AS-external-LSA related functions. */
1533
1534/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1535 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001536static struct in_addr
paul68980082003-03-25 05:07:42 +00001537ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001538{
1539 struct in_addr fwd;
1540 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001541 struct listnode *node;
1542 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001543
1544 fwd.s_addr = 0;
1545
1546 if (!nexthop.s_addr)
1547 return fwd;
1548
1549 /* Check whether nexthop is covered by OSPF network. */
1550 nh.family = AF_INET;
1551 nh.u.prefix4 = nexthop;
1552 nh.prefixlen = IPV4_MAX_BITLEN;
1553
paul1eb8ef22005-04-07 07:30:20 +00001554 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1555 if (if_is_operative (oi->ifp))
1556 if (oi->address->family == AF_INET)
1557 if (prefix_match (oi->address, &nh))
1558 return nexthop;
paul718e3742002-12-13 20:15:29 +00001559
1560 return fwd;
1561}
1562
paul718e3742002-12-13 20:15:29 +00001563/* NSSA-external-LSA related functions. */
1564
1565/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001566
paul718e3742002-12-13 20:15:29 +00001567struct in_addr
1568ospf_get_ip_from_ifp (struct ospf_interface *oi)
1569{
1570 struct in_addr fwd;
1571
1572 fwd.s_addr = 0;
1573
paul2e3b2e42002-12-13 21:03:13 +00001574 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001575 return oi->address->u.prefix4;
1576
1577 return fwd;
1578}
1579
1580/* Get 1st IP connection for Forward Addr */
1581struct in_addr
paulf2c80652002-12-13 21:44:27 +00001582ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001583{
1584 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001585 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001586 struct listnode *node;
1587 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001588
1589 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001590 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001591
paul1eb8ef22005-04-07 07:30:20 +00001592 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001593 {
paul2e3b2e42002-12-13 21:03:13 +00001594 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001595 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001596 if (oi->address && oi->address->family == AF_INET)
1597 {
1598 if (best_default.s_addr == 0)
1599 best_default = oi->address->u.prefix4;
1600 if (oi->area == area)
1601 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001602 }
paul718e3742002-12-13 20:15:29 +00001603 }
paulf2c80652002-12-13 21:44:27 +00001604 if (best_default.s_addr != 0)
1605 return best_default;
paul718e3742002-12-13 20:15:29 +00001606
paul68980082003-03-25 05:07:42 +00001607 if (best_default.s_addr != 0)
1608 return best_default;
1609
paul718e3742002-12-13 20:15:29 +00001610 return fwd;
1611}
hassobeebba72004-06-20 21:00:27 +00001612
paul718e3742002-12-13 20:15:29 +00001613#define DEFAULT_DEFAULT_METRIC 20
1614#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1615#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1616
1617#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1618
1619int
paul68980082003-03-25 05:07:42 +00001620metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001621{
paul68980082003-03-25 05:07:42 +00001622 return (ospf->dmetric[src].type < 0 ?
1623 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001624}
1625
1626int
paul68980082003-03-25 05:07:42 +00001627metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001628{
paul68980082003-03-25 05:07:42 +00001629 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001630 {
1631 if (src == DEFAULT_ROUTE)
1632 {
paul68980082003-03-25 05:07:42 +00001633 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001634 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1635 else
1636 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1637 }
paul68980082003-03-25 05:07:42 +00001638 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001639 return DEFAULT_DEFAULT_METRIC;
1640 else
paul68980082003-03-25 05:07:42 +00001641 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001642 }
1643
paul68980082003-03-25 05:07:42 +00001644 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001645}
1646
1647/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001648static void
paul68980082003-03-25 05:07:42 +00001649ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1650 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001651{
1652 struct prefix_ipv4 *p = &ei->p;
1653 struct in_addr mask, fwd_addr;
1654 u_int32_t mvalue;
1655 int mtype;
1656 int type;
1657
1658 /* Put Network Mask. */
1659 masklen2ip (p->prefixlen, &mask);
1660 stream_put_ipv4 (s, mask.s_addr);
1661
1662 /* If prefix is default, specify DEFAULT_ROUTE. */
1663 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1664
1665 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001666 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001667
1668 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001669 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001670
1671 /* Put type of external metric. */
1672 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1673
1674 /* Put 0 metric. TOS metric is not supported. */
1675 stream_put_ospf_metric (s, mvalue);
1676
1677 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001678 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001679
1680 /* Put forwarding address. */
1681 stream_put_ipv4 (s, fwd_addr.s_addr);
1682
1683 /* Put route tag -- This value should be introduced from configuration. */
1684 stream_putl (s, 0);
1685}
1686
1687/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001688static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001689ospf_external_lsa_new (struct ospf *ospf,
1690 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001691{
1692 struct stream *s;
1693 struct lsa_header *lsah;
1694 struct ospf_lsa *new;
1695 struct in_addr id;
1696 int length;
1697
1698 if (ei == NULL)
1699 {
1700 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001701 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001702 return NULL;
1703 }
1704
1705 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001706 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001707
1708 /* If old Link State ID is specified, refresh LSA with same ID. */
1709 if (old_id)
1710 id = *old_id;
1711 /* Get Link State with unique ID. */
1712 else
1713 {
paul68980082003-03-25 05:07:42 +00001714 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001715 if (id.s_addr == 0xffffffff)
1716 {
1717 /* Maybe Link State ID not available. */
1718 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001719 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001720 return NULL;
1721 }
1722 }
1723
1724 /* Create new stream for LSA. */
1725 s = stream_new (OSPF_MAX_LSA_SIZE);
1726 lsah = (struct lsa_header *) STREAM_DATA (s);
1727
1728 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001729 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1730 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001731
1732 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001733 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001734
1735 /* Set length. */
1736 length = stream_get_endp (s);
1737 lsah->length = htons (length);
1738
1739 /* Now, create OSPF LSA instance. */
1740 new = ospf_lsa_new ();
1741 new->area = NULL;
1742 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1743
1744 /* Copy LSA data to store, discard stream. */
1745 new->data = ospf_lsa_data_new (length);
1746 memcpy (new->data, lsah, length);
1747 stream_free (s);
1748
1749 return new;
1750}
1751
paul718e3742002-12-13 20:15:29 +00001752/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001753static void
paul68980082003-03-25 05:07:42 +00001754ospf_install_flood_nssa (struct ospf *ospf,
1755 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001756{
pauld4a53d52003-07-12 21:30:57 +00001757 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001758 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001759 struct ospf_area *area;
1760 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001761
pauld4a53d52003-07-12 21:30:57 +00001762 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1763 * which originated from an NSSA area. In which case it should not be
1764 * flooded back to NSSA areas.
1765 */
1766 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1767 return;
1768
paul718e3742002-12-13 20:15:29 +00001769 /* NSSA Originate or Refresh (If anyNSSA)
1770
1771 LSA is self-originated. And just installed as Type-5.
1772 Additionally, install as Type-7 LSDB for every attached NSSA.
1773
1774 P-Bit controls which ABR performs translation to outside world; If
1775 we are an ABR....do not set the P-bit, because we send the Type-5,
1776 not as the ABR Translator, but as the ASBR owner within the AS!
1777
1778 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1779 elected ABR Translator will see the P-bit, Translate, and re-flood.
1780
1781 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1782 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1783
paul1eb8ef22005-04-07 07:30:20 +00001784 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001785 {
hasso0c14ad82003-07-03 08:36:02 +00001786 /* Don't install Type-7 LSA's into nonNSSA area */
1787 if (area->external_routing != OSPF_AREA_NSSA)
1788 continue;
paul718e3742002-12-13 20:15:29 +00001789
paul68980082003-03-25 05:07:42 +00001790 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001791 new = ospf_lsa_dup (lsa);
1792 new->area = area;
1793 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001794
paul68980082003-03-25 05:07:42 +00001795 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001796 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001797 {
pauld4a53d52003-07-12 21:30:57 +00001798 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001799
1800 /* set non-zero FWD ADDR
1801
1802 draft-ietf-ospf-nssa-update-09.txt
1803
1804 if the network between the NSSA AS boundary router and the
1805 adjacent AS is advertised into OSPF as an internal OSPF route,
1806 the forwarding address should be the next op address as is cu
1807 currently done with type-5 LSAs. If the intervening network is
1808 not adversited into OSPF as an internal OSPF route and the
1809 type-7 LSA's P-bit is set a forwarding address should be
1810 selected from one of the router's active OSPF inteface addresses
1811 which belong to the NSSA. If no such addresses exist, then
1812 no type-7 LSA's with the P-bit set should originate from this
1813 router. */
1814
pauld4a53d52003-07-12 21:30:57 +00001815 /* kevinm: not updating lsa anymore, just new */
1816 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001817
1818 if (extlsa->e[0].fwd_addr.s_addr == 0)
1819 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001820
pauld7480322003-05-16 17:31:51 +00001821 if (extlsa->e[0].fwd_addr.s_addr == 0)
1822 {
1823 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001824 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
pauld4a53d52003-07-12 21:30:57 +00001825 ospf_lsa_discard(new);
pauld7480322003-05-16 17:31:51 +00001826 return;
1827 }
paulf2c80652002-12-13 21:44:27 +00001828 }
paul68980082003-03-25 05:07:42 +00001829 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001830 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001831
paul68980082003-03-25 05:07:42 +00001832 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001833 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001834
1835 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001836 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001837 }
paul718e3742002-12-13 20:15:29 +00001838}
pauld4a53d52003-07-12 21:30:57 +00001839
paul4dadc292005-05-06 21:37:42 +00001840static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001841ospf_lsa_translated_nssa_new (struct ospf *ospf,
1842 struct ospf_lsa *type7)
1843{
1844
1845 struct ospf_lsa *new;
1846 struct as_external_lsa *ext, *extnew;
1847 struct external_info ei;
1848
1849 ext = (struct as_external_lsa *)(type7->data);
1850
1851 /* need external_info struct, fill in bare minimum */
1852 ei.p.family = AF_INET;
1853 ei.p.prefix = type7->data->id;
1854 ei.p.prefixlen = ip_masklen (ext->mask);
1855 ei.type = ZEBRA_ROUTE_OSPF;
1856 ei.nexthop = ext->header.adv_router;
1857 ei.route_map_set.metric = -1;
1858 ei.route_map_set.metric_type = -1;
1859 ei.tag = 0;
1860
1861 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1862 {
1863 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001864 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001865 "Translated Type-5 for %s",
1866 inet_ntoa (ei.p.prefix));
1867 return NULL;
1868 }
1869
1870 extnew = (struct as_external_lsa *)(new->data);
1871
1872 /* copy over Type-7 data to new */
1873 extnew->e[0].tos = ext->e[0].tos;
1874 extnew->e[0].route_tag = ext->e[0].route_tag;
1875 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1876 new->data->ls_seqnum = type7->data->ls_seqnum;
1877
1878 /* add translated flag, checksum and lock new lsa */
1879 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1880 ospf_lsa_checksum (new->data);
1881 new = ospf_lsa_lock (new);
1882
1883 return new;
1884}
1885
1886/* compare type-5 to type-7
1887 * -1: err, 0: same, 1: different
1888 */
paul4dadc292005-05-06 21:37:42 +00001889static int
pauld4a53d52003-07-12 21:30:57 +00001890ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1891{
1892
1893 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1894 *e7 = (struct as_external_lsa *)t7;
1895
1896
1897 /* sanity checks */
1898 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1899 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1900 return -1;
1901
1902 if (t5->data->id.s_addr != t7->data->id.s_addr)
1903 return -1;
1904
1905 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1906 return LSA_REFRESH_FORCE;
1907
1908 if (e5->mask.s_addr != e7->mask.s_addr)
1909 return LSA_REFRESH_FORCE;
1910
1911 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1912 return LSA_REFRESH_FORCE;
1913
1914 if (e5->e[0].route_tag != e7->e[0].route_tag)
1915 return LSA_REFRESH_FORCE;
1916
1917 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1918 return LSA_REFRESH_FORCE;
1919
1920 return LSA_REFRESH_IF_CHANGED;
1921}
1922
1923/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1924struct ospf_lsa *
1925ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1926{
1927 struct ospf_lsa *new;
1928 struct as_external_lsa *extnew;
1929
1930 /* we cant use ospf_external_lsa_originate() as we need to set
1931 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1932 */
1933
1934 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1935 {
1936 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001937 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001938 "Type-7, Id %s, to Type-5",
1939 inet_ntoa (type7->data->id));
1940 return NULL;
1941 }
1942
1943 extnew = (struct as_external_lsa *)new;
1944
1945 if (IS_DEBUG_OSPF_NSSA)
1946 {
ajse588f212004-12-08 18:12:06 +00001947 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001948 "translated Type 7, installed:");
1949 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001950 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1951 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001952 }
1953
1954 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1955 {
1956 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001957 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001958 "Could not install LSA "
1959 "id %s", inet_ntoa (type7->data->id));
1960 return NULL;
1961 }
1962
1963 ospf->lsa_originate_count++;
1964 ospf_flood_through_as (ospf, NULL, new);
1965
1966 return new;
1967}
1968
1969/* Refresh Translated from NSSA AS-external-LSA. */
1970struct ospf_lsa *
1971ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1972 struct ospf_lsa *type5)
1973{
1974 struct ospf_lsa *new = NULL;
1975
1976 /* Sanity checks. */
1977 assert (type7 || type5);
1978 if (type7)
1979 assert (type7->data);
1980 if (type5)
1981 assert (type5->data);
1982 assert (ospf->anyNSSA);
1983
1984 /* get required data according to what has been given */
1985 if (type7 && type5 == NULL)
1986 {
1987 /* find the translated Type-5 for this Type-7 */
1988 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1989 struct prefix_ipv4 p =
1990 {
1991 .prefix = type7->data->id,
1992 .prefixlen = ip_masklen (ext->mask),
1993 .family = AF_INET,
1994 };
1995
1996 type5 = ospf_external_info_find_lsa (ospf, &p);
1997 }
1998 else if (type5 && type7 == NULL)
1999 {
2000 /* find the type-7 from which supplied type-5 was translated,
2001 * ie find first type-7 with same LSA Id.
2002 */
paul1eb8ef22005-04-07 07:30:20 +00002003 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002004 struct route_node *rn;
2005 struct ospf_lsa *lsa;
2006 struct ospf_area *area;
2007
paul1eb8ef22005-04-07 07:30:20 +00002008 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002009 {
2010 if (area->external_routing != OSPF_AREA_NSSA
2011 && !type7)
2012 continue;
2013
2014 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2015 {
2016 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2017 {
2018 type7 = lsa;
2019 break;
2020 }
2021 }
2022 }
2023 }
2024
2025 /* do we have type7? */
2026 if (!type7)
2027 {
2028 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002029 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002030 "Type-5 LSA Id %s",
2031 inet_ntoa (type7->data->id));
2032 return NULL;
2033 }
2034
2035 /* do we have valid translated type5? */
2036 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2037 {
2038 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002039 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002040 "found for Type-7 with Id %s",
2041 inet_ntoa (type7->data->id));
2042 return NULL;
2043 }
2044
2045 /* Delete LSA from neighbor retransmit-list. */
2046 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2047
2048 /* create new translated LSA */
2049 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2050 {
2051 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002052 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002053 "Type-7 for %s to Type-5",
2054 inet_ntoa (type7->data->id));
2055 return NULL;
2056 }
2057
2058 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2059 {
2060 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002061 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002062 "translated LSA, Id %s",
2063 inet_ntoa (new->data->id));
2064 return NULL;
2065 }
2066
2067 /* Flood LSA through area. */
2068 ospf_flood_through_as (ospf, NULL, new);
2069
2070 return new;
2071}
paul718e3742002-12-13 20:15:29 +00002072
2073int
2074is_prefix_default (struct prefix_ipv4 *p)
2075{
2076 struct prefix_ipv4 q;
2077
2078 q.family = AF_INET;
2079 q.prefix.s_addr = 0;
2080 q.prefixlen = 0;
2081
2082 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2083}
2084
2085/* Originate an AS-external-LSA, install and flood. */
2086struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002087ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002088{
2089 struct ospf_lsa *new;
2090
2091 /* Added for NSSA project....
2092
2093 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2094 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2095 every area. The Type-7's are flooded to every IR and every ABR; We
2096 install the Type-5 LSDB so that the normal "refresh" code operates
2097 as usual, and flag them as not used during ASE calculations. The
2098 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2099 Address of non-zero.
2100
2101 If an ABR is the elected NSSA translator, following SPF and during
2102 the ABR task it will translate all the scanned Type-7's, with P-bit
2103 ON and not-self generated, and translate to Type-5's throughout the
2104 non-NSSA/STUB AS.
2105
2106 A difference in operation depends whether this ASBR is an ABR
2107 or not. If not an ABR, the P-bit is ON, to indicate that any
2108 elected NSSA-ABR can perform its translation.
2109
2110 If an ABR, the P-bit is OFF; No ABR will perform translation and
2111 this ASBR will flood the Type-5 LSA as usual.
2112
2113 For the case where this ASBR is not an ABR, the ASE calculations
2114 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2115 demonstrate to the user that there are LSA's that belong to any
2116 attached NSSA.
2117
2118 Finally, it just so happens that when the ABR is translating every
2119 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2120 approved Type-5 (translated from Type-7); at the end of translation
2121 if any Translated Type-5's remain unapproved, then they must be
2122 flushed from the AS.
2123
2124 */
2125
2126 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002127 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002128 return NULL;
2129
2130 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002131 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002132 {
2133 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002134 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002135 inet_ntoa (ei->p.prefix));
2136 return NULL;
2137 }
2138
2139 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002140 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002141
2142 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002143 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002144
2145 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002146 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002147
paul718e3742002-12-13 20:15:29 +00002148 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002149 if (ospf->anyNSSA &&
2150 /* stay away from translated LSAs! */
2151 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002152 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002153
2154 /* Debug logging. */
2155 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2156 {
ajse588f212004-12-08 18:12:06 +00002157 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002158 new->data->type, inet_ntoa (new->data->id), new);
2159 ospf_lsa_header_dump (new->data);
2160 }
2161
2162 return new;
2163}
2164
2165/* Originate AS-external-LSA from external info with initial flag. */
2166int
paul68980082003-03-25 05:07:42 +00002167ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002168{
paul68980082003-03-25 05:07:42 +00002169 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002170 struct route_node *rn;
2171 struct external_info *ei;
2172 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002173 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002174
paul68980082003-03-25 05:07:42 +00002175 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002176
2177 /* Originate As-external-LSA from all type of distribute source. */
2178 if ((rt = EXTERNAL_INFO (type)))
2179 for (rn = route_top (rt); rn; rn = route_next (rn))
2180 if ((ei = rn->info) != NULL)
2181 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002182 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002183 zlog_warn ("LSA: AS-external-LSA was not originated.");
2184
2185 return 0;
2186}
2187
paul4dadc292005-05-06 21:37:42 +00002188static struct external_info *
paul020709f2003-04-04 02:44:16 +00002189ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002190{
2191 int type;
2192 struct route_node *rn;
2193 struct prefix_ipv4 p;
2194
2195 p.family = AF_INET;
2196 p.prefix.s_addr = 0;
2197 p.prefixlen = 0;
2198
2199 /* First, lookup redistributed default route. */
2200 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2201 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2202 {
2203 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2204 if (rn != NULL)
2205 {
2206 route_unlock_node (rn);
2207 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002208 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002209 return rn->info;
2210 }
2211 }
2212
2213 return NULL;
2214}
2215
2216int
paul68980082003-03-25 05:07:42 +00002217ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002218{
2219 int *origin;
2220 struct prefix_ipv4 p;
2221 struct in_addr nexthop;
2222 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002223 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002224
paul020709f2003-04-04 02:44:16 +00002225 ospf = ospf_lookup ();
2226
paul718e3742002-12-13 20:15:29 +00002227 /* Get originate flags. */
paul68980082003-03-25 05:07:42 +00002228 origin = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002229
2230 p.family = AF_INET;
2231 p.prefix.s_addr = 0;
2232 p.prefixlen = 0;
2233
2234 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
2235 {
2236 /* If there is no default route via redistribute,
2237 then originate AS-external-LSA with nexthop 0 (self). */
2238 nexthop.s_addr = 0;
2239 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2240 }
2241
paul020709f2003-04-04 02:44:16 +00002242 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002243 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002244
2245 return 0;
2246}
2247
paul645878f2003-04-13 21:42:11 +00002248/* Flush any NSSA LSAs for given prefix */
2249void
2250ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2251{
paul1eb8ef22005-04-07 07:30:20 +00002252 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002253 struct ospf_lsa *lsa;
2254 struct ospf_area *area;
2255
paul1eb8ef22005-04-07 07:30:20 +00002256 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002257 {
paul1eb8ef22005-04-07 07:30:20 +00002258 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002259 {
2260 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2261 ospf->router_id)))
2262 {
2263 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002264 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002265 inet_ntoa (p->prefix), p->prefixlen);
2266 continue;
2267 }
2268 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2269 if (!IS_LSA_MAXAGE (lsa))
2270 {
2271 ospf_refresher_unregister_lsa (ospf, lsa);
2272 ospf_lsa_flush_area (lsa, area);
2273 }
2274 }
paul645878f2003-04-13 21:42:11 +00002275 }
2276}
paul645878f2003-04-13 21:42:11 +00002277
paul718e3742002-12-13 20:15:29 +00002278/* Flush an AS-external-LSA from LSDB and routing domain. */
2279void
paul68980082003-03-25 05:07:42 +00002280ospf_external_lsa_flush (struct ospf *ospf,
2281 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002282 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002283{
2284 struct ospf_lsa *lsa;
2285
2286 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002287 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002288 inet_ntoa (p->prefix), p->prefixlen);
2289
2290 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002291 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002292 {
2293 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002294 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002295 inet_ntoa (p->prefix), p->prefixlen);
2296 return;
2297 }
hassobeebba72004-06-20 21:00:27 +00002298
pauld4a53d52003-07-12 21:30:57 +00002299 /* If LSA is selforiginated, not a translated LSA, and there is
2300 * NSSA area, flush Type-7 LSA's at first.
2301 */
2302 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2303 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002304 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002305
2306 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002307 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002308
2309 /* There must be no self-originated LSA in rtrs_external. */
2310#if 0
2311 /* Remove External route from Zebra. */
2312 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2313#endif
2314
2315 if (!IS_LSA_MAXAGE (lsa))
2316 {
2317 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002318 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002319
2320 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002321 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002322 }
2323
2324 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002325 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002326}
2327
2328void
paul68980082003-03-25 05:07:42 +00002329ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002330{
2331 struct prefix_ipv4 p;
2332 struct external_info *ei;
2333 struct ospf_lsa *lsa;
2334
2335 p.family = AF_INET;
2336 p.prefixlen = 0;
2337 p.prefix.s_addr = 0;
2338
paul020709f2003-04-04 02:44:16 +00002339 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002340 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002341
2342 if (ei)
2343 {
2344 if (lsa)
2345 {
2346 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002347 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002348 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002349 }
2350 else
2351 {
2352 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002353 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002354 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002355 }
2356 }
2357 else
2358 {
2359 if (lsa)
2360 {
2361 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002362 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002363 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002364 }
2365 }
2366}
2367
2368void
paul68980082003-03-25 05:07:42 +00002369ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002370{
2371 struct route_node *rn;
2372 struct external_info *ei;
2373
2374 if (type != DEFAULT_ROUTE)
2375 if (EXTERNAL_INFO(type))
2376 /* Refresh each redistributed AS-external-LSAs. */
2377 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2378 if ((ei = rn->info))
2379 if (!is_prefix_default (&ei->p))
2380 {
2381 struct ospf_lsa *lsa;
2382
paul68980082003-03-25 05:07:42 +00002383 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2384 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002385 else
paul68980082003-03-25 05:07:42 +00002386 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002387 }
2388}
2389
2390/* Refresh AS-external-LSA. */
2391void
paul68980082003-03-25 05:07:42 +00002392ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002393 struct external_info *ei, int force)
2394{
2395 struct ospf_lsa *new;
2396 int changed;
2397
2398 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002399 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002400 {
pauld4a53d52003-07-12 21:30:57 +00002401 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002402 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002403 "redist check fail",
2404 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002405 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002406 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002407 return;
2408 }
2409
2410 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002411 {
2412 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002413 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002414 lsa->data->type, inet_ntoa (lsa->data->id));
2415 return;
2416 }
paul718e3742002-12-13 20:15:29 +00002417
2418 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002419 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002420
2421 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002422 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002423
paul68980082003-03-25 05:07:42 +00002424 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002425
2426 if (new == NULL)
2427 {
2428 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002429 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002430 inet_ntoa (lsa->data->id));
2431 return;
2432 }
2433
2434 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2435
2436 /* Record timestamp. */
2437 gettimeofday (&new->tv_orig, NULL);
2438
2439 /* Re-calculate checksum. */
2440 ospf_lsa_checksum (new->data);
2441
paul68980082003-03-25 05:07:42 +00002442 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002443
2444 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002445 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002446
paul718e3742002-12-13 20:15:29 +00002447 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002448 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002449 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002450
pauld4a53d52003-07-12 21:30:57 +00002451 /* Register self-originated LSA to refresh queue.
2452 * Translated LSAs should not be registered, but refreshed upon
2453 * refresh of the Type-7
2454 */
2455 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2456 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002457
2458 /* Debug logging. */
2459 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2460 {
ajse588f212004-12-08 18:12:06 +00002461 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002462 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002463 ospf_lsa_header_dump (new->data);
2464 }
2465
2466 return;
2467}
2468
2469
2470/* LSA installation functions. */
2471
2472/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002473static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002474ospf_router_lsa_install (struct ospf *ospf,
2475 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002476{
2477 struct ospf_area *area = new->area;
2478
2479 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2480 The entire routing table must be recalculated, starting with
2481 the shortest path calculations for each area (not just the
2482 area whose link-state database has changed).
2483 */
2484 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002485 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002486
2487 if (IS_LSA_SELF (new))
2488 {
2489 /* Set router-LSA refresh timer. */
2490 OSPF_TIMER_OFF (area->t_router_lsa_self);
2491 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002492 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002493
2494 /* Set self-originated router-LSA. */
2495 ospf_lsa_unlock (area->router_lsa_self);
2496 area->router_lsa_self = ospf_lsa_lock (new);
2497
2498 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002499 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002500 new->data->type, inet_ntoa (new->data->id),
2501 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002502 }
2503
2504 return new;
2505}
2506
2507#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2508 if (!(T)) \
2509 (T) = thread_add_timer (master, (F), oi, (V))
2510
2511/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002512static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002513ospf_network_lsa_install (struct ospf *ospf,
2514 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002515 struct ospf_lsa *new,
2516 int rt_recalc)
2517{
2518
2519 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2520 The entire routing table must be recalculated, starting with
2521 the shortest path calculations for each area (not just the
2522 area whose link-state database has changed).
2523 */
2524 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002525 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002526
2527 /* We supposed that when LSA is originated by us, we pass the int
2528 for which it was originated. If LSA was received by flooding,
2529 the RECEIVED flag is set, so we do not link the LSA to the int. */
2530 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2531 {
2532 /* Set LSRefresh timer. */
2533 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2534
2535 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2536 ospf_network_lsa_refresh_timer,
2537 OSPF_LS_REFRESH_TIME);
2538
2539 ospf_lsa_unlock (oi->network_lsa_self);
2540 oi->network_lsa_self = ospf_lsa_lock (new);
2541 }
2542
2543 return new;
2544}
2545
2546/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002547static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002548ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2549 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002550{
paul718e3742002-12-13 20:15:29 +00002551 if (rt_recalc && !IS_LSA_SELF (new))
2552 {
2553 /* RFC 2328 Section 13.2 Summary-LSAs
2554 The best route to the destination described by the summary-
2555 LSA must be recalculated (see Section 16.5). If this
2556 destination is an AS boundary router, it may also be
2557 necessary to re-examine all the AS-external-LSAs.
2558 */
2559
2560#if 0
2561 /* This doesn't exist yet... */
2562 ospf_summary_incremental_update(new); */
2563#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002564 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002565#endif /* #if 0 */
2566
2567 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002568 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002569 }
2570
2571 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002572 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002573
2574 return new;
2575}
2576
2577/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002578static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002579ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2580 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002581{
2582 if (rt_recalc && !IS_LSA_SELF (new))
2583 {
2584 /* RFC 2328 Section 13.2 Summary-LSAs
2585 The best route to the destination described by the summary-
2586 LSA must be recalculated (see Section 16.5). If this
2587 destination is an AS boundary router, it may also be
2588 necessary to re-examine all the AS-external-LSAs.
2589 */
2590#if 0
2591 /* These don't exist yet... */
2592 ospf_summary_incremental_update(new);
2593 /* Isn't this done by the above call?
2594 - RFC 2328 Section 16.5 implies it should be */
2595 /* ospf_ase_calculate_schedule(); */
2596#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002597 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002598#endif /* #if 0 */
2599 }
2600
2601 /* register LSA to refresh-list. */
2602 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002603 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002604
2605 return new;
2606}
2607
2608/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002609static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002610ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2611 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002612{
paul68980082003-03-25 05:07:42 +00002613 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002614 /* If LSA is not self-originated, calculate an external route. */
2615 if (rt_recalc)
2616 {
2617 /* RFC 2328 Section 13.2 AS-external-LSAs
2618 The best route to the destination described by the AS-
2619 external-LSA must be recalculated (see Section 16.6).
2620 */
2621
2622 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002623 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002624 }
2625
pauld4a53d52003-07-12 21:30:57 +00002626 if (new->data->type == OSPF_AS_NSSA_LSA)
2627 {
2628 /* There is no point to register selforiginate Type-7 LSA for
2629 * refreshing. We rely on refreshing Type-5 LSA's
2630 */
2631 if (IS_LSA_SELF (new))
2632 return new;
2633 else
2634 {
2635 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2636 * New translations will be taken care of by the abr_task.
2637 */
2638 ospf_translated_nssa_refresh (ospf, new, NULL);
2639 }
2640 }
pauld7480322003-05-16 17:31:51 +00002641
pauld4a53d52003-07-12 21:30:57 +00002642 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002643 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002644 */
hassobeebba72004-06-20 21:00:27 +00002645 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002646 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002647
2648 return new;
2649}
2650
2651void
paul68980082003-03-25 05:07:42 +00002652ospf_discard_from_db (struct ospf *ospf,
2653 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002654{
2655 struct ospf_lsa *old;
2656
2657 old = ospf_lsdb_lookup (lsdb, lsa);
2658
2659 if (!old)
2660 return;
2661
2662 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002663 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002664
2665 switch (old->data->type)
2666 {
2667 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002668 ospf_ase_unregister_external_lsa (old, ospf);
2669 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2670 break;
paul718e3742002-12-13 20:15:29 +00002671#ifdef HAVE_OPAQUE_LSA
2672 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002673 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002674 break;
paul69310a62005-05-11 18:09:59 +00002675#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002676 case OSPF_AS_NSSA_LSA:
2677 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2678 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002679 break;
paul718e3742002-12-13 20:15:29 +00002680 default:
paul68980082003-03-25 05:07:42 +00002681 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002682 break;
2683 }
2684
paul68980082003-03-25 05:07:42 +00002685 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002686 ospf_lsa_discard (old);
2687}
2688
paul718e3742002-12-13 20:15:29 +00002689struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002690ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2691 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002692{
2693 struct ospf_lsa *new = NULL;
2694 struct ospf_lsa *old = NULL;
2695 struct ospf_lsdb *lsdb = NULL;
2696 int rt_recalc;
2697
2698 /* Set LSDB. */
2699 switch (lsa->data->type)
2700 {
paulf2c80652002-12-13 21:44:27 +00002701 /* kevinm */
2702 case OSPF_AS_NSSA_LSA:
2703 if (lsa->area)
2704 lsdb = lsa->area->lsdb;
2705 else
paul68980082003-03-25 05:07:42 +00002706 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002707 break;
paul718e3742002-12-13 20:15:29 +00002708 case OSPF_AS_EXTERNAL_LSA:
2709#ifdef HAVE_OPAQUE_LSA
2710 case OSPF_OPAQUE_AS_LSA:
2711#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002712 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002713 break;
2714 default:
2715 lsdb = lsa->area->lsdb;
2716 break;
2717 }
2718
paul718e3742002-12-13 20:15:29 +00002719 assert (lsdb);
2720
2721 /* RFC 2328 13.2. Installing LSAs in the database
2722
2723 Installing a new LSA in the database, either as the result of
2724 flooding or a newly self-originated LSA, may cause the OSPF
2725 routing table structure to be recalculated. The contents of the
2726 new LSA should be compared to the old instance, if present. If
2727 there is no difference, there is no need to recalculate the
2728 routing table. When comparing an LSA to its previous instance,
2729 the following are all considered to be differences in contents:
2730
2731 o The LSA's Options field has changed.
2732
2733 o One of the LSA instances has LS age set to MaxAge, and
2734 the other does not.
2735
2736 o The length field in the LSA header has changed.
2737
2738 o The body of the LSA (i.e., anything outside the 20-byte
2739 LSA header) has changed. Note that this excludes changes
2740 in LS Sequence Number and LS Checksum.
2741
2742 */
2743 /* Look up old LSA and determine if any SPF calculation or incremental
2744 update is needed */
2745 old = ospf_lsdb_lookup (lsdb, lsa);
2746
2747 /* Do comparision and record if recalc needed. */
2748 rt_recalc = 0;
2749 if ( old == NULL || ospf_lsa_different(old, lsa))
2750 rt_recalc = 1;
2751
paul7ddf1d62003-10-13 09:06:46 +00002752 /*
2753 Sequence number check (Section 14.1 of rfc 2328)
2754 "Premature aging is used when it is time for a self-originated
2755 LSA's sequence number field to wrap. At this point, the current
2756 LSA instance (having LS sequence number MaxSequenceNumber) must
2757 be prematurely aged and flushed from the routing domain before a
2758 new instance with sequence number equal to InitialSequenceNumber
2759 can be originated. "
2760 */
2761
paul553ff112004-06-06 09:41:00 +00002762 if (ntohl(lsa->data->ls_seqnum) - 1 == htonl(OSPF_MAX_SEQUENCE_NUMBER))
paul7ddf1d62003-10-13 09:06:46 +00002763 {
2764 if (ospf_lsa_is_self_originated(ospf, lsa))
2765 {
paul0c2be262004-05-31 14:16:54 +00002766 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2767
2768 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002769 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2770 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2771
2772 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2773 {
ajse588f212004-12-08 18:12:06 +00002774 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002775 "lsa 0x%lx", (u_long)lsa);
2776 ospf_lsa_header_dump (lsa->data);
2777 }
2778 }
2779 else
2780 {
2781 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2782 {
ajse588f212004-12-08 18:12:06 +00002783 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002784 "that was not self originated. Ignoring\n");
2785 ospf_lsa_header_dump (lsa->data);
2786 }
2787 return old;
2788 }
2789 }
2790
paul718e3742002-12-13 20:15:29 +00002791 /* discard old LSA from LSDB */
2792 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002793 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002794
paul718e3742002-12-13 20:15:29 +00002795 /* Calculate Checksum if self-originated?. */
2796 if (IS_LSA_SELF (lsa))
2797 ospf_lsa_checksum (lsa->data);
2798
hassofe71a972004-12-22 16:16:02 +00002799 /* Insert LSA to LSDB. */
2800 ospf_lsdb_add (lsdb, lsa);
2801 lsa->lsdb = lsdb;
2802
paul718e3742002-12-13 20:15:29 +00002803 /* Do LSA specific installation process. */
2804 switch (lsa->data->type)
2805 {
2806 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002807 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002808 break;
2809 case OSPF_NETWORK_LSA:
2810 assert (oi);
paul68980082003-03-25 05:07:42 +00002811 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002812 break;
2813 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002814 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002815 break;
2816 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002817 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002818 break;
2819 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002820 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002821 break;
2822#ifdef HAVE_OPAQUE_LSA
2823 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002824 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002825 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002826 else
paul68980082003-03-25 05:07:42 +00002827 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002828 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002829 case OSPF_OPAQUE_AREA_LSA:
2830 case OSPF_OPAQUE_AS_LSA:
2831 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2832 break;
2833#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002834 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002835 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002836 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002837 break;
2838 }
2839
2840 if (new == NULL)
2841 return new; /* Installation failed, cannot proceed further -- endo. */
2842
2843 /* Debug logs. */
2844 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2845 {
2846 char area_str[INET_ADDRSTRLEN];
2847
2848 switch (lsa->data->type)
2849 {
2850 case OSPF_AS_EXTERNAL_LSA:
2851#ifdef HAVE_OPAQUE_LSA
2852 case OSPF_OPAQUE_AS_LSA:
2853#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002854 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002855 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002856 dump_lsa_key (new),
2857 LOOKUP (ospf_lsa_type_msg, new->data->type));
2858 break;
2859 default:
2860 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002861 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002862 dump_lsa_key (new),
2863 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2864 break;
2865 }
2866 }
2867
paul7ddf1d62003-10-13 09:06:46 +00002868 /*
2869 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2870 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2871 */
2872 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2873 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002874 {
paul7ddf1d62003-10-13 09:06:46 +00002875 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002876 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002877 new->data->type,
2878 inet_ntoa (new->data->id),
2879 lsa);
paul68980082003-03-25 05:07:42 +00002880 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002881 }
2882
2883 return new;
2884}
2885
2886
paul4dadc292005-05-06 21:37:42 +00002887static int
paul68980082003-03-25 05:07:42 +00002888ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002889{
paul1eb8ef22005-04-07 07:30:20 +00002890 struct listnode *node, *nnode;
2891 struct ospf_interface *oi;
2892
2893 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002894 {
paul718e3742002-12-13 20:15:29 +00002895 struct route_node *rn;
2896 struct ospf_neighbor *nbr;
2897
2898 if (ospf_if_is_enable (oi))
2899 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2900 if ((nbr = rn->info) != NULL)
2901 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2902 {
2903 route_unlock_node (rn);
2904 return 0;
2905 }
2906 }
2907
2908 return 1;
2909}
2910
2911
2912#ifdef ORIGINAL_CODING
2913/* This function flood the maxaged LSA to DR. */
2914void
2915ospf_maxage_flood (struct ospf_lsa *lsa)
2916{
2917 switch (lsa->data->type)
2918 {
2919 case OSPF_ROUTER_LSA:
2920 case OSPF_NETWORK_LSA:
2921 case OSPF_SUMMARY_LSA:
2922 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002923 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002924#ifdef HAVE_OPAQUE_LSA
2925 case OSPF_OPAQUE_LINK_LSA:
2926 case OSPF_OPAQUE_AREA_LSA:
2927#endif /* HAVE_OPAQUE_LSA */
2928 ospf_flood_through_area (lsa->area, NULL, lsa);
2929 break;
2930 case OSPF_AS_EXTERNAL_LSA:
2931#ifdef HAVE_OPAQUE_LSA
2932 case OSPF_OPAQUE_AS_LSA:
2933#endif /* HAVE_OPAQUE_LSA */
2934 ospf_flood_through_as (NULL, lsa);
2935 break;
2936 default:
2937 break;
2938 }
2939}
2940#endif /* ORIGINAL_CODING */
2941
paul4dadc292005-05-06 21:37:42 +00002942static int
paul718e3742002-12-13 20:15:29 +00002943ospf_maxage_lsa_remover (struct thread *thread)
2944{
paul68980082003-03-25 05:07:42 +00002945 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002946 struct ospf_lsa *lsa;
2947 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002948 int reschedule = 0;
2949
paul68980082003-03-25 05:07:42 +00002950 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002951
2952 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002953 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002954
paul68980082003-03-25 05:07:42 +00002955 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002956
2957 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002958 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002959 {
paul718e3742002-12-13 20:15:29 +00002960 if (lsa->retransmit_counter > 0)
2961 {
2962 reschedule = 1;
2963 continue;
2964 }
2965
2966 /* Remove LSA from the LSDB */
2967 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2968 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002969 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002970 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002971
2972 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002973 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002974 lsa->data->type, inet_ntoa (lsa->data->id));
2975
2976 /* Flood max age LSA. */
2977#ifdef ORIGINAL_CODING
2978 ospf_maxage_flood (lsa);
2979#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002980 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002981#endif /* ORIGINAL_CODING */
2982
paul7ddf1d62003-10-13 09:06:46 +00002983 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2984 {
2985 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002986 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002987 (u_long)lsa);
2988 ospf_router_lsa_originate(lsa->area);
2989 }
2990
paul718e3742002-12-13 20:15:29 +00002991 /* Remove from lsdb. */
paul68980082003-03-25 05:07:42 +00002992 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002993 ospf_lsdb_delete (lsa->lsdb, lsa);
2994 }
2995
2996 /* A MaxAge LSA must be removed immediately from the router's link
2997 state database as soon as both a) it is no longer contained on any
2998 neighbor Link state retransmission lists and b) none of the router's
2999 neighbors are in states Exchange or Loading. */
3000 if (reschedule)
paul68980082003-03-25 05:07:42 +00003001 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003002
3003 return 0;
3004}
3005
paul4dadc292005-05-06 21:37:42 +00003006static int
paul68980082003-03-25 05:07:42 +00003007ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003008{
hasso52dc7ee2004-09-23 19:18:23 +00003009 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003010 struct ospf_lsa *lsa;
3011
3012 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3013 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003014 return 1;
3015
3016 return 0;
3017}
3018
3019void
paul68980082003-03-25 05:07:42 +00003020ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003021{
hasso52dc7ee2004-09-23 19:18:23 +00003022 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003023
paul68980082003-03-25 05:07:42 +00003024 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003025 {
paul68980082003-03-25 05:07:42 +00003026 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00003027 ospf_lsa_unlock (lsa);
3028 }
3029}
3030
3031void
paul68980082003-03-25 05:07:42 +00003032ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003033{
3034 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3035 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003036 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003037 {
3038 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003039 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003040 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3041 return;
3042 }
3043
paul68980082003-03-25 05:07:42 +00003044 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003045
3046 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003047 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003048
paul68980082003-03-25 05:07:42 +00003049 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003050}
3051
paul4dadc292005-05-06 21:37:42 +00003052static int
paul68980082003-03-25 05:07:42 +00003053ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003054{
paul718e3742002-12-13 20:15:29 +00003055 /* Stay away from any Local Translated Type-7 LSAs */
3056 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3057 return 0;
paul718e3742002-12-13 20:15:29 +00003058
3059 if (IS_LSA_MAXAGE (lsa))
3060 /* Self-originated LSAs should NOT time-out instead,
3061 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003062 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003063 {
3064 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003065 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003066
3067 switch (lsa->data->type)
3068 {
paul718e3742002-12-13 20:15:29 +00003069#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003070 case OSPF_OPAQUE_LINK_LSA:
3071 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003072 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003073 /*
3074 * As a general rule, whenever network topology has changed
3075 * (due to an LSA removal in this case), routing recalculation
3076 * should be triggered. However, this is not true for opaque
3077 * LSAs. Even if an opaque LSA instance is going to be removed
3078 * from the routing domain, it does not mean a change in network
3079 * topology, and thus, routing recalculation is not needed here.
3080 */
3081 break;
paul718e3742002-12-13 20:15:29 +00003082#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003083 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003084 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003085 ospf_ase_incremental_update (ospf, lsa);
3086 break;
paul718e3742002-12-13 20:15:29 +00003087 default:
paul68980082003-03-25 05:07:42 +00003088 ospf_spf_calculate_schedule (ospf);
3089 break;
paul718e3742002-12-13 20:15:29 +00003090 }
paul68980082003-03-25 05:07:42 +00003091 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003092 }
3093
3094 return 0;
3095}
3096
3097/* Periodical check of MaxAge LSA. */
3098int
paul68980082003-03-25 05:07:42 +00003099ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003100{
paul68980082003-03-25 05:07:42 +00003101 struct ospf *ospf = THREAD_ARG (thread);
3102 struct route_node *rn;
3103 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003104 struct ospf_area *area;
3105 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003106
paul68980082003-03-25 05:07:42 +00003107 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003108
paul1eb8ef22005-04-07 07:30:20 +00003109 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003110 {
paul68980082003-03-25 05:07:42 +00003111 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3112 ospf_lsa_maxage_walker_remover (ospf, lsa);
3113 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3114 ospf_lsa_maxage_walker_remover (ospf, lsa);
3115 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3116 ospf_lsa_maxage_walker_remover (ospf, lsa);
3117 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3118 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003119#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003120 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3121 ospf_lsa_maxage_walker_remover (ospf, lsa);
3122 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3123 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003124#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003125 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3126 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003127 }
3128
paul4fb949e2003-05-10 20:06:51 +00003129 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003130 if (ospf->lsdb)
3131 {
3132 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3133 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003134#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003135 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3136 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003137#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003138 }
paul718e3742002-12-13 20:15:29 +00003139
paul68980082003-03-25 05:07:42 +00003140 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3141 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003142 return 0;
3143}
3144
paul68980082003-03-25 05:07:42 +00003145struct ospf_lsa *
3146ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3147 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003148{
paul68980082003-03-25 05:07:42 +00003149 struct ospf_lsa *lsa;
3150 struct in_addr mask, id;
3151 struct lsa_header_mask
3152 {
3153 struct lsa_header header;
3154 struct in_addr mask;
3155 } *hmask;
paul718e3742002-12-13 20:15:29 +00003156
paul68980082003-03-25 05:07:42 +00003157 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3158 if (lsa == NULL)
3159 return NULL;
paul718e3742002-12-13 20:15:29 +00003160
paul68980082003-03-25 05:07:42 +00003161 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003162
paul68980082003-03-25 05:07:42 +00003163 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003164
paul68980082003-03-25 05:07:42 +00003165 if (mask.s_addr != hmask->mask.s_addr)
3166 {
3167 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3168 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3169 if (!lsa)
3170 return NULL;
3171 }
paul718e3742002-12-13 20:15:29 +00003172
paul68980082003-03-25 05:07:42 +00003173 return lsa;
paul718e3742002-12-13 20:15:29 +00003174}
3175
3176struct ospf_lsa *
3177ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3178 struct in_addr id, struct in_addr adv_router)
3179{
paule05fba42003-04-13 20:20:53 +00003180 struct ospf *ospf = ospf_lookup();
3181 assert(ospf);
3182
paul718e3742002-12-13 20:15:29 +00003183 switch (type)
3184 {
3185 case OSPF_ROUTER_LSA:
3186 case OSPF_NETWORK_LSA:
3187 case OSPF_SUMMARY_LSA:
3188 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003189 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003190#ifdef HAVE_OPAQUE_LSA
3191 case OSPF_OPAQUE_LINK_LSA:
3192 case OSPF_OPAQUE_AREA_LSA:
3193#endif /* HAVE_OPAQUE_LSA */
3194 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
3195 break;
3196 case OSPF_AS_EXTERNAL_LSA:
3197#ifdef HAVE_OPAQUE_LSA
3198 case OSPF_OPAQUE_AS_LSA:
3199#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003200 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003201 break;
3202 default:
3203 break;
3204 }
3205
3206 return NULL;
3207}
3208
3209struct ospf_lsa *
3210ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3211 struct in_addr id)
3212{
3213 struct ospf_lsa *lsa;
3214 struct route_node *rn;
3215
3216 switch (type)
3217 {
3218 case OSPF_ROUTER_LSA:
3219 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3220 break;
3221 case OSPF_NETWORK_LSA:
3222 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3223 if ((lsa = rn->info))
3224 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3225 {
3226 route_unlock_node (rn);
3227 return lsa;
3228 }
3229 break;
3230 case OSPF_SUMMARY_LSA:
3231 case OSPF_ASBR_SUMMARY_LSA:
3232 /* Currently not used. */
3233 assert (1);
3234 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3235 break;
3236 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003237 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003238#ifdef HAVE_OPAQUE_LSA
3239 case OSPF_OPAQUE_LINK_LSA:
3240 case OSPF_OPAQUE_AREA_LSA:
3241 case OSPF_OPAQUE_AS_LSA:
3242 /* Currently not used. */
3243 break;
3244#endif /* HAVE_OPAQUE_LSA */
3245 default:
3246 break;
3247 }
3248
3249 return NULL;
3250}
3251
3252struct ospf_lsa *
3253ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3254{
3255 struct ospf_lsa *match;
3256
3257#ifdef HAVE_OPAQUE_LSA
3258 /*
3259 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3260 * is redefined to have two subfields; opaque-type and opaque-id.
3261 * However, it is harmless to treat the two sub fields together, as if
3262 * they two were forming a unique LSA-ID.
3263 */
3264#endif /* HAVE_OPAQUE_LSA */
3265
3266 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3267
3268 if (match == NULL)
3269 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003270 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003271 lsah->type, inet_ntoa (lsah->id));
3272
3273 return match;
3274}
3275
3276/* return +n, l1 is more recent.
3277 return -n, l2 is more recent.
3278 return 0, l1 and l2 is identical. */
3279int
3280ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3281{
3282 int r;
3283 int x, y;
3284
3285 if (l1 == NULL && l2 == NULL)
3286 return 0;
3287 if (l1 == NULL)
3288 return -1;
3289 if (l2 == NULL)
3290 return 1;
3291
3292 /* compare LS sequence number. */
3293 x = (int) ntohl (l1->data->ls_seqnum);
3294 y = (int) ntohl (l2->data->ls_seqnum);
3295 if (x > y)
3296 return 1;
3297 if (x < y)
3298 return -1;
3299
3300 /* compare LS checksum. */
3301 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3302 if (r)
3303 return r;
3304
3305 /* compare LS age. */
3306 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3307 return 1;
3308 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3309 return -1;
3310
3311 /* compare LS age with MaxAgeDiff. */
3312 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3313 return -1;
3314 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3315 return 1;
3316
3317 /* LSAs are identical. */
3318 return 0;
3319}
3320
3321/* If two LSAs are different, return 1, otherwise return 0. */
3322int
3323ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3324{
3325 char *p1, *p2;
3326 assert (l1);
3327 assert (l2);
3328 assert (l1->data);
3329 assert (l2->data);
3330
3331 if (l1->data->options != l2->data->options)
3332 return 1;
3333
3334 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3335 return 1;
3336
3337 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3338 return 1;
3339
3340 if (l1->data->length != l2->data->length)
3341 return 1;
3342
3343 if (l1->data->length == 0)
3344 return 1;
3345
pauld1825832003-04-03 01:27:01 +00003346 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003347
3348 p1 = (char *) l1->data;
3349 p2 = (char *) l2->data;
3350
3351 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3352 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3353 return 1;
3354
3355 return 0;
3356}
3357
3358#ifdef ORIGINAL_CODING
3359void
3360ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3361 struct ospf_lsa *self,
3362 struct ospf_lsa *new)
3363{
3364 u_int32_t seqnum;
3365
3366 /* Adjust LS Sequence Number. */
3367 seqnum = ntohl (new->data->ls_seqnum) + 1;
3368 self->data->ls_seqnum = htonl (seqnum);
3369
3370 /* Recalculate LSA checksum. */
3371 ospf_lsa_checksum (self->data);
3372
3373 /* Reflooding LSA. */
3374 /* RFC2328 Section 13.3
3375 On non-broadcast networks, separate Link State Update
3376 packets must be sent, as unicasts, to each adjacent neighbor
3377 (i.e., those in state Exchange or greater). The destination
3378 IP addresses for these packets are the neighbors' IP
3379 addresses. */
3380 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3381 {
3382 struct route_node *rn;
3383 struct ospf_neighbor *onbr;
3384
3385 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3386 if ((onbr = rn->info) != NULL)
3387 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3388 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3389 }
3390 else
3391 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3392
3393 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003394 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003395 self->data->type, inet_ntoa (self->data->id));
3396}
3397#else /* ORIGINAL_CODING */
3398static int
paul68980082003-03-25 05:07:42 +00003399ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003400{
3401 if (lsa == NULL || !IS_LSA_SELF (lsa))
3402 return 0;
3403
3404 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003405 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 +00003406
3407 /* Force given lsa's age to MaxAge. */
3408 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3409
3410 switch (lsa->data->type)
3411 {
3412#ifdef HAVE_OPAQUE_LSA
3413 case OSPF_OPAQUE_LINK_LSA:
3414 case OSPF_OPAQUE_AREA_LSA:
3415 case OSPF_OPAQUE_AS_LSA:
3416 ospf_opaque_lsa_refresh (lsa);
3417 break;
3418#endif /* HAVE_OPAQUE_LSA */
3419 default:
paul68980082003-03-25 05:07:42 +00003420 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003421 break;
3422 }
3423
3424 return 0;
3425}
3426
3427void
paul68980082003-03-25 05:07:42 +00003428ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003429{
paul1eb8ef22005-04-07 07:30:20 +00003430 struct listnode *node, *nnode;
3431 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003432 struct ospf_area *area;
3433 struct ospf_interface *oi;
3434 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003435 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003436 int need_to_flush_ase = 0;
3437
paul1eb8ef22005-04-07 07:30:20 +00003438 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003439 {
paul718e3742002-12-13 20:15:29 +00003440 if ((lsa = area->router_lsa_self) != NULL)
3441 {
3442 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003443 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 +00003444
3445 ospf_lsa_flush_area (lsa, area);
3446 ospf_lsa_unlock (area->router_lsa_self);
3447 area->router_lsa_self = NULL;
3448 OSPF_TIMER_OFF (area->t_router_lsa_self);
3449 }
3450
paul1eb8ef22005-04-07 07:30:20 +00003451 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003452 {
paul718e3742002-12-13 20:15:29 +00003453 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003454 && oi->state == ISM_DR
3455 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003456 {
3457 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003458 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 +00003459
3460 ospf_lsa_flush_area (oi->network_lsa_self, area);
3461 ospf_lsa_unlock (oi->network_lsa_self);
3462 oi->network_lsa_self = NULL;
3463 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3464 }
3465
3466 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3467 && area->external_routing == OSPF_AREA_DEFAULT)
3468 need_to_flush_ase = 1;
3469 }
3470
paul68980082003-03-25 05:07:42 +00003471 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3472 ospf_lsa_flush_schedule (ospf, lsa);
3473 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3474 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003475#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003476 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3477 ospf_lsa_flush_schedule (ospf, lsa);
3478 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3479 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003480#endif /* HAVE_OPAQUE_LSA */
3481 }
3482
3483 if (need_to_flush_ase)
3484 {
paul68980082003-03-25 05:07:42 +00003485 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3486 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003487#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003488 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3489 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003490#endif /* HAVE_OPAQUE_LSA */
3491 }
3492
3493 /*
3494 * Make sure that the MaxAge LSA remover is executed immediately,
3495 * without conflicting to other threads.
3496 */
paul68980082003-03-25 05:07:42 +00003497 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003498 {
paul68980082003-03-25 05:07:42 +00003499 OSPF_TIMER_OFF (ospf->t_maxage);
3500 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003501 }
3502
3503 return;
3504}
3505#endif /* ORIGINAL_CODING */
3506
3507/* If there is self-originated LSA, then return 1, otherwise return 0. */
3508/* An interface-independent version of ospf_lsa_is_self_originated */
3509int
paul68980082003-03-25 05:07:42 +00003510ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003511{
hasso52dc7ee2004-09-23 19:18:23 +00003512 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003513 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003514
3515 /* This LSA is already checked. */
3516 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3517 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3518
3519 /* Make sure LSA is self-checked. */
3520 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3521
3522 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003523 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003524 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3525
3526 /* LSA is router-LSA. */
3527 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003528 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003529 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3530
3531 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3532 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003533 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003534 {
paul718e3742002-12-13 20:15:29 +00003535 /* Ignore virtual link. */
3536 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3537 if (oi->address->family == AF_INET)
3538 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3539 {
3540 /* to make it easier later */
3541 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3542 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3543 }
3544 }
3545
3546 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3547}
3548
3549/* Get unique Link State ID. */
3550struct in_addr
paul68980082003-03-25 05:07:42 +00003551ospf_lsa_unique_id (struct ospf *ospf,
3552 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003553{
3554 struct ospf_lsa *lsa;
3555 struct in_addr mask, id;
3556
3557 id = p->prefix;
3558
3559 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003560 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003561 if (lsa)
3562 {
3563 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3564 if (ip_masklen (al->mask) == p->prefixlen)
3565 {
3566 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003567 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003568 "Can't get Link State ID for %s/%d",
3569 inet_ntoa (p->prefix), p->prefixlen);
3570 /* id.s_addr = 0; */
3571 id.s_addr = 0xffffffff;
3572 return id;
3573 }
3574 /* Masklen differs, then apply wildcard mask to Link State ID. */
3575 else
3576 {
3577 masklen2ip (p->prefixlen, &mask);
3578
3579 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003580 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3581 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003582 if (lsa)
3583 {
3584 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003585 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003586 "Can't get Link State ID for %s/%d",
3587 inet_ntoa (p->prefix), p->prefixlen);
3588 /* id.s_addr = 0; */
3589 id.s_addr = 0xffffffff;
3590 return id;
3591 }
3592 }
3593 }
3594
3595 return id;
3596}
3597
3598
3599#define LSA_ACTION_ORIGN_RTR 1
3600#define LSA_ACTION_ORIGN_NET 2
3601#define LSA_ACTION_FLOOD_AREA 3
3602#define LSA_ACTION_FLOOD_AS 4
3603#define LSA_ACTION_FLUSH_AREA 5
3604#define LSA_ACTION_FLUSH_AS 6
3605
3606struct lsa_action
3607{
3608 u_char action;
3609 struct ospf_area *area;
3610 struct ospf_interface *oi;
3611 struct ospf_lsa *lsa;
3612};
3613
paul4dadc292005-05-06 21:37:42 +00003614static int
paul718e3742002-12-13 20:15:29 +00003615ospf_lsa_action (struct thread *t)
3616{
3617 struct lsa_action *data;
paul020709f2003-04-04 02:44:16 +00003618 struct ospf *ospf;
3619
3620 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00003621
3622 data = THREAD_ARG (t);
3623
3624 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003625 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003626 data->action);
3627
3628 switch (data->action)
3629 {
3630 case LSA_ACTION_ORIGN_RTR:
3631 ospf_router_lsa_refresh (data->area->router_lsa_self);
3632 break;
3633 case LSA_ACTION_ORIGN_NET:
3634 ospf_network_lsa_originate (data->oi);
3635 break;
3636 case LSA_ACTION_FLOOD_AREA:
3637 ospf_flood_through_area (data->area, NULL, data->lsa);
3638 break;
3639 case LSA_ACTION_FLOOD_AS:
paul68980082003-03-25 05:07:42 +00003640 ospf_flood_through_as (ospf, NULL, data->lsa);
paul718e3742002-12-13 20:15:29 +00003641 break;
3642 case LSA_ACTION_FLUSH_AREA:
3643 ospf_lsa_flush_area (data->lsa, data->area);
3644 break;
3645 case LSA_ACTION_FLUSH_AS:
paul68980082003-03-25 05:07:42 +00003646 ospf_lsa_flush_as (ospf, data->lsa);
paul718e3742002-12-13 20:15:29 +00003647 break;
3648 }
3649
3650 ospf_lsa_unlock (data->lsa);
3651 XFREE (MTYPE_OSPF_MESSAGE, data);
3652 return 0;
3653}
3654
3655void
3656ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3657{
3658 struct lsa_action *data;
3659
3660 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3661 memset (data, 0, sizeof (struct lsa_action));
3662
3663 data->action = LSA_ACTION_FLOOD_AREA;
3664 data->area = area;
3665 data->lsa = ospf_lsa_lock (lsa);
3666
3667 thread_add_event (master, ospf_lsa_action, data, 0);
3668}
3669
3670void
3671ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3672{
3673 struct lsa_action *data;
3674
3675 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3676 memset (data, 0, sizeof (struct lsa_action));
3677
3678 data->action = LSA_ACTION_FLUSH_AREA;
3679 data->area = area;
3680 data->lsa = ospf_lsa_lock (lsa);
3681
3682 thread_add_event (master, ospf_lsa_action, data, 0);
3683}
3684
3685
3686/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003687static void
paul68980082003-03-25 05:07:42 +00003688ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003689{
3690 struct external_info *ei;
3691 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3692
3693 switch (lsa->data->type)
3694 {
3695 /* Router and Network LSAs are processed differently. */
3696 case OSPF_ROUTER_LSA:
3697 case OSPF_NETWORK_LSA:
3698 break;
3699 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003700 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003701 break;
3702 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003703 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003704 break;
3705 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003706 /* Translated from NSSA Type-5s are refreshed when
3707 * from refresh of Type-7 - do not refresh these directly.
3708 */
3709 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3710 break;
paul718e3742002-12-13 20:15:29 +00003711 ei = ospf_external_info_check (lsa);
3712 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003713 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003714 else
pauld4a53d52003-07-12 21:30:57 +00003715 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003716 break;
3717#ifdef HAVE_OPAQUE_LSA
3718 case OSPF_OPAQUE_LINK_LSA:
3719 case OSPF_OPAQUE_AREA_LSA:
3720 case OSPF_OPAQUE_AS_LSA:
3721 ospf_opaque_lsa_refresh (lsa);
3722 break;
pauld7480322003-05-16 17:31:51 +00003723#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003724 default:
3725 break;
paul718e3742002-12-13 20:15:29 +00003726 }
3727}
3728
3729void
paul68980082003-03-25 05:07:42 +00003730ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003731{
3732 u_int16_t index, current_index;
3733
3734 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3735
3736 if (lsa->refresh_list < 0)
3737 {
3738 int delay;
3739
3740 if (LS_AGE (lsa) == 0 &&
3741 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3742 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3743 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3744 else
3745 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3746 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3747 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3748
3749 if (delay < 0)
3750 delay = 0;
3751
paul68980082003-03-25 05:07:42 +00003752 current_index = ospf->lsa_refresh_queue.index +
3753 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003754
3755 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3756 % (OSPF_LSA_REFRESHER_SLOTS);
3757
3758 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003759 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003760 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003761 if (!ospf->lsa_refresh_queue.qs[index])
3762 ospf->lsa_refresh_queue.qs[index] = list_new ();
3763 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003764 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003765 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003766 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003767 "setting refresh_list on lsa %p (slod %d)",
3768 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003769 }
3770}
3771
3772void
paul68980082003-03-25 05:07:42 +00003773ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003774{
3775 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3776 if (lsa->refresh_list >= 0)
3777 {
hasso52dc7ee2004-09-23 19:18:23 +00003778 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003779 listnode_delete (refresh_list, lsa);
3780 if (!listcount (refresh_list))
3781 {
3782 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003783 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003784 }
3785 ospf_lsa_unlock (lsa);
3786 lsa->refresh_list = -1;
3787 }
3788}
3789
3790int
3791ospf_lsa_refresh_walker (struct thread *t)
3792{
hasso52dc7ee2004-09-23 19:18:23 +00003793 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003794 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003795 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003796 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003797 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003798 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003799
3800 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003801 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003802
3803
paul68980082003-03-25 05:07:42 +00003804 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003805
ajs9dbc7972005-03-13 19:27:22 +00003806 /* Note: if clock has jumped backwards, then time change could be negative,
3807 so we are careful to cast the expression to unsigned before taking
3808 modulus. */
paul68980082003-03-25 05:07:42 +00003809 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003810 ((unsigned long)(ospf->lsa_refresh_queue.index +
3811 (time (NULL) - ospf->lsa_refresher_started) /
3812 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003813
3814 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003815 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003816 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003817
paul68980082003-03-25 05:07:42 +00003818 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003819 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3820 {
3821 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003822 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003823 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003824
paul68980082003-03-25 05:07:42 +00003825 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003826
paul68980082003-03-25 05:07:42 +00003827 ospf->lsa_refresh_queue.qs [i] = NULL;
3828
paul718e3742002-12-13 20:15:29 +00003829 if (refresh_list)
3830 {
paul1eb8ef22005-04-07 07:30:20 +00003831 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003832 {
paul718e3742002-12-13 20:15:29 +00003833 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003834 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003835 "refresh lsa %p (slot %d)",
3836 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003837
3838 list_delete_node (refresh_list, node);
3839 ospf_lsa_unlock (lsa);
3840 lsa->refresh_list = -1;
3841 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003842 }
3843 list_free (refresh_list);
3844 }
3845 }
3846
paul68980082003-03-25 05:07:42 +00003847 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3848 ospf, ospf->lsa_refresh_interval);
3849 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003850
paul1eb8ef22005-04-07 07:30:20 +00003851 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3852 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003853
3854 list_delete (lsa_to_refresh);
3855
3856 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003857 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003858
3859 return 0;
3860}
3861