blob: a0afbad39594099b36c086c25e54ec0a6b4e9b36 [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. */
440 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000441 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
442 /* If ASBR set External flag */
443 else if (IS_OSPF_ASBR (area->ospf))
444 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
445
446 /* Set ABR dependent flags */
447 if (IS_OSPF_ABR (area->ospf))
448 {
449 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000450 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000451 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000452 */
pauld4a53d52003-07-12 21:30:57 +0000453 if ( (area->external_routing == OSPF_AREA_NSSA)
454 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
455 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000456 }
paul718e3742002-12-13 20:15:29 +0000457 return flags;
458}
459
460/* Lookup neighbor other than myself.
461 And check neighbor count,
462 Point-to-Point link must have only 1 neighbor. */
463struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000464ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000465{
paul718e3742002-12-13 20:15:29 +0000466 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000467 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000468
469 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000470 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
471 if ((nbr = rn->info))
472 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000473 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000474 {
475 route_unlock_node (rn);
476 break;
477 }
paul718e3742002-12-13 20:15:29 +0000478
479 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000480 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000481 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
482
483 return nbr;
484}
485
paul88d6cf32005-10-29 12:50:09 +0000486/* Determine cost of link, taking RFC3137 stub-router support into
487 * consideration
488 */
489static u_int16_t
490ospf_link_cost (struct ospf_interface *oi)
491{
492 /* RFC3137 stub router support */
493 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
494 return oi->output_cost;
495 else
496 return OSPF_OUTPUT_COST_INFINITE;
497}
498
paul718e3742002-12-13 20:15:29 +0000499/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000500static char
paul718e3742002-12-13 20:15:29 +0000501link_info_set (struct stream *s, struct in_addr id,
502 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
503{
paul779adb02006-01-18 15:07:38 +0000504 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
505 * vast majority of cases. Some rare routers with lots of links need more.
506 * we try accomodate those here.
507 */
508 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
509 {
510 size_t ret = OSPF_MAX_LSA_SIZE;
511
512 /* Can we enlarge the stream still? */
513 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
514 {
515 /* we futz the size here for simplicity, really we need to account
516 * for just:
517 * IP Header - (sizeof (struct ip))
518 * OSPF Header - OSPF_HEADER_SIZE
519 * LSA Header - OSPF_LSA_HEADER_SIZE
520 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
521 *
522 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
523 */
524 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
525 }
526
527 if (ret == OSPF_MAX_LSA_SIZE)
528 {
529 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
530 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
531 return 0;
532 }
533 }
534
paul718e3742002-12-13 20:15:29 +0000535 /* TOS based routing is not supported. */
536 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
537 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
538 stream_putc (s, type); /* Link Type. */
539 stream_putc (s, tos); /* TOS = 0. */
540 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000541
542 return 1;
paul718e3742002-12-13 20:15:29 +0000543}
544
545/* Describe Point-to-Point link. */
paul4dadc292005-05-06 21:37:42 +0000546static int
paul718e3742002-12-13 20:15:29 +0000547lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
548{
549 int links = 0;
550 struct ospf_neighbor *nbr;
551 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000552 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000553
554 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000555 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000556
paul68980082003-03-25 05:07:42 +0000557 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000558 if (nbr->state == NSM_Full)
559 {
560 /* For unnumbered point-to-point networks, the Link Data field
561 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000562 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
563 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000564 }
565
hasso3fb9cd62004-10-19 19:44:43 +0000566 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000567 {
568 /* Option 1:
569 link_type = LSA_LINK_TYPE_STUB;
570 link_id = nbr->address.u.prefix4;
571 link_data.s_addr = 0xffffffff;
572 link_cost = o->output_cost; */
573
574 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
575 mask.s_addr = 0xffffffff;
paul779adb02006-01-18 15:07:38 +0000576 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
577 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000578 }
579 else
580 {
581 /* Option 2: We need to include link to a stub
582 network regardless of the state of the neighbor */
583 masklen2ip (oi->address->prefixlen, &mask);
584 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000585 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
586 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000587 }
paul718e3742002-12-13 20:15:29 +0000588 return links;
589}
590
591/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000592static int
paul718e3742002-12-13 20:15:29 +0000593lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
594{
595 struct ospf_neighbor *dr;
596 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000597 u_int16_t cost = ospf_link_cost (oi);
598
paul718e3742002-12-13 20:15:29 +0000599 /* Describe Type 3 Link. */
600 if (oi->state == ISM_Waiting)
601 {
602 masklen2ip (oi->address->prefixlen, &mask);
603 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000604 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
605 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000606 }
607
608 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
609 /* Describe Type 2 link. */
610 if (dr && (dr->state == NSM_Full ||
611 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000612 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000613 {
paul779adb02006-01-18 15:07:38 +0000614 return link_info_set (s, DR (oi), oi->address->u.prefix4,
615 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000616 }
617 /* Describe type 3 link. */
618 else
619 {
620 masklen2ip (oi->address->prefixlen, &mask);
621 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000622 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
623 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000624 }
paul718e3742002-12-13 20:15:29 +0000625}
626
paul4dadc292005-05-06 21:37:42 +0000627static int
paul718e3742002-12-13 20:15:29 +0000628lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
629{
630 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000631
paul718e3742002-12-13 20:15:29 +0000632 /* Describe Type 3 Link. */
633 if (oi->state != ISM_Loopback)
634 return 0;
635
636 mask.s_addr = 0xffffffff;
637 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000638 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000639}
640
641/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000642static int
paul718e3742002-12-13 20:15:29 +0000643lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
644{
645 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000646 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000647
paul718e3742002-12-13 20:15:29 +0000648 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000649 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000650 if (nbr->state == NSM_Full)
651 {
paul779adb02006-01-18 15:07:38 +0000652 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
653 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000654 }
655
656 return 0;
657}
658
659#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
660
paul7afa08d2002-12-13 20:59:45 +0000661/* this function add for support point-to-multipoint ,see rfc2328
66212.4.1.4.*/
663/* from "edward rrr" <edward_rrr@hotmail.com>
664 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000665static int
paul68980082003-03-25 05:07:42 +0000666lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000667{
668 int links = 0;
669 struct route_node *rn;
670 struct ospf_neighbor *nbr = NULL;
671 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000672 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000673
674 mask.s_addr = 0xffffffff;
675 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000676 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000677
paul1cc8f762003-04-05 19:34:32 +0000678 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000679 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000680
681 /* Search neighbor, */
682 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
683 if ((nbr = rn->info) != NULL)
684 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000685 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000686 if (nbr->state == NSM_Full)
687
688 {
paul779adb02006-01-18 15:07:38 +0000689 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
690 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000691 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000692 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000693 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000694 }
695
696 return links;
paul7afa08d2002-12-13 20:59:45 +0000697}
698
paul718e3742002-12-13 20:15:29 +0000699/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000700static int
paul718e3742002-12-13 20:15:29 +0000701router_lsa_link_set (struct stream *s, struct ospf_area *area)
702{
hasso52dc7ee2004-09-23 19:18:23 +0000703 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000704 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000705 int links = 0;
706
paul1eb8ef22005-04-07 07:30:20 +0000707 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000708 {
paul718e3742002-12-13 20:15:29 +0000709 struct interface *ifp = oi->ifp;
710
711 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000712 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000713 {
714 if (oi->state != ISM_Down)
715 {
716 /* Describe each link. */
717 switch (oi->type)
718 {
719 case OSPF_IFTYPE_POINTOPOINT:
720 links += lsa_link_ptop_set (s, oi);
721 break;
722 case OSPF_IFTYPE_BROADCAST:
723 links += lsa_link_broadcast_set (s, oi);
724 break;
725 case OSPF_IFTYPE_NBMA:
726 links += lsa_link_nbma_set (s, oi);
727 break;
728 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000729 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000730 break;
731 case OSPF_IFTYPE_VIRTUALLINK:
732 links += lsa_link_virtuallink_set (s, oi);
733 break;
734 case OSPF_IFTYPE_LOOPBACK:
735 links += lsa_link_loopback_set (s, oi);
736 }
737 }
738 }
739 }
740
741 return links;
742}
743
744/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000745static void
paul718e3742002-12-13 20:15:29 +0000746ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
747{
748 unsigned long putp;
749 u_int16_t cnt;
750
751 /* Set flags. */
752 stream_putc (s, router_lsa_flags (area));
753
754 /* Set Zero fields. */
755 stream_putc (s, 0);
756
757 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000758 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000759
760 /* Forward word */
761 stream_putw(s, 0);
762
763 /* Set all link information. */
764 cnt = router_lsa_link_set (s, area);
765
766 /* Set # of links here. */
767 stream_putw_at (s, putp, cnt);
768}
paul88d6cf32005-10-29 12:50:09 +0000769
770static int
771ospf_stub_router_timer (struct thread *t)
772{
773 struct ospf_area *area = THREAD_ARG (t);
774
775 area->t_stub_router = NULL;
776
777 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
778
779 /* clear stub route state and generate router-lsa refresh, don't
780 * clobber an administratively set stub-router state though.
781 */
782 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
783 return 0;
784
785 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
786
787 ospf_router_lsa_timer_add (area);
788
789 return 0;
790}
paul718e3742002-12-13 20:15:29 +0000791
paul88d6cf32005-10-29 12:50:09 +0000792inline static void
793ospf_stub_router_check (struct ospf_area *area)
794{
795 /* area must either be administratively configured to be stub
796 * or startup-time stub-router must be configured and we must in a pre-stub
797 * state.
798 */
799 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
800 {
801 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
802 return;
803 }
804
805 /* not admin-stubbed, check whether startup stubbing is configured and
806 * whether it's not been done yet
807 */
808 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
809 return;
810
811 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
812 {
813 /* stub-router is hence done forever for this area, even if someone
814 * tries configure it (take effect next restart).
815 */
816 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
817 return;
818 }
819
820 /* startup stub-router configured and not yet done */
821 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
822
823 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
824 area->ospf->stub_router_startup_time);
825}
826
paul718e3742002-12-13 20:15:29 +0000827/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000828static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000829ospf_router_lsa_new (struct ospf_area *area)
830{
paul68980082003-03-25 05:07:42 +0000831 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000832 struct stream *s;
833 struct lsa_header *lsah;
834 struct ospf_lsa *new;
835 int length;
836
837 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000838 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000839
paul88d6cf32005-10-29 12:50:09 +0000840 /* check whether stub-router is desired, and if this is the first
841 * router LSA.
842 */
843 ospf_stub_router_check (area);
844
paul718e3742002-12-13 20:15:29 +0000845 /* Create a stream for LSA. */
846 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000847 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000848 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000849 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000850
851 /* Set router-LSA body fields. */
852 ospf_router_lsa_body_set (s, area);
853
854 /* Set length. */
855 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000856 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000857 lsah->length = htons (length);
858
859 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000860 if ( (new = ospf_lsa_new ()) == NULL)
861 {
862 zlog_err ("%s: Unable to create new lsa", __func__);
863 return NULL;
864 }
865
paul718e3742002-12-13 20:15:29 +0000866 new->area = area;
867 SET_FLAG (new->flags, OSPF_LSA_SELF);
868
869 /* Copy LSA data to store, discard stream. */
870 new->data = ospf_lsa_data_new (length);
871 memcpy (new->data, lsah, length);
872 stream_free (s);
873
874 return new;
875}
876
877/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000878static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000879ospf_router_lsa_originate (struct ospf_area *area)
880{
881 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000882
paul718e3742002-12-13 20:15:29 +0000883 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000884 if ( (new = ospf_router_lsa_new (area)) == NULL)
885 {
886 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
887 return NULL;
888 }
paul718e3742002-12-13 20:15:29 +0000889
890 /* Sanity check. */
891 if (new->data->adv_router.s_addr == 0)
892 {
893 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000894 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000895 ospf_lsa_discard (new);
896 return NULL;
897 }
898
899 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000900 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000901
902 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000903 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000904
905 /* Flooding new LSA through area. */
906 ospf_flood_through_area (area, NULL, new);
907
908 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
909 {
ajse588f212004-12-08 18:12:06 +0000910 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000911 new->data->type, inet_ntoa (new->data->id), new);
912 ospf_lsa_header_dump (new->data);
913 }
914
915 return new;
916}
917
918/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000919static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000920ospf_router_lsa_refresh (struct ospf_lsa *lsa)
921{
922 struct ospf_area *area = lsa->area;
923 struct ospf_lsa *new;
924
925 /* Sanity check. */
926 assert (lsa->data);
927
928 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000929 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000930
931 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000932 if ( (new = ospf_router_lsa_new (area)) == NULL)
933 {
934 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
935 return NULL;
936 }
937
paul718e3742002-12-13 20:15:29 +0000938 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
939
paul68980082003-03-25 05:07:42 +0000940 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000941
942 /* Flood LSA through area. */
943 ospf_flood_through_area (area, NULL, new);
944
945 /* Debug logging. */
946 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
947 {
ajse588f212004-12-08 18:12:06 +0000948 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000949 new->data->type, inet_ntoa (new->data->id));
950 ospf_lsa_header_dump (new->data);
951 }
952
953 return NULL;
954}
955
paul4dadc292005-05-06 21:37:42 +0000956static int
paul718e3742002-12-13 20:15:29 +0000957ospf_router_lsa_timer (struct thread *t)
958{
959 struct ospf_area *area;
960
961 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000962 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000963
964 area = THREAD_ARG (t);
965 area->t_router_lsa_self = NULL;
966
967 /* Now refresh router-LSA. */
968 if (area->router_lsa_self)
969 ospf_router_lsa_refresh (area->router_lsa_self);
970 /* Newly originate router-LSA. */
971 else
972 ospf_router_lsa_originate (area);
973
974 return 0;
975}
976
977void
978ospf_router_lsa_timer_add (struct ospf_area *area)
979{
980 /* Keep area's self-originated router-LSA. */
981 struct ospf_lsa *lsa = area->router_lsa_self;
982
983 /* Cancel previously scheduled router-LSA timer. */
984 if (area->t_router_lsa_self)
985 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000986 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000987
988 OSPF_TIMER_OFF (area->t_router_lsa_self);
989
990 /* If router-LSA is originated previously, check the interval time. */
991 if (lsa)
992 {
993 int delay;
994 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
995 {
996 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
997 ospf_router_lsa_timer, delay);
998 return;
999 }
1000 }
1001
1002 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001003 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001004
1005 /* Immediately refresh router-LSA. */
1006 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
1007}
1008
1009int
paul68980082003-03-25 05:07:42 +00001010ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001011{
paul68980082003-03-25 05:07:42 +00001012 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00001013 struct listnode *node, *nnode;
1014 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001015
1016 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001017 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +00001018
paul68980082003-03-25 05:07:42 +00001019 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +00001020
paul1eb8ef22005-04-07 07:30:20 +00001021 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00001022 {
paul718e3742002-12-13 20:15:29 +00001023 struct ospf_lsa *lsa = area->router_lsa_self;
1024 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +00001025 const char *area_str;
paul718e3742002-12-13 20:15:29 +00001026
1027 /* Keep Area ID string. */
1028 area_str = AREA_NAME (area);
1029
1030 /* If LSA not exist in this Area, originate new. */
1031 if (lsa == NULL)
1032 {
1033 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001034 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001035
1036 ospf_router_lsa_originate (area);
1037 }
1038 /* If router-ID is changed, Link ID must change.
1039 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001040 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001041 {
1042 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001043 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001044 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1045 ospf_lsa_flush_area (lsa, area);
1046 ospf_lsa_unlock (area->router_lsa_self);
1047 area->router_lsa_self = NULL;
1048
1049 /* Refresh router-LSA, (not install) and flood through area. */
1050 ospf_router_lsa_timer_add (area);
1051 }
1052 else
1053 {
1054 rl = (struct router_lsa *) lsa->data;
1055 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001056 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001057 ospf_router_lsa_timer_add (area);
1058 }
1059 }
1060
1061 return 0;
1062}
1063
1064
1065/* network-LSA related functions. */
1066/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001067static void
paul718e3742002-12-13 20:15:29 +00001068ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1069{
1070 struct in_addr mask;
1071 struct route_node *rn;
1072 struct ospf_neighbor *nbr;
1073
1074 masklen2ip (oi->address->prefixlen, &mask);
1075 stream_put_ipv4 (s, mask.s_addr);
1076
1077 /* The network-LSA lists those routers that are fully adjacent to
1078 the Designated Router; each fully adjacent router is identified by
1079 its OSPF Router ID. The Designated Router includes itself in this
1080 list. RFC2328, Section 12.4.2 */
1081
1082 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1083 if ((nbr = rn->info) != NULL)
1084 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1085 stream_put_ipv4 (s, nbr->router_id.s_addr);
1086}
1087
paul4dadc292005-05-06 21:37:42 +00001088static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001089ospf_network_lsa_new (struct ospf_interface *oi)
1090{
1091 struct stream *s;
1092 struct ospf_lsa *new;
1093 struct lsa_header *lsah;
1094 int length;
1095
1096 /* If there are no neighbours on this network (the net is stub),
1097 the router does not originate network-LSA (see RFC 12.4.2) */
1098 if (oi->full_nbrs == 0)
1099 return NULL;
1100
1101 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001102 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001103
1104 /* Create new stream for LSA. */
1105 s = stream_new (OSPF_MAX_LSA_SIZE);
1106 lsah = (struct lsa_header *) STREAM_DATA (s);
1107
1108 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001109 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001110
1111 /* Set network-LSA body fields. */
1112 ospf_network_lsa_body_set (s, oi);
1113
1114 /* Set length. */
1115 length = stream_get_endp (s);
1116 lsah->length = htons (length);
1117
1118 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001119 if ( (new = ospf_lsa_new ()) == NULL)
1120 {
1121 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1122 return NULL;
1123 }
1124
paul718e3742002-12-13 20:15:29 +00001125 new->area = oi->area;
1126 SET_FLAG (new->flags, OSPF_LSA_SELF);
1127
1128 /* Copy LSA to store. */
1129 new->data = ospf_lsa_data_new (length);
1130 memcpy (new->data, lsah, length);
1131 stream_free (s);
1132
1133 return new;
1134}
1135
1136/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001137static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001138ospf_network_lsa_originate (struct ospf_interface *oi)
1139{
1140 struct ospf_lsa *new;
1141
1142 /* Create new network-LSA instance. */
1143 new = ospf_network_lsa_new (oi);
1144 if (new == NULL)
1145 return NULL;
1146
1147 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001148 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001149
1150 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001151 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001152
1153 /* Flooding new LSA through area. */
1154 ospf_flood_through_area (oi->area, NULL, new);
1155
1156 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1157 {
ajse588f212004-12-08 18:12:06 +00001158 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001159 new->data->type, inet_ntoa (new->data->id), new);
1160 ospf_lsa_header_dump (new->data);
1161 }
1162
1163 return new;
1164}
1165
1166int
1167ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1168{
1169 struct ospf_area *area = lsa->area;
1170 struct ospf_lsa *new;
1171
1172 assert (lsa->data);
1173
1174 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001175 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001176
1177 /* Create new network-LSA instance. */
1178 new = ospf_network_lsa_new (oi);
1179 if (new == NULL)
1180 return -1;
1181 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1182
paul68980082003-03-25 05:07:42 +00001183 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001184
1185 /* Flood LSA through aera. */
1186 ospf_flood_through_area (area, NULL, new);
1187
1188 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1189 {
ajse588f212004-12-08 18:12:06 +00001190 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001191 new->data->type, inet_ntoa (new->data->id));
1192 ospf_lsa_header_dump (new->data);
1193 }
1194
1195 return 0;
1196}
1197
paul4dadc292005-05-06 21:37:42 +00001198static int
paul718e3742002-12-13 20:15:29 +00001199ospf_network_lsa_refresh_timer (struct thread *t)
1200{
1201 struct ospf_interface *oi;
1202
1203 oi = THREAD_ARG (t);
1204 oi->t_network_lsa_self = NULL;
1205
1206 if (oi->network_lsa_self)
1207 /* Now refresh network-LSA. */
1208 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1209 else
1210 /* Newly create network-LSA. */
1211 ospf_network_lsa_originate (oi);
1212
1213 return 0;
1214}
1215
1216void
1217ospf_network_lsa_timer_add (struct ospf_interface *oi)
1218{
1219 /* Keep interface's self-originated network-LSA. */
1220 struct ospf_lsa *lsa = oi->network_lsa_self;
1221
1222 /* Cancel previously schedules network-LSA timer. */
1223 if (oi->t_network_lsa_self)
1224 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001225 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001226 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1227
1228 /* If network-LSA is originated previously, check the interval time. */
1229 if (lsa)
1230 {
1231 int delay;
1232 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1233 {
1234 oi->t_network_lsa_self =
1235 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1236 oi, delay);
1237 return;
1238 }
1239 }
1240
1241 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001242 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001243
1244 /* Immediately refresh network-LSA. */
1245 oi->t_network_lsa_self =
1246 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1247}
1248
1249
paul4dadc292005-05-06 21:37:42 +00001250static void
paul718e3742002-12-13 20:15:29 +00001251stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1252{
1253 u_int32_t metric;
1254 char *mp;
1255
1256 /* Put 0 metric. TOS metric is not supported. */
1257 metric = htonl (metric_value);
1258 mp = (char *) &metric;
1259 mp++;
1260 stream_put (s, mp, 3);
1261}
1262
1263/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001264static void
paul718e3742002-12-13 20:15:29 +00001265ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1266 u_int32_t metric)
1267{
1268 struct in_addr mask;
1269
1270 masklen2ip (p->prefixlen, &mask);
1271
1272 /* Put Network Mask. */
1273 stream_put_ipv4 (s, mask.s_addr);
1274
1275 /* Set # TOS. */
1276 stream_putc (s, (u_char) 0);
1277
1278 /* Set metric. */
1279 stream_put_ospf_metric (s, metric);
1280}
1281
paul4dadc292005-05-06 21:37:42 +00001282static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001283ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1284 u_int32_t metric, struct in_addr id)
1285{
1286 struct stream *s;
1287 struct ospf_lsa *new;
1288 struct lsa_header *lsah;
1289 int length;
1290
paulc24d6022005-11-20 14:54:12 +00001291 if (id.s_addr == 0xffffffff)
1292 {
1293 /* Maybe Link State ID not available. */
1294 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1295 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1296 OSPF_SUMMARY_LSA);
1297 return NULL;
1298 }
1299
paul718e3742002-12-13 20:15:29 +00001300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001301 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001302
1303 /* Create new stream for LSA. */
1304 s = stream_new (OSPF_MAX_LSA_SIZE);
1305 lsah = (struct lsa_header *) STREAM_DATA (s);
1306
paul68980082003-03-25 05:07:42 +00001307 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1308 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001309
1310 /* Set summary-LSA body fields. */
1311 ospf_summary_lsa_body_set (s, p, metric);
1312
1313 /* Set length. */
1314 length = stream_get_endp (s);
1315 lsah->length = htons (length);
1316
1317 /* Create OSPF LSA instance. */
1318 new = ospf_lsa_new ();
1319 new->area = area;
1320 SET_FLAG (new->flags, OSPF_LSA_SELF);
1321
1322 /* Copy LSA to store. */
1323 new->data = ospf_lsa_data_new (length);
1324 memcpy (new->data, lsah, length);
1325 stream_free (s);
1326
1327 return new;
1328}
1329
1330/* Originate Summary-LSA. */
1331struct ospf_lsa *
1332ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1333 struct ospf_area *area)
1334{
1335 struct ospf_lsa *new;
1336 struct in_addr id;
1337
paul68980082003-03-25 05:07:42 +00001338 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001339
paulc24d6022005-11-20 14:54:12 +00001340 if (id.s_addr == 0xffffffff)
1341 {
1342 /* Maybe Link State ID not available. */
1343 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1344 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1345 OSPF_SUMMARY_LSA);
1346 return NULL;
1347 }
1348
paul718e3742002-12-13 20:15:29 +00001349 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001350 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1351 return NULL;
paul718e3742002-12-13 20:15:29 +00001352
1353 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001354 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001355
1356 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001357 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001358
1359 /* Flooding new LSA through area. */
1360 ospf_flood_through_area (area, NULL, new);
1361
1362 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1363 {
ajse588f212004-12-08 18:12:06 +00001364 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001365 new->data->type, inet_ntoa (new->data->id), new);
1366 ospf_lsa_header_dump (new->data);
1367 }
1368
1369 return new;
1370}
1371
1372struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001373ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001374{
1375 struct ospf_lsa *new;
1376 struct summary_lsa *sl;
1377 struct prefix p;
1378
1379 /* Sanity check. */
1380 assert (lsa->data);
1381
1382 sl = (struct summary_lsa *)lsa->data;
1383 p.prefixlen = ip_masklen (sl->mask);
1384 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1385 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001386
1387 if (!new)
1388 return NULL;
1389
paul718e3742002-12-13 20:15:29 +00001390 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1391
1392 /* Re-calculate checksum. */
1393 ospf_lsa_checksum (new->data);
1394
paul68980082003-03-25 05:07:42 +00001395 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001396
1397 /* Flood LSA through AS. */
1398 ospf_flood_through_area (new->area, NULL, new);
1399
1400 /* Debug logging. */
1401 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1402 {
ajse588f212004-12-08 18:12:06 +00001403 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001404 new->data->type, inet_ntoa (new->data->id));
1405 ospf_lsa_header_dump (new->data);
1406 }
1407
1408 return new;
1409}
1410
1411
1412/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001413static void
paul718e3742002-12-13 20:15:29 +00001414ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1415 u_int32_t metric)
1416{
1417 struct in_addr mask;
1418
1419 masklen2ip (p->prefixlen, &mask);
1420
1421 /* Put Network Mask. */
1422 stream_put_ipv4 (s, mask.s_addr);
1423
1424 /* Set # TOS. */
1425 stream_putc (s, (u_char) 0);
1426
1427 /* Set metric. */
1428 stream_put_ospf_metric (s, metric);
1429}
1430
paul4dadc292005-05-06 21:37:42 +00001431static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001432ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1433 u_int32_t metric, struct in_addr id)
1434{
1435 struct stream *s;
1436 struct ospf_lsa *new;
1437 struct lsa_header *lsah;
1438 int length;
1439
paulc24d6022005-11-20 14:54:12 +00001440 if (id.s_addr == 0xffffffff)
1441 {
1442 /* Maybe Link State ID not available. */
1443 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1444 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1445 OSPF_ASBR_SUMMARY_LSA);
1446 return NULL;
1447 }
1448
paul718e3742002-12-13 20:15:29 +00001449 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001450 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001451
1452 /* Create new stream for LSA. */
1453 s = stream_new (OSPF_MAX_LSA_SIZE);
1454 lsah = (struct lsa_header *) STREAM_DATA (s);
1455
paul68980082003-03-25 05:07:42 +00001456 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1457 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001458
1459 /* Set summary-LSA body fields. */
1460 ospf_summary_asbr_lsa_body_set (s, p, metric);
1461
1462 /* Set length. */
1463 length = stream_get_endp (s);
1464 lsah->length = htons (length);
1465
1466 /* Create OSPF LSA instance. */
1467 new = ospf_lsa_new ();
1468 new->area = area;
1469 SET_FLAG (new->flags, OSPF_LSA_SELF);
1470
1471 /* Copy LSA to store. */
1472 new->data = ospf_lsa_data_new (length);
1473 memcpy (new->data, lsah, length);
1474 stream_free (s);
1475
1476 return new;
1477}
1478
1479/* Originate summary-ASBR-LSA. */
1480struct ospf_lsa *
1481ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1482 struct ospf_area *area)
1483{
1484 struct ospf_lsa *new;
1485 struct in_addr id;
1486
paul68980082003-03-25 05:07:42 +00001487 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001488
paulc24d6022005-11-20 14:54:12 +00001489 if (id.s_addr == 0xffffffff)
1490 {
1491 /* Maybe Link State ID not available. */
1492 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1493 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1494 OSPF_ASBR_SUMMARY_LSA);
1495 return NULL;
1496 }
1497
paul718e3742002-12-13 20:15:29 +00001498 /* Create new summary-LSA instance. */
1499 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001500 if (!new)
1501 return NULL;
paul718e3742002-12-13 20:15:29 +00001502
1503 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001504 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001505
1506 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001507 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001508
1509 /* Flooding new LSA through area. */
1510 ospf_flood_through_area (area, NULL, new);
1511
1512 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1513 {
ajse588f212004-12-08 18:12:06 +00001514 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001515 new->data->type, inet_ntoa (new->data->id), new);
1516 ospf_lsa_header_dump (new->data);
1517 }
1518
1519 return new;
1520}
1521
1522struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001523ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001524{
1525 struct ospf_lsa *new;
1526 struct summary_lsa *sl;
1527 struct prefix p;
1528
1529 /* Sanity check. */
1530 assert (lsa->data);
1531
1532 sl = (struct summary_lsa *)lsa->data;
1533 p.prefixlen = ip_masklen (sl->mask);
1534 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1535 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001536 if (!new)
1537 return NULL;
paul718e3742002-12-13 20:15:29 +00001538
1539 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1540
1541 /* Re-calculate checksum. */
1542 ospf_lsa_checksum (new->data);
1543
paul68980082003-03-25 05:07:42 +00001544 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001545
1546 /* Flood LSA through area. */
1547 ospf_flood_through_area (new->area, NULL, new);
1548
1549 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1550 {
ajse588f212004-12-08 18:12:06 +00001551 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001552 new->data->type, inet_ntoa (new->data->id));
1553 ospf_lsa_header_dump (new->data);
1554 }
1555
1556 return new;
1557}
1558
1559/* AS-external-LSA related functions. */
1560
1561/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1562 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001563static struct in_addr
paul68980082003-03-25 05:07:42 +00001564ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001565{
1566 struct in_addr fwd;
1567 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001568 struct listnode *node;
1569 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001570
1571 fwd.s_addr = 0;
1572
1573 if (!nexthop.s_addr)
1574 return fwd;
1575
1576 /* Check whether nexthop is covered by OSPF network. */
1577 nh.family = AF_INET;
1578 nh.u.prefix4 = nexthop;
1579 nh.prefixlen = IPV4_MAX_BITLEN;
1580
paul1eb8ef22005-04-07 07:30:20 +00001581 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1582 if (if_is_operative (oi->ifp))
1583 if (oi->address->family == AF_INET)
1584 if (prefix_match (oi->address, &nh))
1585 return nexthop;
paul718e3742002-12-13 20:15:29 +00001586
1587 return fwd;
1588}
1589
paul718e3742002-12-13 20:15:29 +00001590/* NSSA-external-LSA related functions. */
1591
1592/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001593
paul718e3742002-12-13 20:15:29 +00001594struct in_addr
1595ospf_get_ip_from_ifp (struct ospf_interface *oi)
1596{
1597 struct in_addr fwd;
1598
1599 fwd.s_addr = 0;
1600
paul2e3b2e42002-12-13 21:03:13 +00001601 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001602 return oi->address->u.prefix4;
1603
1604 return fwd;
1605}
1606
1607/* Get 1st IP connection for Forward Addr */
1608struct in_addr
paulf2c80652002-12-13 21:44:27 +00001609ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001610{
1611 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001612 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001613 struct listnode *node;
1614 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001615
1616 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001617 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001618
paul1eb8ef22005-04-07 07:30:20 +00001619 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001620 {
paul2e3b2e42002-12-13 21:03:13 +00001621 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001622 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001623 if (oi->address && oi->address->family == AF_INET)
1624 {
1625 if (best_default.s_addr == 0)
1626 best_default = oi->address->u.prefix4;
1627 if (oi->area == area)
1628 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001629 }
paul718e3742002-12-13 20:15:29 +00001630 }
paulf2c80652002-12-13 21:44:27 +00001631 if (best_default.s_addr != 0)
1632 return best_default;
paul718e3742002-12-13 20:15:29 +00001633
paul68980082003-03-25 05:07:42 +00001634 if (best_default.s_addr != 0)
1635 return best_default;
1636
paul718e3742002-12-13 20:15:29 +00001637 return fwd;
1638}
hassobeebba72004-06-20 21:00:27 +00001639
paul718e3742002-12-13 20:15:29 +00001640#define DEFAULT_DEFAULT_METRIC 20
1641#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1642#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1643
1644#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1645
1646int
paul68980082003-03-25 05:07:42 +00001647metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001648{
paul68980082003-03-25 05:07:42 +00001649 return (ospf->dmetric[src].type < 0 ?
1650 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001651}
1652
1653int
paul68980082003-03-25 05:07:42 +00001654metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001655{
paul68980082003-03-25 05:07:42 +00001656 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001657 {
1658 if (src == DEFAULT_ROUTE)
1659 {
paul68980082003-03-25 05:07:42 +00001660 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001661 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1662 else
1663 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1664 }
paul68980082003-03-25 05:07:42 +00001665 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001666 return DEFAULT_DEFAULT_METRIC;
1667 else
paul68980082003-03-25 05:07:42 +00001668 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001669 }
1670
paul68980082003-03-25 05:07:42 +00001671 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001672}
1673
1674/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001675static void
paul68980082003-03-25 05:07:42 +00001676ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1677 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001678{
1679 struct prefix_ipv4 *p = &ei->p;
1680 struct in_addr mask, fwd_addr;
1681 u_int32_t mvalue;
1682 int mtype;
1683 int type;
1684
1685 /* Put Network Mask. */
1686 masklen2ip (p->prefixlen, &mask);
1687 stream_put_ipv4 (s, mask.s_addr);
1688
1689 /* If prefix is default, specify DEFAULT_ROUTE. */
1690 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1691
1692 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001693 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001694
1695 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001696 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001697
1698 /* Put type of external metric. */
1699 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1700
1701 /* Put 0 metric. TOS metric is not supported. */
1702 stream_put_ospf_metric (s, mvalue);
1703
1704 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001705 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001706
1707 /* Put forwarding address. */
1708 stream_put_ipv4 (s, fwd_addr.s_addr);
1709
1710 /* Put route tag -- This value should be introduced from configuration. */
1711 stream_putl (s, 0);
1712}
1713
1714/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001715static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001716ospf_external_lsa_new (struct ospf *ospf,
1717 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001718{
1719 struct stream *s;
1720 struct lsa_header *lsah;
1721 struct ospf_lsa *new;
1722 struct in_addr id;
1723 int length;
1724
1725 if (ei == NULL)
1726 {
1727 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001728 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001729 return NULL;
1730 }
1731
1732 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001733 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001734
1735 /* If old Link State ID is specified, refresh LSA with same ID. */
1736 if (old_id)
1737 id = *old_id;
1738 /* Get Link State with unique ID. */
1739 else
1740 {
paul68980082003-03-25 05:07:42 +00001741 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001742 if (id.s_addr == 0xffffffff)
1743 {
1744 /* Maybe Link State ID not available. */
1745 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001746 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001747 return NULL;
1748 }
1749 }
1750
1751 /* Create new stream for LSA. */
1752 s = stream_new (OSPF_MAX_LSA_SIZE);
1753 lsah = (struct lsa_header *) STREAM_DATA (s);
1754
1755 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001756 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1757 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001758
1759 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001760 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001761
1762 /* Set length. */
1763 length = stream_get_endp (s);
1764 lsah->length = htons (length);
1765
1766 /* Now, create OSPF LSA instance. */
1767 new = ospf_lsa_new ();
1768 new->area = NULL;
1769 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1770
1771 /* Copy LSA data to store, discard stream. */
1772 new->data = ospf_lsa_data_new (length);
1773 memcpy (new->data, lsah, length);
1774 stream_free (s);
1775
1776 return new;
1777}
1778
paul718e3742002-12-13 20:15:29 +00001779/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001780static void
paul68980082003-03-25 05:07:42 +00001781ospf_install_flood_nssa (struct ospf *ospf,
1782 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001783{
pauld4a53d52003-07-12 21:30:57 +00001784 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001785 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001786 struct ospf_area *area;
1787 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001788
pauld4a53d52003-07-12 21:30:57 +00001789 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1790 * which originated from an NSSA area. In which case it should not be
1791 * flooded back to NSSA areas.
1792 */
1793 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1794 return;
1795
paul718e3742002-12-13 20:15:29 +00001796 /* NSSA Originate or Refresh (If anyNSSA)
1797
1798 LSA is self-originated. And just installed as Type-5.
1799 Additionally, install as Type-7 LSDB for every attached NSSA.
1800
1801 P-Bit controls which ABR performs translation to outside world; If
1802 we are an ABR....do not set the P-bit, because we send the Type-5,
1803 not as the ABR Translator, but as the ASBR owner within the AS!
1804
1805 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1806 elected ABR Translator will see the P-bit, Translate, and re-flood.
1807
1808 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1809 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1810
paul1eb8ef22005-04-07 07:30:20 +00001811 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001812 {
hasso0c14ad82003-07-03 08:36:02 +00001813 /* Don't install Type-7 LSA's into nonNSSA area */
1814 if (area->external_routing != OSPF_AREA_NSSA)
1815 continue;
paul718e3742002-12-13 20:15:29 +00001816
paul68980082003-03-25 05:07:42 +00001817 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001818 new = ospf_lsa_dup (lsa);
1819 new->area = area;
1820 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001821
paul68980082003-03-25 05:07:42 +00001822 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001823 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001824 {
pauld4a53d52003-07-12 21:30:57 +00001825 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001826
1827 /* set non-zero FWD ADDR
1828
1829 draft-ietf-ospf-nssa-update-09.txt
1830
1831 if the network between the NSSA AS boundary router and the
1832 adjacent AS is advertised into OSPF as an internal OSPF route,
1833 the forwarding address should be the next op address as is cu
1834 currently done with type-5 LSAs. If the intervening network is
1835 not adversited into OSPF as an internal OSPF route and the
1836 type-7 LSA's P-bit is set a forwarding address should be
1837 selected from one of the router's active OSPF inteface addresses
1838 which belong to the NSSA. If no such addresses exist, then
1839 no type-7 LSA's with the P-bit set should originate from this
1840 router. */
1841
pauld4a53d52003-07-12 21:30:57 +00001842 /* kevinm: not updating lsa anymore, just new */
1843 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001844
1845 if (extlsa->e[0].fwd_addr.s_addr == 0)
1846 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001847
pauld7480322003-05-16 17:31:51 +00001848 if (extlsa->e[0].fwd_addr.s_addr == 0)
1849 {
1850 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001851 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
pauld4a53d52003-07-12 21:30:57 +00001852 ospf_lsa_discard(new);
pauld7480322003-05-16 17:31:51 +00001853 return;
1854 }
paulf2c80652002-12-13 21:44:27 +00001855 }
paul68980082003-03-25 05:07:42 +00001856 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001857 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001858
paul68980082003-03-25 05:07:42 +00001859 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001860 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001861
1862 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001863 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001864 }
paul718e3742002-12-13 20:15:29 +00001865}
pauld4a53d52003-07-12 21:30:57 +00001866
paul4dadc292005-05-06 21:37:42 +00001867static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001868ospf_lsa_translated_nssa_new (struct ospf *ospf,
1869 struct ospf_lsa *type7)
1870{
1871
1872 struct ospf_lsa *new;
1873 struct as_external_lsa *ext, *extnew;
1874 struct external_info ei;
1875
1876 ext = (struct as_external_lsa *)(type7->data);
1877
1878 /* need external_info struct, fill in bare minimum */
1879 ei.p.family = AF_INET;
1880 ei.p.prefix = type7->data->id;
1881 ei.p.prefixlen = ip_masklen (ext->mask);
1882 ei.type = ZEBRA_ROUTE_OSPF;
1883 ei.nexthop = ext->header.adv_router;
1884 ei.route_map_set.metric = -1;
1885 ei.route_map_set.metric_type = -1;
1886 ei.tag = 0;
1887
1888 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1889 {
1890 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001891 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001892 "Translated Type-5 for %s",
1893 inet_ntoa (ei.p.prefix));
1894 return NULL;
1895 }
1896
1897 extnew = (struct as_external_lsa *)(new->data);
1898
1899 /* copy over Type-7 data to new */
1900 extnew->e[0].tos = ext->e[0].tos;
1901 extnew->e[0].route_tag = ext->e[0].route_tag;
1902 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1903 new->data->ls_seqnum = type7->data->ls_seqnum;
1904
1905 /* add translated flag, checksum and lock new lsa */
1906 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1907 ospf_lsa_checksum (new->data);
1908 new = ospf_lsa_lock (new);
1909
1910 return new;
1911}
1912
1913/* compare type-5 to type-7
1914 * -1: err, 0: same, 1: different
1915 */
paul4dadc292005-05-06 21:37:42 +00001916static int
pauld4a53d52003-07-12 21:30:57 +00001917ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1918{
1919
1920 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1921 *e7 = (struct as_external_lsa *)t7;
1922
1923
1924 /* sanity checks */
1925 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1926 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1927 return -1;
1928
1929 if (t5->data->id.s_addr != t7->data->id.s_addr)
1930 return -1;
1931
1932 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1933 return LSA_REFRESH_FORCE;
1934
1935 if (e5->mask.s_addr != e7->mask.s_addr)
1936 return LSA_REFRESH_FORCE;
1937
1938 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1939 return LSA_REFRESH_FORCE;
1940
1941 if (e5->e[0].route_tag != e7->e[0].route_tag)
1942 return LSA_REFRESH_FORCE;
1943
1944 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1945 return LSA_REFRESH_FORCE;
1946
1947 return LSA_REFRESH_IF_CHANGED;
1948}
1949
1950/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1951struct ospf_lsa *
1952ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1953{
1954 struct ospf_lsa *new;
1955 struct as_external_lsa *extnew;
1956
1957 /* we cant use ospf_external_lsa_originate() as we need to set
1958 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1959 */
1960
1961 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1962 {
1963 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001964 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001965 "Type-7, Id %s, to Type-5",
1966 inet_ntoa (type7->data->id));
1967 return NULL;
1968 }
1969
1970 extnew = (struct as_external_lsa *)new;
1971
1972 if (IS_DEBUG_OSPF_NSSA)
1973 {
ajse588f212004-12-08 18:12:06 +00001974 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001975 "translated Type 7, installed:");
1976 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001977 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1978 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001979 }
1980
1981 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1982 {
1983 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001984 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001985 "Could not install LSA "
1986 "id %s", inet_ntoa (type7->data->id));
1987 return NULL;
1988 }
1989
1990 ospf->lsa_originate_count++;
1991 ospf_flood_through_as (ospf, NULL, new);
1992
1993 return new;
1994}
1995
1996/* Refresh Translated from NSSA AS-external-LSA. */
1997struct ospf_lsa *
1998ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1999 struct ospf_lsa *type5)
2000{
2001 struct ospf_lsa *new = NULL;
2002
2003 /* Sanity checks. */
2004 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00002005 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00002006 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002007 if (type7)
2008 assert (type7->data);
2009 if (type5)
2010 assert (type5->data);
2011 assert (ospf->anyNSSA);
2012
2013 /* get required data according to what has been given */
2014 if (type7 && type5 == NULL)
2015 {
2016 /* find the translated Type-5 for this Type-7 */
2017 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2018 struct prefix_ipv4 p =
2019 {
2020 .prefix = type7->data->id,
2021 .prefixlen = ip_masklen (ext->mask),
2022 .family = AF_INET,
2023 };
2024
2025 type5 = ospf_external_info_find_lsa (ospf, &p);
2026 }
2027 else if (type5 && type7 == NULL)
2028 {
2029 /* find the type-7 from which supplied type-5 was translated,
2030 * ie find first type-7 with same LSA Id.
2031 */
paul1eb8ef22005-04-07 07:30:20 +00002032 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002033 struct route_node *rn;
2034 struct ospf_lsa *lsa;
2035 struct ospf_area *area;
2036
paul1eb8ef22005-04-07 07:30:20 +00002037 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002038 {
2039 if (area->external_routing != OSPF_AREA_NSSA
2040 && !type7)
2041 continue;
2042
2043 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2044 {
2045 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2046 {
2047 type7 = lsa;
2048 break;
2049 }
2050 }
2051 }
2052 }
2053
2054 /* do we have type7? */
2055 if (!type7)
2056 {
2057 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002058 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002059 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002060 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002061 return NULL;
2062 }
2063
2064 /* do we have valid translated type5? */
2065 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2066 {
2067 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002068 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002069 "found for Type-7 with Id %s",
2070 inet_ntoa (type7->data->id));
2071 return NULL;
2072 }
2073
2074 /* Delete LSA from neighbor retransmit-list. */
2075 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2076
2077 /* create new translated LSA */
2078 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2079 {
2080 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002081 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002082 "Type-7 for %s to Type-5",
2083 inet_ntoa (type7->data->id));
2084 return NULL;
2085 }
2086
2087 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2088 {
2089 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002090 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002091 "translated LSA, Id %s",
2092 inet_ntoa (new->data->id));
2093 return NULL;
2094 }
2095
2096 /* Flood LSA through area. */
2097 ospf_flood_through_as (ospf, NULL, new);
2098
2099 return new;
2100}
paul718e3742002-12-13 20:15:29 +00002101
2102int
2103is_prefix_default (struct prefix_ipv4 *p)
2104{
2105 struct prefix_ipv4 q;
2106
2107 q.family = AF_INET;
2108 q.prefix.s_addr = 0;
2109 q.prefixlen = 0;
2110
2111 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2112}
2113
2114/* Originate an AS-external-LSA, install and flood. */
2115struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002116ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002117{
2118 struct ospf_lsa *new;
2119
2120 /* Added for NSSA project....
2121
2122 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2123 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2124 every area. The Type-7's are flooded to every IR and every ABR; We
2125 install the Type-5 LSDB so that the normal "refresh" code operates
2126 as usual, and flag them as not used during ASE calculations. The
2127 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2128 Address of non-zero.
2129
2130 If an ABR is the elected NSSA translator, following SPF and during
2131 the ABR task it will translate all the scanned Type-7's, with P-bit
2132 ON and not-self generated, and translate to Type-5's throughout the
2133 non-NSSA/STUB AS.
2134
2135 A difference in operation depends whether this ASBR is an ABR
2136 or not. If not an ABR, the P-bit is ON, to indicate that any
2137 elected NSSA-ABR can perform its translation.
2138
2139 If an ABR, the P-bit is OFF; No ABR will perform translation and
2140 this ASBR will flood the Type-5 LSA as usual.
2141
2142 For the case where this ASBR is not an ABR, the ASE calculations
2143 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2144 demonstrate to the user that there are LSA's that belong to any
2145 attached NSSA.
2146
2147 Finally, it just so happens that when the ABR is translating every
2148 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2149 approved Type-5 (translated from Type-7); at the end of translation
2150 if any Translated Type-5's remain unapproved, then they must be
2151 flushed from the AS.
2152
2153 */
2154
2155 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002156 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002157 return NULL;
2158
2159 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002160 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002161 {
2162 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002163 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002164 inet_ntoa (ei->p.prefix));
2165 return NULL;
2166 }
2167
2168 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002169 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002170
2171 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002172 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002173
2174 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002175 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002176
paul718e3742002-12-13 20:15:29 +00002177 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002178 if (ospf->anyNSSA &&
2179 /* stay away from translated LSAs! */
2180 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002181 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002182
2183 /* Debug logging. */
2184 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2185 {
ajse588f212004-12-08 18:12:06 +00002186 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002187 new->data->type, inet_ntoa (new->data->id), new);
2188 ospf_lsa_header_dump (new->data);
2189 }
2190
2191 return new;
2192}
2193
2194/* Originate AS-external-LSA from external info with initial flag. */
2195int
paul68980082003-03-25 05:07:42 +00002196ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002197{
paul68980082003-03-25 05:07:42 +00002198 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002199 struct route_node *rn;
2200 struct external_info *ei;
2201 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002202 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002203
paul68980082003-03-25 05:07:42 +00002204 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002205
2206 /* Originate As-external-LSA from all type of distribute source. */
2207 if ((rt = EXTERNAL_INFO (type)))
2208 for (rn = route_top (rt); rn; rn = route_next (rn))
2209 if ((ei = rn->info) != NULL)
2210 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002211 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002212 zlog_warn ("LSA: AS-external-LSA was not originated.");
2213
2214 return 0;
2215}
2216
paul4dadc292005-05-06 21:37:42 +00002217static struct external_info *
paul020709f2003-04-04 02:44:16 +00002218ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002219{
2220 int type;
2221 struct route_node *rn;
2222 struct prefix_ipv4 p;
2223
2224 p.family = AF_INET;
2225 p.prefix.s_addr = 0;
2226 p.prefixlen = 0;
2227
2228 /* First, lookup redistributed default route. */
2229 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2230 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2231 {
2232 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2233 if (rn != NULL)
2234 {
2235 route_unlock_node (rn);
2236 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002237 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002238 return rn->info;
2239 }
2240 }
2241
2242 return NULL;
2243}
2244
2245int
paul68980082003-03-25 05:07:42 +00002246ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002247{
paul718e3742002-12-13 20:15:29 +00002248 struct prefix_ipv4 p;
2249 struct in_addr nexthop;
2250 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002251 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002252
Paul Jakma4021b602006-05-12 22:55:41 +00002253 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002254
2255 p.family = AF_INET;
2256 p.prefix.s_addr = 0;
2257 p.prefixlen = 0;
2258
Paul Jakma4021b602006-05-12 22:55:41 +00002259 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002260 {
2261 /* If there is no default route via redistribute,
2262 then originate AS-external-LSA with nexthop 0 (self). */
2263 nexthop.s_addr = 0;
2264 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2265 }
2266
paul020709f2003-04-04 02:44:16 +00002267 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002268 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002269
2270 return 0;
2271}
2272
paul645878f2003-04-13 21:42:11 +00002273/* Flush any NSSA LSAs for given prefix */
2274void
2275ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2276{
paul1eb8ef22005-04-07 07:30:20 +00002277 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002278 struct ospf_lsa *lsa;
2279 struct ospf_area *area;
2280
paul1eb8ef22005-04-07 07:30:20 +00002281 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002282 {
paul1eb8ef22005-04-07 07:30:20 +00002283 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002284 {
2285 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2286 ospf->router_id)))
2287 {
2288 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002289 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002290 inet_ntoa (p->prefix), p->prefixlen);
2291 continue;
2292 }
2293 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2294 if (!IS_LSA_MAXAGE (lsa))
2295 {
2296 ospf_refresher_unregister_lsa (ospf, lsa);
2297 ospf_lsa_flush_area (lsa, area);
2298 }
2299 }
paul645878f2003-04-13 21:42:11 +00002300 }
2301}
paul645878f2003-04-13 21:42:11 +00002302
paul718e3742002-12-13 20:15:29 +00002303/* Flush an AS-external-LSA from LSDB and routing domain. */
2304void
paul68980082003-03-25 05:07:42 +00002305ospf_external_lsa_flush (struct ospf *ospf,
2306 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002307 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002308{
2309 struct ospf_lsa *lsa;
2310
2311 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002312 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002313 inet_ntoa (p->prefix), p->prefixlen);
2314
2315 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002316 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002317 {
2318 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002319 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002320 inet_ntoa (p->prefix), p->prefixlen);
2321 return;
2322 }
hassobeebba72004-06-20 21:00:27 +00002323
pauld4a53d52003-07-12 21:30:57 +00002324 /* If LSA is selforiginated, not a translated LSA, and there is
2325 * NSSA area, flush Type-7 LSA's at first.
2326 */
2327 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2328 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002329 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002330
2331 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002332 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002333
2334 /* There must be no self-originated LSA in rtrs_external. */
2335#if 0
2336 /* Remove External route from Zebra. */
2337 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2338#endif
2339
2340 if (!IS_LSA_MAXAGE (lsa))
2341 {
2342 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002343 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002344
2345 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002346 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002347 }
2348
2349 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002350 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002351}
2352
2353void
paul68980082003-03-25 05:07:42 +00002354ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002355{
2356 struct prefix_ipv4 p;
2357 struct external_info *ei;
2358 struct ospf_lsa *lsa;
2359
2360 p.family = AF_INET;
2361 p.prefixlen = 0;
2362 p.prefix.s_addr = 0;
2363
paul020709f2003-04-04 02:44:16 +00002364 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002365 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002366
2367 if (ei)
2368 {
2369 if (lsa)
2370 {
2371 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002372 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002373 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002374 }
2375 else
2376 {
2377 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002378 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002379 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002380 }
2381 }
2382 else
2383 {
2384 if (lsa)
2385 {
2386 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002387 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002388 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002389 }
2390 }
2391}
2392
2393void
paul68980082003-03-25 05:07:42 +00002394ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002395{
2396 struct route_node *rn;
2397 struct external_info *ei;
2398
2399 if (type != DEFAULT_ROUTE)
2400 if (EXTERNAL_INFO(type))
2401 /* Refresh each redistributed AS-external-LSAs. */
2402 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2403 if ((ei = rn->info))
2404 if (!is_prefix_default (&ei->p))
2405 {
2406 struct ospf_lsa *lsa;
2407
paul68980082003-03-25 05:07:42 +00002408 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2409 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002410 else
paul68980082003-03-25 05:07:42 +00002411 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002412 }
2413}
2414
2415/* Refresh AS-external-LSA. */
2416void
paul68980082003-03-25 05:07:42 +00002417ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002418 struct external_info *ei, int force)
2419{
2420 struct ospf_lsa *new;
2421 int changed;
2422
2423 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002424 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002425 {
pauld4a53d52003-07-12 21:30:57 +00002426 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002427 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002428 "redist check fail",
2429 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002430 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002431 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002432 return;
2433 }
2434
2435 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002436 {
2437 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002438 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002439 lsa->data->type, inet_ntoa (lsa->data->id));
2440 return;
2441 }
paul718e3742002-12-13 20:15:29 +00002442
2443 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002444 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002445
2446 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002447 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002448
paul68980082003-03-25 05:07:42 +00002449 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002450
2451 if (new == NULL)
2452 {
2453 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002454 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002455 inet_ntoa (lsa->data->id));
2456 return;
2457 }
2458
2459 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2460
2461 /* Record timestamp. */
2462 gettimeofday (&new->tv_orig, NULL);
2463
2464 /* Re-calculate checksum. */
2465 ospf_lsa_checksum (new->data);
2466
paul68980082003-03-25 05:07:42 +00002467 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002468
2469 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002470 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002471
paul718e3742002-12-13 20:15:29 +00002472 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002473 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002474 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002475
pauld4a53d52003-07-12 21:30:57 +00002476 /* Register self-originated LSA to refresh queue.
2477 * Translated LSAs should not be registered, but refreshed upon
2478 * refresh of the Type-7
2479 */
2480 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2481 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002482
2483 /* Debug logging. */
2484 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2485 {
ajse588f212004-12-08 18:12:06 +00002486 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002487 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002488 ospf_lsa_header_dump (new->data);
2489 }
2490
2491 return;
2492}
2493
2494
2495/* LSA installation functions. */
2496
2497/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002498static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002499ospf_router_lsa_install (struct ospf *ospf,
2500 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002501{
2502 struct ospf_area *area = new->area;
2503
2504 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2505 The entire routing table must be recalculated, starting with
2506 the shortest path calculations for each area (not just the
2507 area whose link-state database has changed).
2508 */
2509 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002510 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002511
2512 if (IS_LSA_SELF (new))
2513 {
2514 /* Set router-LSA refresh timer. */
2515 OSPF_TIMER_OFF (area->t_router_lsa_self);
2516 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002517 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002518
2519 /* Set self-originated router-LSA. */
2520 ospf_lsa_unlock (area->router_lsa_self);
2521 area->router_lsa_self = ospf_lsa_lock (new);
2522
2523 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002524 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002525 new->data->type, inet_ntoa (new->data->id),
2526 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002527 }
2528
2529 return new;
2530}
2531
2532#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2533 if (!(T)) \
2534 (T) = thread_add_timer (master, (F), oi, (V))
2535
2536/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002537static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002538ospf_network_lsa_install (struct ospf *ospf,
2539 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002540 struct ospf_lsa *new,
2541 int rt_recalc)
2542{
2543
2544 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2545 The entire routing table must be recalculated, starting with
2546 the shortest path calculations for each area (not just the
2547 area whose link-state database has changed).
2548 */
2549 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002550 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002551
2552 /* We supposed that when LSA is originated by us, we pass the int
2553 for which it was originated. If LSA was received by flooding,
2554 the RECEIVED flag is set, so we do not link the LSA to the int. */
2555 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2556 {
2557 /* Set LSRefresh timer. */
2558 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2559
2560 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2561 ospf_network_lsa_refresh_timer,
2562 OSPF_LS_REFRESH_TIME);
2563
2564 ospf_lsa_unlock (oi->network_lsa_self);
2565 oi->network_lsa_self = ospf_lsa_lock (new);
2566 }
2567
2568 return new;
2569}
2570
2571/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002572static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002573ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2574 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002575{
paul718e3742002-12-13 20:15:29 +00002576 if (rt_recalc && !IS_LSA_SELF (new))
2577 {
2578 /* RFC 2328 Section 13.2 Summary-LSAs
2579 The best route to the destination described by the summary-
2580 LSA must be recalculated (see Section 16.5). If this
2581 destination is an AS boundary router, it may also be
2582 necessary to re-examine all the AS-external-LSAs.
2583 */
2584
2585#if 0
2586 /* This doesn't exist yet... */
2587 ospf_summary_incremental_update(new); */
2588#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002589 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002590#endif /* #if 0 */
2591
2592 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002593 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002594 }
2595
2596 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002597 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002598
2599 return new;
2600}
2601
2602/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002603static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002604ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2605 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002606{
2607 if (rt_recalc && !IS_LSA_SELF (new))
2608 {
2609 /* RFC 2328 Section 13.2 Summary-LSAs
2610 The best route to the destination described by the summary-
2611 LSA must be recalculated (see Section 16.5). If this
2612 destination is an AS boundary router, it may also be
2613 necessary to re-examine all the AS-external-LSAs.
2614 */
2615#if 0
2616 /* These don't exist yet... */
2617 ospf_summary_incremental_update(new);
2618 /* Isn't this done by the above call?
2619 - RFC 2328 Section 16.5 implies it should be */
2620 /* ospf_ase_calculate_schedule(); */
2621#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002622 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002623#endif /* #if 0 */
2624 }
2625
2626 /* register LSA to refresh-list. */
2627 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002628 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002629
2630 return new;
2631}
2632
2633/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002634static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002635ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2636 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002637{
paul68980082003-03-25 05:07:42 +00002638 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002639 /* If LSA is not self-originated, calculate an external route. */
2640 if (rt_recalc)
2641 {
2642 /* RFC 2328 Section 13.2 AS-external-LSAs
2643 The best route to the destination described by the AS-
2644 external-LSA must be recalculated (see Section 16.6).
2645 */
2646
2647 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002648 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002649 }
2650
pauld4a53d52003-07-12 21:30:57 +00002651 if (new->data->type == OSPF_AS_NSSA_LSA)
2652 {
2653 /* There is no point to register selforiginate Type-7 LSA for
2654 * refreshing. We rely on refreshing Type-5 LSA's
2655 */
2656 if (IS_LSA_SELF (new))
2657 return new;
2658 else
2659 {
2660 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2661 * New translations will be taken care of by the abr_task.
2662 */
2663 ospf_translated_nssa_refresh (ospf, new, NULL);
2664 }
2665 }
pauld7480322003-05-16 17:31:51 +00002666
pauld4a53d52003-07-12 21:30:57 +00002667 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002668 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002669 */
hassobeebba72004-06-20 21:00:27 +00002670 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002671 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002672
2673 return new;
2674}
2675
2676void
paul68980082003-03-25 05:07:42 +00002677ospf_discard_from_db (struct ospf *ospf,
2678 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002679{
2680 struct ospf_lsa *old;
2681
Paul Jakmaac904de2006-06-15 12:04:57 +00002682 if (!lsdb)
2683 {
2684 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2685 if (!lsa)
2686 zlog_warn ("%s: and NULL LSA!", __func__);
2687 else
2688 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2689 lsa->data->type, inet_ntoa (lsa->data->id));
2690 return;
2691 }
2692
paul718e3742002-12-13 20:15:29 +00002693 old = ospf_lsdb_lookup (lsdb, lsa);
2694
2695 if (!old)
2696 return;
2697
2698 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002699 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002700
2701 switch (old->data->type)
2702 {
2703 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002704 ospf_ase_unregister_external_lsa (old, ospf);
2705 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2706 break;
paul718e3742002-12-13 20:15:29 +00002707#ifdef HAVE_OPAQUE_LSA
2708 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002709 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002710 break;
paul69310a62005-05-11 18:09:59 +00002711#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002712 case OSPF_AS_NSSA_LSA:
2713 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2714 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002715 break;
paul718e3742002-12-13 20:15:29 +00002716 default:
paul68980082003-03-25 05:07:42 +00002717 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002718 break;
2719 }
2720
paul68980082003-03-25 05:07:42 +00002721 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002722 ospf_lsa_discard (old);
2723}
2724
paul718e3742002-12-13 20:15:29 +00002725struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002726ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2727 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002728{
2729 struct ospf_lsa *new = NULL;
2730 struct ospf_lsa *old = NULL;
2731 struct ospf_lsdb *lsdb = NULL;
2732 int rt_recalc;
2733
2734 /* Set LSDB. */
2735 switch (lsa->data->type)
2736 {
paulf2c80652002-12-13 21:44:27 +00002737 /* kevinm */
2738 case OSPF_AS_NSSA_LSA:
2739 if (lsa->area)
2740 lsdb = lsa->area->lsdb;
2741 else
paul68980082003-03-25 05:07:42 +00002742 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002743 break;
paul718e3742002-12-13 20:15:29 +00002744 case OSPF_AS_EXTERNAL_LSA:
2745#ifdef HAVE_OPAQUE_LSA
2746 case OSPF_OPAQUE_AS_LSA:
2747#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002748 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002749 break;
2750 default:
2751 lsdb = lsa->area->lsdb;
2752 break;
2753 }
2754
paul718e3742002-12-13 20:15:29 +00002755 assert (lsdb);
2756
2757 /* RFC 2328 13.2. Installing LSAs in the database
2758
2759 Installing a new LSA in the database, either as the result of
2760 flooding or a newly self-originated LSA, may cause the OSPF
2761 routing table structure to be recalculated. The contents of the
2762 new LSA should be compared to the old instance, if present. If
2763 there is no difference, there is no need to recalculate the
2764 routing table. When comparing an LSA to its previous instance,
2765 the following are all considered to be differences in contents:
2766
2767 o The LSA's Options field has changed.
2768
2769 o One of the LSA instances has LS age set to MaxAge, and
2770 the other does not.
2771
2772 o The length field in the LSA header has changed.
2773
2774 o The body of the LSA (i.e., anything outside the 20-byte
2775 LSA header) has changed. Note that this excludes changes
2776 in LS Sequence Number and LS Checksum.
2777
2778 */
2779 /* Look up old LSA and determine if any SPF calculation or incremental
2780 update is needed */
2781 old = ospf_lsdb_lookup (lsdb, lsa);
2782
2783 /* Do comparision and record if recalc needed. */
2784 rt_recalc = 0;
2785 if ( old == NULL || ospf_lsa_different(old, lsa))
2786 rt_recalc = 1;
2787
paul7ddf1d62003-10-13 09:06:46 +00002788 /*
2789 Sequence number check (Section 14.1 of rfc 2328)
2790 "Premature aging is used when it is time for a self-originated
2791 LSA's sequence number field to wrap. At this point, the current
2792 LSA instance (having LS sequence number MaxSequenceNumber) must
2793 be prematurely aged and flushed from the routing domain before a
2794 new instance with sequence number equal to InitialSequenceNumber
2795 can be originated. "
2796 */
2797
Paul Jakmac2b478d2006-03-30 14:16:11 +00002798 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002799 {
2800 if (ospf_lsa_is_self_originated(ospf, lsa))
2801 {
paul0c2be262004-05-31 14:16:54 +00002802 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2803
2804 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002805 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2806 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2807
2808 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2809 {
ajse588f212004-12-08 18:12:06 +00002810 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002811 "lsa 0x%lx", (u_long)lsa);
2812 ospf_lsa_header_dump (lsa->data);
2813 }
2814 }
2815 else
2816 {
2817 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2818 {
ajse588f212004-12-08 18:12:06 +00002819 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002820 "that was not self originated. Ignoring\n");
2821 ospf_lsa_header_dump (lsa->data);
2822 }
2823 return old;
2824 }
2825 }
2826
paul718e3742002-12-13 20:15:29 +00002827 /* discard old LSA from LSDB */
2828 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002829 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002830
paul718e3742002-12-13 20:15:29 +00002831 /* Calculate Checksum if self-originated?. */
2832 if (IS_LSA_SELF (lsa))
2833 ospf_lsa_checksum (lsa->data);
2834
hassofe71a972004-12-22 16:16:02 +00002835 /* Insert LSA to LSDB. */
2836 ospf_lsdb_add (lsdb, lsa);
2837 lsa->lsdb = lsdb;
2838
paul718e3742002-12-13 20:15:29 +00002839 /* Do LSA specific installation process. */
2840 switch (lsa->data->type)
2841 {
2842 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002843 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002844 break;
2845 case OSPF_NETWORK_LSA:
2846 assert (oi);
paul68980082003-03-25 05:07:42 +00002847 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002848 break;
2849 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002850 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002851 break;
2852 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002853 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002854 break;
2855 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002856 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002857 break;
2858#ifdef HAVE_OPAQUE_LSA
2859 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002860 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002861 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002862 else
paul68980082003-03-25 05:07:42 +00002863 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002864 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002865 case OSPF_OPAQUE_AREA_LSA:
2866 case OSPF_OPAQUE_AS_LSA:
2867 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2868 break;
2869#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002870 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002871 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002872 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002873 break;
2874 }
2875
2876 if (new == NULL)
2877 return new; /* Installation failed, cannot proceed further -- endo. */
2878
2879 /* Debug logs. */
2880 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2881 {
2882 char area_str[INET_ADDRSTRLEN];
2883
2884 switch (lsa->data->type)
2885 {
2886 case OSPF_AS_EXTERNAL_LSA:
2887#ifdef HAVE_OPAQUE_LSA
2888 case OSPF_OPAQUE_AS_LSA:
2889#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002890 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002891 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002892 dump_lsa_key (new),
2893 LOOKUP (ospf_lsa_type_msg, new->data->type));
2894 break;
2895 default:
2896 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002897 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002898 dump_lsa_key (new),
2899 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2900 break;
2901 }
2902 }
2903
paul7ddf1d62003-10-13 09:06:46 +00002904 /*
2905 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2906 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2907 */
2908 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2909 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002910 {
paul7ddf1d62003-10-13 09:06:46 +00002911 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002912 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002913 new->data->type,
2914 inet_ntoa (new->data->id),
2915 lsa);
paul68980082003-03-25 05:07:42 +00002916 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002917 }
2918
2919 return new;
2920}
2921
2922
paul4dadc292005-05-06 21:37:42 +00002923static int
paul68980082003-03-25 05:07:42 +00002924ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002925{
paul1eb8ef22005-04-07 07:30:20 +00002926 struct listnode *node, *nnode;
2927 struct ospf_interface *oi;
2928
2929 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002930 {
paul718e3742002-12-13 20:15:29 +00002931 struct route_node *rn;
2932 struct ospf_neighbor *nbr;
2933
2934 if (ospf_if_is_enable (oi))
2935 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2936 if ((nbr = rn->info) != NULL)
2937 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2938 {
2939 route_unlock_node (rn);
2940 return 0;
2941 }
2942 }
2943
2944 return 1;
2945}
2946
2947
2948#ifdef ORIGINAL_CODING
2949/* This function flood the maxaged LSA to DR. */
2950void
2951ospf_maxage_flood (struct ospf_lsa *lsa)
2952{
2953 switch (lsa->data->type)
2954 {
2955 case OSPF_ROUTER_LSA:
2956 case OSPF_NETWORK_LSA:
2957 case OSPF_SUMMARY_LSA:
2958 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002959 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002960#ifdef HAVE_OPAQUE_LSA
2961 case OSPF_OPAQUE_LINK_LSA:
2962 case OSPF_OPAQUE_AREA_LSA:
2963#endif /* HAVE_OPAQUE_LSA */
2964 ospf_flood_through_area (lsa->area, NULL, lsa);
2965 break;
2966 case OSPF_AS_EXTERNAL_LSA:
2967#ifdef HAVE_OPAQUE_LSA
2968 case OSPF_OPAQUE_AS_LSA:
2969#endif /* HAVE_OPAQUE_LSA */
2970 ospf_flood_through_as (NULL, lsa);
2971 break;
2972 default:
2973 break;
2974 }
2975}
2976#endif /* ORIGINAL_CODING */
2977
paul4dadc292005-05-06 21:37:42 +00002978static int
paul718e3742002-12-13 20:15:29 +00002979ospf_maxage_lsa_remover (struct thread *thread)
2980{
paul68980082003-03-25 05:07:42 +00002981 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002982 struct ospf_lsa *lsa;
2983 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002984 int reschedule = 0;
2985
paul68980082003-03-25 05:07:42 +00002986 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002987
2988 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002989 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002990
paul68980082003-03-25 05:07:42 +00002991 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002992
2993 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002994 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002995 {
paul718e3742002-12-13 20:15:29 +00002996 if (lsa->retransmit_counter > 0)
2997 {
2998 reschedule = 1;
2999 continue;
3000 }
3001
3002 /* Remove LSA from the LSDB */
3003 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
3004 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003005 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00003006 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00003007
3008 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003009 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00003010 lsa->data->type, inet_ntoa (lsa->data->id));
3011
3012 /* Flood max age LSA. */
3013#ifdef ORIGINAL_CODING
3014 ospf_maxage_flood (lsa);
3015#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00003016 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00003017#endif /* ORIGINAL_CODING */
3018
paul7ddf1d62003-10-13 09:06:46 +00003019 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3020 {
3021 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003022 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00003023 (u_long)lsa);
3024 ospf_router_lsa_originate(lsa->area);
3025 }
3026
paul718e3742002-12-13 20:15:29 +00003027 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00003028 if (lsa->lsdb)
3029 {
3030 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
3031 ospf_lsdb_delete (lsa->lsdb, lsa);
3032 }
3033 else
3034 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
3035 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003036 }
3037
3038 /* A MaxAge LSA must be removed immediately from the router's link
3039 state database as soon as both a) it is no longer contained on any
3040 neighbor Link state retransmission lists and b) none of the router's
3041 neighbors are in states Exchange or Loading. */
3042 if (reschedule)
paul68980082003-03-25 05:07:42 +00003043 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003044
3045 return 0;
3046}
3047
paul4dadc292005-05-06 21:37:42 +00003048static int
paul68980082003-03-25 05:07:42 +00003049ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003050{
hasso52dc7ee2004-09-23 19:18:23 +00003051 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003052 struct ospf_lsa *lsa;
3053
3054 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3055 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003056 return 1;
3057
3058 return 0;
3059}
3060
3061void
paul68980082003-03-25 05:07:42 +00003062ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003063{
hasso52dc7ee2004-09-23 19:18:23 +00003064 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003065
paul68980082003-03-25 05:07:42 +00003066 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003067 {
paul68980082003-03-25 05:07:42 +00003068 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00003069 ospf_lsa_unlock (lsa);
3070 }
3071}
3072
3073void
paul68980082003-03-25 05:07:42 +00003074ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003075{
3076 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3077 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003078 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003079 {
3080 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003081 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003082 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3083 return;
3084 }
3085
paul68980082003-03-25 05:07:42 +00003086 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003087
3088 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003089 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003090
paul68980082003-03-25 05:07:42 +00003091 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003092}
3093
paul4dadc292005-05-06 21:37:42 +00003094static int
paul68980082003-03-25 05:07:42 +00003095ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003096{
paul718e3742002-12-13 20:15:29 +00003097 /* Stay away from any Local Translated Type-7 LSAs */
3098 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3099 return 0;
paul718e3742002-12-13 20:15:29 +00003100
3101 if (IS_LSA_MAXAGE (lsa))
3102 /* Self-originated LSAs should NOT time-out instead,
3103 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003104 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003105 {
3106 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003107 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003108
3109 switch (lsa->data->type)
3110 {
paul718e3742002-12-13 20:15:29 +00003111#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003112 case OSPF_OPAQUE_LINK_LSA:
3113 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003114 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003115 /*
3116 * As a general rule, whenever network topology has changed
3117 * (due to an LSA removal in this case), routing recalculation
3118 * should be triggered. However, this is not true for opaque
3119 * LSAs. Even if an opaque LSA instance is going to be removed
3120 * from the routing domain, it does not mean a change in network
3121 * topology, and thus, routing recalculation is not needed here.
3122 */
3123 break;
paul718e3742002-12-13 20:15:29 +00003124#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003125 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003126 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003127 ospf_ase_incremental_update (ospf, lsa);
3128 break;
paul718e3742002-12-13 20:15:29 +00003129 default:
paul68980082003-03-25 05:07:42 +00003130 ospf_spf_calculate_schedule (ospf);
3131 break;
paul718e3742002-12-13 20:15:29 +00003132 }
paul68980082003-03-25 05:07:42 +00003133 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003134 }
3135
3136 return 0;
3137}
3138
3139/* Periodical check of MaxAge LSA. */
3140int
paul68980082003-03-25 05:07:42 +00003141ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003142{
paul68980082003-03-25 05:07:42 +00003143 struct ospf *ospf = THREAD_ARG (thread);
3144 struct route_node *rn;
3145 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003146 struct ospf_area *area;
3147 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003148
paul68980082003-03-25 05:07:42 +00003149 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003150
paul1eb8ef22005-04-07 07:30:20 +00003151 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003152 {
paul68980082003-03-25 05:07:42 +00003153 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3154 ospf_lsa_maxage_walker_remover (ospf, lsa);
3155 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3156 ospf_lsa_maxage_walker_remover (ospf, lsa);
3157 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3158 ospf_lsa_maxage_walker_remover (ospf, lsa);
3159 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3160 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003161#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003162 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3163 ospf_lsa_maxage_walker_remover (ospf, lsa);
3164 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3165 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003166#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003167 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3168 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003169 }
3170
paul4fb949e2003-05-10 20:06:51 +00003171 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003172 if (ospf->lsdb)
3173 {
3174 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3175 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003176#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003177 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3178 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003179#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003180 }
paul718e3742002-12-13 20:15:29 +00003181
paul68980082003-03-25 05:07:42 +00003182 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3183 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003184 return 0;
3185}
3186
paul68980082003-03-25 05:07:42 +00003187struct ospf_lsa *
3188ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3189 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003190{
paul68980082003-03-25 05:07:42 +00003191 struct ospf_lsa *lsa;
3192 struct in_addr mask, id;
3193 struct lsa_header_mask
3194 {
3195 struct lsa_header header;
3196 struct in_addr mask;
3197 } *hmask;
paul718e3742002-12-13 20:15:29 +00003198
paul68980082003-03-25 05:07:42 +00003199 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3200 if (lsa == NULL)
3201 return NULL;
paul718e3742002-12-13 20:15:29 +00003202
paul68980082003-03-25 05:07:42 +00003203 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003204
paul68980082003-03-25 05:07:42 +00003205 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003206
paul68980082003-03-25 05:07:42 +00003207 if (mask.s_addr != hmask->mask.s_addr)
3208 {
3209 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3210 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3211 if (!lsa)
3212 return NULL;
3213 }
paul718e3742002-12-13 20:15:29 +00003214
paul68980082003-03-25 05:07:42 +00003215 return lsa;
paul718e3742002-12-13 20:15:29 +00003216}
3217
3218struct ospf_lsa *
3219ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3220 struct in_addr id, struct in_addr adv_router)
3221{
paule05fba42003-04-13 20:20:53 +00003222 struct ospf *ospf = ospf_lookup();
3223 assert(ospf);
3224
paul718e3742002-12-13 20:15:29 +00003225 switch (type)
3226 {
3227 case OSPF_ROUTER_LSA:
3228 case OSPF_NETWORK_LSA:
3229 case OSPF_SUMMARY_LSA:
3230 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003231 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003232#ifdef HAVE_OPAQUE_LSA
3233 case OSPF_OPAQUE_LINK_LSA:
3234 case OSPF_OPAQUE_AREA_LSA:
3235#endif /* HAVE_OPAQUE_LSA */
3236 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003237 case OSPF_AS_EXTERNAL_LSA:
3238#ifdef HAVE_OPAQUE_LSA
3239 case OSPF_OPAQUE_AS_LSA:
3240#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003241 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003242 default:
3243 break;
3244 }
3245
3246 return NULL;
3247}
3248
3249struct ospf_lsa *
3250ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3251 struct in_addr id)
3252{
3253 struct ospf_lsa *lsa;
3254 struct route_node *rn;
3255
3256 switch (type)
3257 {
3258 case OSPF_ROUTER_LSA:
3259 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003260 case OSPF_NETWORK_LSA:
3261 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3262 if ((lsa = rn->info))
3263 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3264 {
3265 route_unlock_node (rn);
3266 return lsa;
3267 }
3268 break;
3269 case OSPF_SUMMARY_LSA:
3270 case OSPF_ASBR_SUMMARY_LSA:
3271 /* Currently not used. */
3272 assert (1);
3273 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003274 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003275 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003276#ifdef HAVE_OPAQUE_LSA
3277 case OSPF_OPAQUE_LINK_LSA:
3278 case OSPF_OPAQUE_AREA_LSA:
3279 case OSPF_OPAQUE_AS_LSA:
3280 /* Currently not used. */
3281 break;
3282#endif /* HAVE_OPAQUE_LSA */
3283 default:
3284 break;
3285 }
3286
3287 return NULL;
3288}
3289
3290struct ospf_lsa *
3291ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3292{
3293 struct ospf_lsa *match;
3294
3295#ifdef HAVE_OPAQUE_LSA
3296 /*
3297 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3298 * is redefined to have two subfields; opaque-type and opaque-id.
3299 * However, it is harmless to treat the two sub fields together, as if
3300 * they two were forming a unique LSA-ID.
3301 */
3302#endif /* HAVE_OPAQUE_LSA */
3303
3304 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3305
3306 if (match == NULL)
3307 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003308 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003309 lsah->type, inet_ntoa (lsah->id));
3310
3311 return match;
3312}
3313
3314/* return +n, l1 is more recent.
3315 return -n, l2 is more recent.
3316 return 0, l1 and l2 is identical. */
3317int
3318ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3319{
3320 int r;
3321 int x, y;
3322
3323 if (l1 == NULL && l2 == NULL)
3324 return 0;
3325 if (l1 == NULL)
3326 return -1;
3327 if (l2 == NULL)
3328 return 1;
3329
3330 /* compare LS sequence number. */
3331 x = (int) ntohl (l1->data->ls_seqnum);
3332 y = (int) ntohl (l2->data->ls_seqnum);
3333 if (x > y)
3334 return 1;
3335 if (x < y)
3336 return -1;
3337
3338 /* compare LS checksum. */
3339 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3340 if (r)
3341 return r;
3342
3343 /* compare LS age. */
3344 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3345 return 1;
3346 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3347 return -1;
3348
3349 /* compare LS age with MaxAgeDiff. */
3350 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3351 return -1;
3352 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3353 return 1;
3354
3355 /* LSAs are identical. */
3356 return 0;
3357}
3358
3359/* If two LSAs are different, return 1, otherwise return 0. */
3360int
3361ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3362{
3363 char *p1, *p2;
3364 assert (l1);
3365 assert (l2);
3366 assert (l1->data);
3367 assert (l2->data);
3368
3369 if (l1->data->options != l2->data->options)
3370 return 1;
3371
3372 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3373 return 1;
3374
3375 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3376 return 1;
3377
3378 if (l1->data->length != l2->data->length)
3379 return 1;
3380
3381 if (l1->data->length == 0)
3382 return 1;
3383
pauld1825832003-04-03 01:27:01 +00003384 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003385
3386 p1 = (char *) l1->data;
3387 p2 = (char *) l2->data;
3388
3389 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3390 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3391 return 1;
3392
3393 return 0;
3394}
3395
3396#ifdef ORIGINAL_CODING
3397void
3398ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3399 struct ospf_lsa *self,
3400 struct ospf_lsa *new)
3401{
3402 u_int32_t seqnum;
3403
3404 /* Adjust LS Sequence Number. */
3405 seqnum = ntohl (new->data->ls_seqnum) + 1;
3406 self->data->ls_seqnum = htonl (seqnum);
3407
3408 /* Recalculate LSA checksum. */
3409 ospf_lsa_checksum (self->data);
3410
3411 /* Reflooding LSA. */
3412 /* RFC2328 Section 13.3
3413 On non-broadcast networks, separate Link State Update
3414 packets must be sent, as unicasts, to each adjacent neighbor
3415 (i.e., those in state Exchange or greater). The destination
3416 IP addresses for these packets are the neighbors' IP
3417 addresses. */
3418 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3419 {
3420 struct route_node *rn;
3421 struct ospf_neighbor *onbr;
3422
3423 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3424 if ((onbr = rn->info) != NULL)
3425 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3426 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3427 }
3428 else
3429 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3430
3431 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003432 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003433 self->data->type, inet_ntoa (self->data->id));
3434}
3435#else /* ORIGINAL_CODING */
3436static int
paul68980082003-03-25 05:07:42 +00003437ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003438{
3439 if (lsa == NULL || !IS_LSA_SELF (lsa))
3440 return 0;
3441
3442 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003443 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003444
3445 /* Force given lsa's age to MaxAge. */
3446 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3447
3448 switch (lsa->data->type)
3449 {
3450#ifdef HAVE_OPAQUE_LSA
3451 case OSPF_OPAQUE_LINK_LSA:
3452 case OSPF_OPAQUE_AREA_LSA:
3453 case OSPF_OPAQUE_AS_LSA:
3454 ospf_opaque_lsa_refresh (lsa);
3455 break;
3456#endif /* HAVE_OPAQUE_LSA */
3457 default:
paul68980082003-03-25 05:07:42 +00003458 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003459 break;
3460 }
3461
3462 return 0;
3463}
3464
3465void
paul68980082003-03-25 05:07:42 +00003466ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003467{
paul1eb8ef22005-04-07 07:30:20 +00003468 struct listnode *node, *nnode;
3469 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003470 struct ospf_area *area;
3471 struct ospf_interface *oi;
3472 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003473 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003474 int need_to_flush_ase = 0;
3475
paul1eb8ef22005-04-07 07:30:20 +00003476 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003477 {
paul718e3742002-12-13 20:15:29 +00003478 if ((lsa = area->router_lsa_self) != NULL)
3479 {
3480 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003481 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 +00003482
3483 ospf_lsa_flush_area (lsa, area);
3484 ospf_lsa_unlock (area->router_lsa_self);
3485 area->router_lsa_self = NULL;
3486 OSPF_TIMER_OFF (area->t_router_lsa_self);
3487 }
3488
paul1eb8ef22005-04-07 07:30:20 +00003489 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003490 {
paul718e3742002-12-13 20:15:29 +00003491 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003492 && oi->state == ISM_DR
3493 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003494 {
3495 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003496 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 +00003497
3498 ospf_lsa_flush_area (oi->network_lsa_self, area);
3499 ospf_lsa_unlock (oi->network_lsa_self);
3500 oi->network_lsa_self = NULL;
3501 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3502 }
3503
3504 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3505 && area->external_routing == OSPF_AREA_DEFAULT)
3506 need_to_flush_ase = 1;
3507 }
3508
paul68980082003-03-25 05:07:42 +00003509 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3510 ospf_lsa_flush_schedule (ospf, lsa);
3511 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3512 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003513#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003514 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3515 ospf_lsa_flush_schedule (ospf, lsa);
3516 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3517 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003518#endif /* HAVE_OPAQUE_LSA */
3519 }
3520
3521 if (need_to_flush_ase)
3522 {
paul68980082003-03-25 05:07:42 +00003523 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3524 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003525#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003526 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3527 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003528#endif /* HAVE_OPAQUE_LSA */
3529 }
3530
3531 /*
3532 * Make sure that the MaxAge LSA remover is executed immediately,
3533 * without conflicting to other threads.
3534 */
paul68980082003-03-25 05:07:42 +00003535 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003536 {
paul68980082003-03-25 05:07:42 +00003537 OSPF_TIMER_OFF (ospf->t_maxage);
3538 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003539 }
3540
3541 return;
3542}
3543#endif /* ORIGINAL_CODING */
3544
3545/* If there is self-originated LSA, then return 1, otherwise return 0. */
3546/* An interface-independent version of ospf_lsa_is_self_originated */
3547int
paul68980082003-03-25 05:07:42 +00003548ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003549{
hasso52dc7ee2004-09-23 19:18:23 +00003550 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003551 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003552
3553 /* This LSA is already checked. */
3554 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3555 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3556
3557 /* Make sure LSA is self-checked. */
3558 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3559
3560 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003561 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003562 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3563
3564 /* LSA is router-LSA. */
3565 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003566 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003567 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3568
3569 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3570 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003571 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003572 {
paul718e3742002-12-13 20:15:29 +00003573 /* Ignore virtual link. */
3574 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3575 if (oi->address->family == AF_INET)
3576 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3577 {
3578 /* to make it easier later */
3579 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3580 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3581 }
3582 }
3583
3584 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3585}
3586
3587/* Get unique Link State ID. */
3588struct in_addr
paul68980082003-03-25 05:07:42 +00003589ospf_lsa_unique_id (struct ospf *ospf,
3590 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003591{
3592 struct ospf_lsa *lsa;
3593 struct in_addr mask, id;
3594
3595 id = p->prefix;
3596
3597 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003598 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003599 if (lsa)
3600 {
3601 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3602 if (ip_masklen (al->mask) == p->prefixlen)
3603 {
3604 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003605 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003606 "Can't get Link State ID for %s/%d",
3607 inet_ntoa (p->prefix), p->prefixlen);
3608 /* id.s_addr = 0; */
3609 id.s_addr = 0xffffffff;
3610 return id;
3611 }
3612 /* Masklen differs, then apply wildcard mask to Link State ID. */
3613 else
3614 {
3615 masklen2ip (p->prefixlen, &mask);
3616
3617 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003618 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3619 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003620 if (lsa)
3621 {
3622 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003623 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003624 "Can't get Link State ID for %s/%d",
3625 inet_ntoa (p->prefix), p->prefixlen);
3626 /* id.s_addr = 0; */
3627 id.s_addr = 0xffffffff;
3628 return id;
3629 }
3630 }
3631 }
3632
3633 return id;
3634}
3635
3636
Paul Jakma70461d72006-05-12 22:57:57 +00003637#define LSA_ACTION_FLOOD_AREA 1
3638#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003639
3640struct lsa_action
3641{
3642 u_char action;
3643 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003644 struct ospf_lsa *lsa;
3645};
3646
paul4dadc292005-05-06 21:37:42 +00003647static int
paul718e3742002-12-13 20:15:29 +00003648ospf_lsa_action (struct thread *t)
3649{
3650 struct lsa_action *data;
3651
3652 data = THREAD_ARG (t);
3653
3654 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003655 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003656 data->action);
3657
3658 switch (data->action)
3659 {
paul718e3742002-12-13 20:15:29 +00003660 case LSA_ACTION_FLOOD_AREA:
3661 ospf_flood_through_area (data->area, NULL, data->lsa);
3662 break;
paul718e3742002-12-13 20:15:29 +00003663 case LSA_ACTION_FLUSH_AREA:
3664 ospf_lsa_flush_area (data->lsa, data->area);
3665 break;
paul718e3742002-12-13 20:15:29 +00003666 }
3667
3668 ospf_lsa_unlock (data->lsa);
3669 XFREE (MTYPE_OSPF_MESSAGE, data);
3670 return 0;
3671}
3672
3673void
3674ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3675{
3676 struct lsa_action *data;
3677
3678 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3679 memset (data, 0, sizeof (struct lsa_action));
3680
3681 data->action = LSA_ACTION_FLOOD_AREA;
3682 data->area = area;
3683 data->lsa = ospf_lsa_lock (lsa);
3684
3685 thread_add_event (master, ospf_lsa_action, data, 0);
3686}
3687
3688void
3689ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3690{
3691 struct lsa_action *data;
3692
3693 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3694 memset (data, 0, sizeof (struct lsa_action));
3695
3696 data->action = LSA_ACTION_FLUSH_AREA;
3697 data->area = area;
3698 data->lsa = ospf_lsa_lock (lsa);
3699
3700 thread_add_event (master, ospf_lsa_action, data, 0);
3701}
3702
3703
3704/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003705static void
paul68980082003-03-25 05:07:42 +00003706ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003707{
3708 struct external_info *ei;
3709 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3710
3711 switch (lsa->data->type)
3712 {
3713 /* Router and Network LSAs are processed differently. */
3714 case OSPF_ROUTER_LSA:
3715 case OSPF_NETWORK_LSA:
3716 break;
3717 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003718 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003719 break;
3720 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003721 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003722 break;
3723 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003724 /* Translated from NSSA Type-5s are refreshed when
3725 * from refresh of Type-7 - do not refresh these directly.
3726 */
3727 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3728 break;
paul718e3742002-12-13 20:15:29 +00003729 ei = ospf_external_info_check (lsa);
3730 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003731 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003732 else
pauld4a53d52003-07-12 21:30:57 +00003733 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003734 break;
3735#ifdef HAVE_OPAQUE_LSA
3736 case OSPF_OPAQUE_LINK_LSA:
3737 case OSPF_OPAQUE_AREA_LSA:
3738 case OSPF_OPAQUE_AS_LSA:
3739 ospf_opaque_lsa_refresh (lsa);
3740 break;
pauld7480322003-05-16 17:31:51 +00003741#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003742 default:
3743 break;
paul718e3742002-12-13 20:15:29 +00003744 }
3745}
3746
3747void
paul68980082003-03-25 05:07:42 +00003748ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003749{
3750 u_int16_t index, current_index;
3751
3752 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3753
3754 if (lsa->refresh_list < 0)
3755 {
3756 int delay;
3757
3758 if (LS_AGE (lsa) == 0 &&
3759 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3760 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3761 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3762 else
3763 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3764 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3765 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3766
3767 if (delay < 0)
3768 delay = 0;
3769
paul68980082003-03-25 05:07:42 +00003770 current_index = ospf->lsa_refresh_queue.index +
3771 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003772
3773 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3774 % (OSPF_LSA_REFRESHER_SLOTS);
3775
3776 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003777 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003778 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003779 if (!ospf->lsa_refresh_queue.qs[index])
3780 ospf->lsa_refresh_queue.qs[index] = list_new ();
3781 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003782 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003783 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003784 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003785 "setting refresh_list on lsa %p (slod %d)",
3786 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003787 }
3788}
3789
3790void
paul68980082003-03-25 05:07:42 +00003791ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003792{
3793 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3794 if (lsa->refresh_list >= 0)
3795 {
hasso52dc7ee2004-09-23 19:18:23 +00003796 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003797 listnode_delete (refresh_list, lsa);
3798 if (!listcount (refresh_list))
3799 {
3800 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003801 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003802 }
3803 ospf_lsa_unlock (lsa);
3804 lsa->refresh_list = -1;
3805 }
3806}
3807
3808int
3809ospf_lsa_refresh_walker (struct thread *t)
3810{
hasso52dc7ee2004-09-23 19:18:23 +00003811 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003812 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003813 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003814 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003815 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003816 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003817
3818 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003819 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003820
3821
paul68980082003-03-25 05:07:42 +00003822 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003823
ajs9dbc7972005-03-13 19:27:22 +00003824 /* Note: if clock has jumped backwards, then time change could be negative,
3825 so we are careful to cast the expression to unsigned before taking
3826 modulus. */
paul68980082003-03-25 05:07:42 +00003827 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003828 ((unsigned long)(ospf->lsa_refresh_queue.index +
3829 (time (NULL) - ospf->lsa_refresher_started) /
3830 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003831
3832 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003833 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003834 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003835
paul68980082003-03-25 05:07:42 +00003836 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003837 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3838 {
3839 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003840 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003841 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003842
paul68980082003-03-25 05:07:42 +00003843 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003844
paul68980082003-03-25 05:07:42 +00003845 ospf->lsa_refresh_queue.qs [i] = NULL;
3846
paul718e3742002-12-13 20:15:29 +00003847 if (refresh_list)
3848 {
paul1eb8ef22005-04-07 07:30:20 +00003849 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003850 {
paul718e3742002-12-13 20:15:29 +00003851 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003852 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003853 "refresh lsa %p (slot %d)",
3854 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003855
3856 list_delete_node (refresh_list, node);
3857 ospf_lsa_unlock (lsa);
3858 lsa->refresh_list = -1;
3859 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003860 }
3861 list_free (refresh_list);
3862 }
3863 }
3864
paul68980082003-03-25 05:07:42 +00003865 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3866 ospf, ospf->lsa_refresh_interval);
3867 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003868
paul1eb8ef22005-04-07 07:30:20 +00003869 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3870 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003871
3872 list_delete (lsa_to_refresh);
3873
3874 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003875 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003876
3877 return 0;
3878}
3879