blob: d4cb5fde3620af1cf08602697796b014528eea62 [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))
152 zlog_info ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
153 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;
189 sp = (char *) &lsa->options;
190
191 for (ep = sp + length; sp < ep; sp = q)
192 {
193 q = sp + MODX;
194 if (q > ep)
195 q = ep;
196 for (p = sp; p < q; p++)
197 {
198 c0 += *p;
199 c1 += c0;
200 }
201 c0 %= 255;
202 c1 %= 255;
203 }
204
205 x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
206 if (x <= 0)
207 x += 255;
208 y = 510 - c0 - x;
209 if (y > 255)
210 y -= 255;
211
212 /* take care endian issue. */
213 lsa->checksum = htons ((x << 8) + y);
214
215 return (lsa->checksum);
216}
217
218
219
220/* Create OSPF LSA. */
221struct ospf_lsa *
222ospf_lsa_new ()
223{
224 struct ospf_lsa *new;
225
226 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
227 memset (new, 0, sizeof (struct ospf_lsa));
228
229 new->flags = 0;
230 new->lock = 1;
231 new->retransmit_counter = 0;
232 gettimeofday (&new->tv_recv, NULL);
233 new->tv_orig = new->tv_recv;
234 new->refresh_list = -1;
235
236 return new;
237}
238
239/* Duplicate OSPF LSA. */
240struct ospf_lsa *
241ospf_lsa_dup (struct ospf_lsa *lsa)
242{
243 struct ospf_lsa *new;
244
245 if (lsa == NULL)
246 return NULL;
247
248 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
249
250 memcpy (new, lsa, sizeof (struct ospf_lsa));
251 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
252 new->lock = 1;
253 new->retransmit_counter = 0;
254 new->data = ospf_lsa_data_dup (lsa->data);
255
paulf2c80652002-12-13 21:44:27 +0000256 /* kevinm: Clear the refresh_list, otherwise there are going
257 to be problems when we try to remove the LSA from the
258 queue (which it's not a member of.)
259 XXX: Should we add the LSA to the refresh_list queue? */
260 new->refresh_list = -1;
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
263 zlog_info ("LSA: duplicated %p (new: %p)", lsa, new);
264
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))
275 zlog_info ("LSA: freed %p", lsa);
276
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))
354 zlog_info ("LSA[Type%d:%s]: data freed %p",
355 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[] = {
367 "Type255,id(255.255.255.255),ar(255.255.255.255)",
368 };
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
410 ospf_output_forward (s, OSPF_LSA_HEADER_SIZE);
411}
412
paul68980082003-03-25 05:07:42 +0000413
paul718e3742002-12-13 20:15:29 +0000414/* router-LSA related functions. */
415/* Get router-LSA flags. */
416u_char
417router_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);
450#ifdef HAVE_NSSA
451 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000452 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000453 */
pauld4a53d52003-07-12 21:30:57 +0000454 if ( (area->external_routing == OSPF_AREA_NSSA)
455 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
456 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000457#endif /* HAVE_NSSA */
458 }
paul718e3742002-12-13 20:15:29 +0000459 return flags;
460}
461
462/* Lookup neighbor other than myself.
463 And check neighbor count,
464 Point-to-Point link must have only 1 neighbor. */
465struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000466ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000467{
paul718e3742002-12-13 20:15:29 +0000468 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000469 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000470
471 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000472 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
473 if ((nbr = rn->info))
474 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000475 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000476 {
477 route_unlock_node (rn);
478 break;
479 }
paul718e3742002-12-13 20:15:29 +0000480
481 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000482 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000483 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
484
485 return nbr;
486}
487
488/* Set a link information. */
489void
490link_info_set (struct stream *s, struct in_addr id,
491 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
492{
493 /* TOS based routing is not supported. */
494 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
495 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
496 stream_putc (s, type); /* Link Type. */
497 stream_putc (s, tos); /* TOS = 0. */
498 stream_putw (s, cost); /* Link Cost. */
499}
500
501/* Describe Point-to-Point link. */
502int
503lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
504{
505 int links = 0;
506 struct ospf_neighbor *nbr;
507 struct in_addr id, mask;
508
509 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
510 zlog_info ("LSA[Type1]: Set link Point-to-Point");
511
paul68980082003-03-25 05:07:42 +0000512 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000513 if (nbr->state == NSM_Full)
514 {
515 /* For unnumbered point-to-point networks, the Link Data field
516 should specify the interface's MIB-II ifIndex value. */
517 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
518 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
519 links++;
520 }
521
522 if (oi->connected->destination != NULL)
523 {
524 /* Option 1:
525 link_type = LSA_LINK_TYPE_STUB;
526 link_id = nbr->address.u.prefix4;
527 link_data.s_addr = 0xffffffff;
528 link_cost = o->output_cost; */
529
530 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
531 mask.s_addr = 0xffffffff;
532 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
533 }
534 else
535 {
536 /* Option 2: We need to include link to a stub
537 network regardless of the state of the neighbor */
538 masklen2ip (oi->address->prefixlen, &mask);
539 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
540 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
541 }
542 links++;
543
544 return links;
545}
546
547/* Describe Broadcast Link. */
548int
549lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
550{
551 struct ospf_neighbor *dr;
552 struct in_addr id, mask;
553
554 /* Describe Type 3 Link. */
555 if (oi->state == ISM_Waiting)
556 {
557 masklen2ip (oi->address->prefixlen, &mask);
558 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
559 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
560 return 1;
561 }
562
563 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
564 /* Describe Type 2 link. */
565 if (dr && (dr->state == NSM_Full ||
566 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000567 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000568 {
569 link_info_set (s, DR (oi), oi->address->u.prefix4,
570 LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);
571 }
572 /* Describe type 3 link. */
573 else
574 {
575 masklen2ip (oi->address->prefixlen, &mask);
576 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
577 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
578 }
579 return 1;
580}
581
582int
583lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
584{
585 struct in_addr id, mask;
586
587 /* Describe Type 3 Link. */
588 if (oi->state != ISM_Loopback)
589 return 0;
590
591 mask.s_addr = 0xffffffff;
592 id.s_addr = oi->address->u.prefix4.s_addr;
593 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
594 return 1;
595}
596
597/* Describe Virtual Link. */
598int
599lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
600{
601 struct ospf_neighbor *nbr;
602
paul718e3742002-12-13 20:15:29 +0000603 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000604 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000605 if (nbr->state == NSM_Full)
606 {
607 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
608 LSA_LINK_TYPE_VIRTUALLINK, 0, oi->output_cost);
609 return 1;
610 }
611
612 return 0;
613}
614
615#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
616
paul7afa08d2002-12-13 20:59:45 +0000617/* this function add for support point-to-multipoint ,see rfc2328
61812.4.1.4.*/
619/* from "edward rrr" <edward_rrr@hotmail.com>
620 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul68980082003-03-25 05:07:42 +0000621int
622lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000623{
624 int links = 0;
625 struct route_node *rn;
626 struct ospf_neighbor *nbr = NULL;
627 struct in_addr id, mask;
628
629 mask.s_addr = 0xffffffff;
630 id.s_addr = oi->address->u.prefix4.s_addr;
631 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
632 links++;
633
paul1cc8f762003-04-05 19:34:32 +0000634 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
635 zlog_info ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000636
637 /* Search neighbor, */
638 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
639 if ((nbr = rn->info) != NULL)
640 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000641 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000642 if (nbr->state == NSM_Full)
643
644 {
paul7afa08d2002-12-13 20:59:45 +0000645 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
646 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
647 links++;
paul1cc8f762003-04-05 19:34:32 +0000648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
649 zlog_info ("PointToMultipoint: set link to %s",
650 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000651 }
652
653 return links;
paul7afa08d2002-12-13 20:59:45 +0000654}
655
paul718e3742002-12-13 20:15:29 +0000656/* Set router-LSA link information. */
657int
658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
660 listnode node;
661 int links = 0;
662
663 for (node = listhead (area->oiflist); node; node = nextnode (node))
664 {
665 struct ospf_interface *oi = node->data;
666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000669 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000686 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
702void
703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
715 putp = s->putp;
716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
726
727/* Create new router-LSA. */
728struct ospf_lsa *
729ospf_router_lsa_new (struct ospf_area *area)
730{
paul68980082003-03-25 05:07:42 +0000731 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000732 struct stream *s;
733 struct lsa_header *lsah;
734 struct ospf_lsa *new;
735 int length;
736
737 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
738 zlog_info ("LSA[Type1]: Create router-LSA instance");
739
740 /* Create a stream for LSA. */
741 s = stream_new (OSPF_MAX_LSA_SIZE);
742 lsah = (struct lsa_header *) STREAM_DATA (s);
743
744#ifdef HAVE_NSSA
745 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000746 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
paul718e3742002-12-13 20:15:29 +0000747#else /* ! HAVE_NSSA */
748 /* Set LSA common header fields. */
749 lsa_header_set (s, LSA_OPTIONS_GET (area),
paul718e3742002-12-13 20:15:29 +0000750#endif /* HAVE_NSSA */
pauld4a53d52003-07-12 21:30:57 +0000751 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000752
753 /* Set router-LSA body fields. */
754 ospf_router_lsa_body_set (s, area);
755
756 /* Set length. */
757 length = stream_get_endp (s);
758 lsah->length = htons (length);
759
760 /* Now, create OSPF LSA instance. */
761 new = ospf_lsa_new ();
762 new->area = area;
763 SET_FLAG (new->flags, OSPF_LSA_SELF);
764
765 /* Copy LSA data to store, discard stream. */
766 new->data = ospf_lsa_data_new (length);
767 memcpy (new->data, lsah, length);
768 stream_free (s);
769
770 return new;
771}
772
773/* Originate Router-LSA. */
774struct ospf_lsa *
775ospf_router_lsa_originate (struct ospf_area *area)
776{
777 struct ospf_lsa *new;
778
779 /* Create new router-LSA instance. */
780 new = ospf_router_lsa_new (area);
781
782 /* Sanity check. */
783 if (new->data->adv_router.s_addr == 0)
784 {
785 if (IS_DEBUG_OSPF_EVENT)
786 zlog_info ("LSA[Type1]: AdvRouter is 0, discard");
787 ospf_lsa_discard (new);
788 return NULL;
789 }
790
791 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000792 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000793
794 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000795 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000796
797 /* Flooding new LSA through area. */
798 ospf_flood_through_area (area, NULL, new);
799
800 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
801 {
802 zlog_info ("LSA[Type%d:%s]: Originate router-LSA %p",
803 new->data->type, inet_ntoa (new->data->id), new);
804 ospf_lsa_header_dump (new->data);
805 }
806
807 return new;
808}
809
810/* Refresh router-LSA. */
811struct ospf_lsa *
812ospf_router_lsa_refresh (struct ospf_lsa *lsa)
813{
814 struct ospf_area *area = lsa->area;
815 struct ospf_lsa *new;
816
817 /* Sanity check. */
818 assert (lsa->data);
819
820 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000821 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000822
823 /* Create new router-LSA instance. */
824 new = ospf_router_lsa_new (area);
825 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
826
paul68980082003-03-25 05:07:42 +0000827 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000828
829 /* Flood LSA through area. */
830 ospf_flood_through_area (area, NULL, new);
831
832 /* Debug logging. */
833 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
834 {
835 zlog_info ("LSA[Type%d:%s]: router-LSA refresh",
836 new->data->type, inet_ntoa (new->data->id));
837 ospf_lsa_header_dump (new->data);
838 }
839
840 return NULL;
841}
842
843int
844ospf_router_lsa_timer (struct thread *t)
845{
846 struct ospf_area *area;
847
848 if (IS_DEBUG_OSPF_EVENT)
849 zlog_info ("Timer[router-LSA]: (router-LSA Refresh expire)");
850
851 area = THREAD_ARG (t);
852 area->t_router_lsa_self = NULL;
853
854 /* Now refresh router-LSA. */
855 if (area->router_lsa_self)
856 ospf_router_lsa_refresh (area->router_lsa_self);
857 /* Newly originate router-LSA. */
858 else
859 ospf_router_lsa_originate (area);
860
861 return 0;
862}
863
864void
865ospf_router_lsa_timer_add (struct ospf_area *area)
866{
867 /* Keep area's self-originated router-LSA. */
868 struct ospf_lsa *lsa = area->router_lsa_self;
869
870 /* Cancel previously scheduled router-LSA timer. */
871 if (area->t_router_lsa_self)
872 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
873 zlog_info ("LSA[Type1]: Cancel previous router-LSA timer");
874
875 OSPF_TIMER_OFF (area->t_router_lsa_self);
876
877 /* If router-LSA is originated previously, check the interval time. */
878 if (lsa)
879 {
880 int delay;
881 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
882 {
883 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
884 ospf_router_lsa_timer, delay);
885 return;
886 }
887 }
888
889 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
890 zlog_info ("LSA[Type1]: Scheduling router-LSA origination right away");
891
892 /* Immediately refresh router-LSA. */
893 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
894}
895
896int
paul68980082003-03-25 05:07:42 +0000897ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000898{
paul68980082003-03-25 05:07:42 +0000899 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000900 listnode node;
901
902 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
903 zlog_info ("Timer[router-LSA Update]: (timer expire)");
904
paul68980082003-03-25 05:07:42 +0000905 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000906
paul68980082003-03-25 05:07:42 +0000907 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000908 {
909 struct ospf_area *area = getdata (node);
910 struct ospf_lsa *lsa = area->router_lsa_self;
911 struct router_lsa *rl;
912 char *area_str;
913
914 /* Keep Area ID string. */
915 area_str = AREA_NAME (area);
916
917 /* If LSA not exist in this Area, originate new. */
918 if (lsa == NULL)
919 {
920 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
921 zlog_info("LSA[Type1]: Create router-LSA for Area %s", area_str);
922
923 ospf_router_lsa_originate (area);
924 }
925 /* If router-ID is changed, Link ID must change.
926 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000927 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000928 {
929 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
930 zlog_info("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
931 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
932 ospf_lsa_flush_area (lsa, area);
933 ospf_lsa_unlock (area->router_lsa_self);
934 area->router_lsa_self = NULL;
935
936 /* Refresh router-LSA, (not install) and flood through area. */
937 ospf_router_lsa_timer_add (area);
938 }
939 else
940 {
941 rl = (struct router_lsa *) lsa->data;
942 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000943 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +0000944 ospf_router_lsa_timer_add (area);
945 }
946 }
947
948 return 0;
949}
950
951
952/* network-LSA related functions. */
953/* Originate Network-LSA. */
954void
955ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
956{
957 struct in_addr mask;
958 struct route_node *rn;
959 struct ospf_neighbor *nbr;
960
961 masklen2ip (oi->address->prefixlen, &mask);
962 stream_put_ipv4 (s, mask.s_addr);
963
964 /* The network-LSA lists those routers that are fully adjacent to
965 the Designated Router; each fully adjacent router is identified by
966 its OSPF Router ID. The Designated Router includes itself in this
967 list. RFC2328, Section 12.4.2 */
968
969 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
970 if ((nbr = rn->info) != NULL)
971 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
972 stream_put_ipv4 (s, nbr->router_id.s_addr);
973}
974
975struct ospf_lsa *
976ospf_network_lsa_new (struct ospf_interface *oi)
977{
978 struct stream *s;
979 struct ospf_lsa *new;
980 struct lsa_header *lsah;
981 int length;
982
983 /* If there are no neighbours on this network (the net is stub),
984 the router does not originate network-LSA (see RFC 12.4.2) */
985 if (oi->full_nbrs == 0)
986 return NULL;
987
988 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
989 zlog_info ("LSA[Type2]: Create network-LSA instance");
990
991 /* Create new stream for LSA. */
992 s = stream_new (OSPF_MAX_LSA_SIZE);
993 lsah = (struct lsa_header *) STREAM_DATA (s);
994
995 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +0000996 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000997
998 /* Set network-LSA body fields. */
999 ospf_network_lsa_body_set (s, oi);
1000
1001 /* Set length. */
1002 length = stream_get_endp (s);
1003 lsah->length = htons (length);
1004
1005 /* Create OSPF LSA instance. */
1006 new = ospf_lsa_new ();
1007 new->area = oi->area;
1008 SET_FLAG (new->flags, OSPF_LSA_SELF);
1009
1010 /* Copy LSA to store. */
1011 new->data = ospf_lsa_data_new (length);
1012 memcpy (new->data, lsah, length);
1013 stream_free (s);
1014
1015 return new;
1016}
1017
1018/* Originate network-LSA. */
1019struct ospf_lsa *
1020ospf_network_lsa_originate (struct ospf_interface *oi)
1021{
1022 struct ospf_lsa *new;
1023
1024 /* Create new network-LSA instance. */
1025 new = ospf_network_lsa_new (oi);
1026 if (new == NULL)
1027 return NULL;
1028
1029 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001030 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001031
1032 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001033 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001034
1035 /* Flooding new LSA through area. */
1036 ospf_flood_through_area (oi->area, NULL, new);
1037
1038 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1039 {
1040 zlog_info ("LSA[Type%d:%s]: Originate network-LSA %p",
1041 new->data->type, inet_ntoa (new->data->id), new);
1042 ospf_lsa_header_dump (new->data);
1043 }
1044
1045 return new;
1046}
1047
1048int
1049ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1050{
1051 struct ospf_area *area = lsa->area;
1052 struct ospf_lsa *new;
1053
1054 assert (lsa->data);
1055
1056 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001057 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001058
1059 /* Create new network-LSA instance. */
1060 new = ospf_network_lsa_new (oi);
1061 if (new == NULL)
1062 return -1;
1063 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1064
paul68980082003-03-25 05:07:42 +00001065 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001066
1067 /* Flood LSA through aera. */
1068 ospf_flood_through_area (area, NULL, new);
1069
1070 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1071 {
1072 zlog_info ("LSA[Type%d:%s]: network-LSA refresh",
1073 new->data->type, inet_ntoa (new->data->id));
1074 ospf_lsa_header_dump (new->data);
1075 }
1076
1077 return 0;
1078}
1079
1080int
1081ospf_network_lsa_refresh_timer (struct thread *t)
1082{
1083 struct ospf_interface *oi;
1084
1085 oi = THREAD_ARG (t);
1086 oi->t_network_lsa_self = NULL;
1087
1088 if (oi->network_lsa_self)
1089 /* Now refresh network-LSA. */
1090 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1091 else
1092 /* Newly create network-LSA. */
1093 ospf_network_lsa_originate (oi);
1094
1095 return 0;
1096}
1097
1098void
1099ospf_network_lsa_timer_add (struct ospf_interface *oi)
1100{
1101 /* Keep interface's self-originated network-LSA. */
1102 struct ospf_lsa *lsa = oi->network_lsa_self;
1103
1104 /* Cancel previously schedules network-LSA timer. */
1105 if (oi->t_network_lsa_self)
1106 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1107 zlog_info ("LSA[Type2]: Cancel previous network-LSA timer");
1108 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1109
1110 /* If network-LSA is originated previously, check the interval time. */
1111 if (lsa)
1112 {
1113 int delay;
1114 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1115 {
1116 oi->t_network_lsa_self =
1117 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1118 oi, delay);
1119 return;
1120 }
1121 }
1122
1123 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1124 zlog_info ("Scheduling network-LSA origination right away");
1125
1126 /* Immediately refresh network-LSA. */
1127 oi->t_network_lsa_self =
1128 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1129}
1130
1131
1132void
1133stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1134{
1135 u_int32_t metric;
1136 char *mp;
1137
1138 /* Put 0 metric. TOS metric is not supported. */
1139 metric = htonl (metric_value);
1140 mp = (char *) &metric;
1141 mp++;
1142 stream_put (s, mp, 3);
1143}
1144
1145/* summary-LSA related functions. */
1146void
1147ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1148 u_int32_t metric)
1149{
1150 struct in_addr mask;
1151
1152 masklen2ip (p->prefixlen, &mask);
1153
1154 /* Put Network Mask. */
1155 stream_put_ipv4 (s, mask.s_addr);
1156
1157 /* Set # TOS. */
1158 stream_putc (s, (u_char) 0);
1159
1160 /* Set metric. */
1161 stream_put_ospf_metric (s, metric);
1162}
1163
1164struct ospf_lsa *
1165ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1166 u_int32_t metric, struct in_addr id)
1167{
1168 struct stream *s;
1169 struct ospf_lsa *new;
1170 struct lsa_header *lsah;
1171 int length;
1172
1173 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1174 zlog_info ("LSA[Type3]: Create summary-LSA instance");
1175
1176 /* Create new stream for LSA. */
1177 s = stream_new (OSPF_MAX_LSA_SIZE);
1178 lsah = (struct lsa_header *) STREAM_DATA (s);
1179
paul68980082003-03-25 05:07:42 +00001180 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1181 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001182
1183 /* Set summary-LSA body fields. */
1184 ospf_summary_lsa_body_set (s, p, metric);
1185
1186 /* Set length. */
1187 length = stream_get_endp (s);
1188 lsah->length = htons (length);
1189
1190 /* Create OSPF LSA instance. */
1191 new = ospf_lsa_new ();
1192 new->area = area;
1193 SET_FLAG (new->flags, OSPF_LSA_SELF);
1194
1195 /* Copy LSA to store. */
1196 new->data = ospf_lsa_data_new (length);
1197 memcpy (new->data, lsah, length);
1198 stream_free (s);
1199
1200 return new;
1201}
1202
1203/* Originate Summary-LSA. */
1204struct ospf_lsa *
1205ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1206 struct ospf_area *area)
1207{
1208 struct ospf_lsa *new;
1209 struct in_addr id;
1210
paul68980082003-03-25 05:07:42 +00001211 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001212
1213 /* Create new summary-LSA instance. */
1214 new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id);
1215
1216 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001217 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001218
1219 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001220 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001221
1222 /* Flooding new LSA through area. */
1223 ospf_flood_through_area (area, NULL, new);
1224
1225 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1226 {
1227 zlog_info ("LSA[Type%d:%s]: Originate summary-LSA %p",
1228 new->data->type, inet_ntoa (new->data->id), new);
1229 ospf_lsa_header_dump (new->data);
1230 }
1231
1232 return new;
1233}
1234
1235struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001236ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001237{
1238 struct ospf_lsa *new;
1239 struct summary_lsa *sl;
1240 struct prefix p;
1241
1242 /* Sanity check. */
1243 assert (lsa->data);
1244
1245 sl = (struct summary_lsa *)lsa->data;
1246 p.prefixlen = ip_masklen (sl->mask);
1247 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1248 sl->header.id);
1249
1250 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1251
1252 /* Re-calculate checksum. */
1253 ospf_lsa_checksum (new->data);
1254
paul68980082003-03-25 05:07:42 +00001255 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001256
1257 /* Flood LSA through AS. */
1258 ospf_flood_through_area (new->area, NULL, new);
1259
1260 /* Debug logging. */
1261 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1262 {
1263 zlog_info ("LSA[Type%d:%s]: summary-LSA refresh",
1264 new->data->type, inet_ntoa (new->data->id));
1265 ospf_lsa_header_dump (new->data);
1266 }
1267
1268 return new;
1269}
1270
1271
1272/* summary-ASBR-LSA related functions. */
1273void
1274ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1275 u_int32_t metric)
1276{
1277 struct in_addr mask;
1278
1279 masklen2ip (p->prefixlen, &mask);
1280
1281 /* Put Network Mask. */
1282 stream_put_ipv4 (s, mask.s_addr);
1283
1284 /* Set # TOS. */
1285 stream_putc (s, (u_char) 0);
1286
1287 /* Set metric. */
1288 stream_put_ospf_metric (s, metric);
1289}
1290
1291struct ospf_lsa *
1292ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1293 u_int32_t metric, struct in_addr id)
1294{
1295 struct stream *s;
1296 struct ospf_lsa *new;
1297 struct lsa_header *lsah;
1298 int length;
1299
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 zlog_info ("LSA[Type3]: Create summary-LSA instance");
1302
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_ASBR_SUMMARY_LSA,
1308 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001309
1310 /* Set summary-LSA body fields. */
1311 ospf_summary_asbr_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-ASBR-LSA. */
1331struct ospf_lsa *
1332ospf_summary_asbr_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_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001339
1340 /* Create new summary-LSA instance. */
1341 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
1342
1343 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001344 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001345
1346 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001347 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001348
1349 /* Flooding new LSA through area. */
1350 ospf_flood_through_area (area, NULL, new);
1351
1352 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1353 {
1354 zlog_info ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
1355 new->data->type, inet_ntoa (new->data->id), new);
1356 ospf_lsa_header_dump (new->data);
1357 }
1358
1359 return new;
1360}
1361
1362struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001363ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001364{
1365 struct ospf_lsa *new;
1366 struct summary_lsa *sl;
1367 struct prefix p;
1368
1369 /* Sanity check. */
1370 assert (lsa->data);
1371
1372 sl = (struct summary_lsa *)lsa->data;
1373 p.prefixlen = ip_masklen (sl->mask);
1374 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1375 sl->header.id);
1376
1377 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1378
1379 /* Re-calculate checksum. */
1380 ospf_lsa_checksum (new->data);
1381
paul68980082003-03-25 05:07:42 +00001382 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001383
1384 /* Flood LSA through area. */
1385 ospf_flood_through_area (new->area, NULL, new);
1386
1387 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1388 {
1389 zlog_info ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
1390 new->data->type, inet_ntoa (new->data->id));
1391 ospf_lsa_header_dump (new->data);
1392 }
1393
1394 return new;
1395}
1396
1397/* AS-external-LSA related functions. */
1398
1399/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1400 is connected, else 0*/
1401struct in_addr
paul68980082003-03-25 05:07:42 +00001402ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001403{
1404 struct in_addr fwd;
1405 struct prefix nh;
paul718e3742002-12-13 20:15:29 +00001406 listnode n1;
1407
1408 fwd.s_addr = 0;
1409
1410 if (!nexthop.s_addr)
1411 return fwd;
1412
1413 /* Check whether nexthop is covered by OSPF network. */
1414 nh.family = AF_INET;
1415 nh.u.prefix4 = nexthop;
1416 nh.prefixlen = IPV4_MAX_BITLEN;
1417
paul68980082003-03-25 05:07:42 +00001418 for (n1 = listhead (ospf->oiflist); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00001419 {
1420 struct ospf_interface *oi = getdata (n1);
1421
paul2e3b2e42002-12-13 21:03:13 +00001422 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001423 if (oi->address->family == AF_INET)
1424 if (prefix_match (oi->address, &nh))
1425 return nexthop;
1426 }
1427
1428 return fwd;
1429}
1430
1431#ifdef HAVE_NSSA
1432/* NSSA-external-LSA related functions. */
1433
1434/* Get 1st IP connection for Forward Addr */
1435
1436struct in_addr
1437ospf_get_ip_from_ifp (struct ospf_interface *oi)
1438{
1439 struct in_addr fwd;
1440
1441 fwd.s_addr = 0;
1442
paul2e3b2e42002-12-13 21:03:13 +00001443 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001444 return oi->address->u.prefix4;
1445
1446 return fwd;
1447}
1448
1449/* Get 1st IP connection for Forward Addr */
1450struct in_addr
paulf2c80652002-12-13 21:44:27 +00001451ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001452{
1453 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001454 struct in_addr best_default;
paul718e3742002-12-13 20:15:29 +00001455 listnode n1;
1456
1457 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001458 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001459
paul68980082003-03-25 05:07:42 +00001460 for (n1 = listhead (area->ospf->oiflist); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00001461 {
1462 struct ospf_interface *oi = getdata (n1);
1463
paul2e3b2e42002-12-13 21:03:13 +00001464 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001465 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001466 if (oi->address && oi->address->family == AF_INET)
1467 {
1468 if (best_default.s_addr == 0)
1469 best_default = oi->address->u.prefix4;
1470 if (oi->area == area)
1471 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001472 }
paul718e3742002-12-13 20:15:29 +00001473 }
paulf2c80652002-12-13 21:44:27 +00001474 if (best_default.s_addr != 0)
1475 return best_default;
paul718e3742002-12-13 20:15:29 +00001476
paul68980082003-03-25 05:07:42 +00001477 if (best_default.s_addr != 0)
1478 return best_default;
1479
paul718e3742002-12-13 20:15:29 +00001480 return fwd;
1481}
1482#endif /* HAVE_NSSA */
1483
1484#define DEFAULT_DEFAULT_METRIC 20
1485#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1486#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1487
1488#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1489
1490int
paul68980082003-03-25 05:07:42 +00001491metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001492{
paul68980082003-03-25 05:07:42 +00001493 return (ospf->dmetric[src].type < 0 ?
1494 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001495}
1496
1497int
paul68980082003-03-25 05:07:42 +00001498metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001499{
paul68980082003-03-25 05:07:42 +00001500 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001501 {
1502 if (src == DEFAULT_ROUTE)
1503 {
paul68980082003-03-25 05:07:42 +00001504 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001505 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1506 else
1507 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1508 }
paul68980082003-03-25 05:07:42 +00001509 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001510 return DEFAULT_DEFAULT_METRIC;
1511 else
paul68980082003-03-25 05:07:42 +00001512 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001513 }
1514
paul68980082003-03-25 05:07:42 +00001515 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001516}
1517
1518/* Set AS-external-LSA body. */
1519void
paul68980082003-03-25 05:07:42 +00001520ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1521 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001522{
1523 struct prefix_ipv4 *p = &ei->p;
1524 struct in_addr mask, fwd_addr;
1525 u_int32_t mvalue;
1526 int mtype;
1527 int type;
1528
1529 /* Put Network Mask. */
1530 masklen2ip (p->prefixlen, &mask);
1531 stream_put_ipv4 (s, mask.s_addr);
1532
1533 /* If prefix is default, specify DEFAULT_ROUTE. */
1534 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1535
1536 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001537 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001538
1539 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001540 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001541
1542 /* Put type of external metric. */
1543 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1544
1545 /* Put 0 metric. TOS metric is not supported. */
1546 stream_put_ospf_metric (s, mvalue);
1547
1548 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001549 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001550
1551 /* Put forwarding address. */
1552 stream_put_ipv4 (s, fwd_addr.s_addr);
1553
1554 /* Put route tag -- This value should be introduced from configuration. */
1555 stream_putl (s, 0);
1556}
1557
1558/* Create new external-LSA. */
1559struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001560ospf_external_lsa_new (struct ospf *ospf,
1561 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001562{
1563 struct stream *s;
1564 struct lsa_header *lsah;
1565 struct ospf_lsa *new;
1566 struct in_addr id;
1567 int length;
1568
1569 if (ei == NULL)
1570 {
1571 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1572 zlog_warn ("LSA[Type5]: External info is NULL, could not originated");
1573 return NULL;
1574 }
1575
1576 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1577 zlog_info ("LSA[Type5]: Originate AS-external-LSA instance");
1578
1579 /* If old Link State ID is specified, refresh LSA with same ID. */
1580 if (old_id)
1581 id = *old_id;
1582 /* Get Link State with unique ID. */
1583 else
1584 {
paul68980082003-03-25 05:07:42 +00001585 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001586 if (id.s_addr == 0xffffffff)
1587 {
1588 /* Maybe Link State ID not available. */
1589 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1590 zlog_info ("LSA[Type5]: Link ID not available, can't originate");
1591 return NULL;
1592 }
1593 }
1594
1595 /* Create new stream for LSA. */
1596 s = stream_new (OSPF_MAX_LSA_SIZE);
1597 lsah = (struct lsa_header *) STREAM_DATA (s);
1598
1599 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001600 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1601 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001602
1603 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001604 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001605
1606 /* Set length. */
1607 length = stream_get_endp (s);
1608 lsah->length = htons (length);
1609
1610 /* Now, create OSPF LSA instance. */
1611 new = ospf_lsa_new ();
1612 new->area = NULL;
1613 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1614
1615 /* Copy LSA data to store, discard stream. */
1616 new->data = ospf_lsa_data_new (length);
1617 memcpy (new->data, lsah, length);
1618 stream_free (s);
1619
1620 return new;
1621}
1622
1623#ifdef HAVE_NSSA
paul718e3742002-12-13 20:15:29 +00001624/* As Type-7 */
1625void
paul68980082003-03-25 05:07:42 +00001626ospf_install_flood_nssa (struct ospf *ospf,
1627 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001628{
pauld4a53d52003-07-12 21:30:57 +00001629 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001630 struct as_external_lsa *extlsa;
paulf2c80652002-12-13 21:44:27 +00001631 listnode node;
paul718e3742002-12-13 20:15:29 +00001632
pauld4a53d52003-07-12 21:30:57 +00001633 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1634 * which originated from an NSSA area. In which case it should not be
1635 * flooded back to NSSA areas.
1636 */
1637 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1638 return;
1639
paul718e3742002-12-13 20:15:29 +00001640 /* NSSA Originate or Refresh (If anyNSSA)
1641
1642 LSA is self-originated. And just installed as Type-5.
1643 Additionally, install as Type-7 LSDB for every attached NSSA.
1644
1645 P-Bit controls which ABR performs translation to outside world; If
1646 we are an ABR....do not set the P-bit, because we send the Type-5,
1647 not as the ABR Translator, but as the ASBR owner within the AS!
1648
1649 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1650 elected ABR Translator will see the P-bit, Translate, and re-flood.
1651
1652 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1653 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1654
paul68980082003-03-25 05:07:42 +00001655 for (node = listhead (ospf->areas); node; nextnode (node))
1656 {
1657 struct ospf_area *area = getdata (node);
hasso0c14ad82003-07-03 08:36:02 +00001658
1659 /* Don't install Type-7 LSA's into nonNSSA area */
1660 if (area->external_routing != OSPF_AREA_NSSA)
1661 continue;
paul718e3742002-12-13 20:15:29 +00001662
paul68980082003-03-25 05:07:42 +00001663 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001664 new = ospf_lsa_dup (lsa);
1665 new->area = area;
1666 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001667
paul68980082003-03-25 05:07:42 +00001668 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001669 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001670 {
pauld4a53d52003-07-12 21:30:57 +00001671 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001672
1673 /* set non-zero FWD ADDR
1674
1675 draft-ietf-ospf-nssa-update-09.txt
1676
1677 if the network between the NSSA AS boundary router and the
1678 adjacent AS is advertised into OSPF as an internal OSPF route,
1679 the forwarding address should be the next op address as is cu
1680 currently done with type-5 LSAs. If the intervening network is
1681 not adversited into OSPF as an internal OSPF route and the
1682 type-7 LSA's P-bit is set a forwarding address should be
1683 selected from one of the router's active OSPF inteface addresses
1684 which belong to the NSSA. If no such addresses exist, then
1685 no type-7 LSA's with the P-bit set should originate from this
1686 router. */
1687
pauld4a53d52003-07-12 21:30:57 +00001688 /* kevinm: not updating lsa anymore, just new */
1689 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001690
1691 if (extlsa->e[0].fwd_addr.s_addr == 0)
1692 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001693
pauld7480322003-05-16 17:31:51 +00001694 if (extlsa->e[0].fwd_addr.s_addr == 0)
1695 {
1696 if (IS_DEBUG_OSPF_NSSA)
1697 zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
pauld4a53d52003-07-12 21:30:57 +00001698 ospf_lsa_discard(new);
pauld7480322003-05-16 17:31:51 +00001699 return;
1700 }
paulf2c80652002-12-13 21:44:27 +00001701 }
paul68980082003-03-25 05:07:42 +00001702 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001703 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001704
paul68980082003-03-25 05:07:42 +00001705 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001706 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001707
1708 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001709 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001710 }
paul718e3742002-12-13 20:15:29 +00001711}
pauld4a53d52003-07-12 21:30:57 +00001712
1713struct ospf_lsa *
1714ospf_lsa_translated_nssa_new (struct ospf *ospf,
1715 struct ospf_lsa *type7)
1716{
1717
1718 struct ospf_lsa *new;
1719 struct as_external_lsa *ext, *extnew;
1720 struct external_info ei;
1721
1722 ext = (struct as_external_lsa *)(type7->data);
1723
1724 /* need external_info struct, fill in bare minimum */
1725 ei.p.family = AF_INET;
1726 ei.p.prefix = type7->data->id;
1727 ei.p.prefixlen = ip_masklen (ext->mask);
1728 ei.type = ZEBRA_ROUTE_OSPF;
1729 ei.nexthop = ext->header.adv_router;
1730 ei.route_map_set.metric = -1;
1731 ei.route_map_set.metric_type = -1;
1732 ei.tag = 0;
1733
1734 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1735 {
1736 if (IS_DEBUG_OSPF_NSSA)
1737 zlog_info ("ospf_nssa_translate_originate(): Could not originate "
1738 "Translated Type-5 for %s",
1739 inet_ntoa (ei.p.prefix));
1740 return NULL;
1741 }
1742
1743 extnew = (struct as_external_lsa *)(new->data);
1744
1745 /* copy over Type-7 data to new */
1746 extnew->e[0].tos = ext->e[0].tos;
1747 extnew->e[0].route_tag = ext->e[0].route_tag;
1748 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1749 new->data->ls_seqnum = type7->data->ls_seqnum;
1750
1751 /* add translated flag, checksum and lock new lsa */
1752 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1753 ospf_lsa_checksum (new->data);
1754 new = ospf_lsa_lock (new);
1755
1756 return new;
1757}
1758
1759/* compare type-5 to type-7
1760 * -1: err, 0: same, 1: different
1761 */
1762int
1763ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1764{
1765
1766 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1767 *e7 = (struct as_external_lsa *)t7;
1768
1769
1770 /* sanity checks */
1771 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1772 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1773 return -1;
1774
1775 if (t5->data->id.s_addr != t7->data->id.s_addr)
1776 return -1;
1777
1778 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1779 return LSA_REFRESH_FORCE;
1780
1781 if (e5->mask.s_addr != e7->mask.s_addr)
1782 return LSA_REFRESH_FORCE;
1783
1784 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1785 return LSA_REFRESH_FORCE;
1786
1787 if (e5->e[0].route_tag != e7->e[0].route_tag)
1788 return LSA_REFRESH_FORCE;
1789
1790 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1791 return LSA_REFRESH_FORCE;
1792
1793 return LSA_REFRESH_IF_CHANGED;
1794}
1795
1796/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1797struct ospf_lsa *
1798ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1799{
1800 struct ospf_lsa *new;
1801 struct as_external_lsa *extnew;
1802
1803 /* we cant use ospf_external_lsa_originate() as we need to set
1804 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1805 */
1806
1807 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1808 {
1809 if (IS_DEBUG_OSPF_NSSA)
1810 zlog_info ("ospf_translated_nssa_originate(): Could not translate "
1811 "Type-7, Id %s, to Type-5",
1812 inet_ntoa (type7->data->id));
1813 return NULL;
1814 }
1815
1816 extnew = (struct as_external_lsa *)new;
1817
1818 if (IS_DEBUG_OSPF_NSSA)
1819 {
1820 zlog_info ("ospf_translated_nssa_originate(): "
1821 "translated Type 7, installed:");
1822 ospf_lsa_header_dump (new->data);
1823 zlog_info (" Network mask: %d",ip_masklen (extnew->mask));
1824 zlog_info (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
1825 }
1826
1827 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1828 {
1829 if (IS_DEBUG_OSPF_NSSA);
1830 zlog_warn ("ospf_lsa_translated_nssa_originate(): "
1831 "Could not install LSA "
1832 "id %s", inet_ntoa (type7->data->id));
1833 return NULL;
1834 }
1835
1836 ospf->lsa_originate_count++;
1837 ospf_flood_through_as (ospf, NULL, new);
1838
1839 return new;
1840}
1841
1842/* Refresh Translated from NSSA AS-external-LSA. */
1843struct ospf_lsa *
1844ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1845 struct ospf_lsa *type5)
1846{
1847 struct ospf_lsa *new = NULL;
1848
1849 /* Sanity checks. */
1850 assert (type7 || type5);
1851 if (type7)
1852 assert (type7->data);
1853 if (type5)
1854 assert (type5->data);
1855 assert (ospf->anyNSSA);
1856
1857 /* get required data according to what has been given */
1858 if (type7 && type5 == NULL)
1859 {
1860 /* find the translated Type-5 for this Type-7 */
1861 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1862 struct prefix_ipv4 p =
1863 {
1864 .prefix = type7->data->id,
1865 .prefixlen = ip_masklen (ext->mask),
1866 .family = AF_INET,
1867 };
1868
1869 type5 = ospf_external_info_find_lsa (ospf, &p);
1870 }
1871 else if (type5 && type7 == NULL)
1872 {
1873 /* find the type-7 from which supplied type-5 was translated,
1874 * ie find first type-7 with same LSA Id.
1875 */
1876 listnode ln;
1877 struct route_node *rn;
1878 struct ospf_lsa *lsa;
1879 struct ospf_area *area;
1880
1881 LIST_LOOP (ospf->areas, area, ln)
1882 {
1883 if (area->external_routing != OSPF_AREA_NSSA
1884 && !type7)
1885 continue;
1886
1887 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1888 {
1889 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1890 {
1891 type7 = lsa;
1892 break;
1893 }
1894 }
1895 }
1896 }
1897
1898 /* do we have type7? */
1899 if (!type7)
1900 {
1901 if (IS_DEBUG_OSPF_NSSA)
1902 zlog_info ("ospf_translated_nssa_refresh(): no Type-7 found for "
1903 "Type-5 LSA Id %s",
1904 inet_ntoa (type7->data->id));
1905 return NULL;
1906 }
1907
1908 /* do we have valid translated type5? */
1909 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1910 {
1911 if (IS_DEBUG_OSPF_NSSA)
1912 zlog_info ("ospf_translated_nssa_refresh(): No translated Type-5 "
1913 "found for Type-7 with Id %s",
1914 inet_ntoa (type7->data->id));
1915 return NULL;
1916 }
1917
1918 /* Delete LSA from neighbor retransmit-list. */
1919 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1920
1921 /* create new translated LSA */
1922 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1923 {
1924 if (IS_DEBUG_OSPF_NSSA)
1925 zlog_info ("ospf_translated_nssa_refresh(): Could not translate "
1926 "Type-7 for %s to Type-5",
1927 inet_ntoa (type7->data->id));
1928 return NULL;
1929 }
1930
1931 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1932 {
1933 if (IS_DEBUG_OSPF_NSSA)
1934 zlog_info ("ospf_translated_nssa_refresh(): Could not install "
1935 "translated LSA, Id %s",
1936 inet_ntoa (new->data->id));
1937 return NULL;
1938 }
1939
1940 /* Flood LSA through area. */
1941 ospf_flood_through_as (ospf, NULL, new);
1942
1943 return new;
1944}
paul718e3742002-12-13 20:15:29 +00001945#endif /* HAVE_NSSA */
1946
1947int
1948is_prefix_default (struct prefix_ipv4 *p)
1949{
1950 struct prefix_ipv4 q;
1951
1952 q.family = AF_INET;
1953 q.prefix.s_addr = 0;
1954 q.prefixlen = 0;
1955
1956 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1957}
1958
1959/* Originate an AS-external-LSA, install and flood. */
1960struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001961ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001962{
1963 struct ospf_lsa *new;
1964
1965 /* Added for NSSA project....
1966
1967 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1968 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1969 every area. The Type-7's are flooded to every IR and every ABR; We
1970 install the Type-5 LSDB so that the normal "refresh" code operates
1971 as usual, and flag them as not used during ASE calculations. The
1972 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1973 Address of non-zero.
1974
1975 If an ABR is the elected NSSA translator, following SPF and during
1976 the ABR task it will translate all the scanned Type-7's, with P-bit
1977 ON and not-self generated, and translate to Type-5's throughout the
1978 non-NSSA/STUB AS.
1979
1980 A difference in operation depends whether this ASBR is an ABR
1981 or not. If not an ABR, the P-bit is ON, to indicate that any
1982 elected NSSA-ABR can perform its translation.
1983
1984 If an ABR, the P-bit is OFF; No ABR will perform translation and
1985 this ASBR will flood the Type-5 LSA as usual.
1986
1987 For the case where this ASBR is not an ABR, the ASE calculations
1988 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
1989 demonstrate to the user that there are LSA's that belong to any
1990 attached NSSA.
1991
1992 Finally, it just so happens that when the ABR is translating every
1993 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
1994 approved Type-5 (translated from Type-7); at the end of translation
1995 if any Translated Type-5's remain unapproved, then they must be
1996 flushed from the AS.
1997
1998 */
1999
2000 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002001 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002002 return NULL;
2003
2004 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002005 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002006 {
2007 if (IS_DEBUG_OSPF_EVENT)
2008 zlog_info ("LSA[Type5:%s]: Could not originate AS-external-LSA",
2009 inet_ntoa (ei->p.prefix));
2010 return NULL;
2011 }
2012
2013 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002014 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002015
2016 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002017 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002018
2019 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002020 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002021
2022#ifdef HAVE_NSSA
2023 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002024 if (ospf->anyNSSA &&
2025 /* stay away from translated LSAs! */
2026 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002027 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002028#endif /* HAVE_NSSA */
2029
2030 /* Debug logging. */
2031 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2032 {
2033 zlog_info ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
2034 new->data->type, inet_ntoa (new->data->id), new);
2035 ospf_lsa_header_dump (new->data);
2036 }
2037
2038 return new;
2039}
2040
2041/* Originate AS-external-LSA from external info with initial flag. */
2042int
paul68980082003-03-25 05:07:42 +00002043ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002044{
paul68980082003-03-25 05:07:42 +00002045 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002046 struct route_node *rn;
2047 struct external_info *ei;
2048 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002049 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002050
paul68980082003-03-25 05:07:42 +00002051 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002052
2053 /* Originate As-external-LSA from all type of distribute source. */
2054 if ((rt = EXTERNAL_INFO (type)))
2055 for (rn = route_top (rt); rn; rn = route_next (rn))
2056 if ((ei = rn->info) != NULL)
2057 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002058 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002059 zlog_warn ("LSA: AS-external-LSA was not originated.");
2060
2061 return 0;
2062}
2063
2064struct external_info *
paul020709f2003-04-04 02:44:16 +00002065ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002066{
2067 int type;
2068 struct route_node *rn;
2069 struct prefix_ipv4 p;
2070
2071 p.family = AF_INET;
2072 p.prefix.s_addr = 0;
2073 p.prefixlen = 0;
2074
2075 /* First, lookup redistributed default route. */
2076 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2077 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2078 {
2079 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2080 if (rn != NULL)
2081 {
2082 route_unlock_node (rn);
2083 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002084 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002085 return rn->info;
2086 }
2087 }
2088
2089 return NULL;
2090}
2091
2092int
paul68980082003-03-25 05:07:42 +00002093ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002094{
2095 int *origin;
2096 struct prefix_ipv4 p;
2097 struct in_addr nexthop;
2098 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002099 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002100
paul020709f2003-04-04 02:44:16 +00002101 ospf = ospf_lookup ();
2102
paul718e3742002-12-13 20:15:29 +00002103 /* Get originate flags. */
paul68980082003-03-25 05:07:42 +00002104 origin = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002105
2106 p.family = AF_INET;
2107 p.prefix.s_addr = 0;
2108 p.prefixlen = 0;
2109
2110 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
2111 {
2112 /* If there is no default route via redistribute,
2113 then originate AS-external-LSA with nexthop 0 (self). */
2114 nexthop.s_addr = 0;
2115 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2116 }
2117
paul020709f2003-04-04 02:44:16 +00002118 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002119 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002120
2121 return 0;
2122}
2123
paul645878f2003-04-13 21:42:11 +00002124#ifdef HAVE_NSSA
2125/* Flush any NSSA LSAs for given prefix */
2126void
2127ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2128{
2129 struct listnode *node;
2130 struct ospf_lsa *lsa;
2131 struct ospf_area *area;
2132
pauld7480322003-05-16 17:31:51 +00002133 for (node = listhead (ospf->areas); node; nextnode (node))
paul645878f2003-04-13 21:42:11 +00002134 {
pauld7480322003-05-16 17:31:51 +00002135 if (((area = getdata (node)) != NULL)
2136 && (area->external_routing == OSPF_AREA_NSSA))
2137 {
2138 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2139 ospf->router_id)))
2140 {
2141 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2142 zlog_warn ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
2143 inet_ntoa (p->prefix), p->prefixlen);
2144 continue;
2145 }
2146 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2147 if (!IS_LSA_MAXAGE (lsa))
2148 {
2149 ospf_refresher_unregister_lsa (ospf, lsa);
2150 ospf_lsa_flush_area (lsa, area);
2151 }
2152 }
paul645878f2003-04-13 21:42:11 +00002153 }
2154}
2155#endif /* HAVE_NSSA */
2156
paul718e3742002-12-13 20:15:29 +00002157/* Flush an AS-external-LSA from LSDB and routing domain. */
2158void
paul68980082003-03-25 05:07:42 +00002159ospf_external_lsa_flush (struct ospf *ospf,
2160 u_char type, struct prefix_ipv4 *p,
paul718e3742002-12-13 20:15:29 +00002161 unsigned int ifindex, struct in_addr nexthop)
2162{
2163 struct ospf_lsa *lsa;
2164
2165 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2166 zlog_info ("LSA: Flushing AS-external-LSA %s/%d",
2167 inet_ntoa (p->prefix), p->prefixlen);
2168
2169 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002170 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002171 {
2172 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2173 zlog_warn ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
2174 inet_ntoa (p->prefix), p->prefixlen);
2175 return;
2176 }
pauld7480322003-05-16 17:31:51 +00002177#ifdef HAVE_NSSA
pauld4a53d52003-07-12 21:30:57 +00002178 /* If LSA is selforiginated, not a translated LSA, and there is
2179 * NSSA area, flush Type-7 LSA's at first.
2180 */
2181 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2182 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002183 ospf_nssa_lsa_flush (ospf, p);
2184#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002185
2186 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002187 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002188
2189 /* There must be no self-originated LSA in rtrs_external. */
2190#if 0
2191 /* Remove External route from Zebra. */
2192 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2193#endif
2194
2195 if (!IS_LSA_MAXAGE (lsa))
2196 {
2197 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002198 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002199
2200 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002201 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002202 }
2203
2204 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2205 zlog_info ("ospf_external_lsa_flush(): stop");
2206}
2207
2208void
paul68980082003-03-25 05:07:42 +00002209ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002210{
2211 struct prefix_ipv4 p;
2212 struct external_info *ei;
2213 struct ospf_lsa *lsa;
2214
2215 p.family = AF_INET;
2216 p.prefixlen = 0;
2217 p.prefix.s_addr = 0;
2218
paul020709f2003-04-04 02:44:16 +00002219 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002220 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002221
2222 if (ei)
2223 {
2224 if (lsa)
2225 {
2226 if (IS_DEBUG_OSPF_EVENT)
2227 zlog_info ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002228 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002229 }
2230 else
2231 {
2232 if (IS_DEBUG_OSPF_EVENT)
2233 zlog_info ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002234 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002235 }
2236 }
2237 else
2238 {
2239 if (lsa)
2240 {
2241 if (IS_DEBUG_OSPF_EVENT)
2242 zlog_info ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002243 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002244 }
2245 }
2246}
2247
2248void
paul68980082003-03-25 05:07:42 +00002249ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002250{
2251 struct route_node *rn;
2252 struct external_info *ei;
2253
2254 if (type != DEFAULT_ROUTE)
2255 if (EXTERNAL_INFO(type))
2256 /* Refresh each redistributed AS-external-LSAs. */
2257 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2258 if ((ei = rn->info))
2259 if (!is_prefix_default (&ei->p))
2260 {
2261 struct ospf_lsa *lsa;
2262
paul68980082003-03-25 05:07:42 +00002263 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2264 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002265 else
paul68980082003-03-25 05:07:42 +00002266 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002267 }
2268}
2269
2270/* Refresh AS-external-LSA. */
2271void
paul68980082003-03-25 05:07:42 +00002272ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002273 struct external_info *ei, int force)
2274{
2275 struct ospf_lsa *new;
2276 int changed;
2277
2278 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002279 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002280 {
pauld4a53d52003-07-12 21:30:57 +00002281 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2282 zlog_warn ("LSA[Type%d:%s]: Could not be refreshed, "
2283 "redist check fail",
2284 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002285 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
2286 ei->ifindex, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00002287 return;
2288 }
2289
2290 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002291 {
2292 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2293 zlog_info ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
2294 lsa->data->type, inet_ntoa (lsa->data->id));
2295 return;
2296 }
paul718e3742002-12-13 20:15:29 +00002297
2298 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002299 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002300
2301 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002302 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002303
paul68980082003-03-25 05:07:42 +00002304 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002305
2306 if (new == NULL)
2307 {
2308 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2309 zlog_warn ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
2310 inet_ntoa (lsa->data->id));
2311 return;
2312 }
2313
2314 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2315
2316 /* Record timestamp. */
2317 gettimeofday (&new->tv_orig, NULL);
2318
2319 /* Re-calculate checksum. */
2320 ospf_lsa_checksum (new->data);
2321
paul68980082003-03-25 05:07:42 +00002322 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002323
2324 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002325 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002326
2327#ifdef HAVE_NSSA
2328 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002329 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002330 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002331#endif /* HAVE_NSSA */
2332
pauld4a53d52003-07-12 21:30:57 +00002333 /* Register self-originated LSA to refresh queue.
2334 * Translated LSAs should not be registered, but refreshed upon
2335 * refresh of the Type-7
2336 */
paul8fc0f642003-07-13 01:36:06 +00002337#ifdef HAVE_NSSA
pauld4a53d52003-07-12 21:30:57 +00002338 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
paul8fc0f642003-07-13 01:36:06 +00002339#endif
pauld4a53d52003-07-12 21:30:57 +00002340 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002341
2342 /* Debug logging. */
2343 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2344 {
2345 zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002346 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002347 ospf_lsa_header_dump (new->data);
2348 }
2349
2350 return;
2351}
2352
2353
2354/* LSA installation functions. */
2355
2356/* Install router-LSA to an area. */
2357struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002358ospf_router_lsa_install (struct ospf *ospf,
2359 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002360{
2361 struct ospf_area *area = new->area;
2362
2363 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2364 The entire routing table must be recalculated, starting with
2365 the shortest path calculations for each area (not just the
2366 area whose link-state database has changed).
2367 */
2368 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002369 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002370
2371 if (IS_LSA_SELF (new))
2372 {
2373 /* Set router-LSA refresh timer. */
2374 OSPF_TIMER_OFF (area->t_router_lsa_self);
2375 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002376 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002377
2378 /* Set self-originated router-LSA. */
2379 ospf_lsa_unlock (area->router_lsa_self);
2380 area->router_lsa_self = ospf_lsa_lock (new);
2381
2382 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
paul0c2be262004-05-31 14:16:54 +00002383 zlog_info("LSA[Type%d]: ID %s seq 0x%x is self-originated",
2384 new->data->type, inet_ntoa (new->data->id),
2385 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002386 }
2387
2388 return new;
2389}
2390
2391#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2392 if (!(T)) \
2393 (T) = thread_add_timer (master, (F), oi, (V))
2394
2395/* Install network-LSA to an area. */
2396struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002397ospf_network_lsa_install (struct ospf *ospf,
2398 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002399 struct ospf_lsa *new,
2400 int rt_recalc)
2401{
2402
2403 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2404 The entire routing table must be recalculated, starting with
2405 the shortest path calculations for each area (not just the
2406 area whose link-state database has changed).
2407 */
2408 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002409 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002410
2411 /* We supposed that when LSA is originated by us, we pass the int
2412 for which it was originated. If LSA was received by flooding,
2413 the RECEIVED flag is set, so we do not link the LSA to the int. */
2414 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2415 {
2416 /* Set LSRefresh timer. */
2417 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2418
2419 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2420 ospf_network_lsa_refresh_timer,
2421 OSPF_LS_REFRESH_TIME);
2422
2423 ospf_lsa_unlock (oi->network_lsa_self);
2424 oi->network_lsa_self = ospf_lsa_lock (new);
2425 }
2426
2427 return new;
2428}
2429
2430/* Install summary-LSA to an area. */
2431struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002432ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2433 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002434{
paul718e3742002-12-13 20:15:29 +00002435 if (rt_recalc && !IS_LSA_SELF (new))
2436 {
2437 /* RFC 2328 Section 13.2 Summary-LSAs
2438 The best route to the destination described by the summary-
2439 LSA must be recalculated (see Section 16.5). If this
2440 destination is an AS boundary router, it may also be
2441 necessary to re-examine all the AS-external-LSAs.
2442 */
2443
2444#if 0
2445 /* This doesn't exist yet... */
2446 ospf_summary_incremental_update(new); */
2447#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002448 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002449#endif /* #if 0 */
2450
2451 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2452 zlog_info ("ospf_summary_lsa_install(): SPF scheduled");
2453 }
2454
2455 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002456 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002457
2458 return new;
2459}
2460
2461/* Install ASBR-summary-LSA to an area. */
2462struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002463ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2464 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002465{
2466 if (rt_recalc && !IS_LSA_SELF (new))
2467 {
2468 /* RFC 2328 Section 13.2 Summary-LSAs
2469 The best route to the destination described by the summary-
2470 LSA must be recalculated (see Section 16.5). If this
2471 destination is an AS boundary router, it may also be
2472 necessary to re-examine all the AS-external-LSAs.
2473 */
2474#if 0
2475 /* These don't exist yet... */
2476 ospf_summary_incremental_update(new);
2477 /* Isn't this done by the above call?
2478 - RFC 2328 Section 16.5 implies it should be */
2479 /* ospf_ase_calculate_schedule(); */
2480#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002481 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002482#endif /* #if 0 */
2483 }
2484
2485 /* register LSA to refresh-list. */
2486 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002487 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002488
2489 return new;
2490}
2491
2492/* Install AS-external-LSA. */
2493struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002494ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2495 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002496{
paul68980082003-03-25 05:07:42 +00002497 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002498 /* If LSA is not self-originated, calculate an external route. */
2499 if (rt_recalc)
2500 {
2501 /* RFC 2328 Section 13.2 AS-external-LSAs
2502 The best route to the destination described by the AS-
2503 external-LSA must be recalculated (see Section 16.6).
2504 */
2505
2506 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002507 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002508 }
2509
pauld7480322003-05-16 17:31:51 +00002510#ifdef HAVE_NSSA
pauld4a53d52003-07-12 21:30:57 +00002511 if (new->data->type == OSPF_AS_NSSA_LSA)
2512 {
2513 /* There is no point to register selforiginate Type-7 LSA for
2514 * refreshing. We rely on refreshing Type-5 LSA's
2515 */
2516 if (IS_LSA_SELF (new))
2517 return new;
2518 else
2519 {
2520 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2521 * New translations will be taken care of by the abr_task.
2522 */
2523 ospf_translated_nssa_refresh (ospf, new, NULL);
2524 }
2525 }
pauld7480322003-05-16 17:31:51 +00002526#endif /* HAVE_NSSA */
2527
pauld4a53d52003-07-12 21:30:57 +00002528 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002529 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002530 */
paul8fc0f642003-07-13 01:36:06 +00002531 if (IS_LSA_SELF (new)
2532#ifdef HAVE_NSSA
2533 && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT )
2534#endif /* HAVE_NSSA */
2535 )
2536
paul68980082003-03-25 05:07:42 +00002537 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002538
2539 return new;
2540}
2541
2542void
paul68980082003-03-25 05:07:42 +00002543ospf_discard_from_db (struct ospf *ospf,
2544 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002545{
2546 struct ospf_lsa *old;
2547
2548 old = ospf_lsdb_lookup (lsdb, lsa);
2549
2550 if (!old)
2551 return;
2552
2553 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002554 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002555
2556 switch (old->data->type)
2557 {
2558 case OSPF_AS_EXTERNAL_LSA:
2559#ifdef HAVE_OPAQUE_LSA
2560 case OSPF_OPAQUE_AS_LSA:
2561#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002562 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2563 ospf_ase_unregister_external_lsa (old, ospf);
paul718e3742002-12-13 20:15:29 +00002564 break;
pauld7480322003-05-16 17:31:51 +00002565#ifdef HAVE_NSSA
2566 case OSPF_AS_NSSA_LSA:
2567 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2568 ospf_ase_unregister_external_lsa (old, ospf);
2569 break;
2570#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002571 default:
paul68980082003-03-25 05:07:42 +00002572 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002573 break;
2574 }
2575
paul68980082003-03-25 05:07:42 +00002576 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002577 ospf_lsa_discard (old);
2578}
2579
paul718e3742002-12-13 20:15:29 +00002580struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002581ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2582 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002583{
2584 struct ospf_lsa *new = NULL;
2585 struct ospf_lsa *old = NULL;
2586 struct ospf_lsdb *lsdb = NULL;
2587 int rt_recalc;
2588
2589 /* Set LSDB. */
2590 switch (lsa->data->type)
2591 {
paul68980082003-03-25 05:07:42 +00002592#ifdef HAVE_NSSA
paulf2c80652002-12-13 21:44:27 +00002593 /* kevinm */
2594 case OSPF_AS_NSSA_LSA:
2595 if (lsa->area)
2596 lsdb = lsa->area->lsdb;
2597 else
paul68980082003-03-25 05:07:42 +00002598 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002599 break;
paul68980082003-03-25 05:07:42 +00002600#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002601 case OSPF_AS_EXTERNAL_LSA:
2602#ifdef HAVE_OPAQUE_LSA
2603 case OSPF_OPAQUE_AS_LSA:
2604#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002605 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002606 break;
2607 default:
2608 lsdb = lsa->area->lsdb;
2609 break;
2610 }
2611
paul718e3742002-12-13 20:15:29 +00002612 assert (lsdb);
2613
2614 /* RFC 2328 13.2. Installing LSAs in the database
2615
2616 Installing a new LSA in the database, either as the result of
2617 flooding or a newly self-originated LSA, may cause the OSPF
2618 routing table structure to be recalculated. The contents of the
2619 new LSA should be compared to the old instance, if present. If
2620 there is no difference, there is no need to recalculate the
2621 routing table. When comparing an LSA to its previous instance,
2622 the following are all considered to be differences in contents:
2623
2624 o The LSA's Options field has changed.
2625
2626 o One of the LSA instances has LS age set to MaxAge, and
2627 the other does not.
2628
2629 o The length field in the LSA header has changed.
2630
2631 o The body of the LSA (i.e., anything outside the 20-byte
2632 LSA header) has changed. Note that this excludes changes
2633 in LS Sequence Number and LS Checksum.
2634
2635 */
2636 /* Look up old LSA and determine if any SPF calculation or incremental
2637 update is needed */
2638 old = ospf_lsdb_lookup (lsdb, lsa);
2639
2640 /* Do comparision and record if recalc needed. */
2641 rt_recalc = 0;
2642 if ( old == NULL || ospf_lsa_different(old, lsa))
2643 rt_recalc = 1;
2644
paul7ddf1d62003-10-13 09:06:46 +00002645 /*
2646 Sequence number check (Section 14.1 of rfc 2328)
2647 "Premature aging is used when it is time for a self-originated
2648 LSA's sequence number field to wrap. At this point, the current
2649 LSA instance (having LS sequence number MaxSequenceNumber) must
2650 be prematurely aged and flushed from the routing domain before a
2651 new instance with sequence number equal to InitialSequenceNumber
2652 can be originated. "
2653 */
2654
paul553ff112004-06-06 09:41:00 +00002655 if (ntohl(lsa->data->ls_seqnum) - 1 == htonl(OSPF_MAX_SEQUENCE_NUMBER))
paul7ddf1d62003-10-13 09:06:46 +00002656 {
2657 if (ospf_lsa_is_self_originated(ospf, lsa))
2658 {
paul0c2be262004-05-31 14:16:54 +00002659 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2660
2661 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002662 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2663 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2664
2665 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2666 {
2667 zlog_info ("ospf_lsa_install() Premature Aging "
2668 "lsa 0x%lx", (u_long)lsa);
2669 ospf_lsa_header_dump (lsa->data);
2670 }
2671 }
2672 else
2673 {
2674 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2675 {
2676 zlog_info ("ospf_lsa_install() got an lsa with seq 0x80000000 "
2677 "that was not self originated. Ignoring\n");
2678 ospf_lsa_header_dump (lsa->data);
2679 }
2680 return old;
2681 }
2682 }
2683
paul718e3742002-12-13 20:15:29 +00002684 /* discard old LSA from LSDB */
2685 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002686 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002687
2688 /* Insert LSA to LSDB. */
2689 ospf_lsdb_add (lsdb, lsa);
2690 lsa->lsdb = lsdb;
2691
2692 /* Calculate Checksum if self-originated?. */
2693 if (IS_LSA_SELF (lsa))
2694 ospf_lsa_checksum (lsa->data);
2695
2696 /* Do LSA specific installation process. */
2697 switch (lsa->data->type)
2698 {
2699 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002700 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002701 break;
2702 case OSPF_NETWORK_LSA:
2703 assert (oi);
paul68980082003-03-25 05:07:42 +00002704 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002705 break;
2706 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002707 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002708 break;
2709 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002710 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002711 break;
2712 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002713 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002714 break;
2715#ifdef HAVE_OPAQUE_LSA
2716 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002717 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002718 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002719 else
paul68980082003-03-25 05:07:42 +00002720 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002721 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002722 case OSPF_OPAQUE_AREA_LSA:
2723 case OSPF_OPAQUE_AS_LSA:
2724 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2725 break;
2726#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00002727#ifdef HAVE_NSSA
pauld4a53d52003-07-12 21:30:57 +00002728 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002729 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002730#endif /* HAVE_NSSA */
pauld4a53d52003-07-12 21:30:57 +00002731 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002732 break;
2733 }
2734
2735 if (new == NULL)
2736 return new; /* Installation failed, cannot proceed further -- endo. */
2737
2738 /* Debug logs. */
2739 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2740 {
2741 char area_str[INET_ADDRSTRLEN];
2742
2743 switch (lsa->data->type)
2744 {
2745 case OSPF_AS_EXTERNAL_LSA:
2746#ifdef HAVE_OPAQUE_LSA
2747 case OSPF_OPAQUE_AS_LSA:
2748#endif /* HAVE_OPAQUE_LSA */
paulf2c80652002-12-13 21:44:27 +00002749#ifdef HAVE_NSSA
2750 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002751#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002752 zlog_info ("LSA[%s]: Install %s",
2753 dump_lsa_key (new),
2754 LOOKUP (ospf_lsa_type_msg, new->data->type));
2755 break;
2756 default:
2757 strcpy (area_str, inet_ntoa (new->area->area_id));
2758 zlog_info ("LSA[%s]: Install %s to Area %s",
2759 dump_lsa_key (new),
2760 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2761 break;
2762 }
2763 }
2764
paul7ddf1d62003-10-13 09:06:46 +00002765 /*
2766 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2767 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2768 */
2769 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2770 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002771 {
paul7ddf1d62003-10-13 09:06:46 +00002772 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
paul0c2be262004-05-31 14:16:54 +00002773 zlog_info ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
2774 new->data->type,
2775 inet_ntoa (new->data->id),
2776 lsa);
paul68980082003-03-25 05:07:42 +00002777 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002778 }
2779
2780 return new;
2781}
2782
2783
2784int
paul68980082003-03-25 05:07:42 +00002785ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002786{
2787 listnode node;
2788
paul68980082003-03-25 05:07:42 +00002789 for (node = listhead (ospf->oiflist); node; node = nextnode (node))
paul718e3742002-12-13 20:15:29 +00002790 {
2791 struct ospf_interface *oi = getdata (node);
2792 struct route_node *rn;
2793 struct ospf_neighbor *nbr;
2794
2795 if (ospf_if_is_enable (oi))
2796 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2797 if ((nbr = rn->info) != NULL)
2798 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2799 {
2800 route_unlock_node (rn);
2801 return 0;
2802 }
2803 }
2804
2805 return 1;
2806}
2807
2808
2809#ifdef ORIGINAL_CODING
2810/* This function flood the maxaged LSA to DR. */
2811void
2812ospf_maxage_flood (struct ospf_lsa *lsa)
2813{
2814 switch (lsa->data->type)
2815 {
2816 case OSPF_ROUTER_LSA:
2817 case OSPF_NETWORK_LSA:
2818 case OSPF_SUMMARY_LSA:
2819 case OSPF_ASBR_SUMMARY_LSA:
2820#ifdef HAVE_NSSA
2821 case OSPF_AS_NSSA_LSA:
2822#endif /* HAVE_NSSA */
2823#ifdef HAVE_OPAQUE_LSA
2824 case OSPF_OPAQUE_LINK_LSA:
2825 case OSPF_OPAQUE_AREA_LSA:
2826#endif /* HAVE_OPAQUE_LSA */
2827 ospf_flood_through_area (lsa->area, NULL, lsa);
2828 break;
2829 case OSPF_AS_EXTERNAL_LSA:
2830#ifdef HAVE_OPAQUE_LSA
2831 case OSPF_OPAQUE_AS_LSA:
2832#endif /* HAVE_OPAQUE_LSA */
2833 ospf_flood_through_as (NULL, lsa);
2834 break;
2835 default:
2836 break;
2837 }
2838}
2839#endif /* ORIGINAL_CODING */
2840
2841int
2842ospf_maxage_lsa_remover (struct thread *thread)
2843{
paul68980082003-03-25 05:07:42 +00002844 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002845 listnode node;
2846 listnode next;
2847 int reschedule = 0;
2848
paul68980082003-03-25 05:07:42 +00002849 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002850
2851 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2852 zlog_info ("LSA[MaxAge]: remover Start");
2853
paul68980082003-03-25 05:07:42 +00002854 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002855
2856 if (!reschedule)
paul68980082003-03-25 05:07:42 +00002857 for (node = listhead (ospf->maxage_lsa); node; node = next)
paul718e3742002-12-13 20:15:29 +00002858 {
2859 struct ospf_lsa *lsa = getdata (node);
2860 next = node->next;
2861
2862 if (lsa->retransmit_counter > 0)
2863 {
2864 reschedule = 1;
2865 continue;
2866 }
2867
2868 /* Remove LSA from the LSDB */
2869 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2870 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
paul7ddf1d62003-10-13 09:06:46 +00002871 zlog_info ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
2872 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002873
2874 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2875 zlog_info ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2876 lsa->data->type, inet_ntoa (lsa->data->id));
2877
2878 /* Flood max age LSA. */
2879#ifdef ORIGINAL_CODING
2880 ospf_maxage_flood (lsa);
2881#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002882 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002883#endif /* ORIGINAL_CODING */
2884
paul7ddf1d62003-10-13 09:06:46 +00002885 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2886 {
2887 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2888 zlog_info ("originating new router lsa for lsa 0x%lx \n",
2889 (u_long)lsa);
2890 ospf_router_lsa_originate(lsa->area);
2891 }
2892
paul718e3742002-12-13 20:15:29 +00002893 /* Remove from lsdb. */
paul68980082003-03-25 05:07:42 +00002894 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002895 ospf_lsdb_delete (lsa->lsdb, lsa);
2896 }
2897
2898 /* A MaxAge LSA must be removed immediately from the router's link
2899 state database as soon as both a) it is no longer contained on any
2900 neighbor Link state retransmission lists and b) none of the router's
2901 neighbors are in states Exchange or Loading. */
2902 if (reschedule)
paul68980082003-03-25 05:07:42 +00002903 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002904
2905 return 0;
2906}
2907
2908int
paul68980082003-03-25 05:07:42 +00002909ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002910{
2911 listnode node;
2912
paul68980082003-03-25 05:07:42 +00002913 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002914 if (((struct ospf_lsa *) node->data) == new)
2915 return 1;
2916
2917 return 0;
2918}
2919
2920void
paul68980082003-03-25 05:07:42 +00002921ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002922{
2923 listnode n;
2924
paul68980082003-03-25 05:07:42 +00002925 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002926 {
paul68980082003-03-25 05:07:42 +00002927 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00002928 ospf_lsa_unlock (lsa);
2929 }
2930}
2931
2932void
paul68980082003-03-25 05:07:42 +00002933ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002934{
2935 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2936 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00002937 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002938 {
2939 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2940 zlog_info ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2941 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2942 return;
2943 }
2944
paul68980082003-03-25 05:07:42 +00002945 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00002946
2947 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2948 zlog_info ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
2949
paul68980082003-03-25 05:07:42 +00002950 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002951}
2952
2953int
paul68980082003-03-25 05:07:42 +00002954ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002955{
2956#ifdef HAVE_NSSA
2957 /* Stay away from any Local Translated Type-7 LSAs */
2958 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2959 return 0;
2960#endif /* HAVE_NSSA */
2961
2962 if (IS_LSA_MAXAGE (lsa))
2963 /* Self-originated LSAs should NOT time-out instead,
2964 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002965 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002966 {
2967 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2968 zlog_info("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
2969
2970 switch (lsa->data->type)
2971 {
paul718e3742002-12-13 20:15:29 +00002972#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002973 case OSPF_OPAQUE_LINK_LSA:
2974 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002975 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002976 /*
2977 * As a general rule, whenever network topology has changed
2978 * (due to an LSA removal in this case), routing recalculation
2979 * should be triggered. However, this is not true for opaque
2980 * LSAs. Even if an opaque LSA instance is going to be removed
2981 * from the routing domain, it does not mean a change in network
2982 * topology, and thus, routing recalculation is not needed here.
2983 */
2984 break;
paul718e3742002-12-13 20:15:29 +00002985#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002986 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002987#ifdef HAVE_NSSA
2988 case OSPF_AS_NSSA_LSA:
2989#endif /* HAVE_NSSA */
2990 ospf_ase_incremental_update (ospf, lsa);
2991 break;
paul718e3742002-12-13 20:15:29 +00002992 default:
paul68980082003-03-25 05:07:42 +00002993 ospf_spf_calculate_schedule (ospf);
2994 break;
paul718e3742002-12-13 20:15:29 +00002995 }
paul68980082003-03-25 05:07:42 +00002996 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002997 }
2998
2999 return 0;
3000}
3001
3002/* Periodical check of MaxAge LSA. */
3003int
paul68980082003-03-25 05:07:42 +00003004ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003005{
paul68980082003-03-25 05:07:42 +00003006 struct ospf *ospf = THREAD_ARG (thread);
3007 struct route_node *rn;
3008 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003009 listnode node;
3010
paul68980082003-03-25 05:07:42 +00003011 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003012
paul68980082003-03-25 05:07:42 +00003013 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00003014 {
3015 struct ospf_area *area = node->data;
3016
paul68980082003-03-25 05:07:42 +00003017 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3018 ospf_lsa_maxage_walker_remover (ospf, lsa);
3019 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3020 ospf_lsa_maxage_walker_remover (ospf, lsa);
3021 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3022 ospf_lsa_maxage_walker_remover (ospf, lsa);
3023 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3024 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003025#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003026 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3027 ospf_lsa_maxage_walker_remover (ospf, lsa);
3028 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3029 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003030#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003031#ifdef HAVE_NSSA
3032 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3033 ospf_lsa_maxage_walker_remover (ospf, lsa);
3034#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00003035 }
3036
paul4fb949e2003-05-10 20:06:51 +00003037 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003038 if (ospf->lsdb)
3039 {
3040 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3041 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003042#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003043 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3044 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003045#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003046 }
paul718e3742002-12-13 20:15:29 +00003047
paul68980082003-03-25 05:07:42 +00003048 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3049 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003050 return 0;
3051}
3052
paul68980082003-03-25 05:07:42 +00003053struct ospf_lsa *
3054ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3055 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003056{
paul68980082003-03-25 05:07:42 +00003057 struct ospf_lsa *lsa;
3058 struct in_addr mask, id;
3059 struct lsa_header_mask
3060 {
3061 struct lsa_header header;
3062 struct in_addr mask;
3063 } *hmask;
paul718e3742002-12-13 20:15:29 +00003064
paul68980082003-03-25 05:07:42 +00003065 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3066 if (lsa == NULL)
3067 return NULL;
paul718e3742002-12-13 20:15:29 +00003068
paul68980082003-03-25 05:07:42 +00003069 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003070
paul68980082003-03-25 05:07:42 +00003071 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003072
paul68980082003-03-25 05:07:42 +00003073 if (mask.s_addr != hmask->mask.s_addr)
3074 {
3075 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3076 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3077 if (!lsa)
3078 return NULL;
3079 }
paul718e3742002-12-13 20:15:29 +00003080
paul68980082003-03-25 05:07:42 +00003081 return lsa;
paul718e3742002-12-13 20:15:29 +00003082}
3083
3084struct ospf_lsa *
3085ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3086 struct in_addr id, struct in_addr adv_router)
3087{
paule05fba42003-04-13 20:20:53 +00003088 struct ospf *ospf = ospf_lookup();
3089 assert(ospf);
3090
paul718e3742002-12-13 20:15:29 +00003091 switch (type)
3092 {
3093 case OSPF_ROUTER_LSA:
3094 case OSPF_NETWORK_LSA:
3095 case OSPF_SUMMARY_LSA:
3096 case OSPF_ASBR_SUMMARY_LSA:
3097#ifdef HAVE_NSSA
3098 case OSPF_AS_NSSA_LSA:
3099#endif /* HAVE_NSSA */
3100#ifdef HAVE_OPAQUE_LSA
3101 case OSPF_OPAQUE_LINK_LSA:
3102 case OSPF_OPAQUE_AREA_LSA:
3103#endif /* HAVE_OPAQUE_LSA */
3104 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
3105 break;
3106 case OSPF_AS_EXTERNAL_LSA:
3107#ifdef HAVE_OPAQUE_LSA
3108 case OSPF_OPAQUE_AS_LSA:
3109#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003110 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003111 break;
3112 default:
3113 break;
3114 }
3115
3116 return NULL;
3117}
3118
3119struct ospf_lsa *
3120ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3121 struct in_addr id)
3122{
3123 struct ospf_lsa *lsa;
3124 struct route_node *rn;
3125
3126 switch (type)
3127 {
3128 case OSPF_ROUTER_LSA:
3129 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3130 break;
3131 case OSPF_NETWORK_LSA:
3132 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3133 if ((lsa = rn->info))
3134 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3135 {
3136 route_unlock_node (rn);
3137 return lsa;
3138 }
3139 break;
3140 case OSPF_SUMMARY_LSA:
3141 case OSPF_ASBR_SUMMARY_LSA:
3142 /* Currently not used. */
3143 assert (1);
3144 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3145 break;
3146 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003147 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003148#ifdef HAVE_OPAQUE_LSA
3149 case OSPF_OPAQUE_LINK_LSA:
3150 case OSPF_OPAQUE_AREA_LSA:
3151 case OSPF_OPAQUE_AS_LSA:
3152 /* Currently not used. */
3153 break;
3154#endif /* HAVE_OPAQUE_LSA */
3155 default:
3156 break;
3157 }
3158
3159 return NULL;
3160}
3161
3162struct ospf_lsa *
3163ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3164{
3165 struct ospf_lsa *match;
3166
3167#ifdef HAVE_OPAQUE_LSA
3168 /*
3169 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3170 * is redefined to have two subfields; opaque-type and opaque-id.
3171 * However, it is harmless to treat the two sub fields together, as if
3172 * they two were forming a unique LSA-ID.
3173 */
3174#endif /* HAVE_OPAQUE_LSA */
3175
3176 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3177
3178 if (match == NULL)
3179 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3180 zlog_info ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
3181 lsah->type, inet_ntoa (lsah->id));
3182
3183 return match;
3184}
3185
3186/* return +n, l1 is more recent.
3187 return -n, l2 is more recent.
3188 return 0, l1 and l2 is identical. */
3189int
3190ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3191{
3192 int r;
3193 int x, y;
3194
3195 if (l1 == NULL && l2 == NULL)
3196 return 0;
3197 if (l1 == NULL)
3198 return -1;
3199 if (l2 == NULL)
3200 return 1;
3201
3202 /* compare LS sequence number. */
3203 x = (int) ntohl (l1->data->ls_seqnum);
3204 y = (int) ntohl (l2->data->ls_seqnum);
3205 if (x > y)
3206 return 1;
3207 if (x < y)
3208 return -1;
3209
3210 /* compare LS checksum. */
3211 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3212 if (r)
3213 return r;
3214
3215 /* compare LS age. */
3216 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3217 return 1;
3218 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3219 return -1;
3220
3221 /* compare LS age with MaxAgeDiff. */
3222 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3223 return -1;
3224 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3225 return 1;
3226
3227 /* LSAs are identical. */
3228 return 0;
3229}
3230
3231/* If two LSAs are different, return 1, otherwise return 0. */
3232int
3233ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3234{
3235 char *p1, *p2;
3236 assert (l1);
3237 assert (l2);
3238 assert (l1->data);
3239 assert (l2->data);
3240
3241 if (l1->data->options != l2->data->options)
3242 return 1;
3243
3244 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3245 return 1;
3246
3247 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3248 return 1;
3249
3250 if (l1->data->length != l2->data->length)
3251 return 1;
3252
3253 if (l1->data->length == 0)
3254 return 1;
3255
pauld1825832003-04-03 01:27:01 +00003256 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003257
3258 p1 = (char *) l1->data;
3259 p2 = (char *) l2->data;
3260
3261 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3262 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3263 return 1;
3264
3265 return 0;
3266}
3267
3268#ifdef ORIGINAL_CODING
3269void
3270ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3271 struct ospf_lsa *self,
3272 struct ospf_lsa *new)
3273{
3274 u_int32_t seqnum;
3275
3276 /* Adjust LS Sequence Number. */
3277 seqnum = ntohl (new->data->ls_seqnum) + 1;
3278 self->data->ls_seqnum = htonl (seqnum);
3279
3280 /* Recalculate LSA checksum. */
3281 ospf_lsa_checksum (self->data);
3282
3283 /* Reflooding LSA. */
3284 /* RFC2328 Section 13.3
3285 On non-broadcast networks, separate Link State Update
3286 packets must be sent, as unicasts, to each adjacent neighbor
3287 (i.e., those in state Exchange or greater). The destination
3288 IP addresses for these packets are the neighbors' IP
3289 addresses. */
3290 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3291 {
3292 struct route_node *rn;
3293 struct ospf_neighbor *onbr;
3294
3295 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3296 if ((onbr = rn->info) != NULL)
3297 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3298 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3299 }
3300 else
3301 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3302
3303 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3304 zlog_info ("LSA[Type%d:%s]: Flush self-originated LSA",
3305 self->data->type, inet_ntoa (self->data->id));
3306}
3307#else /* ORIGINAL_CODING */
3308static int
paul68980082003-03-25 05:07:42 +00003309ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003310{
3311 if (lsa == NULL || !IS_LSA_SELF (lsa))
3312 return 0;
3313
3314 if (IS_DEBUG_OSPF_EVENT)
3315 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3316
3317 /* Force given lsa's age to MaxAge. */
3318 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3319
3320 switch (lsa->data->type)
3321 {
3322#ifdef HAVE_OPAQUE_LSA
3323 case OSPF_OPAQUE_LINK_LSA:
3324 case OSPF_OPAQUE_AREA_LSA:
3325 case OSPF_OPAQUE_AS_LSA:
3326 ospf_opaque_lsa_refresh (lsa);
3327 break;
3328#endif /* HAVE_OPAQUE_LSA */
3329 default:
paul68980082003-03-25 05:07:42 +00003330 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003331 break;
3332 }
3333
3334 return 0;
3335}
3336
3337void
paul68980082003-03-25 05:07:42 +00003338ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003339{
3340 listnode n1, n2;
3341 struct ospf_area *area;
3342 struct ospf_interface *oi;
3343 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003344 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003345 int need_to_flush_ase = 0;
3346
paul68980082003-03-25 05:07:42 +00003347 for (n1 = listhead (ospf->areas); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00003348 {
3349 if ((area = getdata (n1)) == NULL)
3350 continue;
3351
3352 if ((lsa = area->router_lsa_self) != NULL)
3353 {
3354 if (IS_DEBUG_OSPF_EVENT)
3355 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3356
3357 ospf_lsa_flush_area (lsa, area);
3358 ospf_lsa_unlock (area->router_lsa_self);
3359 area->router_lsa_self = NULL;
3360 OSPF_TIMER_OFF (area->t_router_lsa_self);
3361 }
3362
3363 for (n2 = listhead (area->oiflist); n2; nextnode (n2))
3364 {
3365 if ((oi = getdata (n2)) == NULL)
3366 continue;
3367
3368 if ((lsa = oi->network_lsa_self) != NULL
3369 && oi->state == ISM_DR
3370 && oi->full_nbrs > 0)
3371 {
3372 if (IS_DEBUG_OSPF_EVENT)
3373 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3374
3375 ospf_lsa_flush_area (oi->network_lsa_self, area);
3376 ospf_lsa_unlock (oi->network_lsa_self);
3377 oi->network_lsa_self = NULL;
3378 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3379 }
3380
3381 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3382 && area->external_routing == OSPF_AREA_DEFAULT)
3383 need_to_flush_ase = 1;
3384 }
3385
paul68980082003-03-25 05:07:42 +00003386 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3387 ospf_lsa_flush_schedule (ospf, lsa);
3388 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3389 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003390#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003391 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3392 ospf_lsa_flush_schedule (ospf, lsa);
3393 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3394 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003395#endif /* HAVE_OPAQUE_LSA */
3396 }
3397
3398 if (need_to_flush_ase)
3399 {
paul68980082003-03-25 05:07:42 +00003400 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3401 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003402#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003403 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3404 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003405#endif /* HAVE_OPAQUE_LSA */
3406 }
3407
3408 /*
3409 * Make sure that the MaxAge LSA remover is executed immediately,
3410 * without conflicting to other threads.
3411 */
paul68980082003-03-25 05:07:42 +00003412 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003413 {
paul68980082003-03-25 05:07:42 +00003414 OSPF_TIMER_OFF (ospf->t_maxage);
3415 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003416 }
3417
3418 return;
3419}
3420#endif /* ORIGINAL_CODING */
3421
3422/* If there is self-originated LSA, then return 1, otherwise return 0. */
3423/* An interface-independent version of ospf_lsa_is_self_originated */
3424int
paul68980082003-03-25 05:07:42 +00003425ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003426{
3427 listnode node;
3428
3429 /* This LSA is already checked. */
3430 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3431 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3432
3433 /* Make sure LSA is self-checked. */
3434 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3435
3436 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003437 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003438 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3439
3440 /* LSA is router-LSA. */
3441 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003442 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003443 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3444
3445 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3446 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul68980082003-03-25 05:07:42 +00003447 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00003448 {
3449 struct ospf_interface *oi = getdata (node);
3450
3451 /* Ignore virtual link. */
3452 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3453 if (oi->address->family == AF_INET)
3454 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3455 {
3456 /* to make it easier later */
3457 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3458 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3459 }
3460 }
3461
3462 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3463}
3464
3465/* Get unique Link State ID. */
3466struct in_addr
paul68980082003-03-25 05:07:42 +00003467ospf_lsa_unique_id (struct ospf *ospf,
3468 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003469{
3470 struct ospf_lsa *lsa;
3471 struct in_addr mask, id;
3472
3473 id = p->prefix;
3474
3475 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003476 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003477 if (lsa)
3478 {
3479 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3480 if (ip_masklen (al->mask) == p->prefixlen)
3481 {
3482 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3483 zlog_warn ("ospf_lsa_unique_id(): "
3484 "Can't get Link State ID for %s/%d",
3485 inet_ntoa (p->prefix), p->prefixlen);
3486 /* id.s_addr = 0; */
3487 id.s_addr = 0xffffffff;
3488 return id;
3489 }
3490 /* Masklen differs, then apply wildcard mask to Link State ID. */
3491 else
3492 {
3493 masklen2ip (p->prefixlen, &mask);
3494
3495 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003496 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3497 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003498 if (lsa)
3499 {
3500 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3501 zlog_warn ("ospf_lsa_unique_id(): "
3502 "Can't get Link State ID for %s/%d",
3503 inet_ntoa (p->prefix), p->prefixlen);
3504 /* id.s_addr = 0; */
3505 id.s_addr = 0xffffffff;
3506 return id;
3507 }
3508 }
3509 }
3510
3511 return id;
3512}
3513
3514
3515#define LSA_ACTION_ORIGN_RTR 1
3516#define LSA_ACTION_ORIGN_NET 2
3517#define LSA_ACTION_FLOOD_AREA 3
3518#define LSA_ACTION_FLOOD_AS 4
3519#define LSA_ACTION_FLUSH_AREA 5
3520#define LSA_ACTION_FLUSH_AS 6
3521
3522struct lsa_action
3523{
3524 u_char action;
3525 struct ospf_area *area;
3526 struct ospf_interface *oi;
3527 struct ospf_lsa *lsa;
3528};
3529
3530int
3531ospf_lsa_action (struct thread *t)
3532{
3533 struct lsa_action *data;
paul020709f2003-04-04 02:44:16 +00003534 struct ospf *ospf;
3535
3536 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00003537
3538 data = THREAD_ARG (t);
3539
3540 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3541 zlog_info ("LSA[Action]: Performing scheduled LSA action: %d",
3542 data->action);
3543
3544 switch (data->action)
3545 {
3546 case LSA_ACTION_ORIGN_RTR:
3547 ospf_router_lsa_refresh (data->area->router_lsa_self);
3548 break;
3549 case LSA_ACTION_ORIGN_NET:
3550 ospf_network_lsa_originate (data->oi);
3551 break;
3552 case LSA_ACTION_FLOOD_AREA:
3553 ospf_flood_through_area (data->area, NULL, data->lsa);
3554 break;
3555 case LSA_ACTION_FLOOD_AS:
paul68980082003-03-25 05:07:42 +00003556 ospf_flood_through_as (ospf, NULL, data->lsa);
paul718e3742002-12-13 20:15:29 +00003557 break;
3558 case LSA_ACTION_FLUSH_AREA:
3559 ospf_lsa_flush_area (data->lsa, data->area);
3560 break;
3561 case LSA_ACTION_FLUSH_AS:
paul68980082003-03-25 05:07:42 +00003562 ospf_lsa_flush_as (ospf, data->lsa);
paul718e3742002-12-13 20:15:29 +00003563 break;
3564 }
3565
3566 ospf_lsa_unlock (data->lsa);
3567 XFREE (MTYPE_OSPF_MESSAGE, data);
3568 return 0;
3569}
3570
3571void
3572ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3573{
3574 struct lsa_action *data;
3575
3576 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3577 memset (data, 0, sizeof (struct lsa_action));
3578
3579 data->action = LSA_ACTION_FLOOD_AREA;
3580 data->area = area;
3581 data->lsa = ospf_lsa_lock (lsa);
3582
3583 thread_add_event (master, ospf_lsa_action, data, 0);
3584}
3585
3586void
3587ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3588{
3589 struct lsa_action *data;
3590
3591 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3592 memset (data, 0, sizeof (struct lsa_action));
3593
3594 data->action = LSA_ACTION_FLUSH_AREA;
3595 data->area = area;
3596 data->lsa = ospf_lsa_lock (lsa);
3597
3598 thread_add_event (master, ospf_lsa_action, data, 0);
3599}
3600
3601
3602/* LSA Refreshment functions. */
3603void
paul68980082003-03-25 05:07:42 +00003604ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003605{
3606 struct external_info *ei;
3607 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3608
3609 switch (lsa->data->type)
3610 {
3611 /* Router and Network LSAs are processed differently. */
3612 case OSPF_ROUTER_LSA:
3613 case OSPF_NETWORK_LSA:
3614 break;
3615 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003616 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003617 break;
3618 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003619 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003620 break;
3621 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003622#ifdef HAVE_NSSA
3623 /* Translated from NSSA Type-5s are refreshed when
3624 * from refresh of Type-7 - do not refresh these directly.
3625 */
3626 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3627 break;
3628#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00003629 ei = ospf_external_info_check (lsa);
3630 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003631 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003632 else
pauld4a53d52003-07-12 21:30:57 +00003633 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003634 break;
3635#ifdef HAVE_OPAQUE_LSA
3636 case OSPF_OPAQUE_LINK_LSA:
3637 case OSPF_OPAQUE_AREA_LSA:
3638 case OSPF_OPAQUE_AS_LSA:
3639 ospf_opaque_lsa_refresh (lsa);
3640 break;
pauld7480322003-05-16 17:31:51 +00003641#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003642 default:
3643 break;
paul718e3742002-12-13 20:15:29 +00003644 }
3645}
3646
3647void
paul68980082003-03-25 05:07:42 +00003648ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003649{
3650 u_int16_t index, current_index;
3651
3652 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3653
3654 if (lsa->refresh_list < 0)
3655 {
3656 int delay;
3657
3658 if (LS_AGE (lsa) == 0 &&
3659 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3660 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3661 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3662 else
3663 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3664 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3665 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3666
3667 if (delay < 0)
3668 delay = 0;
3669
paul68980082003-03-25 05:07:42 +00003670 current_index = ospf->lsa_refresh_queue.index +
3671 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003672
3673 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3674 % (OSPF_LSA_REFRESHER_SLOTS);
3675
3676 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
pauld4a53d52003-07-12 21:30:57 +00003677 zlog_info ("LSA[Refresh]: lsa %s with age %d added to index %d",
3678 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003679 if (!ospf->lsa_refresh_queue.qs[index])
3680 ospf->lsa_refresh_queue.qs[index] = list_new ();
3681 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003682 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003683 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
pauld4a53d52003-07-12 21:30:57 +00003684 zlog_info ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
3685 "setting refresh_list on lsa %p (slod %d)",
3686 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003687 }
3688}
3689
3690void
paul68980082003-03-25 05:07:42 +00003691ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003692{
3693 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3694 if (lsa->refresh_list >= 0)
3695 {
paul68980082003-03-25 05:07:42 +00003696 list refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003697 listnode_delete (refresh_list, lsa);
3698 if (!listcount (refresh_list))
3699 {
3700 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003701 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003702 }
3703 ospf_lsa_unlock (lsa);
3704 lsa->refresh_list = -1;
3705 }
3706}
3707
3708int
3709ospf_lsa_refresh_walker (struct thread *t)
3710{
3711 list refresh_list;
3712 listnode node;
paul68980082003-03-25 05:07:42 +00003713 struct ospf *ospf = THREAD_ARG (t);
paul718e3742002-12-13 20:15:29 +00003714 int i;
3715 list lsa_to_refresh = list_new ();
3716
3717 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3718 zlog_info ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3719
3720
paul68980082003-03-25 05:07:42 +00003721 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003722
paul68980082003-03-25 05:07:42 +00003723 ospf->lsa_refresh_queue.index =
3724 (ospf->lsa_refresh_queue.index +
3725 (time (NULL) - ospf->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
paul718e3742002-12-13 20:15:29 +00003726 % OSPF_LSA_REFRESHER_SLOTS;
3727
3728 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3729 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003730 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003731
paul68980082003-03-25 05:07:42 +00003732 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003733 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3734 {
3735 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
pauld4a53d52003-07-12 21:30:57 +00003736 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
3737 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003738
paul68980082003-03-25 05:07:42 +00003739 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003740
paul68980082003-03-25 05:07:42 +00003741 ospf->lsa_refresh_queue.qs [i] = NULL;
3742
paul718e3742002-12-13 20:15:29 +00003743 if (refresh_list)
3744 {
3745 for (node = listhead (refresh_list); node;)
3746 {
3747 listnode next;
3748 struct ospf_lsa *lsa = getdata (node);
3749 next = node->next;
3750
3751 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
pauld4a53d52003-07-12 21:30:57 +00003752 zlog_info ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
3753 "refresh lsa %p (slot %d)",
3754 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003755
3756 list_delete_node (refresh_list, node);
3757 ospf_lsa_unlock (lsa);
3758 lsa->refresh_list = -1;
3759 listnode_add (lsa_to_refresh, lsa);
3760 node = next;
3761 }
3762 list_free (refresh_list);
3763 }
3764 }
3765
paul68980082003-03-25 05:07:42 +00003766 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3767 ospf, ospf->lsa_refresh_interval);
3768 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003769
3770 for (node = listhead (lsa_to_refresh); node; nextnode (node))
paul68980082003-03-25 05:07:42 +00003771 ospf_lsa_refresh (ospf, getdata (node));
paul718e3742002-12-13 20:15:29 +00003772
3773 list_delete (lsa_to_refresh);
3774
3775 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3776 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
3777
3778 return 0;
3779}
3780