blob: 509afc8a6a879c75c3704b0cb1310e0a64c2d4c4 [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
Paul Jakma075c2012006-03-30 14:34:31 +0000205 x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
paul718e3742002-12-13 20:15:29 +0000206 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. */
Paul Jakma9560fa82006-06-26 12:50:06 +0000440 if (area->external_routing == OSPF_AREA_STUB
441 || area->external_routing == OSPF_AREA_NSSA)
paul942b6c12003-06-22 08:22:18 +0000442 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
443 /* If ASBR set External flag */
444 else if (IS_OSPF_ASBR (area->ospf))
445 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
446
447 /* Set ABR dependent flags */
448 if (IS_OSPF_ABR (area->ospf))
449 {
450 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000451 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000452 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000453 */
pauld4a53d52003-07-12 21:30:57 +0000454 if ( (area->external_routing == OSPF_AREA_NSSA)
455 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
456 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000457 }
paul718e3742002-12-13 20:15:29 +0000458 return flags;
459}
460
461/* Lookup neighbor other than myself.
462 And check neighbor count,
463 Point-to-Point link must have only 1 neighbor. */
464struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000465ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000466{
paul718e3742002-12-13 20:15:29 +0000467 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000468 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000469
470 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000471 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
472 if ((nbr = rn->info))
473 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000474 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000475 {
476 route_unlock_node (rn);
477 break;
478 }
paul718e3742002-12-13 20:15:29 +0000479
480 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000481 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000482 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
483
484 return nbr;
485}
486
paul88d6cf32005-10-29 12:50:09 +0000487/* Determine cost of link, taking RFC3137 stub-router support into
488 * consideration
489 */
490static u_int16_t
491ospf_link_cost (struct ospf_interface *oi)
492{
493 /* RFC3137 stub router support */
494 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
495 return oi->output_cost;
496 else
497 return OSPF_OUTPUT_COST_INFINITE;
498}
499
paul718e3742002-12-13 20:15:29 +0000500/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000501static char
paul718e3742002-12-13 20:15:29 +0000502link_info_set (struct stream *s, struct in_addr id,
503 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
504{
paul779adb02006-01-18 15:07:38 +0000505 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
506 * vast majority of cases. Some rare routers with lots of links need more.
507 * we try accomodate those here.
508 */
509 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
510 {
511 size_t ret = OSPF_MAX_LSA_SIZE;
512
513 /* Can we enlarge the stream still? */
514 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
515 {
516 /* we futz the size here for simplicity, really we need to account
517 * for just:
518 * IP Header - (sizeof (struct ip))
519 * OSPF Header - OSPF_HEADER_SIZE
520 * LSA Header - OSPF_LSA_HEADER_SIZE
521 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
522 *
523 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
524 */
525 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
526 }
527
528 if (ret == OSPF_MAX_LSA_SIZE)
529 {
530 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
531 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
532 return 0;
533 }
534 }
535
paul718e3742002-12-13 20:15:29 +0000536 /* TOS based routing is not supported. */
537 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
538 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
539 stream_putc (s, type); /* Link Type. */
540 stream_putc (s, tos); /* TOS = 0. */
541 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000542
543 return 1;
paul718e3742002-12-13 20:15:29 +0000544}
545
546/* Describe Point-to-Point link. */
paul4dadc292005-05-06 21:37:42 +0000547static int
paul718e3742002-12-13 20:15:29 +0000548lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
549{
550 int links = 0;
551 struct ospf_neighbor *nbr;
552 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000553 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000554
555 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000556 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000557
paul68980082003-03-25 05:07:42 +0000558 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000559 if (nbr->state == NSM_Full)
560 {
561 /* For unnumbered point-to-point networks, the Link Data field
562 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000563 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
564 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000565 }
566
hasso3fb9cd62004-10-19 19:44:43 +0000567 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000568 {
569 /* Option 1:
570 link_type = LSA_LINK_TYPE_STUB;
571 link_id = nbr->address.u.prefix4;
572 link_data.s_addr = 0xffffffff;
573 link_cost = o->output_cost; */
574
575 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
576 mask.s_addr = 0xffffffff;
paul779adb02006-01-18 15:07:38 +0000577 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
578 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000579 }
580 else
581 {
582 /* Option 2: We need to include link to a stub
583 network regardless of the state of the neighbor */
584 masklen2ip (oi->address->prefixlen, &mask);
585 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000586 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
587 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000588 }
paul718e3742002-12-13 20:15:29 +0000589 return links;
590}
591
592/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000593static int
paul718e3742002-12-13 20:15:29 +0000594lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
595{
596 struct ospf_neighbor *dr;
597 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000598 u_int16_t cost = ospf_link_cost (oi);
599
paul718e3742002-12-13 20:15:29 +0000600 /* Describe Type 3 Link. */
601 if (oi->state == ISM_Waiting)
602 {
603 masklen2ip (oi->address->prefixlen, &mask);
604 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000605 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
606 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000607 }
608
609 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
610 /* Describe Type 2 link. */
611 if (dr && (dr->state == NSM_Full ||
612 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000613 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000614 {
paul779adb02006-01-18 15:07:38 +0000615 return link_info_set (s, DR (oi), oi->address->u.prefix4,
616 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000617 }
618 /* Describe type 3 link. */
619 else
620 {
621 masklen2ip (oi->address->prefixlen, &mask);
622 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000623 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
624 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000625 }
paul718e3742002-12-13 20:15:29 +0000626}
627
paul4dadc292005-05-06 21:37:42 +0000628static int
paul718e3742002-12-13 20:15:29 +0000629lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
630{
631 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000632
paul718e3742002-12-13 20:15:29 +0000633 /* Describe Type 3 Link. */
634 if (oi->state != ISM_Loopback)
635 return 0;
636
637 mask.s_addr = 0xffffffff;
638 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000639 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000640}
641
642/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000643static int
paul718e3742002-12-13 20:15:29 +0000644lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
645{
646 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000647 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000648
paul718e3742002-12-13 20:15:29 +0000649 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000650 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000651 if (nbr->state == NSM_Full)
652 {
paul779adb02006-01-18 15:07:38 +0000653 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
654 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000655 }
656
657 return 0;
658}
659
660#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
661
paul7afa08d2002-12-13 20:59:45 +0000662/* this function add for support point-to-multipoint ,see rfc2328
66312.4.1.4.*/
664/* from "edward rrr" <edward_rrr@hotmail.com>
665 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000666static int
paul68980082003-03-25 05:07:42 +0000667lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000668{
669 int links = 0;
670 struct route_node *rn;
671 struct ospf_neighbor *nbr = NULL;
672 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000673 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000674
675 mask.s_addr = 0xffffffff;
676 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000677 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000678
paul1cc8f762003-04-05 19:34:32 +0000679 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000680 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000681
682 /* Search neighbor, */
683 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
684 if ((nbr = rn->info) != NULL)
685 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000686 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000687 if (nbr->state == NSM_Full)
688
689 {
paul779adb02006-01-18 15:07:38 +0000690 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
691 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000692 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000693 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000694 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000695 }
696
697 return links;
paul7afa08d2002-12-13 20:59:45 +0000698}
699
paul718e3742002-12-13 20:15:29 +0000700/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000701static int
paul718e3742002-12-13 20:15:29 +0000702router_lsa_link_set (struct stream *s, struct ospf_area *area)
703{
hasso52dc7ee2004-09-23 19:18:23 +0000704 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000705 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000706 int links = 0;
707
paul1eb8ef22005-04-07 07:30:20 +0000708 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000709 {
paul718e3742002-12-13 20:15:29 +0000710 struct interface *ifp = oi->ifp;
711
712 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000713 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000714 {
715 if (oi->state != ISM_Down)
716 {
717 /* Describe each link. */
718 switch (oi->type)
719 {
720 case OSPF_IFTYPE_POINTOPOINT:
721 links += lsa_link_ptop_set (s, oi);
722 break;
723 case OSPF_IFTYPE_BROADCAST:
724 links += lsa_link_broadcast_set (s, oi);
725 break;
726 case OSPF_IFTYPE_NBMA:
727 links += lsa_link_nbma_set (s, oi);
728 break;
729 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000730 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000731 break;
732 case OSPF_IFTYPE_VIRTUALLINK:
733 links += lsa_link_virtuallink_set (s, oi);
734 break;
735 case OSPF_IFTYPE_LOOPBACK:
736 links += lsa_link_loopback_set (s, oi);
737 }
738 }
739 }
740 }
741
742 return links;
743}
744
745/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000746static void
paul718e3742002-12-13 20:15:29 +0000747ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
748{
749 unsigned long putp;
750 u_int16_t cnt;
751
752 /* Set flags. */
753 stream_putc (s, router_lsa_flags (area));
754
755 /* Set Zero fields. */
756 stream_putc (s, 0);
757
758 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000759 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000760
761 /* Forward word */
762 stream_putw(s, 0);
763
764 /* Set all link information. */
765 cnt = router_lsa_link_set (s, area);
766
767 /* Set # of links here. */
768 stream_putw_at (s, putp, cnt);
769}
paul88d6cf32005-10-29 12:50:09 +0000770
771static int
772ospf_stub_router_timer (struct thread *t)
773{
774 struct ospf_area *area = THREAD_ARG (t);
775
776 area->t_stub_router = NULL;
777
778 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
779
780 /* clear stub route state and generate router-lsa refresh, don't
781 * clobber an administratively set stub-router state though.
782 */
783 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
784 return 0;
785
786 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
787
788 ospf_router_lsa_timer_add (area);
789
790 return 0;
791}
paul718e3742002-12-13 20:15:29 +0000792
paul88d6cf32005-10-29 12:50:09 +0000793inline static void
794ospf_stub_router_check (struct ospf_area *area)
795{
796 /* area must either be administratively configured to be stub
797 * or startup-time stub-router must be configured and we must in a pre-stub
798 * state.
799 */
800 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
801 {
802 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
803 return;
804 }
805
806 /* not admin-stubbed, check whether startup stubbing is configured and
807 * whether it's not been done yet
808 */
809 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
810 return;
811
812 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
813 {
814 /* stub-router is hence done forever for this area, even if someone
815 * tries configure it (take effect next restart).
816 */
817 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
818 return;
819 }
820
821 /* startup stub-router configured and not yet done */
822 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
823
824 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
825 area->ospf->stub_router_startup_time);
826}
827
paul718e3742002-12-13 20:15:29 +0000828/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000829static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000830ospf_router_lsa_new (struct ospf_area *area)
831{
paul68980082003-03-25 05:07:42 +0000832 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000833 struct stream *s;
834 struct lsa_header *lsah;
835 struct ospf_lsa *new;
836 int length;
837
838 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000839 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000840
paul88d6cf32005-10-29 12:50:09 +0000841 /* check whether stub-router is desired, and if this is the first
842 * router LSA.
843 */
844 ospf_stub_router_check (area);
845
paul718e3742002-12-13 20:15:29 +0000846 /* Create a stream for LSA. */
847 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000848 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000849 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000850 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000851
852 /* Set router-LSA body fields. */
853 ospf_router_lsa_body_set (s, area);
854
855 /* Set length. */
856 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000857 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000858 lsah->length = htons (length);
859
860 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000861 if ( (new = ospf_lsa_new ()) == NULL)
862 {
863 zlog_err ("%s: Unable to create new lsa", __func__);
864 return NULL;
865 }
866
paul718e3742002-12-13 20:15:29 +0000867 new->area = area;
868 SET_FLAG (new->flags, OSPF_LSA_SELF);
869
870 /* Copy LSA data to store, discard stream. */
871 new->data = ospf_lsa_data_new (length);
872 memcpy (new->data, lsah, length);
873 stream_free (s);
874
875 return new;
876}
877
878/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000879static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000880ospf_router_lsa_originate (struct ospf_area *area)
881{
882 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000883
paul718e3742002-12-13 20:15:29 +0000884 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000885 if ( (new = ospf_router_lsa_new (area)) == NULL)
886 {
887 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
888 return NULL;
889 }
paul718e3742002-12-13 20:15:29 +0000890
891 /* Sanity check. */
892 if (new->data->adv_router.s_addr == 0)
893 {
894 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000895 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000896 ospf_lsa_discard (new);
897 return NULL;
898 }
899
900 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000901 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000902
903 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000904 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000905
906 /* Flooding new LSA through area. */
907 ospf_flood_through_area (area, NULL, new);
908
909 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
910 {
ajse588f212004-12-08 18:12:06 +0000911 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000912 new->data->type, inet_ntoa (new->data->id), new);
913 ospf_lsa_header_dump (new->data);
914 }
915
916 return new;
917}
918
919/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000920static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000921ospf_router_lsa_refresh (struct ospf_lsa *lsa)
922{
923 struct ospf_area *area = lsa->area;
924 struct ospf_lsa *new;
925
926 /* Sanity check. */
927 assert (lsa->data);
928
929 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000930 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000931
932 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000933 if ( (new = ospf_router_lsa_new (area)) == NULL)
934 {
935 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
936 return NULL;
937 }
938
paul718e3742002-12-13 20:15:29 +0000939 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
940
paul68980082003-03-25 05:07:42 +0000941 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000942
943 /* Flood LSA through area. */
944 ospf_flood_through_area (area, NULL, new);
945
946 /* Debug logging. */
947 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
948 {
ajse588f212004-12-08 18:12:06 +0000949 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000950 new->data->type, inet_ntoa (new->data->id));
951 ospf_lsa_header_dump (new->data);
952 }
953
954 return NULL;
955}
956
paul4dadc292005-05-06 21:37:42 +0000957static int
paul718e3742002-12-13 20:15:29 +0000958ospf_router_lsa_timer (struct thread *t)
959{
960 struct ospf_area *area;
961
962 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000963 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000964
965 area = THREAD_ARG (t);
966 area->t_router_lsa_self = NULL;
967
968 /* Now refresh router-LSA. */
969 if (area->router_lsa_self)
970 ospf_router_lsa_refresh (area->router_lsa_self);
971 /* Newly originate router-LSA. */
972 else
973 ospf_router_lsa_originate (area);
974
975 return 0;
976}
977
978void
979ospf_router_lsa_timer_add (struct ospf_area *area)
980{
981 /* Keep area's self-originated router-LSA. */
982 struct ospf_lsa *lsa = area->router_lsa_self;
983
984 /* Cancel previously scheduled router-LSA timer. */
985 if (area->t_router_lsa_self)
986 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000987 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000988
989 OSPF_TIMER_OFF (area->t_router_lsa_self);
990
991 /* If router-LSA is originated previously, check the interval time. */
992 if (lsa)
993 {
994 int delay;
995 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
996 {
997 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
998 ospf_router_lsa_timer, delay);
999 return;
1000 }
1001 }
1002
1003 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001004 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001005
1006 /* Immediately refresh router-LSA. */
1007 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
1008}
1009
1010int
paul68980082003-03-25 05:07:42 +00001011ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001012{
paul68980082003-03-25 05:07:42 +00001013 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00001014 struct listnode *node, *nnode;
1015 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001016
1017 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001018 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +00001019
paul68980082003-03-25 05:07:42 +00001020 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +00001021
paul1eb8ef22005-04-07 07:30:20 +00001022 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00001023 {
paul718e3742002-12-13 20:15:29 +00001024 struct ospf_lsa *lsa = area->router_lsa_self;
1025 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +00001026 const char *area_str;
paul718e3742002-12-13 20:15:29 +00001027
1028 /* Keep Area ID string. */
1029 area_str = AREA_NAME (area);
1030
1031 /* If LSA not exist in this Area, originate new. */
1032 if (lsa == NULL)
1033 {
1034 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001035 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001036
1037 ospf_router_lsa_originate (area);
1038 }
1039 /* If router-ID is changed, Link ID must change.
1040 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001041 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001042 {
1043 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001044 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001045 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1046 ospf_lsa_flush_area (lsa, area);
1047 ospf_lsa_unlock (area->router_lsa_self);
1048 area->router_lsa_self = NULL;
1049
1050 /* Refresh router-LSA, (not install) and flood through area. */
1051 ospf_router_lsa_timer_add (area);
1052 }
1053 else
1054 {
1055 rl = (struct router_lsa *) lsa->data;
1056 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001057 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001058 ospf_router_lsa_timer_add (area);
1059 }
1060 }
1061
1062 return 0;
1063}
1064
1065
1066/* network-LSA related functions. */
1067/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001068static void
paul718e3742002-12-13 20:15:29 +00001069ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1070{
1071 struct in_addr mask;
1072 struct route_node *rn;
1073 struct ospf_neighbor *nbr;
1074
1075 masklen2ip (oi->address->prefixlen, &mask);
1076 stream_put_ipv4 (s, mask.s_addr);
1077
1078 /* The network-LSA lists those routers that are fully adjacent to
1079 the Designated Router; each fully adjacent router is identified by
1080 its OSPF Router ID. The Designated Router includes itself in this
1081 list. RFC2328, Section 12.4.2 */
1082
1083 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1084 if ((nbr = rn->info) != NULL)
1085 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1086 stream_put_ipv4 (s, nbr->router_id.s_addr);
1087}
1088
paul4dadc292005-05-06 21:37:42 +00001089static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001090ospf_network_lsa_new (struct ospf_interface *oi)
1091{
1092 struct stream *s;
1093 struct ospf_lsa *new;
1094 struct lsa_header *lsah;
1095 int length;
1096
1097 /* If there are no neighbours on this network (the net is stub),
1098 the router does not originate network-LSA (see RFC 12.4.2) */
1099 if (oi->full_nbrs == 0)
1100 return NULL;
1101
1102 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001103 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001104
1105 /* Create new stream for LSA. */
1106 s = stream_new (OSPF_MAX_LSA_SIZE);
1107 lsah = (struct lsa_header *) STREAM_DATA (s);
1108
1109 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001110 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001111
1112 /* Set network-LSA body fields. */
1113 ospf_network_lsa_body_set (s, oi);
1114
1115 /* Set length. */
1116 length = stream_get_endp (s);
1117 lsah->length = htons (length);
1118
1119 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001120 if ( (new = ospf_lsa_new ()) == NULL)
1121 {
1122 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1123 return NULL;
1124 }
1125
paul718e3742002-12-13 20:15:29 +00001126 new->area = oi->area;
1127 SET_FLAG (new->flags, OSPF_LSA_SELF);
1128
1129 /* Copy LSA to store. */
1130 new->data = ospf_lsa_data_new (length);
1131 memcpy (new->data, lsah, length);
1132 stream_free (s);
1133
1134 return new;
1135}
1136
1137/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001138static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001139ospf_network_lsa_originate (struct ospf_interface *oi)
1140{
1141 struct ospf_lsa *new;
1142
1143 /* Create new network-LSA instance. */
1144 new = ospf_network_lsa_new (oi);
1145 if (new == NULL)
1146 return NULL;
1147
1148 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001149 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001150
1151 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001152 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001153
1154 /* Flooding new LSA through area. */
1155 ospf_flood_through_area (oi->area, NULL, new);
1156
1157 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1158 {
ajse588f212004-12-08 18:12:06 +00001159 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001160 new->data->type, inet_ntoa (new->data->id), new);
1161 ospf_lsa_header_dump (new->data);
1162 }
1163
1164 return new;
1165}
1166
1167int
1168ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1169{
1170 struct ospf_area *area = lsa->area;
1171 struct ospf_lsa *new;
1172
1173 assert (lsa->data);
1174
1175 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001176 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001177
1178 /* Create new network-LSA instance. */
1179 new = ospf_network_lsa_new (oi);
1180 if (new == NULL)
1181 return -1;
1182 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1183
paul68980082003-03-25 05:07:42 +00001184 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001185
1186 /* Flood LSA through aera. */
1187 ospf_flood_through_area (area, NULL, new);
1188
1189 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1190 {
ajse588f212004-12-08 18:12:06 +00001191 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001192 new->data->type, inet_ntoa (new->data->id));
1193 ospf_lsa_header_dump (new->data);
1194 }
1195
1196 return 0;
1197}
1198
paul4dadc292005-05-06 21:37:42 +00001199static int
paul718e3742002-12-13 20:15:29 +00001200ospf_network_lsa_refresh_timer (struct thread *t)
1201{
1202 struct ospf_interface *oi;
1203
1204 oi = THREAD_ARG (t);
1205 oi->t_network_lsa_self = NULL;
1206
1207 if (oi->network_lsa_self)
1208 /* Now refresh network-LSA. */
1209 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1210 else
1211 /* Newly create network-LSA. */
1212 ospf_network_lsa_originate (oi);
1213
1214 return 0;
1215}
1216
1217void
1218ospf_network_lsa_timer_add (struct ospf_interface *oi)
1219{
1220 /* Keep interface's self-originated network-LSA. */
1221 struct ospf_lsa *lsa = oi->network_lsa_self;
1222
1223 /* Cancel previously schedules network-LSA timer. */
1224 if (oi->t_network_lsa_self)
1225 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001226 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001227 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1228
1229 /* If network-LSA is originated previously, check the interval time. */
1230 if (lsa)
1231 {
1232 int delay;
1233 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1234 {
1235 oi->t_network_lsa_self =
1236 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1237 oi, delay);
1238 return;
1239 }
1240 }
1241
1242 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001243 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001244
1245 /* Immediately refresh network-LSA. */
1246 oi->t_network_lsa_self =
1247 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1248}
1249
1250
paul4dadc292005-05-06 21:37:42 +00001251static void
paul718e3742002-12-13 20:15:29 +00001252stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1253{
1254 u_int32_t metric;
1255 char *mp;
1256
1257 /* Put 0 metric. TOS metric is not supported. */
1258 metric = htonl (metric_value);
1259 mp = (char *) &metric;
1260 mp++;
1261 stream_put (s, mp, 3);
1262}
1263
1264/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001265static void
paul718e3742002-12-13 20:15:29 +00001266ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1267 u_int32_t metric)
1268{
1269 struct in_addr mask;
1270
1271 masklen2ip (p->prefixlen, &mask);
1272
1273 /* Put Network Mask. */
1274 stream_put_ipv4 (s, mask.s_addr);
1275
1276 /* Set # TOS. */
1277 stream_putc (s, (u_char) 0);
1278
1279 /* Set metric. */
1280 stream_put_ospf_metric (s, metric);
1281}
1282
paul4dadc292005-05-06 21:37:42 +00001283static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001284ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1285 u_int32_t metric, struct in_addr id)
1286{
1287 struct stream *s;
1288 struct ospf_lsa *new;
1289 struct lsa_header *lsah;
1290 int length;
1291
paulc24d6022005-11-20 14:54:12 +00001292 if (id.s_addr == 0xffffffff)
1293 {
1294 /* Maybe Link State ID not available. */
1295 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1296 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1297 OSPF_SUMMARY_LSA);
1298 return NULL;
1299 }
1300
paul718e3742002-12-13 20:15:29 +00001301 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001302 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001303
1304 /* Create new stream for LSA. */
1305 s = stream_new (OSPF_MAX_LSA_SIZE);
1306 lsah = (struct lsa_header *) STREAM_DATA (s);
1307
paul68980082003-03-25 05:07:42 +00001308 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1309 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001310
1311 /* Set summary-LSA body fields. */
1312 ospf_summary_lsa_body_set (s, p, metric);
1313
1314 /* Set length. */
1315 length = stream_get_endp (s);
1316 lsah->length = htons (length);
1317
1318 /* Create OSPF LSA instance. */
1319 new = ospf_lsa_new ();
1320 new->area = area;
1321 SET_FLAG (new->flags, OSPF_LSA_SELF);
1322
1323 /* Copy LSA to store. */
1324 new->data = ospf_lsa_data_new (length);
1325 memcpy (new->data, lsah, length);
1326 stream_free (s);
1327
1328 return new;
1329}
1330
1331/* Originate Summary-LSA. */
1332struct ospf_lsa *
1333ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1334 struct ospf_area *area)
1335{
1336 struct ospf_lsa *new;
1337 struct in_addr id;
1338
paul68980082003-03-25 05:07:42 +00001339 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001340
paulc24d6022005-11-20 14:54:12 +00001341 if (id.s_addr == 0xffffffff)
1342 {
1343 /* Maybe Link State ID not available. */
1344 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1345 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1346 OSPF_SUMMARY_LSA);
1347 return NULL;
1348 }
1349
paul718e3742002-12-13 20:15:29 +00001350 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001351 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1352 return NULL;
paul718e3742002-12-13 20:15:29 +00001353
1354 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001355 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001356
1357 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001358 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001359
1360 /* Flooding new LSA through area. */
1361 ospf_flood_through_area (area, NULL, new);
1362
1363 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1364 {
ajse588f212004-12-08 18:12:06 +00001365 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001366 new->data->type, inet_ntoa (new->data->id), new);
1367 ospf_lsa_header_dump (new->data);
1368 }
1369
1370 return new;
1371}
1372
1373struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001374ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001375{
1376 struct ospf_lsa *new;
1377 struct summary_lsa *sl;
1378 struct prefix p;
1379
1380 /* Sanity check. */
1381 assert (lsa->data);
1382
1383 sl = (struct summary_lsa *)lsa->data;
1384 p.prefixlen = ip_masklen (sl->mask);
1385 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1386 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001387
1388 if (!new)
1389 return NULL;
1390
paul718e3742002-12-13 20:15:29 +00001391 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1392
1393 /* Re-calculate checksum. */
1394 ospf_lsa_checksum (new->data);
1395
paul68980082003-03-25 05:07:42 +00001396 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001397
1398 /* Flood LSA through AS. */
1399 ospf_flood_through_area (new->area, NULL, new);
1400
1401 /* Debug logging. */
1402 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1403 {
ajse588f212004-12-08 18:12:06 +00001404 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001405 new->data->type, inet_ntoa (new->data->id));
1406 ospf_lsa_header_dump (new->data);
1407 }
1408
1409 return new;
1410}
1411
1412
1413/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001414static void
paul718e3742002-12-13 20:15:29 +00001415ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1416 u_int32_t metric)
1417{
1418 struct in_addr mask;
1419
1420 masklen2ip (p->prefixlen, &mask);
1421
1422 /* Put Network Mask. */
1423 stream_put_ipv4 (s, mask.s_addr);
1424
1425 /* Set # TOS. */
1426 stream_putc (s, (u_char) 0);
1427
1428 /* Set metric. */
1429 stream_put_ospf_metric (s, metric);
1430}
1431
paul4dadc292005-05-06 21:37:42 +00001432static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001433ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1434 u_int32_t metric, struct in_addr id)
1435{
1436 struct stream *s;
1437 struct ospf_lsa *new;
1438 struct lsa_header *lsah;
1439 int length;
1440
paulc24d6022005-11-20 14:54:12 +00001441 if (id.s_addr == 0xffffffff)
1442 {
1443 /* Maybe Link State ID not available. */
1444 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1445 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1446 OSPF_ASBR_SUMMARY_LSA);
1447 return NULL;
1448 }
1449
paul718e3742002-12-13 20:15:29 +00001450 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001451 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001452
1453 /* Create new stream for LSA. */
1454 s = stream_new (OSPF_MAX_LSA_SIZE);
1455 lsah = (struct lsa_header *) STREAM_DATA (s);
1456
paul68980082003-03-25 05:07:42 +00001457 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1458 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001459
1460 /* Set summary-LSA body fields. */
1461 ospf_summary_asbr_lsa_body_set (s, p, metric);
1462
1463 /* Set length. */
1464 length = stream_get_endp (s);
1465 lsah->length = htons (length);
1466
1467 /* Create OSPF LSA instance. */
1468 new = ospf_lsa_new ();
1469 new->area = area;
1470 SET_FLAG (new->flags, OSPF_LSA_SELF);
1471
1472 /* Copy LSA to store. */
1473 new->data = ospf_lsa_data_new (length);
1474 memcpy (new->data, lsah, length);
1475 stream_free (s);
1476
1477 return new;
1478}
1479
1480/* Originate summary-ASBR-LSA. */
1481struct ospf_lsa *
1482ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1483 struct ospf_area *area)
1484{
1485 struct ospf_lsa *new;
1486 struct in_addr id;
1487
paul68980082003-03-25 05:07:42 +00001488 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001489
paulc24d6022005-11-20 14:54:12 +00001490 if (id.s_addr == 0xffffffff)
1491 {
1492 /* Maybe Link State ID not available. */
1493 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1494 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1495 OSPF_ASBR_SUMMARY_LSA);
1496 return NULL;
1497 }
1498
paul718e3742002-12-13 20:15:29 +00001499 /* Create new summary-LSA instance. */
1500 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001501 if (!new)
1502 return NULL;
paul718e3742002-12-13 20:15:29 +00001503
1504 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001505 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001506
1507 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001508 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001509
1510 /* Flooding new LSA through area. */
1511 ospf_flood_through_area (area, NULL, new);
1512
1513 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1514 {
ajse588f212004-12-08 18:12:06 +00001515 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001516 new->data->type, inet_ntoa (new->data->id), new);
1517 ospf_lsa_header_dump (new->data);
1518 }
1519
1520 return new;
1521}
1522
1523struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001524ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001525{
1526 struct ospf_lsa *new;
1527 struct summary_lsa *sl;
1528 struct prefix p;
1529
1530 /* Sanity check. */
1531 assert (lsa->data);
1532
1533 sl = (struct summary_lsa *)lsa->data;
1534 p.prefixlen = ip_masklen (sl->mask);
1535 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1536 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001537 if (!new)
1538 return NULL;
paul718e3742002-12-13 20:15:29 +00001539
1540 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1541
1542 /* Re-calculate checksum. */
1543 ospf_lsa_checksum (new->data);
1544
paul68980082003-03-25 05:07:42 +00001545 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001546
1547 /* Flood LSA through area. */
1548 ospf_flood_through_area (new->area, NULL, new);
1549
1550 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1551 {
ajse588f212004-12-08 18:12:06 +00001552 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001553 new->data->type, inet_ntoa (new->data->id));
1554 ospf_lsa_header_dump (new->data);
1555 }
1556
1557 return new;
1558}
1559
1560/* AS-external-LSA related functions. */
1561
1562/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1563 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001564static struct in_addr
paul68980082003-03-25 05:07:42 +00001565ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001566{
1567 struct in_addr fwd;
1568 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001569 struct listnode *node;
1570 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001571
1572 fwd.s_addr = 0;
1573
1574 if (!nexthop.s_addr)
1575 return fwd;
1576
1577 /* Check whether nexthop is covered by OSPF network. */
1578 nh.family = AF_INET;
1579 nh.u.prefix4 = nexthop;
1580 nh.prefixlen = IPV4_MAX_BITLEN;
1581
paul1eb8ef22005-04-07 07:30:20 +00001582 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1583 if (if_is_operative (oi->ifp))
1584 if (oi->address->family == AF_INET)
1585 if (prefix_match (oi->address, &nh))
1586 return nexthop;
paul718e3742002-12-13 20:15:29 +00001587
1588 return fwd;
1589}
1590
paul718e3742002-12-13 20:15:29 +00001591/* NSSA-external-LSA related functions. */
1592
1593/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001594
paul718e3742002-12-13 20:15:29 +00001595struct in_addr
1596ospf_get_ip_from_ifp (struct ospf_interface *oi)
1597{
1598 struct in_addr fwd;
1599
1600 fwd.s_addr = 0;
1601
paul2e3b2e42002-12-13 21:03:13 +00001602 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001603 return oi->address->u.prefix4;
1604
1605 return fwd;
1606}
1607
1608/* Get 1st IP connection for Forward Addr */
1609struct in_addr
paulf2c80652002-12-13 21:44:27 +00001610ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001611{
1612 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001613 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001614 struct listnode *node;
1615 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001616
1617 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001618 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001619
paul1eb8ef22005-04-07 07:30:20 +00001620 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001621 {
paul2e3b2e42002-12-13 21:03:13 +00001622 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001623 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001624 if (oi->address && oi->address->family == AF_INET)
1625 {
1626 if (best_default.s_addr == 0)
1627 best_default = oi->address->u.prefix4;
1628 if (oi->area == area)
1629 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001630 }
paul718e3742002-12-13 20:15:29 +00001631 }
paulf2c80652002-12-13 21:44:27 +00001632 if (best_default.s_addr != 0)
1633 return best_default;
paul718e3742002-12-13 20:15:29 +00001634
paul68980082003-03-25 05:07:42 +00001635 if (best_default.s_addr != 0)
1636 return best_default;
1637
paul718e3742002-12-13 20:15:29 +00001638 return fwd;
1639}
hassobeebba72004-06-20 21:00:27 +00001640
paul718e3742002-12-13 20:15:29 +00001641#define DEFAULT_DEFAULT_METRIC 20
1642#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1643#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1644
1645#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1646
1647int
paul68980082003-03-25 05:07:42 +00001648metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001649{
paul68980082003-03-25 05:07:42 +00001650 return (ospf->dmetric[src].type < 0 ?
1651 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001652}
1653
1654int
paul68980082003-03-25 05:07:42 +00001655metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001656{
paul68980082003-03-25 05:07:42 +00001657 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001658 {
1659 if (src == DEFAULT_ROUTE)
1660 {
paul68980082003-03-25 05:07:42 +00001661 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001662 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1663 else
1664 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1665 }
paul68980082003-03-25 05:07:42 +00001666 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001667 return DEFAULT_DEFAULT_METRIC;
1668 else
paul68980082003-03-25 05:07:42 +00001669 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001670 }
1671
paul68980082003-03-25 05:07:42 +00001672 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001673}
1674
1675/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001676static void
paul68980082003-03-25 05:07:42 +00001677ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1678 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001679{
1680 struct prefix_ipv4 *p = &ei->p;
1681 struct in_addr mask, fwd_addr;
1682 u_int32_t mvalue;
1683 int mtype;
1684 int type;
1685
1686 /* Put Network Mask. */
1687 masklen2ip (p->prefixlen, &mask);
1688 stream_put_ipv4 (s, mask.s_addr);
1689
1690 /* If prefix is default, specify DEFAULT_ROUTE. */
1691 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1692
1693 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001694 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001695
1696 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001697 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001698
1699 /* Put type of external metric. */
1700 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1701
1702 /* Put 0 metric. TOS metric is not supported. */
1703 stream_put_ospf_metric (s, mvalue);
1704
1705 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001706 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001707
1708 /* Put forwarding address. */
1709 stream_put_ipv4 (s, fwd_addr.s_addr);
1710
1711 /* Put route tag -- This value should be introduced from configuration. */
1712 stream_putl (s, 0);
1713}
1714
1715/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001716static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001717ospf_external_lsa_new (struct ospf *ospf,
1718 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001719{
1720 struct stream *s;
1721 struct lsa_header *lsah;
1722 struct ospf_lsa *new;
1723 struct in_addr id;
1724 int length;
1725
1726 if (ei == NULL)
1727 {
1728 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001729 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001730 return NULL;
1731 }
1732
1733 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001734 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001735
1736 /* If old Link State ID is specified, refresh LSA with same ID. */
1737 if (old_id)
1738 id = *old_id;
1739 /* Get Link State with unique ID. */
1740 else
1741 {
paul68980082003-03-25 05:07:42 +00001742 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001743 if (id.s_addr == 0xffffffff)
1744 {
1745 /* Maybe Link State ID not available. */
1746 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001747 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001748 return NULL;
1749 }
1750 }
1751
1752 /* Create new stream for LSA. */
1753 s = stream_new (OSPF_MAX_LSA_SIZE);
1754 lsah = (struct lsa_header *) STREAM_DATA (s);
1755
1756 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001757 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1758 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001759
1760 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001761 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001762
1763 /* Set length. */
1764 length = stream_get_endp (s);
1765 lsah->length = htons (length);
1766
1767 /* Now, create OSPF LSA instance. */
1768 new = ospf_lsa_new ();
1769 new->area = NULL;
1770 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1771
1772 /* Copy LSA data to store, discard stream. */
1773 new->data = ospf_lsa_data_new (length);
1774 memcpy (new->data, lsah, length);
1775 stream_free (s);
1776
1777 return new;
1778}
1779
paul718e3742002-12-13 20:15:29 +00001780/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001781static void
paul68980082003-03-25 05:07:42 +00001782ospf_install_flood_nssa (struct ospf *ospf,
1783 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001784{
pauld4a53d52003-07-12 21:30:57 +00001785 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001786 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001787 struct ospf_area *area;
1788 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001789
pauld4a53d52003-07-12 21:30:57 +00001790 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1791 * which originated from an NSSA area. In which case it should not be
1792 * flooded back to NSSA areas.
1793 */
1794 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1795 return;
1796
paul718e3742002-12-13 20:15:29 +00001797 /* NSSA Originate or Refresh (If anyNSSA)
1798
1799 LSA is self-originated. And just installed as Type-5.
1800 Additionally, install as Type-7 LSDB for every attached NSSA.
1801
1802 P-Bit controls which ABR performs translation to outside world; If
1803 we are an ABR....do not set the P-bit, because we send the Type-5,
1804 not as the ABR Translator, but as the ASBR owner within the AS!
1805
1806 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1807 elected ABR Translator will see the P-bit, Translate, and re-flood.
1808
1809 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1810 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1811
paul1eb8ef22005-04-07 07:30:20 +00001812 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001813 {
hasso0c14ad82003-07-03 08:36:02 +00001814 /* Don't install Type-7 LSA's into nonNSSA area */
1815 if (area->external_routing != OSPF_AREA_NSSA)
1816 continue;
paul718e3742002-12-13 20:15:29 +00001817
paul68980082003-03-25 05:07:42 +00001818 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001819 new = ospf_lsa_dup (lsa);
1820 new->area = area;
1821 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001822
paul68980082003-03-25 05:07:42 +00001823 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001824 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001825 {
pauld4a53d52003-07-12 21:30:57 +00001826 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001827
1828 /* set non-zero FWD ADDR
1829
1830 draft-ietf-ospf-nssa-update-09.txt
1831
1832 if the network between the NSSA AS boundary router and the
1833 adjacent AS is advertised into OSPF as an internal OSPF route,
1834 the forwarding address should be the next op address as is cu
1835 currently done with type-5 LSAs. If the intervening network is
1836 not adversited into OSPF as an internal OSPF route and the
1837 type-7 LSA's P-bit is set a forwarding address should be
1838 selected from one of the router's active OSPF inteface addresses
1839 which belong to the NSSA. If no such addresses exist, then
1840 no type-7 LSA's with the P-bit set should originate from this
1841 router. */
1842
pauld4a53d52003-07-12 21:30:57 +00001843 /* kevinm: not updating lsa anymore, just new */
1844 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001845
1846 if (extlsa->e[0].fwd_addr.s_addr == 0)
1847 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001848
pauld7480322003-05-16 17:31:51 +00001849 if (extlsa->e[0].fwd_addr.s_addr == 0)
1850 {
1851 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001852 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
pauld4a53d52003-07-12 21:30:57 +00001853 ospf_lsa_discard(new);
pauld7480322003-05-16 17:31:51 +00001854 return;
1855 }
paulf2c80652002-12-13 21:44:27 +00001856 }
paul68980082003-03-25 05:07:42 +00001857 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001858 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001859
paul68980082003-03-25 05:07:42 +00001860 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001861 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001862
1863 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001864 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001865 }
paul718e3742002-12-13 20:15:29 +00001866}
pauld4a53d52003-07-12 21:30:57 +00001867
paul4dadc292005-05-06 21:37:42 +00001868static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001869ospf_lsa_translated_nssa_new (struct ospf *ospf,
1870 struct ospf_lsa *type7)
1871{
1872
1873 struct ospf_lsa *new;
1874 struct as_external_lsa *ext, *extnew;
1875 struct external_info ei;
1876
1877 ext = (struct as_external_lsa *)(type7->data);
1878
1879 /* need external_info struct, fill in bare minimum */
1880 ei.p.family = AF_INET;
1881 ei.p.prefix = type7->data->id;
1882 ei.p.prefixlen = ip_masklen (ext->mask);
1883 ei.type = ZEBRA_ROUTE_OSPF;
1884 ei.nexthop = ext->header.adv_router;
1885 ei.route_map_set.metric = -1;
1886 ei.route_map_set.metric_type = -1;
1887 ei.tag = 0;
1888
1889 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1890 {
1891 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001892 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001893 "Translated Type-5 for %s",
1894 inet_ntoa (ei.p.prefix));
1895 return NULL;
1896 }
1897
1898 extnew = (struct as_external_lsa *)(new->data);
1899
1900 /* copy over Type-7 data to new */
1901 extnew->e[0].tos = ext->e[0].tos;
1902 extnew->e[0].route_tag = ext->e[0].route_tag;
1903 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1904 new->data->ls_seqnum = type7->data->ls_seqnum;
1905
1906 /* add translated flag, checksum and lock new lsa */
1907 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1908 ospf_lsa_checksum (new->data);
1909 new = ospf_lsa_lock (new);
1910
1911 return new;
1912}
1913
1914/* compare type-5 to type-7
1915 * -1: err, 0: same, 1: different
1916 */
paul4dadc292005-05-06 21:37:42 +00001917static int
pauld4a53d52003-07-12 21:30:57 +00001918ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1919{
1920
1921 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1922 *e7 = (struct as_external_lsa *)t7;
1923
1924
1925 /* sanity checks */
1926 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1927 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1928 return -1;
1929
1930 if (t5->data->id.s_addr != t7->data->id.s_addr)
1931 return -1;
1932
1933 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1934 return LSA_REFRESH_FORCE;
1935
1936 if (e5->mask.s_addr != e7->mask.s_addr)
1937 return LSA_REFRESH_FORCE;
1938
1939 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1940 return LSA_REFRESH_FORCE;
1941
1942 if (e5->e[0].route_tag != e7->e[0].route_tag)
1943 return LSA_REFRESH_FORCE;
1944
1945 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1946 return LSA_REFRESH_FORCE;
1947
1948 return LSA_REFRESH_IF_CHANGED;
1949}
1950
1951/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1952struct ospf_lsa *
1953ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1954{
1955 struct ospf_lsa *new;
1956 struct as_external_lsa *extnew;
1957
1958 /* we cant use ospf_external_lsa_originate() as we need to set
1959 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1960 */
1961
1962 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1963 {
1964 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001965 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001966 "Type-7, Id %s, to Type-5",
1967 inet_ntoa (type7->data->id));
1968 return NULL;
1969 }
1970
1971 extnew = (struct as_external_lsa *)new;
1972
1973 if (IS_DEBUG_OSPF_NSSA)
1974 {
ajse588f212004-12-08 18:12:06 +00001975 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001976 "translated Type 7, installed:");
1977 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001978 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1979 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001980 }
1981
1982 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1983 {
1984 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001985 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001986 "Could not install LSA "
1987 "id %s", inet_ntoa (type7->data->id));
1988 return NULL;
1989 }
1990
1991 ospf->lsa_originate_count++;
1992 ospf_flood_through_as (ospf, NULL, new);
1993
1994 return new;
1995}
1996
1997/* Refresh Translated from NSSA AS-external-LSA. */
1998struct ospf_lsa *
1999ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
2000 struct ospf_lsa *type5)
2001{
2002 struct ospf_lsa *new = NULL;
2003
2004 /* Sanity checks. */
2005 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00002006 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00002007 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002008 if (type7)
2009 assert (type7->data);
2010 if (type5)
2011 assert (type5->data);
2012 assert (ospf->anyNSSA);
2013
2014 /* get required data according to what has been given */
2015 if (type7 && type5 == NULL)
2016 {
2017 /* find the translated Type-5 for this Type-7 */
2018 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2019 struct prefix_ipv4 p =
2020 {
2021 .prefix = type7->data->id,
2022 .prefixlen = ip_masklen (ext->mask),
2023 .family = AF_INET,
2024 };
2025
2026 type5 = ospf_external_info_find_lsa (ospf, &p);
2027 }
2028 else if (type5 && type7 == NULL)
2029 {
2030 /* find the type-7 from which supplied type-5 was translated,
2031 * ie find first type-7 with same LSA Id.
2032 */
paul1eb8ef22005-04-07 07:30:20 +00002033 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002034 struct route_node *rn;
2035 struct ospf_lsa *lsa;
2036 struct ospf_area *area;
2037
paul1eb8ef22005-04-07 07:30:20 +00002038 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002039 {
2040 if (area->external_routing != OSPF_AREA_NSSA
2041 && !type7)
2042 continue;
2043
2044 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2045 {
2046 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2047 {
2048 type7 = lsa;
2049 break;
2050 }
2051 }
2052 }
2053 }
2054
2055 /* do we have type7? */
2056 if (!type7)
2057 {
2058 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002059 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002060 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002061 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002062 return NULL;
2063 }
2064
2065 /* do we have valid translated type5? */
2066 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2067 {
2068 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002069 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002070 "found for Type-7 with Id %s",
2071 inet_ntoa (type7->data->id));
2072 return NULL;
2073 }
2074
2075 /* Delete LSA from neighbor retransmit-list. */
2076 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2077
2078 /* create new translated LSA */
2079 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2080 {
2081 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002082 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002083 "Type-7 for %s to Type-5",
2084 inet_ntoa (type7->data->id));
2085 return NULL;
2086 }
2087
2088 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2089 {
2090 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002091 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002092 "translated LSA, Id %s",
2093 inet_ntoa (new->data->id));
2094 return NULL;
2095 }
2096
2097 /* Flood LSA through area. */
2098 ospf_flood_through_as (ospf, NULL, new);
2099
2100 return new;
2101}
paul718e3742002-12-13 20:15:29 +00002102
2103int
2104is_prefix_default (struct prefix_ipv4 *p)
2105{
2106 struct prefix_ipv4 q;
2107
2108 q.family = AF_INET;
2109 q.prefix.s_addr = 0;
2110 q.prefixlen = 0;
2111
2112 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2113}
2114
2115/* Originate an AS-external-LSA, install and flood. */
2116struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002117ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002118{
2119 struct ospf_lsa *new;
2120
2121 /* Added for NSSA project....
2122
2123 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2124 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2125 every area. The Type-7's are flooded to every IR and every ABR; We
2126 install the Type-5 LSDB so that the normal "refresh" code operates
2127 as usual, and flag them as not used during ASE calculations. The
2128 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2129 Address of non-zero.
2130
2131 If an ABR is the elected NSSA translator, following SPF and during
2132 the ABR task it will translate all the scanned Type-7's, with P-bit
2133 ON and not-self generated, and translate to Type-5's throughout the
2134 non-NSSA/STUB AS.
2135
2136 A difference in operation depends whether this ASBR is an ABR
2137 or not. If not an ABR, the P-bit is ON, to indicate that any
2138 elected NSSA-ABR can perform its translation.
2139
2140 If an ABR, the P-bit is OFF; No ABR will perform translation and
2141 this ASBR will flood the Type-5 LSA as usual.
2142
2143 For the case where this ASBR is not an ABR, the ASE calculations
2144 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2145 demonstrate to the user that there are LSA's that belong to any
2146 attached NSSA.
2147
2148 Finally, it just so happens that when the ABR is translating every
2149 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2150 approved Type-5 (translated from Type-7); at the end of translation
2151 if any Translated Type-5's remain unapproved, then they must be
2152 flushed from the AS.
2153
2154 */
2155
2156 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002157 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002158 return NULL;
2159
2160 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002161 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002162 {
2163 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002164 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002165 inet_ntoa (ei->p.prefix));
2166 return NULL;
2167 }
2168
2169 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002170 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002171
2172 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002173 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002174
2175 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002176 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002177
paul718e3742002-12-13 20:15:29 +00002178 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002179 if (ospf->anyNSSA &&
2180 /* stay away from translated LSAs! */
2181 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002182 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002183
2184 /* Debug logging. */
2185 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2186 {
ajse588f212004-12-08 18:12:06 +00002187 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002188 new->data->type, inet_ntoa (new->data->id), new);
2189 ospf_lsa_header_dump (new->data);
2190 }
2191
2192 return new;
2193}
2194
2195/* Originate AS-external-LSA from external info with initial flag. */
2196int
paul68980082003-03-25 05:07:42 +00002197ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002198{
paul68980082003-03-25 05:07:42 +00002199 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002200 struct route_node *rn;
2201 struct external_info *ei;
2202 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002203 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002204
paul68980082003-03-25 05:07:42 +00002205 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002206
2207 /* Originate As-external-LSA from all type of distribute source. */
2208 if ((rt = EXTERNAL_INFO (type)))
2209 for (rn = route_top (rt); rn; rn = route_next (rn))
2210 if ((ei = rn->info) != NULL)
2211 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002212 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002213 zlog_warn ("LSA: AS-external-LSA was not originated.");
2214
2215 return 0;
2216}
2217
paul4dadc292005-05-06 21:37:42 +00002218static struct external_info *
paul020709f2003-04-04 02:44:16 +00002219ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002220{
2221 int type;
2222 struct route_node *rn;
2223 struct prefix_ipv4 p;
2224
2225 p.family = AF_INET;
2226 p.prefix.s_addr = 0;
2227 p.prefixlen = 0;
2228
2229 /* First, lookup redistributed default route. */
2230 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2231 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2232 {
2233 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2234 if (rn != NULL)
2235 {
2236 route_unlock_node (rn);
2237 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002238 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002239 return rn->info;
2240 }
2241 }
2242
2243 return NULL;
2244}
2245
2246int
paul68980082003-03-25 05:07:42 +00002247ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002248{
paul718e3742002-12-13 20:15:29 +00002249 struct prefix_ipv4 p;
2250 struct in_addr nexthop;
2251 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002252 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002253
Paul Jakma4021b602006-05-12 22:55:41 +00002254 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002255
2256 p.family = AF_INET;
2257 p.prefix.s_addr = 0;
2258 p.prefixlen = 0;
2259
Paul Jakma4021b602006-05-12 22:55:41 +00002260 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002261 {
2262 /* If there is no default route via redistribute,
2263 then originate AS-external-LSA with nexthop 0 (self). */
2264 nexthop.s_addr = 0;
2265 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2266 }
2267
paul020709f2003-04-04 02:44:16 +00002268 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002269 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002270
2271 return 0;
2272}
2273
paul645878f2003-04-13 21:42:11 +00002274/* Flush any NSSA LSAs for given prefix */
2275void
2276ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2277{
paul1eb8ef22005-04-07 07:30:20 +00002278 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002279 struct ospf_lsa *lsa;
2280 struct ospf_area *area;
2281
paul1eb8ef22005-04-07 07:30:20 +00002282 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002283 {
paul1eb8ef22005-04-07 07:30:20 +00002284 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002285 {
2286 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2287 ospf->router_id)))
2288 {
2289 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002290 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002291 inet_ntoa (p->prefix), p->prefixlen);
2292 continue;
2293 }
2294 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2295 if (!IS_LSA_MAXAGE (lsa))
2296 {
2297 ospf_refresher_unregister_lsa (ospf, lsa);
2298 ospf_lsa_flush_area (lsa, area);
2299 }
2300 }
paul645878f2003-04-13 21:42:11 +00002301 }
2302}
paul645878f2003-04-13 21:42:11 +00002303
paul718e3742002-12-13 20:15:29 +00002304/* Flush an AS-external-LSA from LSDB and routing domain. */
2305void
paul68980082003-03-25 05:07:42 +00002306ospf_external_lsa_flush (struct ospf *ospf,
2307 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002308 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002309{
2310 struct ospf_lsa *lsa;
2311
2312 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002313 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002314 inet_ntoa (p->prefix), p->prefixlen);
2315
2316 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002317 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002318 {
2319 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002320 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002321 inet_ntoa (p->prefix), p->prefixlen);
2322 return;
2323 }
hassobeebba72004-06-20 21:00:27 +00002324
pauld4a53d52003-07-12 21:30:57 +00002325 /* If LSA is selforiginated, not a translated LSA, and there is
2326 * NSSA area, flush Type-7 LSA's at first.
2327 */
2328 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2329 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002330 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002331
2332 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002333 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002334
2335 /* There must be no self-originated LSA in rtrs_external. */
2336#if 0
2337 /* Remove External route from Zebra. */
2338 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2339#endif
2340
2341 if (!IS_LSA_MAXAGE (lsa))
2342 {
2343 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002344 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002345
2346 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002347 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002348 }
2349
2350 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002351 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002352}
2353
2354void
paul68980082003-03-25 05:07:42 +00002355ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002356{
2357 struct prefix_ipv4 p;
2358 struct external_info *ei;
2359 struct ospf_lsa *lsa;
2360
2361 p.family = AF_INET;
2362 p.prefixlen = 0;
2363 p.prefix.s_addr = 0;
2364
paul020709f2003-04-04 02:44:16 +00002365 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002366 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002367
2368 if (ei)
2369 {
2370 if (lsa)
2371 {
2372 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002373 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002374 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002375 }
2376 else
2377 {
2378 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002379 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002380 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002381 }
2382 }
2383 else
2384 {
2385 if (lsa)
2386 {
2387 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002388 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002389 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002390 }
2391 }
2392}
2393
2394void
paul68980082003-03-25 05:07:42 +00002395ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002396{
2397 struct route_node *rn;
2398 struct external_info *ei;
2399
2400 if (type != DEFAULT_ROUTE)
2401 if (EXTERNAL_INFO(type))
2402 /* Refresh each redistributed AS-external-LSAs. */
2403 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2404 if ((ei = rn->info))
2405 if (!is_prefix_default (&ei->p))
2406 {
2407 struct ospf_lsa *lsa;
2408
paul68980082003-03-25 05:07:42 +00002409 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2410 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002411 else
paul68980082003-03-25 05:07:42 +00002412 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002413 }
2414}
2415
2416/* Refresh AS-external-LSA. */
2417void
paul68980082003-03-25 05:07:42 +00002418ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002419 struct external_info *ei, int force)
2420{
2421 struct ospf_lsa *new;
2422 int changed;
2423
2424 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002425 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002426 {
pauld4a53d52003-07-12 21:30:57 +00002427 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002428 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002429 "redist check fail",
2430 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002431 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002432 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002433 return;
2434 }
2435
2436 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002437 {
2438 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002439 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002440 lsa->data->type, inet_ntoa (lsa->data->id));
2441 return;
2442 }
paul718e3742002-12-13 20:15:29 +00002443
2444 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002445 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002446
2447 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002448 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002449
paul68980082003-03-25 05:07:42 +00002450 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002451
2452 if (new == NULL)
2453 {
2454 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002455 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002456 inet_ntoa (lsa->data->id));
2457 return;
2458 }
2459
2460 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2461
2462 /* Record timestamp. */
2463 gettimeofday (&new->tv_orig, NULL);
2464
2465 /* Re-calculate checksum. */
2466 ospf_lsa_checksum (new->data);
2467
paul68980082003-03-25 05:07:42 +00002468 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002469
2470 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002471 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002472
paul718e3742002-12-13 20:15:29 +00002473 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002474 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002475 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002476
pauld4a53d52003-07-12 21:30:57 +00002477 /* Register self-originated LSA to refresh queue.
2478 * Translated LSAs should not be registered, but refreshed upon
2479 * refresh of the Type-7
2480 */
2481 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2482 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002483
2484 /* Debug logging. */
2485 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2486 {
ajse588f212004-12-08 18:12:06 +00002487 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002488 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002489 ospf_lsa_header_dump (new->data);
2490 }
2491
2492 return;
2493}
2494
2495
2496/* LSA installation functions. */
2497
2498/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002499static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002500ospf_router_lsa_install (struct ospf *ospf,
2501 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002502{
2503 struct ospf_area *area = new->area;
2504
2505 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2506 The entire routing table must be recalculated, starting with
2507 the shortest path calculations for each area (not just the
2508 area whose link-state database has changed).
2509 */
2510 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002511 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002512
2513 if (IS_LSA_SELF (new))
2514 {
2515 /* Set router-LSA refresh timer. */
2516 OSPF_TIMER_OFF (area->t_router_lsa_self);
2517 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002518 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002519
2520 /* Set self-originated router-LSA. */
2521 ospf_lsa_unlock (area->router_lsa_self);
2522 area->router_lsa_self = ospf_lsa_lock (new);
2523
2524 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002525 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002526 new->data->type, inet_ntoa (new->data->id),
2527 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002528 }
2529
2530 return new;
2531}
2532
2533#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2534 if (!(T)) \
2535 (T) = thread_add_timer (master, (F), oi, (V))
2536
2537/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002538static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002539ospf_network_lsa_install (struct ospf *ospf,
2540 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002541 struct ospf_lsa *new,
2542 int rt_recalc)
2543{
2544
2545 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2546 The entire routing table must be recalculated, starting with
2547 the shortest path calculations for each area (not just the
2548 area whose link-state database has changed).
2549 */
2550 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002551 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002552
2553 /* We supposed that when LSA is originated by us, we pass the int
2554 for which it was originated. If LSA was received by flooding,
2555 the RECEIVED flag is set, so we do not link the LSA to the int. */
2556 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2557 {
2558 /* Set LSRefresh timer. */
2559 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2560
2561 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2562 ospf_network_lsa_refresh_timer,
2563 OSPF_LS_REFRESH_TIME);
2564
2565 ospf_lsa_unlock (oi->network_lsa_self);
2566 oi->network_lsa_self = ospf_lsa_lock (new);
2567 }
2568
2569 return new;
2570}
2571
2572/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002573static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002574ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2575 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002576{
paul718e3742002-12-13 20:15:29 +00002577 if (rt_recalc && !IS_LSA_SELF (new))
2578 {
2579 /* RFC 2328 Section 13.2 Summary-LSAs
2580 The best route to the destination described by the summary-
2581 LSA must be recalculated (see Section 16.5). If this
2582 destination is an AS boundary router, it may also be
2583 necessary to re-examine all the AS-external-LSAs.
2584 */
2585
2586#if 0
2587 /* This doesn't exist yet... */
2588 ospf_summary_incremental_update(new); */
2589#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002590 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002591#endif /* #if 0 */
2592
2593 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002594 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002595 }
2596
2597 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002598 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002599
2600 return new;
2601}
2602
2603/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002604static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002605ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2606 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002607{
2608 if (rt_recalc && !IS_LSA_SELF (new))
2609 {
2610 /* RFC 2328 Section 13.2 Summary-LSAs
2611 The best route to the destination described by the summary-
2612 LSA must be recalculated (see Section 16.5). If this
2613 destination is an AS boundary router, it may also be
2614 necessary to re-examine all the AS-external-LSAs.
2615 */
2616#if 0
2617 /* These don't exist yet... */
2618 ospf_summary_incremental_update(new);
2619 /* Isn't this done by the above call?
2620 - RFC 2328 Section 16.5 implies it should be */
2621 /* ospf_ase_calculate_schedule(); */
2622#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002623 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002624#endif /* #if 0 */
2625 }
2626
2627 /* register LSA to refresh-list. */
2628 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002629 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002630
2631 return new;
2632}
2633
2634/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002635static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002636ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2637 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002638{
paul68980082003-03-25 05:07:42 +00002639 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002640 /* If LSA is not self-originated, calculate an external route. */
2641 if (rt_recalc)
2642 {
2643 /* RFC 2328 Section 13.2 AS-external-LSAs
2644 The best route to the destination described by the AS-
2645 external-LSA must be recalculated (see Section 16.6).
2646 */
2647
2648 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002649 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002650 }
2651
pauld4a53d52003-07-12 21:30:57 +00002652 if (new->data->type == OSPF_AS_NSSA_LSA)
2653 {
2654 /* There is no point to register selforiginate Type-7 LSA for
2655 * refreshing. We rely on refreshing Type-5 LSA's
2656 */
2657 if (IS_LSA_SELF (new))
2658 return new;
2659 else
2660 {
2661 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2662 * New translations will be taken care of by the abr_task.
2663 */
2664 ospf_translated_nssa_refresh (ospf, new, NULL);
2665 }
2666 }
pauld7480322003-05-16 17:31:51 +00002667
pauld4a53d52003-07-12 21:30:57 +00002668 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002669 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002670 */
hassobeebba72004-06-20 21:00:27 +00002671 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002672 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002673
2674 return new;
2675}
2676
2677void
paul68980082003-03-25 05:07:42 +00002678ospf_discard_from_db (struct ospf *ospf,
2679 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002680{
2681 struct ospf_lsa *old;
2682
Paul Jakmaac904de2006-06-15 12:04:57 +00002683 if (!lsdb)
2684 {
2685 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2686 if (!lsa)
2687 zlog_warn ("%s: and NULL LSA!", __func__);
2688 else
2689 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2690 lsa->data->type, inet_ntoa (lsa->data->id));
2691 return;
2692 }
2693
paul718e3742002-12-13 20:15:29 +00002694 old = ospf_lsdb_lookup (lsdb, lsa);
2695
2696 if (!old)
2697 return;
2698
2699 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002700 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002701
2702 switch (old->data->type)
2703 {
2704 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002705 ospf_ase_unregister_external_lsa (old, ospf);
2706 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2707 break;
paul718e3742002-12-13 20:15:29 +00002708#ifdef HAVE_OPAQUE_LSA
2709 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002710 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002711 break;
paul69310a62005-05-11 18:09:59 +00002712#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002713 case OSPF_AS_NSSA_LSA:
2714 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2715 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002716 break;
paul718e3742002-12-13 20:15:29 +00002717 default:
paul68980082003-03-25 05:07:42 +00002718 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002719 break;
2720 }
2721
paul68980082003-03-25 05:07:42 +00002722 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002723 ospf_lsa_discard (old);
2724}
2725
paul718e3742002-12-13 20:15:29 +00002726struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002727ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2728 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002729{
2730 struct ospf_lsa *new = NULL;
2731 struct ospf_lsa *old = NULL;
2732 struct ospf_lsdb *lsdb = NULL;
2733 int rt_recalc;
2734
2735 /* Set LSDB. */
2736 switch (lsa->data->type)
2737 {
paulf2c80652002-12-13 21:44:27 +00002738 /* kevinm */
2739 case OSPF_AS_NSSA_LSA:
2740 if (lsa->area)
2741 lsdb = lsa->area->lsdb;
2742 else
paul68980082003-03-25 05:07:42 +00002743 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002744 break;
paul718e3742002-12-13 20:15:29 +00002745 case OSPF_AS_EXTERNAL_LSA:
2746#ifdef HAVE_OPAQUE_LSA
2747 case OSPF_OPAQUE_AS_LSA:
2748#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002749 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002750 break;
2751 default:
2752 lsdb = lsa->area->lsdb;
2753 break;
2754 }
2755
paul718e3742002-12-13 20:15:29 +00002756 assert (lsdb);
2757
2758 /* RFC 2328 13.2. Installing LSAs in the database
2759
2760 Installing a new LSA in the database, either as the result of
2761 flooding or a newly self-originated LSA, may cause the OSPF
2762 routing table structure to be recalculated. The contents of the
2763 new LSA should be compared to the old instance, if present. If
2764 there is no difference, there is no need to recalculate the
2765 routing table. When comparing an LSA to its previous instance,
2766 the following are all considered to be differences in contents:
2767
2768 o The LSA's Options field has changed.
2769
2770 o One of the LSA instances has LS age set to MaxAge, and
2771 the other does not.
2772
2773 o The length field in the LSA header has changed.
2774
2775 o The body of the LSA (i.e., anything outside the 20-byte
2776 LSA header) has changed. Note that this excludes changes
2777 in LS Sequence Number and LS Checksum.
2778
2779 */
2780 /* Look up old LSA and determine if any SPF calculation or incremental
2781 update is needed */
2782 old = ospf_lsdb_lookup (lsdb, lsa);
2783
2784 /* Do comparision and record if recalc needed. */
2785 rt_recalc = 0;
2786 if ( old == NULL || ospf_lsa_different(old, lsa))
2787 rt_recalc = 1;
2788
paul7ddf1d62003-10-13 09:06:46 +00002789 /*
2790 Sequence number check (Section 14.1 of rfc 2328)
2791 "Premature aging is used when it is time for a self-originated
2792 LSA's sequence number field to wrap. At this point, the current
2793 LSA instance (having LS sequence number MaxSequenceNumber) must
2794 be prematurely aged and flushed from the routing domain before a
2795 new instance with sequence number equal to InitialSequenceNumber
2796 can be originated. "
2797 */
2798
Paul Jakmac2b478d2006-03-30 14:16:11 +00002799 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002800 {
2801 if (ospf_lsa_is_self_originated(ospf, lsa))
2802 {
paul0c2be262004-05-31 14:16:54 +00002803 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2804
2805 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002806 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2807 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2808
2809 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2810 {
ajse588f212004-12-08 18:12:06 +00002811 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002812 "lsa 0x%lx", (u_long)lsa);
2813 ospf_lsa_header_dump (lsa->data);
2814 }
2815 }
2816 else
2817 {
2818 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2819 {
ajse588f212004-12-08 18:12:06 +00002820 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002821 "that was not self originated. Ignoring\n");
2822 ospf_lsa_header_dump (lsa->data);
2823 }
2824 return old;
2825 }
2826 }
2827
paul718e3742002-12-13 20:15:29 +00002828 /* discard old LSA from LSDB */
2829 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002830 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002831
paul718e3742002-12-13 20:15:29 +00002832 /* Calculate Checksum if self-originated?. */
2833 if (IS_LSA_SELF (lsa))
2834 ospf_lsa_checksum (lsa->data);
2835
hassofe71a972004-12-22 16:16:02 +00002836 /* Insert LSA to LSDB. */
2837 ospf_lsdb_add (lsdb, lsa);
2838 lsa->lsdb = lsdb;
2839
paul718e3742002-12-13 20:15:29 +00002840 /* Do LSA specific installation process. */
2841 switch (lsa->data->type)
2842 {
2843 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002844 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002845 break;
2846 case OSPF_NETWORK_LSA:
2847 assert (oi);
paul68980082003-03-25 05:07:42 +00002848 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002849 break;
2850 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002851 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002852 break;
2853 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002854 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002855 break;
2856 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002857 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002858 break;
2859#ifdef HAVE_OPAQUE_LSA
2860 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002861 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002862 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002863 else
paul68980082003-03-25 05:07:42 +00002864 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002865 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002866 case OSPF_OPAQUE_AREA_LSA:
2867 case OSPF_OPAQUE_AS_LSA:
2868 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2869 break;
2870#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002871 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002872 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002873 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002874 break;
2875 }
2876
2877 if (new == NULL)
2878 return new; /* Installation failed, cannot proceed further -- endo. */
2879
2880 /* Debug logs. */
2881 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2882 {
2883 char area_str[INET_ADDRSTRLEN];
2884
2885 switch (lsa->data->type)
2886 {
2887 case OSPF_AS_EXTERNAL_LSA:
2888#ifdef HAVE_OPAQUE_LSA
2889 case OSPF_OPAQUE_AS_LSA:
2890#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002891 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002892 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002893 dump_lsa_key (new),
2894 LOOKUP (ospf_lsa_type_msg, new->data->type));
2895 break;
2896 default:
2897 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002898 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002899 dump_lsa_key (new),
2900 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2901 break;
2902 }
2903 }
2904
paul7ddf1d62003-10-13 09:06:46 +00002905 /*
2906 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2907 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2908 */
2909 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2910 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002911 {
paul7ddf1d62003-10-13 09:06:46 +00002912 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002913 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002914 new->data->type,
2915 inet_ntoa (new->data->id),
2916 lsa);
paul68980082003-03-25 05:07:42 +00002917 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002918 }
2919
2920 return new;
2921}
2922
2923
paul4dadc292005-05-06 21:37:42 +00002924static int
paul68980082003-03-25 05:07:42 +00002925ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002926{
paul1eb8ef22005-04-07 07:30:20 +00002927 struct listnode *node, *nnode;
2928 struct ospf_interface *oi;
2929
2930 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002931 {
paul718e3742002-12-13 20:15:29 +00002932 struct route_node *rn;
2933 struct ospf_neighbor *nbr;
2934
2935 if (ospf_if_is_enable (oi))
2936 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2937 if ((nbr = rn->info) != NULL)
2938 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2939 {
2940 route_unlock_node (rn);
2941 return 0;
2942 }
2943 }
2944
2945 return 1;
2946}
2947
2948
2949#ifdef ORIGINAL_CODING
2950/* This function flood the maxaged LSA to DR. */
2951void
2952ospf_maxage_flood (struct ospf_lsa *lsa)
2953{
2954 switch (lsa->data->type)
2955 {
2956 case OSPF_ROUTER_LSA:
2957 case OSPF_NETWORK_LSA:
2958 case OSPF_SUMMARY_LSA:
2959 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002960 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002961#ifdef HAVE_OPAQUE_LSA
2962 case OSPF_OPAQUE_LINK_LSA:
2963 case OSPF_OPAQUE_AREA_LSA:
2964#endif /* HAVE_OPAQUE_LSA */
2965 ospf_flood_through_area (lsa->area, NULL, lsa);
2966 break;
2967 case OSPF_AS_EXTERNAL_LSA:
2968#ifdef HAVE_OPAQUE_LSA
2969 case OSPF_OPAQUE_AS_LSA:
2970#endif /* HAVE_OPAQUE_LSA */
2971 ospf_flood_through_as (NULL, lsa);
2972 break;
2973 default:
2974 break;
2975 }
2976}
2977#endif /* ORIGINAL_CODING */
2978
paul4dadc292005-05-06 21:37:42 +00002979static int
paul718e3742002-12-13 20:15:29 +00002980ospf_maxage_lsa_remover (struct thread *thread)
2981{
paul68980082003-03-25 05:07:42 +00002982 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002983 struct ospf_lsa *lsa;
2984 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002985 int reschedule = 0;
2986
paul68980082003-03-25 05:07:42 +00002987 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002988
2989 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002990 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002991
paul68980082003-03-25 05:07:42 +00002992 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002993
2994 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002995 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002996 {
paul718e3742002-12-13 20:15:29 +00002997 if (lsa->retransmit_counter > 0)
2998 {
2999 reschedule = 1;
3000 continue;
3001 }
3002
3003 /* Remove LSA from the LSDB */
3004 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
3005 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003006 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00003007 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00003008
3009 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003010 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00003011 lsa->data->type, inet_ntoa (lsa->data->id));
3012
3013 /* Flood max age LSA. */
3014#ifdef ORIGINAL_CODING
3015 ospf_maxage_flood (lsa);
3016#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00003017 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00003018#endif /* ORIGINAL_CODING */
3019
paul7ddf1d62003-10-13 09:06:46 +00003020 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3021 {
3022 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003023 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00003024 (u_long)lsa);
3025 ospf_router_lsa_originate(lsa->area);
3026 }
3027
paul718e3742002-12-13 20:15:29 +00003028 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00003029 if (lsa->lsdb)
3030 {
3031 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
3032 ospf_lsdb_delete (lsa->lsdb, lsa);
3033 }
3034 else
3035 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
3036 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003037 }
3038
3039 /* A MaxAge LSA must be removed immediately from the router's link
3040 state database as soon as both a) it is no longer contained on any
3041 neighbor Link state retransmission lists and b) none of the router's
3042 neighbors are in states Exchange or Loading. */
3043 if (reschedule)
paul68980082003-03-25 05:07:42 +00003044 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003045
3046 return 0;
3047}
3048
paul4dadc292005-05-06 21:37:42 +00003049static int
paul68980082003-03-25 05:07:42 +00003050ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003051{
hasso52dc7ee2004-09-23 19:18:23 +00003052 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003053 struct ospf_lsa *lsa;
3054
3055 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3056 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003057 return 1;
3058
3059 return 0;
3060}
3061
3062void
paul68980082003-03-25 05:07:42 +00003063ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003064{
hasso52dc7ee2004-09-23 19:18:23 +00003065 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003066
paul68980082003-03-25 05:07:42 +00003067 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003068 {
paul68980082003-03-25 05:07:42 +00003069 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00003070 ospf_lsa_unlock (lsa);
3071 }
3072}
3073
3074void
paul68980082003-03-25 05:07:42 +00003075ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003076{
3077 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3078 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003079 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003080 {
3081 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003082 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003083 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3084 return;
3085 }
3086
paul68980082003-03-25 05:07:42 +00003087 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003088
3089 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003090 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003091
paul68980082003-03-25 05:07:42 +00003092 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003093}
3094
paul4dadc292005-05-06 21:37:42 +00003095static int
paul68980082003-03-25 05:07:42 +00003096ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003097{
paul718e3742002-12-13 20:15:29 +00003098 /* Stay away from any Local Translated Type-7 LSAs */
3099 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3100 return 0;
paul718e3742002-12-13 20:15:29 +00003101
3102 if (IS_LSA_MAXAGE (lsa))
3103 /* Self-originated LSAs should NOT time-out instead,
3104 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003105 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003106 {
3107 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003108 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003109
3110 switch (lsa->data->type)
3111 {
paul718e3742002-12-13 20:15:29 +00003112#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003113 case OSPF_OPAQUE_LINK_LSA:
3114 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003115 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003116 /*
3117 * As a general rule, whenever network topology has changed
3118 * (due to an LSA removal in this case), routing recalculation
3119 * should be triggered. However, this is not true for opaque
3120 * LSAs. Even if an opaque LSA instance is going to be removed
3121 * from the routing domain, it does not mean a change in network
3122 * topology, and thus, routing recalculation is not needed here.
3123 */
3124 break;
paul718e3742002-12-13 20:15:29 +00003125#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003126 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003127 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003128 ospf_ase_incremental_update (ospf, lsa);
3129 break;
paul718e3742002-12-13 20:15:29 +00003130 default:
paul68980082003-03-25 05:07:42 +00003131 ospf_spf_calculate_schedule (ospf);
3132 break;
paul718e3742002-12-13 20:15:29 +00003133 }
paul68980082003-03-25 05:07:42 +00003134 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003135 }
3136
3137 return 0;
3138}
3139
3140/* Periodical check of MaxAge LSA. */
3141int
paul68980082003-03-25 05:07:42 +00003142ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003143{
paul68980082003-03-25 05:07:42 +00003144 struct ospf *ospf = THREAD_ARG (thread);
3145 struct route_node *rn;
3146 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003147 struct ospf_area *area;
3148 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003149
paul68980082003-03-25 05:07:42 +00003150 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003151
paul1eb8ef22005-04-07 07:30:20 +00003152 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003153 {
paul68980082003-03-25 05:07:42 +00003154 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3155 ospf_lsa_maxage_walker_remover (ospf, lsa);
3156 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3157 ospf_lsa_maxage_walker_remover (ospf, lsa);
3158 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3159 ospf_lsa_maxage_walker_remover (ospf, lsa);
3160 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3161 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003162#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003163 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3164 ospf_lsa_maxage_walker_remover (ospf, lsa);
3165 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3166 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003167#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003168 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3169 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003170 }
3171
paul4fb949e2003-05-10 20:06:51 +00003172 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003173 if (ospf->lsdb)
3174 {
3175 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3176 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003177#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003178 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3179 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003180#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003181 }
paul718e3742002-12-13 20:15:29 +00003182
paul68980082003-03-25 05:07:42 +00003183 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3184 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003185 return 0;
3186}
3187
paul68980082003-03-25 05:07:42 +00003188struct ospf_lsa *
3189ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3190 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003191{
paul68980082003-03-25 05:07:42 +00003192 struct ospf_lsa *lsa;
3193 struct in_addr mask, id;
3194 struct lsa_header_mask
3195 {
3196 struct lsa_header header;
3197 struct in_addr mask;
3198 } *hmask;
paul718e3742002-12-13 20:15:29 +00003199
paul68980082003-03-25 05:07:42 +00003200 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3201 if (lsa == NULL)
3202 return NULL;
paul718e3742002-12-13 20:15:29 +00003203
paul68980082003-03-25 05:07:42 +00003204 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003205
paul68980082003-03-25 05:07:42 +00003206 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003207
paul68980082003-03-25 05:07:42 +00003208 if (mask.s_addr != hmask->mask.s_addr)
3209 {
3210 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3211 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3212 if (!lsa)
3213 return NULL;
3214 }
paul718e3742002-12-13 20:15:29 +00003215
paul68980082003-03-25 05:07:42 +00003216 return lsa;
paul718e3742002-12-13 20:15:29 +00003217}
3218
3219struct ospf_lsa *
3220ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3221 struct in_addr id, struct in_addr adv_router)
3222{
paule05fba42003-04-13 20:20:53 +00003223 struct ospf *ospf = ospf_lookup();
3224 assert(ospf);
3225
paul718e3742002-12-13 20:15:29 +00003226 switch (type)
3227 {
3228 case OSPF_ROUTER_LSA:
3229 case OSPF_NETWORK_LSA:
3230 case OSPF_SUMMARY_LSA:
3231 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003232 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003233#ifdef HAVE_OPAQUE_LSA
3234 case OSPF_OPAQUE_LINK_LSA:
3235 case OSPF_OPAQUE_AREA_LSA:
3236#endif /* HAVE_OPAQUE_LSA */
3237 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003238 case OSPF_AS_EXTERNAL_LSA:
3239#ifdef HAVE_OPAQUE_LSA
3240 case OSPF_OPAQUE_AS_LSA:
3241#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003242 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003243 default:
3244 break;
3245 }
3246
3247 return NULL;
3248}
3249
3250struct ospf_lsa *
3251ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3252 struct in_addr id)
3253{
3254 struct ospf_lsa *lsa;
3255 struct route_node *rn;
3256
3257 switch (type)
3258 {
3259 case OSPF_ROUTER_LSA:
3260 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003261 case OSPF_NETWORK_LSA:
3262 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3263 if ((lsa = rn->info))
3264 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3265 {
3266 route_unlock_node (rn);
3267 return lsa;
3268 }
3269 break;
3270 case OSPF_SUMMARY_LSA:
3271 case OSPF_ASBR_SUMMARY_LSA:
3272 /* Currently not used. */
3273 assert (1);
3274 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003275 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003276 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003277#ifdef HAVE_OPAQUE_LSA
3278 case OSPF_OPAQUE_LINK_LSA:
3279 case OSPF_OPAQUE_AREA_LSA:
3280 case OSPF_OPAQUE_AS_LSA:
3281 /* Currently not used. */
3282 break;
3283#endif /* HAVE_OPAQUE_LSA */
3284 default:
3285 break;
3286 }
3287
3288 return NULL;
3289}
3290
3291struct ospf_lsa *
3292ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3293{
3294 struct ospf_lsa *match;
3295
3296#ifdef HAVE_OPAQUE_LSA
3297 /*
3298 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3299 * is redefined to have two subfields; opaque-type and opaque-id.
3300 * However, it is harmless to treat the two sub fields together, as if
3301 * they two were forming a unique LSA-ID.
3302 */
3303#endif /* HAVE_OPAQUE_LSA */
3304
3305 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3306
3307 if (match == NULL)
3308 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003309 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003310 lsah->type, inet_ntoa (lsah->id));
3311
3312 return match;
3313}
3314
3315/* return +n, l1 is more recent.
3316 return -n, l2 is more recent.
3317 return 0, l1 and l2 is identical. */
3318int
3319ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3320{
3321 int r;
3322 int x, y;
3323
3324 if (l1 == NULL && l2 == NULL)
3325 return 0;
3326 if (l1 == NULL)
3327 return -1;
3328 if (l2 == NULL)
3329 return 1;
3330
3331 /* compare LS sequence number. */
3332 x = (int) ntohl (l1->data->ls_seqnum);
3333 y = (int) ntohl (l2->data->ls_seqnum);
3334 if (x > y)
3335 return 1;
3336 if (x < y)
3337 return -1;
3338
3339 /* compare LS checksum. */
3340 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3341 if (r)
3342 return r;
3343
3344 /* compare LS age. */
3345 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3346 return 1;
3347 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3348 return -1;
3349
3350 /* compare LS age with MaxAgeDiff. */
3351 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3352 return -1;
3353 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3354 return 1;
3355
3356 /* LSAs are identical. */
3357 return 0;
3358}
3359
3360/* If two LSAs are different, return 1, otherwise return 0. */
3361int
3362ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3363{
3364 char *p1, *p2;
3365 assert (l1);
3366 assert (l2);
3367 assert (l1->data);
3368 assert (l2->data);
3369
3370 if (l1->data->options != l2->data->options)
3371 return 1;
3372
3373 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3374 return 1;
3375
3376 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3377 return 1;
3378
3379 if (l1->data->length != l2->data->length)
3380 return 1;
3381
3382 if (l1->data->length == 0)
3383 return 1;
3384
pauld1825832003-04-03 01:27:01 +00003385 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003386
3387 p1 = (char *) l1->data;
3388 p2 = (char *) l2->data;
3389
3390 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3391 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3392 return 1;
3393
3394 return 0;
3395}
3396
3397#ifdef ORIGINAL_CODING
3398void
3399ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3400 struct ospf_lsa *self,
3401 struct ospf_lsa *new)
3402{
3403 u_int32_t seqnum;
3404
3405 /* Adjust LS Sequence Number. */
3406 seqnum = ntohl (new->data->ls_seqnum) + 1;
3407 self->data->ls_seqnum = htonl (seqnum);
3408
3409 /* Recalculate LSA checksum. */
3410 ospf_lsa_checksum (self->data);
3411
3412 /* Reflooding LSA. */
3413 /* RFC2328 Section 13.3
3414 On non-broadcast networks, separate Link State Update
3415 packets must be sent, as unicasts, to each adjacent neighbor
3416 (i.e., those in state Exchange or greater). The destination
3417 IP addresses for these packets are the neighbors' IP
3418 addresses. */
3419 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3420 {
3421 struct route_node *rn;
3422 struct ospf_neighbor *onbr;
3423
3424 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3425 if ((onbr = rn->info) != NULL)
3426 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3427 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3428 }
3429 else
3430 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3431
3432 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003433 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003434 self->data->type, inet_ntoa (self->data->id));
3435}
3436#else /* ORIGINAL_CODING */
3437static int
paul68980082003-03-25 05:07:42 +00003438ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003439{
3440 if (lsa == NULL || !IS_LSA_SELF (lsa))
3441 return 0;
3442
3443 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003444 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 +00003445
3446 /* Force given lsa's age to MaxAge. */
3447 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3448
3449 switch (lsa->data->type)
3450 {
3451#ifdef HAVE_OPAQUE_LSA
3452 case OSPF_OPAQUE_LINK_LSA:
3453 case OSPF_OPAQUE_AREA_LSA:
3454 case OSPF_OPAQUE_AS_LSA:
3455 ospf_opaque_lsa_refresh (lsa);
3456 break;
3457#endif /* HAVE_OPAQUE_LSA */
3458 default:
paul68980082003-03-25 05:07:42 +00003459 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003460 break;
3461 }
3462
3463 return 0;
3464}
3465
3466void
paul68980082003-03-25 05:07:42 +00003467ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003468{
paul1eb8ef22005-04-07 07:30:20 +00003469 struct listnode *node, *nnode;
3470 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003471 struct ospf_area *area;
3472 struct ospf_interface *oi;
3473 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003474 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003475 int need_to_flush_ase = 0;
3476
paul1eb8ef22005-04-07 07:30:20 +00003477 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003478 {
paul718e3742002-12-13 20:15:29 +00003479 if ((lsa = area->router_lsa_self) != NULL)
3480 {
3481 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003482 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 +00003483
3484 ospf_lsa_flush_area (lsa, area);
3485 ospf_lsa_unlock (area->router_lsa_self);
3486 area->router_lsa_self = NULL;
3487 OSPF_TIMER_OFF (area->t_router_lsa_self);
3488 }
3489
paul1eb8ef22005-04-07 07:30:20 +00003490 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003491 {
paul718e3742002-12-13 20:15:29 +00003492 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003493 && oi->state == ISM_DR
3494 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003495 {
3496 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003497 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 +00003498
3499 ospf_lsa_flush_area (oi->network_lsa_self, area);
3500 ospf_lsa_unlock (oi->network_lsa_self);
3501 oi->network_lsa_self = NULL;
3502 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3503 }
3504
3505 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3506 && area->external_routing == OSPF_AREA_DEFAULT)
3507 need_to_flush_ase = 1;
3508 }
3509
paul68980082003-03-25 05:07:42 +00003510 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3511 ospf_lsa_flush_schedule (ospf, lsa);
3512 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3513 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003514#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003515 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3516 ospf_lsa_flush_schedule (ospf, lsa);
3517 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3518 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003519#endif /* HAVE_OPAQUE_LSA */
3520 }
3521
3522 if (need_to_flush_ase)
3523 {
paul68980082003-03-25 05:07:42 +00003524 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3525 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003526#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003527 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3528 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003529#endif /* HAVE_OPAQUE_LSA */
3530 }
3531
3532 /*
3533 * Make sure that the MaxAge LSA remover is executed immediately,
3534 * without conflicting to other threads.
3535 */
paul68980082003-03-25 05:07:42 +00003536 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003537 {
paul68980082003-03-25 05:07:42 +00003538 OSPF_TIMER_OFF (ospf->t_maxage);
3539 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003540 }
3541
3542 return;
3543}
3544#endif /* ORIGINAL_CODING */
3545
3546/* If there is self-originated LSA, then return 1, otherwise return 0. */
3547/* An interface-independent version of ospf_lsa_is_self_originated */
3548int
paul68980082003-03-25 05:07:42 +00003549ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003550{
hasso52dc7ee2004-09-23 19:18:23 +00003551 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003552 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003553
3554 /* This LSA is already checked. */
3555 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3556 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3557
3558 /* Make sure LSA is self-checked. */
3559 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3560
3561 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003562 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003563 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3564
3565 /* LSA is router-LSA. */
3566 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003567 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003568 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3569
3570 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3571 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003572 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003573 {
paul718e3742002-12-13 20:15:29 +00003574 /* Ignore virtual link. */
3575 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3576 if (oi->address->family == AF_INET)
3577 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3578 {
3579 /* to make it easier later */
3580 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3581 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3582 }
3583 }
3584
3585 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3586}
3587
3588/* Get unique Link State ID. */
3589struct in_addr
paul68980082003-03-25 05:07:42 +00003590ospf_lsa_unique_id (struct ospf *ospf,
3591 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003592{
3593 struct ospf_lsa *lsa;
3594 struct in_addr mask, id;
3595
3596 id = p->prefix;
3597
3598 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003599 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003600 if (lsa)
3601 {
3602 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3603 if (ip_masklen (al->mask) == p->prefixlen)
3604 {
3605 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003606 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003607 "Can't get Link State ID for %s/%d",
3608 inet_ntoa (p->prefix), p->prefixlen);
3609 /* id.s_addr = 0; */
3610 id.s_addr = 0xffffffff;
3611 return id;
3612 }
3613 /* Masklen differs, then apply wildcard mask to Link State ID. */
3614 else
3615 {
3616 masklen2ip (p->prefixlen, &mask);
3617
3618 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003619 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3620 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003621 if (lsa)
3622 {
3623 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003624 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003625 "Can't get Link State ID for %s/%d",
3626 inet_ntoa (p->prefix), p->prefixlen);
3627 /* id.s_addr = 0; */
3628 id.s_addr = 0xffffffff;
3629 return id;
3630 }
3631 }
3632 }
3633
3634 return id;
3635}
3636
3637
Paul Jakma70461d72006-05-12 22:57:57 +00003638#define LSA_ACTION_FLOOD_AREA 1
3639#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003640
3641struct lsa_action
3642{
3643 u_char action;
3644 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003645 struct ospf_lsa *lsa;
3646};
3647
paul4dadc292005-05-06 21:37:42 +00003648static int
paul718e3742002-12-13 20:15:29 +00003649ospf_lsa_action (struct thread *t)
3650{
3651 struct lsa_action *data;
3652
3653 data = THREAD_ARG (t);
3654
3655 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003656 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003657 data->action);
3658
3659 switch (data->action)
3660 {
paul718e3742002-12-13 20:15:29 +00003661 case LSA_ACTION_FLOOD_AREA:
3662 ospf_flood_through_area (data->area, NULL, data->lsa);
3663 break;
paul718e3742002-12-13 20:15:29 +00003664 case LSA_ACTION_FLUSH_AREA:
3665 ospf_lsa_flush_area (data->lsa, data->area);
3666 break;
paul718e3742002-12-13 20:15:29 +00003667 }
3668
3669 ospf_lsa_unlock (data->lsa);
3670 XFREE (MTYPE_OSPF_MESSAGE, data);
3671 return 0;
3672}
3673
3674void
3675ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3676{
3677 struct lsa_action *data;
3678
3679 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3680 memset (data, 0, sizeof (struct lsa_action));
3681
3682 data->action = LSA_ACTION_FLOOD_AREA;
3683 data->area = area;
3684 data->lsa = ospf_lsa_lock (lsa);
3685
3686 thread_add_event (master, ospf_lsa_action, data, 0);
3687}
3688
3689void
3690ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3691{
3692 struct lsa_action *data;
3693
3694 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3695 memset (data, 0, sizeof (struct lsa_action));
3696
3697 data->action = LSA_ACTION_FLUSH_AREA;
3698 data->area = area;
3699 data->lsa = ospf_lsa_lock (lsa);
3700
3701 thread_add_event (master, ospf_lsa_action, data, 0);
3702}
3703
3704
3705/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003706static void
paul68980082003-03-25 05:07:42 +00003707ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003708{
3709 struct external_info *ei;
3710 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3711
3712 switch (lsa->data->type)
3713 {
3714 /* Router and Network LSAs are processed differently. */
3715 case OSPF_ROUTER_LSA:
3716 case OSPF_NETWORK_LSA:
3717 break;
3718 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003719 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003720 break;
3721 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003722 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003723 break;
3724 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003725 /* Translated from NSSA Type-5s are refreshed when
3726 * from refresh of Type-7 - do not refresh these directly.
3727 */
3728 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3729 break;
paul718e3742002-12-13 20:15:29 +00003730 ei = ospf_external_info_check (lsa);
3731 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003732 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003733 else
pauld4a53d52003-07-12 21:30:57 +00003734 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003735 break;
3736#ifdef HAVE_OPAQUE_LSA
3737 case OSPF_OPAQUE_LINK_LSA:
3738 case OSPF_OPAQUE_AREA_LSA:
3739 case OSPF_OPAQUE_AS_LSA:
3740 ospf_opaque_lsa_refresh (lsa);
3741 break;
pauld7480322003-05-16 17:31:51 +00003742#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003743 default:
3744 break;
paul718e3742002-12-13 20:15:29 +00003745 }
3746}
3747
3748void
paul68980082003-03-25 05:07:42 +00003749ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003750{
3751 u_int16_t index, current_index;
3752
3753 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3754
3755 if (lsa->refresh_list < 0)
3756 {
3757 int delay;
3758
3759 if (LS_AGE (lsa) == 0 &&
3760 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3761 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3762 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3763 else
3764 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3765 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3766 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3767
3768 if (delay < 0)
3769 delay = 0;
3770
paul68980082003-03-25 05:07:42 +00003771 current_index = ospf->lsa_refresh_queue.index +
3772 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003773
3774 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3775 % (OSPF_LSA_REFRESHER_SLOTS);
3776
3777 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003778 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003779 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003780 if (!ospf->lsa_refresh_queue.qs[index])
3781 ospf->lsa_refresh_queue.qs[index] = list_new ();
3782 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003783 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003784 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003785 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003786 "setting refresh_list on lsa %p (slod %d)",
3787 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003788 }
3789}
3790
3791void
paul68980082003-03-25 05:07:42 +00003792ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003793{
3794 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3795 if (lsa->refresh_list >= 0)
3796 {
hasso52dc7ee2004-09-23 19:18:23 +00003797 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003798 listnode_delete (refresh_list, lsa);
3799 if (!listcount (refresh_list))
3800 {
3801 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003802 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003803 }
3804 ospf_lsa_unlock (lsa);
3805 lsa->refresh_list = -1;
3806 }
3807}
3808
3809int
3810ospf_lsa_refresh_walker (struct thread *t)
3811{
hasso52dc7ee2004-09-23 19:18:23 +00003812 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003813 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003814 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003815 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003816 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003817 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003818
3819 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003820 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003821
3822
paul68980082003-03-25 05:07:42 +00003823 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003824
ajs9dbc7972005-03-13 19:27:22 +00003825 /* Note: if clock has jumped backwards, then time change could be negative,
3826 so we are careful to cast the expression to unsigned before taking
3827 modulus. */
paul68980082003-03-25 05:07:42 +00003828 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003829 ((unsigned long)(ospf->lsa_refresh_queue.index +
3830 (time (NULL) - ospf->lsa_refresher_started) /
3831 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003832
3833 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003834 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003835 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003836
paul68980082003-03-25 05:07:42 +00003837 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003838 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3839 {
3840 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003841 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003842 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003843
paul68980082003-03-25 05:07:42 +00003844 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003845
paul68980082003-03-25 05:07:42 +00003846 ospf->lsa_refresh_queue.qs [i] = NULL;
3847
paul718e3742002-12-13 20:15:29 +00003848 if (refresh_list)
3849 {
paul1eb8ef22005-04-07 07:30:20 +00003850 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003851 {
paul718e3742002-12-13 20:15:29 +00003852 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003853 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003854 "refresh lsa %p (slot %d)",
3855 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003856
3857 list_delete_node (refresh_list, node);
3858 ospf_lsa_unlock (lsa);
3859 lsa->refresh_list = -1;
3860 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003861 }
3862 list_free (refresh_list);
3863 }
3864 }
3865
paul68980082003-03-25 05:07:42 +00003866 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3867 ospf, ospf->lsa_refresh_interval);
3868 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003869
paul1eb8ef22005-04-07 07:30:20 +00003870 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3871 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003872
3873 list_delete (lsa_to_refresh);
3874
3875 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003876 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003877
3878 return 0;
3879}
3880