]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_lsa.c
[lib] fix gensub call in memtypes.awk to pass "g", not g.
[mirror_frr.git] / ospfd / ospf_lsa.c
CommitLineData
718e3744 1/*
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\f
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\f
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))
e588f21f 152 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
718e3744 153 lsa->data->type, inet_ntoa (lsa->data->id), delay);
154
155 assert (delay > 0);
156 }
157
158 return delay;
159}
160
161\f
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\f
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;
c9e52be3 189 sp = (u_char *) &lsa->options;
718e3744 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\f
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
f2c80652 256 /* 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))
e588f21f 263 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
f2c80652 264
718e3744 265 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))
e588f21f 275 zlog_debug ("LSA: freed %p", lsa);
718e3744 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))
e588f21f 354 zlog_debug ("LSA[Type%d:%s]: data freed %p",
718e3744 355 lsah->type, inet_ntoa (lsah->id), lsah);
356
357 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
358}
359
360\f
361/* LSA general functions. */
362
363const char *
364dump_lsa_key (struct ospf_lsa *lsa)
365{
366 static char buf[] = {
52dc7ee6 367 "Type255,id(255.255.255.255),ar(255.255.255.255)"
718e3744 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,
68980084 397 u_char type, struct in_addr id, struct in_addr router_id)
718e3744 398{
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;
68980084 407 lsah->adv_router = router_id;
718e3744 408 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
409
9985f83c 410 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
718e3744 411}
412\f
68980084 413
718e3744 414/* router-LSA related functions. */
415/* Get router-LSA flags. */
4dadc291 416static u_char
718e3744 417router_lsa_flags (struct ospf_area *area)
418{
419 u_char flags;
420
68980084 421 flags = area->ospf->flags;
718e3744 422
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);
68980084 432 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
718e3744 433 if (!OSPF_IS_AREA_BACKBONE (area))
434 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
68980084 435 area->ospf->backbone == NULL) ||
718e3744 436 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)
942b6c19 441 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);
942b6c19 450 /* If Area is NSSA and we are both ABR and unconditional translator,
d4a53d58 451 * set Nt bit to inform other routers.
942b6c19 452 */
d4a53d58 453 if ( (area->external_routing == OSPF_AREA_NSSA)
454 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
455 SET_FLAG (flags, ROUTER_LSA_NT);
942b6c19 456 }
718e3744 457 return flags;
458}
459
460/* Lookup neighbor other than myself.
461 And check neighbor count,
462 Point-to-Point link must have only 1 neighbor. */
463struct ospf_neighbor *
68980084 464ospf_nbr_lookup_ptop (struct ospf_interface *oi)
718e3744 465{
718e3744 466 struct ospf_neighbor *nbr = NULL;
68980084 467 struct route_node *rn;
718e3744 468
469 /* Search neighbor, there must be one of two nbrs. */
68980084 470 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
471 if ((nbr = rn->info))
472 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
718e3744 473 if (nbr->state == NSM_Full)
68980084 474 {
475 route_unlock_node (rn);
476 break;
477 }
718e3744 478
479 /* PtoP link must have only 1 neighbor. */
68980084 480 if (ospf_nbr_count (oi, 0) > 1)
718e3744 481 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
482
483 return nbr;
484}
485
88d6cf37 486/* Determine cost of link, taking RFC3137 stub-router support into
487 * consideration
488 */
489static u_int16_t
490ospf_link_cost (struct ospf_interface *oi)
491{
492 /* RFC3137 stub router support */
493 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
494 return oi->output_cost;
495 else
496 return OSPF_OUTPUT_COST_INFINITE;
497}
498
718e3744 499/* Set a link information. */
779adb01 500static char
718e3744 501link_info_set (struct stream *s, struct in_addr id,
502 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
503{
779adb01 504 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
505 * vast majority of cases. Some rare routers with lots of links need more.
506 * we try accomodate those here.
507 */
508 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
509 {
510 size_t ret = OSPF_MAX_LSA_SIZE;
511
512 /* Can we enlarge the stream still? */
513 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
514 {
515 /* we futz the size here for simplicity, really we need to account
516 * for just:
517 * IP Header - (sizeof (struct ip))
518 * OSPF Header - OSPF_HEADER_SIZE
519 * LSA Header - OSPF_LSA_HEADER_SIZE
520 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
521 *
522 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
523 */
524 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
525 }
526
527 if (ret == OSPF_MAX_LSA_SIZE)
528 {
529 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
530 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
531 return 0;
532 }
533 }
534
718e3744 535 /* TOS based routing is not supported. */
536 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
537 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
538 stream_putc (s, type); /* Link Type. */
539 stream_putc (s, tos); /* TOS = 0. */
540 stream_putw (s, cost); /* Link Cost. */
779adb01 541
542 return 1;
718e3744 543}
544
545/* Describe Point-to-Point link. */
4dadc291 546static int
718e3744 547lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
548{
549 int links = 0;
550 struct ospf_neighbor *nbr;
551 struct in_addr id, mask;
88d6cf37 552 u_int16_t cost = ospf_link_cost (oi);
718e3744 553
554 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 555 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
718e3744 556
68980084 557 if ((nbr = ospf_nbr_lookup_ptop (oi)))
718e3744 558 if (nbr->state == NSM_Full)
559 {
560 /* For unnumbered point-to-point networks, the Link Data field
561 should specify the interface's MIB-II ifIndex value. */
779adb01 562 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
563 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
718e3744 564 }
565
3fb9cd6e 566 if (CONNECTED_DEST_HOST(oi->connected))
718e3744 567 {
568 /* Option 1:
569 link_type = LSA_LINK_TYPE_STUB;
570 link_id = nbr->address.u.prefix4;
571 link_data.s_addr = 0xffffffff;
572 link_cost = o->output_cost; */
573
574 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
575 mask.s_addr = 0xffffffff;
779adb01 576 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
577 oi->output_cost);
718e3744 578 }
579 else
580 {
581 /* Option 2: We need to include link to a stub
582 network regardless of the state of the neighbor */
583 masklen2ip (oi->address->prefixlen, &mask);
584 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
779adb01 585 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
586 oi->output_cost);
718e3744 587 }
718e3744 588 return links;
589}
590
591/* Describe Broadcast Link. */
4dadc291 592static int
718e3744 593lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
594{
595 struct ospf_neighbor *dr;
596 struct in_addr id, mask;
88d6cf37 597 u_int16_t cost = ospf_link_cost (oi);
598
718e3744 599 /* Describe Type 3 Link. */
600 if (oi->state == ISM_Waiting)
601 {
602 masklen2ip (oi->address->prefixlen, &mask);
603 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
779adb01 604 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
605 oi->output_cost);
718e3744 606 }
607
608 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
609 /* Describe Type 2 link. */
610 if (dr && (dr->state == NSM_Full ||
611 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
68980084 612 ospf_nbr_count (oi, NSM_Full) > 0)
718e3744 613 {
779adb01 614 return link_info_set (s, DR (oi), oi->address->u.prefix4,
615 LSA_LINK_TYPE_TRANSIT, 0, cost);
718e3744 616 }
617 /* Describe type 3 link. */
618 else
619 {
620 masklen2ip (oi->address->prefixlen, &mask);
621 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
779adb01 622 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
623 oi->output_cost);
718e3744 624 }
718e3744 625}
626
4dadc291 627static int
718e3744 628lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
629{
630 struct in_addr id, mask;
88d6cf37 631
718e3744 632 /* Describe Type 3 Link. */
633 if (oi->state != ISM_Loopback)
634 return 0;
635
636 mask.s_addr = 0xffffffff;
637 id.s_addr = oi->address->u.prefix4.s_addr;
779adb01 638 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
718e3744 639}
640
641/* Describe Virtual Link. */
4dadc291 642static int
718e3744 643lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
644{
645 struct ospf_neighbor *nbr;
88d6cf37 646 u_int16_t cost = ospf_link_cost (oi);
718e3744 647
718e3744 648 if (oi->state == ISM_PointToPoint)
68980084 649 if ((nbr = ospf_nbr_lookup_ptop (oi)))
718e3744 650 if (nbr->state == NSM_Full)
651 {
779adb01 652 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
653 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
718e3744 654 }
655
656 return 0;
657}
658
659#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
660
7afa08da 661/* this function add for support point-to-multipoint ,see rfc2328
66212.4.1.4.*/
663/* from "edward rrr" <edward_rrr@hotmail.com>
664 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
4dadc291 665static int
68980084 666lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
7afa08da 667{
668 int links = 0;
669 struct route_node *rn;
670 struct ospf_neighbor *nbr = NULL;
671 struct in_addr id, mask;
88d6cf37 672 u_int16_t cost = ospf_link_cost (oi);
7afa08da 673
674 mask.s_addr = 0xffffffff;
675 id.s_addr = oi->address->u.prefix4.s_addr;
779adb01 676 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
7afa08da 677
1cc8f762 678 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 679 zlog_debug ("PointToMultipoint: running ptomultip_set");
7afa08da 680
681 /* Search neighbor, */
682 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
683 if ((nbr = rn->info) != NULL)
684 /* Ignore myself. */
68980084 685 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
7afa08da 686 if (nbr->state == NSM_Full)
687
688 {
779adb01 689 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
690 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
1cc8f762 691 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 692 zlog_debug ("PointToMultipoint: set link to %s",
1cc8f762 693 inet_ntoa(oi->address->u.prefix4));
7afa08da 694 }
695
696 return links;
7afa08da 697}
698
718e3744 699/* Set router-LSA link information. */
4dadc291 700static int
718e3744 701router_lsa_link_set (struct stream *s, struct ospf_area *area)
702{
52dc7ee6 703 struct listnode *node;
1eb8ef25 704 struct ospf_interface *oi;
718e3744 705 int links = 0;
706
1eb8ef25 707 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
718e3744 708 {
718e3744 709 struct interface *ifp = oi->ifp;
710
711 /* Check interface is up, OSPF is enable. */
2e3b2e47 712 if (if_is_operative (ifp))
718e3744 713 {
714 if (oi->state != ISM_Down)
715 {
716 /* Describe each link. */
717 switch (oi->type)
718 {
719 case OSPF_IFTYPE_POINTOPOINT:
720 links += lsa_link_ptop_set (s, oi);
721 break;
722 case OSPF_IFTYPE_BROADCAST:
723 links += lsa_link_broadcast_set (s, oi);
724 break;
725 case OSPF_IFTYPE_NBMA:
726 links += lsa_link_nbma_set (s, oi);
727 break;
728 case OSPF_IFTYPE_POINTOMULTIPOINT:
68980084 729 links += lsa_link_ptomp_set (s, oi);
718e3744 730 break;
731 case OSPF_IFTYPE_VIRTUALLINK:
732 links += lsa_link_virtuallink_set (s, oi);
733 break;
734 case OSPF_IFTYPE_LOOPBACK:
735 links += lsa_link_loopback_set (s, oi);
736 }
737 }
738 }
739 }
740
741 return links;
742}
743
744/* Set router-LSA body. */
4dadc291 745static void
718e3744 746ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
747{
748 unsigned long putp;
749 u_int16_t cnt;
750
751 /* Set flags. */
752 stream_putc (s, router_lsa_flags (area));
753
754 /* Set Zero fields. */
755 stream_putc (s, 0);
756
757 /* Keep pointer to # links. */
9985f83c 758 putp = stream_get_endp(s);
718e3744 759
760 /* Forward word */
761 stream_putw(s, 0);
762
763 /* Set all link information. */
764 cnt = router_lsa_link_set (s, area);
765
766 /* Set # of links here. */
767 stream_putw_at (s, putp, cnt);
768}
88d6cf37 769\f
770static int
771ospf_stub_router_timer (struct thread *t)
772{
773 struct ospf_area *area = THREAD_ARG (t);
774
775 area->t_stub_router = NULL;
776
777 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
778
779 /* clear stub route state and generate router-lsa refresh, don't
780 * clobber an administratively set stub-router state though.
781 */
782 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
783 return 0;
784
785 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
786
787 ospf_router_lsa_timer_add (area);
788
789 return 0;
790}
718e3744 791
88d6cf37 792inline static void
793ospf_stub_router_check (struct ospf_area *area)
794{
795 /* area must either be administratively configured to be stub
796 * or startup-time stub-router must be configured and we must in a pre-stub
797 * state.
798 */
799 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
800 {
801 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
802 return;
803 }
804
805 /* not admin-stubbed, check whether startup stubbing is configured and
806 * whether it's not been done yet
807 */
808 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
809 return;
810
811 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
812 {
813 /* stub-router is hence done forever for this area, even if someone
814 * tries configure it (take effect next restart).
815 */
816 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
817 return;
818 }
819
820 /* startup stub-router configured and not yet done */
821 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
822
823 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
824 area->ospf->stub_router_startup_time);
825}
826\f
718e3744 827/* Create new router-LSA. */
4dadc291 828static struct ospf_lsa *
718e3744 829ospf_router_lsa_new (struct ospf_area *area)
830{
68980084 831 struct ospf *ospf = area->ospf;
718e3744 832 struct stream *s;
833 struct lsa_header *lsah;
834 struct ospf_lsa *new;
835 int length;
836
837 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 838 zlog_debug ("LSA[Type1]: Create router-LSA instance");
718e3744 839
88d6cf37 840 /* check whether stub-router is desired, and if this is the first
841 * router LSA.
842 */
843 ospf_stub_router_check (area);
844
718e3744 845 /* Create a stream for LSA. */
846 s = stream_new (OSPF_MAX_LSA_SIZE);
718e3744 847 /* Set LSA common header fields. */
d4a53d58 848 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
d4a53d58 849 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
718e3744 850
851 /* Set router-LSA body fields. */
852 ospf_router_lsa_body_set (s, area);
853
854 /* Set length. */
855 length = stream_get_endp (s);
779adb01 856 lsah = (struct lsa_header *) STREAM_DATA (s);
718e3744 857 lsah->length = htons (length);
858
859 /* Now, create OSPF LSA instance. */
c24d602e 860 if ( (new = ospf_lsa_new ()) == NULL)
861 {
862 zlog_err ("%s: Unable to create new lsa", __func__);
863 return NULL;
864 }
865
718e3744 866 new->area = area;
867 SET_FLAG (new->flags, OSPF_LSA_SELF);
868
869 /* Copy LSA data to store, discard stream. */
870 new->data = ospf_lsa_data_new (length);
871 memcpy (new->data, lsah, length);
872 stream_free (s);
873
874 return new;
875}
876
877/* Originate Router-LSA. */
88d6cf37 878static struct ospf_lsa *
718e3744 879ospf_router_lsa_originate (struct ospf_area *area)
880{
881 struct ospf_lsa *new;
88d6cf37 882
718e3744 883 /* Create new router-LSA instance. */
c24d602e 884 if ( (new = ospf_router_lsa_new (area)) == NULL)
885 {
886 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
887 return NULL;
888 }
718e3744 889
890 /* Sanity check. */
891 if (new->data->adv_router.s_addr == 0)
892 {
893 if (IS_DEBUG_OSPF_EVENT)
e588f21f 894 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
718e3744 895 ospf_lsa_discard (new);
896 return NULL;
897 }
898
899 /* Install LSA to LSDB. */
68980084 900 new = ospf_lsa_install (area->ospf, NULL, new);
718e3744 901
902 /* Update LSA origination count. */
68980084 903 area->ospf->lsa_originate_count++;
718e3744 904
905 /* Flooding new LSA through area. */
906 ospf_flood_through_area (area, NULL, new);
907
908 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
909 {
e588f21f 910 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
718e3744 911 new->data->type, inet_ntoa (new->data->id), new);
912 ospf_lsa_header_dump (new->data);
913 }
914
915 return new;
916}
917
918/* Refresh router-LSA. */
4dadc291 919static struct ospf_lsa *
718e3744 920ospf_router_lsa_refresh (struct ospf_lsa *lsa)
921{
922 struct ospf_area *area = lsa->area;
923 struct ospf_lsa *new;
924
925 /* Sanity check. */
926 assert (lsa->data);
927
928 /* Delete LSA from neighbor retransmit-list. */
68980084 929 ospf_ls_retransmit_delete_nbr_area (area, lsa);
718e3744 930
931 /* Create new router-LSA instance. */
c24d602e 932 if ( (new = ospf_router_lsa_new (area)) == NULL)
933 {
934 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
935 return NULL;
936 }
937
718e3744 938 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
939
68980084 940 ospf_lsa_install (area->ospf, NULL, new);
718e3744 941
942 /* Flood LSA through area. */
943 ospf_flood_through_area (area, NULL, new);
944
945 /* Debug logging. */
946 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
947 {
e588f21f 948 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
718e3744 949 new->data->type, inet_ntoa (new->data->id));
950 ospf_lsa_header_dump (new->data);
951 }
952
953 return NULL;
954}
955
4dadc291 956static int
718e3744 957ospf_router_lsa_timer (struct thread *t)
958{
959 struct ospf_area *area;
960
961 if (IS_DEBUG_OSPF_EVENT)
e588f21f 962 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
718e3744 963
964 area = THREAD_ARG (t);
965 area->t_router_lsa_self = NULL;
966
967 /* Now refresh router-LSA. */
968 if (area->router_lsa_self)
969 ospf_router_lsa_refresh (area->router_lsa_self);
970 /* Newly originate router-LSA. */
971 else
972 ospf_router_lsa_originate (area);
973
974 return 0;
975}
976
977void
978ospf_router_lsa_timer_add (struct ospf_area *area)
979{
980 /* Keep area's self-originated router-LSA. */
981 struct ospf_lsa *lsa = area->router_lsa_self;
982
983 /* Cancel previously scheduled router-LSA timer. */
984 if (area->t_router_lsa_self)
985 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 986 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
718e3744 987
988 OSPF_TIMER_OFF (area->t_router_lsa_self);
989
990 /* If router-LSA is originated previously, check the interval time. */
991 if (lsa)
992 {
993 int delay;
994 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
995 {
996 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
997 ospf_router_lsa_timer, delay);
998 return;
999 }
1000 }
1001
1002 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1003 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
718e3744 1004
1005 /* Immediately refresh router-LSA. */
1006 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
1007}
1008
1009int
68980084 1010ospf_router_lsa_update_timer (struct thread *thread)
718e3744 1011{
68980084 1012 struct ospf *ospf = THREAD_ARG (thread);
1eb8ef25 1013 struct listnode *node, *nnode;
1014 struct ospf_area *area;
718e3744 1015
1016 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1017 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
718e3744 1018
68980084 1019 ospf->t_router_lsa_update = NULL;
718e3744 1020
1eb8ef25 1021 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 1022 {
718e3744 1023 struct ospf_lsa *lsa = area->router_lsa_self;
1024 struct router_lsa *rl;
eb1ce605 1025 const char *area_str;
718e3744 1026
1027 /* Keep Area ID string. */
1028 area_str = AREA_NAME (area);
1029
1030 /* If LSA not exist in this Area, originate new. */
1031 if (lsa == NULL)
1032 {
1033 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1034 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
718e3744 1035
1036 ospf_router_lsa_originate (area);
1037 }
1038 /* If router-ID is changed, Link ID must change.
1039 First flush old LSA, then originate new. */
68980084 1040 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
718e3744 1041 {
1042 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1043 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
718e3744 1044 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1045 ospf_lsa_flush_area (lsa, area);
1046 ospf_lsa_unlock (area->router_lsa_self);
1047 area->router_lsa_self = NULL;
1048
1049 /* Refresh router-LSA, (not install) and flood through area. */
1050 ospf_router_lsa_timer_add (area);
1051 }
1052 else
1053 {
1054 rl = (struct router_lsa *) lsa->data;
1055 /* Refresh router-LSA, (not install) and flood through area. */
68980084 1056 if (rl->flags != ospf->flags)
718e3744 1057 ospf_router_lsa_timer_add (area);
1058 }
1059 }
1060
1061 return 0;
1062}
1063
1064\f
1065/* network-LSA related functions. */
1066/* Originate Network-LSA. */
4dadc291 1067static void
718e3744 1068ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1069{
1070 struct in_addr mask;
1071 struct route_node *rn;
1072 struct ospf_neighbor *nbr;
1073
1074 masklen2ip (oi->address->prefixlen, &mask);
1075 stream_put_ipv4 (s, mask.s_addr);
1076
1077 /* The network-LSA lists those routers that are fully adjacent to
1078 the Designated Router; each fully adjacent router is identified by
1079 its OSPF Router ID. The Designated Router includes itself in this
1080 list. RFC2328, Section 12.4.2 */
1081
1082 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1083 if ((nbr = rn->info) != NULL)
1084 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1085 stream_put_ipv4 (s, nbr->router_id.s_addr);
1086}
1087
4dadc291 1088static struct ospf_lsa *
718e3744 1089ospf_network_lsa_new (struct ospf_interface *oi)
1090{
1091 struct stream *s;
1092 struct ospf_lsa *new;
1093 struct lsa_header *lsah;
1094 int length;
1095
1096 /* If there are no neighbours on this network (the net is stub),
1097 the router does not originate network-LSA (see RFC 12.4.2) */
1098 if (oi->full_nbrs == 0)
1099 return NULL;
1100
1101 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1102 zlog_debug ("LSA[Type2]: Create network-LSA instance");
718e3744 1103
1104 /* Create new stream for LSA. */
1105 s = stream_new (OSPF_MAX_LSA_SIZE);
1106 lsah = (struct lsa_header *) STREAM_DATA (s);
1107
1108 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
68980084 1109 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
718e3744 1110
1111 /* Set network-LSA body fields. */
1112 ospf_network_lsa_body_set (s, oi);
1113
1114 /* Set length. */
1115 length = stream_get_endp (s);
1116 lsah->length = htons (length);
1117
1118 /* Create OSPF LSA instance. */
c24d602e 1119 if ( (new = ospf_lsa_new ()) == NULL)
1120 {
1121 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1122 return NULL;
1123 }
1124
718e3744 1125 new->area = oi->area;
1126 SET_FLAG (new->flags, OSPF_LSA_SELF);
1127
1128 /* Copy LSA to store. */
1129 new->data = ospf_lsa_data_new (length);
1130 memcpy (new->data, lsah, length);
1131 stream_free (s);
1132
1133 return new;
1134}
1135
1136/* Originate network-LSA. */
4dadc291 1137static struct ospf_lsa *
718e3744 1138ospf_network_lsa_originate (struct ospf_interface *oi)
1139{
1140 struct ospf_lsa *new;
1141
1142 /* Create new network-LSA instance. */
1143 new = ospf_network_lsa_new (oi);
1144 if (new == NULL)
1145 return NULL;
1146
1147 /* Install LSA to LSDB. */
68980084 1148 new = ospf_lsa_install (oi->ospf, oi, new);
718e3744 1149
1150 /* Update LSA origination count. */
68980084 1151 oi->ospf->lsa_originate_count++;
718e3744 1152
1153 /* Flooding new LSA through area. */
1154 ospf_flood_through_area (oi->area, NULL, new);
1155
1156 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1157 {
e588f21f 1158 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
718e3744 1159 new->data->type, inet_ntoa (new->data->id), new);
1160 ospf_lsa_header_dump (new->data);
1161 }
1162
1163 return new;
1164}
1165
1166int
1167ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1168{
1169 struct ospf_area *area = lsa->area;
1170 struct ospf_lsa *new;
1171
1172 assert (lsa->data);
1173
1174 /* Delete LSA from neighbor retransmit-list. */
68980084 1175 ospf_ls_retransmit_delete_nbr_area (area, lsa);
718e3744 1176
1177 /* Create new network-LSA instance. */
1178 new = ospf_network_lsa_new (oi);
1179 if (new == NULL)
1180 return -1;
1181 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1182
68980084 1183 ospf_lsa_install (area->ospf, oi, new);
718e3744 1184
1185 /* Flood LSA through aera. */
1186 ospf_flood_through_area (area, NULL, new);
1187
1188 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1189 {
e588f21f 1190 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
718e3744 1191 new->data->type, inet_ntoa (new->data->id));
1192 ospf_lsa_header_dump (new->data);
1193 }
1194
1195 return 0;
1196}
1197
4dadc291 1198static int
718e3744 1199ospf_network_lsa_refresh_timer (struct thread *t)
1200{
1201 struct ospf_interface *oi;
1202
1203 oi = THREAD_ARG (t);
1204 oi->t_network_lsa_self = NULL;
1205
1206 if (oi->network_lsa_self)
1207 /* Now refresh network-LSA. */
1208 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1209 else
1210 /* Newly create network-LSA. */
1211 ospf_network_lsa_originate (oi);
1212
1213 return 0;
1214}
1215
1216void
1217ospf_network_lsa_timer_add (struct ospf_interface *oi)
1218{
1219 /* Keep interface's self-originated network-LSA. */
1220 struct ospf_lsa *lsa = oi->network_lsa_self;
1221
1222 /* Cancel previously schedules network-LSA timer. */
1223 if (oi->t_network_lsa_self)
1224 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1225 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
718e3744 1226 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1227
1228 /* If network-LSA is originated previously, check the interval time. */
1229 if (lsa)
1230 {
1231 int delay;
1232 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1233 {
1234 oi->t_network_lsa_self =
1235 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1236 oi, delay);
1237 return;
1238 }
1239 }
1240
1241 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1242 zlog_debug ("Scheduling network-LSA origination right away");
718e3744 1243
1244 /* Immediately refresh network-LSA. */
1245 oi->t_network_lsa_self =
1246 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1247}
1248
1249\f
4dadc291 1250static void
718e3744 1251stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1252{
1253 u_int32_t metric;
1254 char *mp;
1255
1256 /* Put 0 metric. TOS metric is not supported. */
1257 metric = htonl (metric_value);
1258 mp = (char *) &metric;
1259 mp++;
1260 stream_put (s, mp, 3);
1261}
1262
1263/* summary-LSA related functions. */
4dadc291 1264static void
718e3744 1265ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1266 u_int32_t metric)
1267{
1268 struct in_addr mask;
1269
1270 masklen2ip (p->prefixlen, &mask);
1271
1272 /* Put Network Mask. */
1273 stream_put_ipv4 (s, mask.s_addr);
1274
1275 /* Set # TOS. */
1276 stream_putc (s, (u_char) 0);
1277
1278 /* Set metric. */
1279 stream_put_ospf_metric (s, metric);
1280}
1281
4dadc291 1282static struct ospf_lsa *
718e3744 1283ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1284 u_int32_t metric, struct in_addr id)
1285{
1286 struct stream *s;
1287 struct ospf_lsa *new;
1288 struct lsa_header *lsah;
1289 int length;
1290
c24d602e 1291 if (id.s_addr == 0xffffffff)
1292 {
1293 /* Maybe Link State ID not available. */
1294 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1295 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1296 OSPF_SUMMARY_LSA);
1297 return NULL;
1298 }
1299
718e3744 1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1301 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
718e3744 1302
1303 /* Create new stream for LSA. */
1304 s = stream_new (OSPF_MAX_LSA_SIZE);
1305 lsah = (struct lsa_header *) STREAM_DATA (s);
1306
68980084 1307 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1308 id, area->ospf->router_id);
718e3744 1309
1310 /* Set summary-LSA body fields. */
1311 ospf_summary_lsa_body_set (s, p, metric);
1312
1313 /* Set length. */
1314 length = stream_get_endp (s);
1315 lsah->length = htons (length);
1316
1317 /* Create OSPF LSA instance. */
1318 new = ospf_lsa_new ();
1319 new->area = area;
1320 SET_FLAG (new->flags, OSPF_LSA_SELF);
1321
1322 /* Copy LSA to store. */
1323 new->data = ospf_lsa_data_new (length);
1324 memcpy (new->data, lsah, length);
1325 stream_free (s);
1326
1327 return new;
1328}
1329
1330/* Originate Summary-LSA. */
1331struct ospf_lsa *
1332ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1333 struct ospf_area *area)
1334{
1335 struct ospf_lsa *new;
1336 struct in_addr id;
1337
68980084 1338 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
718e3744 1339
c24d602e 1340 if (id.s_addr == 0xffffffff)
1341 {
1342 /* Maybe Link State ID not available. */
1343 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1344 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1345 OSPF_SUMMARY_LSA);
1346 return NULL;
1347 }
1348
718e3744 1349 /* Create new summary-LSA instance. */
c24d602e 1350 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1351 return NULL;
718e3744 1352
1353 /* Instlal LSA to LSDB. */
68980084 1354 new = ospf_lsa_install (area->ospf, NULL, new);
718e3744 1355
1356 /* Update LSA origination count. */
68980084 1357 area->ospf->lsa_originate_count++;
718e3744 1358
1359 /* Flooding new LSA through area. */
1360 ospf_flood_through_area (area, NULL, new);
1361
1362 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1363 {
e588f21f 1364 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
718e3744 1365 new->data->type, inet_ntoa (new->data->id), new);
1366 ospf_lsa_header_dump (new->data);
1367 }
1368
1369 return new;
1370}
1371
1372struct ospf_lsa*
68980084 1373ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 1374{
1375 struct ospf_lsa *new;
1376 struct summary_lsa *sl;
1377 struct prefix p;
1378
1379 /* Sanity check. */
1380 assert (lsa->data);
1381
1382 sl = (struct summary_lsa *)lsa->data;
1383 p.prefixlen = ip_masklen (sl->mask);
1384 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1385 sl->header.id);
c24d602e 1386
1387 if (!new)
1388 return NULL;
1389
718e3744 1390 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1391
1392 /* Re-calculate checksum. */
1393 ospf_lsa_checksum (new->data);
1394
68980084 1395 ospf_lsa_install (ospf, NULL, new);
718e3744 1396
1397 /* Flood LSA through AS. */
1398 ospf_flood_through_area (new->area, NULL, new);
1399
1400 /* Debug logging. */
1401 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1402 {
e588f21f 1403 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
718e3744 1404 new->data->type, inet_ntoa (new->data->id));
1405 ospf_lsa_header_dump (new->data);
1406 }
1407
1408 return new;
1409}
1410
1411\f
1412/* summary-ASBR-LSA related functions. */
4dadc291 1413static void
718e3744 1414ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1415 u_int32_t metric)
1416{
1417 struct in_addr mask;
1418
1419 masklen2ip (p->prefixlen, &mask);
1420
1421 /* Put Network Mask. */
1422 stream_put_ipv4 (s, mask.s_addr);
1423
1424 /* Set # TOS. */
1425 stream_putc (s, (u_char) 0);
1426
1427 /* Set metric. */
1428 stream_put_ospf_metric (s, metric);
1429}
1430
4dadc291 1431static struct ospf_lsa *
718e3744 1432ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1433 u_int32_t metric, struct in_addr id)
1434{
1435 struct stream *s;
1436 struct ospf_lsa *new;
1437 struct lsa_header *lsah;
1438 int length;
1439
c24d602e 1440 if (id.s_addr == 0xffffffff)
1441 {
1442 /* Maybe Link State ID not available. */
1443 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1444 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1445 OSPF_ASBR_SUMMARY_LSA);
1446 return NULL;
1447 }
1448
718e3744 1449 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1450 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
718e3744 1451
1452 /* Create new stream for LSA. */
1453 s = stream_new (OSPF_MAX_LSA_SIZE);
1454 lsah = (struct lsa_header *) STREAM_DATA (s);
1455
68980084 1456 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1457 id, area->ospf->router_id);
718e3744 1458
1459 /* Set summary-LSA body fields. */
1460 ospf_summary_asbr_lsa_body_set (s, p, metric);
1461
1462 /* Set length. */
1463 length = stream_get_endp (s);
1464 lsah->length = htons (length);
1465
1466 /* Create OSPF LSA instance. */
1467 new = ospf_lsa_new ();
1468 new->area = area;
1469 SET_FLAG (new->flags, OSPF_LSA_SELF);
1470
1471 /* Copy LSA to store. */
1472 new->data = ospf_lsa_data_new (length);
1473 memcpy (new->data, lsah, length);
1474 stream_free (s);
1475
1476 return new;
1477}
1478
1479/* Originate summary-ASBR-LSA. */
1480struct ospf_lsa *
1481ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1482 struct ospf_area *area)
1483{
1484 struct ospf_lsa *new;
1485 struct in_addr id;
1486
68980084 1487 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
718e3744 1488
c24d602e 1489 if (id.s_addr == 0xffffffff)
1490 {
1491 /* Maybe Link State ID not available. */
1492 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1493 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1494 OSPF_ASBR_SUMMARY_LSA);
1495 return NULL;
1496 }
1497
718e3744 1498 /* Create new summary-LSA instance. */
1499 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
c24d602e 1500 if (!new)
1501 return NULL;
718e3744 1502
1503 /* Install LSA to LSDB. */
68980084 1504 new = ospf_lsa_install (area->ospf, NULL, new);
718e3744 1505
1506 /* Update LSA origination count. */
68980084 1507 area->ospf->lsa_originate_count++;
718e3744 1508
1509 /* Flooding new LSA through area. */
1510 ospf_flood_through_area (area, NULL, new);
1511
1512 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1513 {
e588f21f 1514 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
718e3744 1515 new->data->type, inet_ntoa (new->data->id), new);
1516 ospf_lsa_header_dump (new->data);
1517 }
1518
1519 return new;
1520}
1521
1522struct ospf_lsa*
68980084 1523ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 1524{
1525 struct ospf_lsa *new;
1526 struct summary_lsa *sl;
1527 struct prefix p;
1528
1529 /* Sanity check. */
1530 assert (lsa->data);
1531
1532 sl = (struct summary_lsa *)lsa->data;
1533 p.prefixlen = ip_masklen (sl->mask);
1534 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1535 sl->header.id);
c24d602e 1536 if (!new)
1537 return NULL;
718e3744 1538
1539 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1540
1541 /* Re-calculate checksum. */
1542 ospf_lsa_checksum (new->data);
1543
68980084 1544 ospf_lsa_install (ospf, NULL, new);
718e3744 1545
1546 /* Flood LSA through area. */
1547 ospf_flood_through_area (new->area, NULL, new);
1548
1549 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1550 {
e588f21f 1551 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
718e3744 1552 new->data->type, inet_ntoa (new->data->id));
1553 ospf_lsa_header_dump (new->data);
1554 }
1555
1556 return new;
1557}
1558
1559/* AS-external-LSA related functions. */
1560
1561/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1562 is connected, else 0*/
4dadc291 1563static struct in_addr
68980084 1564ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
718e3744 1565{
1566 struct in_addr fwd;
1567 struct prefix nh;
1eb8ef25 1568 struct listnode *node;
1569 struct ospf_interface *oi;
718e3744 1570
1571 fwd.s_addr = 0;
1572
1573 if (!nexthop.s_addr)
1574 return fwd;
1575
1576 /* Check whether nexthop is covered by OSPF network. */
1577 nh.family = AF_INET;
1578 nh.u.prefix4 = nexthop;
1579 nh.prefixlen = IPV4_MAX_BITLEN;
1580
1eb8ef25 1581 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1582 if (if_is_operative (oi->ifp))
1583 if (oi->address->family == AF_INET)
1584 if (prefix_match (oi->address, &nh))
1585 return nexthop;
718e3744 1586
1587 return fwd;
1588}
1589
718e3744 1590/* NSSA-external-LSA related functions. */
1591
1592/* Get 1st IP connection for Forward Addr */
4dadc291 1593
718e3744 1594struct in_addr
1595ospf_get_ip_from_ifp (struct ospf_interface *oi)
1596{
1597 struct in_addr fwd;
1598
1599 fwd.s_addr = 0;
1600
2e3b2e47 1601 if (if_is_operative (oi->ifp))
718e3744 1602 return oi->address->u.prefix4;
1603
1604 return fwd;
1605}
1606
1607/* Get 1st IP connection for Forward Addr */
1608struct in_addr
f2c80652 1609ospf_get_nssa_ip (struct ospf_area *area)
718e3744 1610{
1611 struct in_addr fwd;
f2c80652 1612 struct in_addr best_default;
1eb8ef25 1613 struct listnode *node;
1614 struct ospf_interface *oi;
718e3744 1615
1616 fwd.s_addr = 0;
f2c80652 1617 best_default.s_addr = 0;
718e3744 1618
1eb8ef25 1619 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
718e3744 1620 {
2e3b2e47 1621 if (if_is_operative (oi->ifp))
718e3744 1622 if (oi->area->external_routing == OSPF_AREA_NSSA)
68980084 1623 if (oi->address && oi->address->family == AF_INET)
1624 {
1625 if (best_default.s_addr == 0)
1626 best_default = oi->address->u.prefix4;
1627 if (oi->area == area)
1628 return oi->address->u.prefix4;
f2c80652 1629 }
718e3744 1630 }
f2c80652 1631 if (best_default.s_addr != 0)
1632 return best_default;
718e3744 1633
68980084 1634 if (best_default.s_addr != 0)
1635 return best_default;
1636
718e3744 1637 return fwd;
1638}
beebba75 1639
718e3744 1640#define DEFAULT_DEFAULT_METRIC 20
1641#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1642#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1643
1644#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1645
1646int
68980084 1647metric_type (struct ospf *ospf, u_char src)
718e3744 1648{
68980084 1649 return (ospf->dmetric[src].type < 0 ?
1650 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
718e3744 1651}
1652
1653int
68980084 1654metric_value (struct ospf *ospf, u_char src)
718e3744 1655{
68980084 1656 if (ospf->dmetric[src].value < 0)
718e3744 1657 {
1658 if (src == DEFAULT_ROUTE)
1659 {
68980084 1660 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
718e3744 1661 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1662 else
1663 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1664 }
68980084 1665 else if (ospf->default_metric < 0)
718e3744 1666 return DEFAULT_DEFAULT_METRIC;
1667 else
68980084 1668 return ospf->default_metric;
718e3744 1669 }
1670
68980084 1671 return ospf->dmetric[src].value;
718e3744 1672}
1673
1674/* Set AS-external-LSA body. */
4dadc291 1675static void
68980084 1676ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1677 struct ospf *ospf)
718e3744 1678{
1679 struct prefix_ipv4 *p = &ei->p;
1680 struct in_addr mask, fwd_addr;
1681 u_int32_t mvalue;
1682 int mtype;
1683 int type;
1684
1685 /* Put Network Mask. */
1686 masklen2ip (p->prefixlen, &mask);
1687 stream_put_ipv4 (s, mask.s_addr);
1688
1689 /* If prefix is default, specify DEFAULT_ROUTE. */
1690 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1691
1692 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
68980084 1693 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
718e3744 1694
1695 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
68980084 1696 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
718e3744 1697
1698 /* Put type of external metric. */
1699 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1700
1701 /* Put 0 metric. TOS metric is not supported. */
1702 stream_put_ospf_metric (s, mvalue);
1703
1704 /* Get forwarding address to nexthop if on the Connection List, else 0. */
68980084 1705 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
718e3744 1706
1707 /* Put forwarding address. */
1708 stream_put_ipv4 (s, fwd_addr.s_addr);
1709
1710 /* Put route tag -- This value should be introduced from configuration. */
1711 stream_putl (s, 0);
1712}
1713
1714/* Create new external-LSA. */
4dadc291 1715static struct ospf_lsa *
68980084 1716ospf_external_lsa_new (struct ospf *ospf,
1717 struct external_info *ei, struct in_addr *old_id)
718e3744 1718{
1719 struct stream *s;
1720 struct lsa_header *lsah;
1721 struct ospf_lsa *new;
1722 struct in_addr id;
1723 int length;
1724
1725 if (ei == NULL)
1726 {
1727 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1728 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
718e3744 1729 return NULL;
1730 }
1731
1732 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1733 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
718e3744 1734
1735 /* If old Link State ID is specified, refresh LSA with same ID. */
1736 if (old_id)
1737 id = *old_id;
1738 /* Get Link State with unique ID. */
1739 else
1740 {
68980084 1741 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
718e3744 1742 if (id.s_addr == 0xffffffff)
1743 {
1744 /* Maybe Link State ID not available. */
1745 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1746 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
718e3744 1747 return NULL;
1748 }
1749 }
1750
1751 /* Create new stream for LSA. */
1752 s = stream_new (OSPF_MAX_LSA_SIZE);
1753 lsah = (struct lsa_header *) STREAM_DATA (s);
1754
1755 /* Set LSA common header fields. */
68980084 1756 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1757 id, ospf->router_id);
718e3744 1758
1759 /* Set AS-external-LSA body fields. */
68980084 1760 ospf_external_lsa_body_set (s, ei, ospf);
718e3744 1761
1762 /* Set length. */
1763 length = stream_get_endp (s);
1764 lsah->length = htons (length);
1765
1766 /* Now, create OSPF LSA instance. */
1767 new = ospf_lsa_new ();
1768 new->area = NULL;
1769 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1770
1771 /* Copy LSA data to store, discard stream. */
1772 new->data = ospf_lsa_data_new (length);
1773 memcpy (new->data, lsah, length);
1774 stream_free (s);
1775
1776 return new;
1777}
1778
718e3744 1779/* As Type-7 */
4dadc291 1780static void
68980084 1781ospf_install_flood_nssa (struct ospf *ospf,
1782 struct ospf_lsa *lsa, struct external_info *ei)
718e3744 1783{
d4a53d58 1784 struct ospf_lsa *new;
68980084 1785 struct as_external_lsa *extlsa;
1eb8ef25 1786 struct ospf_area *area;
1787 struct listnode *node, *nnode;
718e3744 1788
d4a53d58 1789 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1790 * which originated from an NSSA area. In which case it should not be
1791 * flooded back to NSSA areas.
1792 */
1793 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1794 return;
1795
718e3744 1796 /* NSSA Originate or Refresh (If anyNSSA)
1797
1798 LSA is self-originated. And just installed as Type-5.
1799 Additionally, install as Type-7 LSDB for every attached NSSA.
1800
1801 P-Bit controls which ABR performs translation to outside world; If
1802 we are an ABR....do not set the P-bit, because we send the Type-5,
1803 not as the ABR Translator, but as the ASBR owner within the AS!
1804
1805 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1806 elected ABR Translator will see the P-bit, Translate, and re-flood.
1807
1808 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1809 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1810
1eb8ef25 1811 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
68980084 1812 {
0c14ad88 1813 /* Don't install Type-7 LSA's into nonNSSA area */
1814 if (area->external_routing != OSPF_AREA_NSSA)
1815 continue;
718e3744 1816
68980084 1817 /* make lsa duplicate, lock=1 */
d4a53d58 1818 new = ospf_lsa_dup (lsa);
1819 new->area = area;
1820 new->data->type = OSPF_AS_NSSA_LSA;
718e3744 1821
68980084 1822 /* set P-bit if not ABR */
020709f9 1823 if (! IS_OSPF_ABR (ospf))
68980084 1824 {
d4a53d58 1825 SET_FLAG(new->data->options, OSPF_OPTION_NP);
68980084 1826
1827 /* set non-zero FWD ADDR
1828
1829 draft-ietf-ospf-nssa-update-09.txt
1830
1831 if the network between the NSSA AS boundary router and the
1832 adjacent AS is advertised into OSPF as an internal OSPF route,
1833 the forwarding address should be the next op address as is cu
1834 currently done with type-5 LSAs. If the intervening network is
1835 not adversited into OSPF as an internal OSPF route and the
1836 type-7 LSA's P-bit is set a forwarding address should be
1837 selected from one of the router's active OSPF inteface addresses
1838 which belong to the NSSA. If no such addresses exist, then
1839 no type-7 LSA's with the P-bit set should originate from this
1840 router. */
1841
d4a53d58 1842 /* kevinm: not updating lsa anymore, just new */
1843 extlsa = (struct as_external_lsa *)(new->data);
68980084 1844
1845 if (extlsa->e[0].fwd_addr.s_addr == 0)
1846 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
718e3744 1847
d748032f 1848 if (extlsa->e[0].fwd_addr.s_addr == 0)
1849 {
1850 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1851 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
d4a53d58 1852 ospf_lsa_discard(new);
d748032f 1853 return;
1854 }
f2c80652 1855 }
68980084 1856 /* Re-calculate checksum. */
d4a53d58 1857 ospf_lsa_checksum (new->data);
718e3744 1858
68980084 1859 /* install also as Type-7 */
d4a53d58 1860 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
68980084 1861
1862 /* will send each copy, lock=2+n */
d4a53d58 1863 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
1864 }
1865}
1866
4dadc291 1867static struct ospf_lsa *
d4a53d58 1868ospf_lsa_translated_nssa_new (struct ospf *ospf,
1869 struct ospf_lsa *type7)
1870{
1871
1872 struct ospf_lsa *new;
1873 struct as_external_lsa *ext, *extnew;
1874 struct external_info ei;
1875
1876 ext = (struct as_external_lsa *)(type7->data);
1877
1878 /* need external_info struct, fill in bare minimum */
1879 ei.p.family = AF_INET;
1880 ei.p.prefix = type7->data->id;
1881 ei.p.prefixlen = ip_masklen (ext->mask);
1882 ei.type = ZEBRA_ROUTE_OSPF;
1883 ei.nexthop = ext->header.adv_router;
1884 ei.route_map_set.metric = -1;
1885 ei.route_map_set.metric_type = -1;
1886 ei.tag = 0;
1887
1888 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1889 {
1890 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1891 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
d4a53d58 1892 "Translated Type-5 for %s",
1893 inet_ntoa (ei.p.prefix));
1894 return NULL;
1895 }
1896
1897 extnew = (struct as_external_lsa *)(new->data);
1898
1899 /* copy over Type-7 data to new */
1900 extnew->e[0].tos = ext->e[0].tos;
1901 extnew->e[0].route_tag = ext->e[0].route_tag;
1902 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1903 new->data->ls_seqnum = type7->data->ls_seqnum;
1904
1905 /* add translated flag, checksum and lock new lsa */
1906 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1907 ospf_lsa_checksum (new->data);
1908 new = ospf_lsa_lock (new);
1909
1910 return new;
1911}
1912
1913/* compare type-5 to type-7
1914 * -1: err, 0: same, 1: different
1915 */
4dadc291 1916static int
d4a53d58 1917ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1918{
1919
1920 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1921 *e7 = (struct as_external_lsa *)t7;
1922
1923
1924 /* sanity checks */
1925 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1926 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1927 return -1;
1928
1929 if (t5->data->id.s_addr != t7->data->id.s_addr)
1930 return -1;
1931
1932 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1933 return LSA_REFRESH_FORCE;
1934
1935 if (e5->mask.s_addr != e7->mask.s_addr)
1936 return LSA_REFRESH_FORCE;
1937
1938 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1939 return LSA_REFRESH_FORCE;
1940
1941 if (e5->e[0].route_tag != e7->e[0].route_tag)
1942 return LSA_REFRESH_FORCE;
1943
1944 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1945 return LSA_REFRESH_FORCE;
1946
1947 return LSA_REFRESH_IF_CHANGED;
1948}
1949
1950/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1951struct ospf_lsa *
1952ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1953{
1954 struct ospf_lsa *new;
1955 struct as_external_lsa *extnew;
1956
1957 /* we cant use ospf_external_lsa_originate() as we need to set
1958 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1959 */
1960
1961 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1962 {
1963 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1964 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
d4a53d58 1965 "Type-7, Id %s, to Type-5",
1966 inet_ntoa (type7->data->id));
1967 return NULL;
1968 }
1969
1970 extnew = (struct as_external_lsa *)new;
1971
1972 if (IS_DEBUG_OSPF_NSSA)
1973 {
e588f21f 1974 zlog_debug ("ospf_translated_nssa_originate(): "
d4a53d58 1975 "translated Type 7, installed:");
1976 ospf_lsa_header_dump (new->data);
e588f21f 1977 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1978 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
d4a53d58 1979 }
1980
1981 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1982 {
1983 if (IS_DEBUG_OSPF_NSSA);
e588f21f 1984 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
d4a53d58 1985 "Could not install LSA "
1986 "id %s", inet_ntoa (type7->data->id));
1987 return NULL;
1988 }
1989
1990 ospf->lsa_originate_count++;
1991 ospf_flood_through_as (ospf, NULL, new);
1992
1993 return new;
1994}
1995
1996/* Refresh Translated from NSSA AS-external-LSA. */
1997struct ospf_lsa *
1998ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1999 struct ospf_lsa *type5)
2000{
2001 struct ospf_lsa *new = NULL;
2002
2003 /* Sanity checks. */
2004 assert (type7 || type5);
2005 if (type7)
2006 assert (type7->data);
2007 if (type5)
2008 assert (type5->data);
2009 assert (ospf->anyNSSA);
2010
2011 /* get required data according to what has been given */
2012 if (type7 && type5 == NULL)
2013 {
2014 /* find the translated Type-5 for this Type-7 */
2015 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2016 struct prefix_ipv4 p =
2017 {
2018 .prefix = type7->data->id,
2019 .prefixlen = ip_masklen (ext->mask),
2020 .family = AF_INET,
2021 };
2022
2023 type5 = ospf_external_info_find_lsa (ospf, &p);
2024 }
2025 else if (type5 && type7 == NULL)
2026 {
2027 /* find the type-7 from which supplied type-5 was translated,
2028 * ie find first type-7 with same LSA Id.
2029 */
1eb8ef25 2030 struct listnode *ln, *lnn;
d4a53d58 2031 struct route_node *rn;
2032 struct ospf_lsa *lsa;
2033 struct ospf_area *area;
2034
1eb8ef25 2035 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
d4a53d58 2036 {
2037 if (area->external_routing != OSPF_AREA_NSSA
2038 && !type7)
2039 continue;
2040
2041 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2042 {
2043 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2044 {
2045 type7 = lsa;
2046 break;
2047 }
2048 }
2049 }
68980084 2050 }
d4a53d58 2051
2052 /* do we have type7? */
2053 if (!type7)
2054 {
2055 if (IS_DEBUG_OSPF_NSSA)
e588f21f 2056 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
d4a53d58 2057 "Type-5 LSA Id %s",
2058 inet_ntoa (type7->data->id));
2059 return NULL;
2060 }
2061
2062 /* do we have valid translated type5? */
2063 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2064 {
2065 if (IS_DEBUG_OSPF_NSSA)
e588f21f 2066 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
d4a53d58 2067 "found for Type-7 with Id %s",
2068 inet_ntoa (type7->data->id));
2069 return NULL;
2070 }
2071
2072 /* Delete LSA from neighbor retransmit-list. */
2073 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2074
2075 /* create new translated LSA */
2076 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2077 {
2078 if (IS_DEBUG_OSPF_NSSA)
e588f21f 2079 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
d4a53d58 2080 "Type-7 for %s to Type-5",
2081 inet_ntoa (type7->data->id));
2082 return NULL;
2083 }
2084
2085 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2086 {
2087 if (IS_DEBUG_OSPF_NSSA)
e588f21f 2088 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
d4a53d58 2089 "translated LSA, Id %s",
2090 inet_ntoa (new->data->id));
2091 return NULL;
2092 }
2093
2094 /* Flood LSA through area. */
2095 ospf_flood_through_as (ospf, NULL, new);
2096
2097 return new;
718e3744 2098}
718e3744 2099
2100int
2101is_prefix_default (struct prefix_ipv4 *p)
2102{
2103 struct prefix_ipv4 q;
2104
2105 q.family = AF_INET;
2106 q.prefix.s_addr = 0;
2107 q.prefixlen = 0;
2108
2109 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2110}
2111
2112/* Originate an AS-external-LSA, install and flood. */
2113struct ospf_lsa *
68980084 2114ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
718e3744 2115{
2116 struct ospf_lsa *new;
2117
2118 /* Added for NSSA project....
2119
2120 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2121 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2122 every area. The Type-7's are flooded to every IR and every ABR; We
2123 install the Type-5 LSDB so that the normal "refresh" code operates
2124 as usual, and flag them as not used during ASE calculations. The
2125 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2126 Address of non-zero.
2127
2128 If an ABR is the elected NSSA translator, following SPF and during
2129 the ABR task it will translate all the scanned Type-7's, with P-bit
2130 ON and not-self generated, and translate to Type-5's throughout the
2131 non-NSSA/STUB AS.
2132
2133 A difference in operation depends whether this ASBR is an ABR
2134 or not. If not an ABR, the P-bit is ON, to indicate that any
2135 elected NSSA-ABR can perform its translation.
2136
2137 If an ABR, the P-bit is OFF; No ABR will perform translation and
2138 this ASBR will flood the Type-5 LSA as usual.
2139
2140 For the case where this ASBR is not an ABR, the ASE calculations
2141 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2142 demonstrate to the user that there are LSA's that belong to any
2143 attached NSSA.
2144
2145 Finally, it just so happens that when the ABR is translating every
2146 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2147 approved Type-5 (translated from Type-7); at the end of translation
2148 if any Translated Type-5's remain unapproved, then they must be
2149 flushed from the AS.
2150
2151 */
2152
2153 /* Check the AS-external-LSA should be originated. */
68980084 2154 if (!ospf_redistribute_check (ospf, ei, NULL))
718e3744 2155 return NULL;
2156
2157 /* Create new AS-external-LSA instance. */
68980084 2158 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
718e3744 2159 {
2160 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2161 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
718e3744 2162 inet_ntoa (ei->p.prefix));
2163 return NULL;
2164 }
2165
2166 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
68980084 2167 ospf_lsa_install (ospf, NULL, new);
718e3744 2168
2169 /* Update LSA origination count. */
68980084 2170 ospf->lsa_originate_count++;
718e3744 2171
2172 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
68980084 2173 ospf_flood_through_as (ospf, NULL, new);
718e3744 2174
718e3744 2175 /* If there is any attached NSSA, do special handling */
d4a53d58 2176 if (ospf->anyNSSA &&
2177 /* stay away from translated LSAs! */
2178 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
68980084 2179 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
718e3744 2180
2181 /* Debug logging. */
2182 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2183 {
e588f21f 2184 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
718e3744 2185 new->data->type, inet_ntoa (new->data->id), new);
2186 ospf_lsa_header_dump (new->data);
2187 }
2188
2189 return new;
2190}
2191
2192/* Originate AS-external-LSA from external info with initial flag. */
2193int
68980084 2194ospf_external_lsa_originate_timer (struct thread *thread)
718e3744 2195{
68980084 2196 struct ospf *ospf = THREAD_ARG (thread);
718e3744 2197 struct route_node *rn;
2198 struct external_info *ei;
2199 struct route_table *rt;
68980084 2200 int type = THREAD_VAL (thread);
718e3744 2201
68980084 2202 ospf->t_external_lsa = NULL;
718e3744 2203
2204 /* Originate As-external-LSA from all type of distribute source. */
2205 if ((rt = EXTERNAL_INFO (type)))
2206 for (rn = route_top (rt); rn; rn = route_next (rn))
2207 if ((ei = rn->info) != NULL)
2208 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
68980084 2209 if (!ospf_external_lsa_originate (ospf, ei))
718e3744 2210 zlog_warn ("LSA: AS-external-LSA was not originated.");
2211
2212 return 0;
2213}
2214
4dadc291 2215static struct external_info *
020709f9 2216ospf_default_external_info (struct ospf *ospf)
718e3744 2217{
2218 int type;
2219 struct route_node *rn;
2220 struct prefix_ipv4 p;
2221
2222 p.family = AF_INET;
2223 p.prefix.s_addr = 0;
2224 p.prefixlen = 0;
2225
2226 /* First, lookup redistributed default route. */
2227 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2228 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2229 {
2230 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2231 if (rn != NULL)
2232 {
2233 route_unlock_node (rn);
2234 assert (rn->info);
68980084 2235 if (ospf_redistribute_check (ospf, rn->info, NULL))
718e3744 2236 return rn->info;
2237 }
2238 }
2239
2240 return NULL;
2241}
2242
2243int
68980084 2244ospf_default_originate_timer (struct thread *thread)
718e3744 2245{
2246 int *origin;
2247 struct prefix_ipv4 p;
2248 struct in_addr nexthop;
2249 struct external_info *ei;
020709f9 2250 struct ospf *ospf;
718e3744 2251
020709f9 2252 ospf = ospf_lookup ();
2253
718e3744 2254 /* Get originate flags. */
68980084 2255 origin = THREAD_ARG (thread);
718e3744 2256
2257 p.family = AF_INET;
2258 p.prefix.s_addr = 0;
2259 p.prefixlen = 0;
2260
2261 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
2262 {
2263 /* If there is no default route via redistribute,
2264 then originate AS-external-LSA with nexthop 0 (self). */
2265 nexthop.s_addr = 0;
2266 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2267 }
2268
020709f9 2269 if ((ei = ospf_default_external_info (ospf)))
68980084 2270 ospf_external_lsa_originate (ospf, ei);
718e3744 2271
2272 return 0;
2273}
2274
645878f1 2275/* Flush any NSSA LSAs for given prefix */
2276void
2277ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2278{
1eb8ef25 2279 struct listnode *node, *nnode;
645878f1 2280 struct ospf_lsa *lsa;
2281 struct ospf_area *area;
2282
1eb8ef25 2283 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
645878f1 2284 {
1eb8ef25 2285 if (area->external_routing == OSPF_AREA_NSSA)
d748032f 2286 {
2287 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2288 ospf->router_id)))
2289 {
2290 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2291 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
d748032f 2292 inet_ntoa (p->prefix), p->prefixlen);
2293 continue;
2294 }
2295 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2296 if (!IS_LSA_MAXAGE (lsa))
2297 {
2298 ospf_refresher_unregister_lsa (ospf, lsa);
2299 ospf_lsa_flush_area (lsa, area);
2300 }
2301 }
645878f1 2302 }
2303}
645878f1 2304
718e3744 2305/* Flush an AS-external-LSA from LSDB and routing domain. */
2306void
68980084 2307ospf_external_lsa_flush (struct ospf *ospf,
2308 u_char type, struct prefix_ipv4 *p,
5339cfdb 2309 unsigned int ifindex /*, struct in_addr nexthop */)
718e3744 2310{
2311 struct ospf_lsa *lsa;
2312
2313 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2314 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
718e3744 2315 inet_ntoa (p->prefix), p->prefixlen);
2316
2317 /* First lookup LSA from LSDB. */
68980084 2318 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
718e3744 2319 {
2320 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2321 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
718e3744 2322 inet_ntoa (p->prefix), p->prefixlen);
2323 return;
2324 }
beebba75 2325
d4a53d58 2326 /* If LSA is selforiginated, not a translated LSA, and there is
2327 * NSSA area, flush Type-7 LSA's at first.
2328 */
2329 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2330 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
d748032f 2331 ospf_nssa_lsa_flush (ospf, p);
718e3744 2332
2333 /* Sweep LSA from Link State Retransmit List. */
68980084 2334 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
718e3744 2335
2336 /* There must be no self-originated LSA in rtrs_external. */
2337#if 0
2338 /* Remove External route from Zebra. */
2339 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2340#endif
2341
2342 if (!IS_LSA_MAXAGE (lsa))
2343 {
2344 /* Unregister LSA from Refresh queue. */
68980084 2345 ospf_refresher_unregister_lsa (ospf, lsa);
718e3744 2346
2347 /* Flush AS-external-LSA through AS. */
68980084 2348 ospf_lsa_flush_as (ospf, lsa);
718e3744 2349 }
2350
2351 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2352 zlog_debug ("ospf_external_lsa_flush(): stop");
718e3744 2353}
2354
2355void
68980084 2356ospf_external_lsa_refresh_default (struct ospf *ospf)
718e3744 2357{
2358 struct prefix_ipv4 p;
2359 struct external_info *ei;
2360 struct ospf_lsa *lsa;
2361
2362 p.family = AF_INET;
2363 p.prefixlen = 0;
2364 p.prefix.s_addr = 0;
2365
020709f9 2366 ei = ospf_default_external_info (ospf);
68980084 2367 lsa = ospf_external_info_find_lsa (ospf, &p);
718e3744 2368
2369 if (ei)
2370 {
2371 if (lsa)
2372 {
2373 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2374 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
68980084 2375 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
718e3744 2376 }
2377 else
2378 {
2379 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2380 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
68980084 2381 ospf_external_lsa_originate (ospf, ei);
718e3744 2382 }
2383 }
2384 else
2385 {
2386 if (lsa)
2387 {
2388 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2389 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
68980084 2390 ospf_lsa_flush_as (ospf, lsa);
718e3744 2391 }
2392 }
2393}
2394
2395void
68980084 2396ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
718e3744 2397{
2398 struct route_node *rn;
2399 struct external_info *ei;
2400
2401 if (type != DEFAULT_ROUTE)
2402 if (EXTERNAL_INFO(type))
2403 /* Refresh each redistributed AS-external-LSAs. */
2404 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2405 if ((ei = rn->info))
2406 if (!is_prefix_default (&ei->p))
2407 {
2408 struct ospf_lsa *lsa;
2409
68980084 2410 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2411 ospf_external_lsa_refresh (ospf, lsa, ei, force);
718e3744 2412 else
68980084 2413 ospf_external_lsa_originate (ospf, ei);
718e3744 2414 }
2415}
2416
2417/* Refresh AS-external-LSA. */
2418void
68980084 2419ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
718e3744 2420 struct external_info *ei, int force)
2421{
2422 struct ospf_lsa *new;
2423 int changed;
2424
2425 /* Check the AS-external-LSA should be originated. */
68980084 2426 if (!ospf_redistribute_check (ospf, ei, &changed))
718e3744 2427 {
d4a53d58 2428 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 2429 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
d4a53d58 2430 "redist check fail",
2431 lsa->data->type, inet_ntoa (lsa->data->id));
68980084 2432 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
5339cfdb 2433 ei->ifindex /*, ei->nexthop */);
718e3744 2434 return;
2435 }
2436
2437 if (!changed && !force)
d4a53d58 2438 {
2439 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 2440 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
d4a53d58 2441 lsa->data->type, inet_ntoa (lsa->data->id));
2442 return;
2443 }
718e3744 2444
2445 /* Delete LSA from neighbor retransmit-list. */
68980084 2446 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
718e3744 2447
2448 /* Unregister AS-external-LSA from refresh-list. */
68980084 2449 ospf_refresher_unregister_lsa (ospf, lsa);
718e3744 2450
68980084 2451 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
718e3744 2452
2453 if (new == NULL)
2454 {
2455 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 2456 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
718e3744 2457 inet_ntoa (lsa->data->id));
2458 return;
2459 }
2460
2461 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2462
2463 /* Record timestamp. */
2464 gettimeofday (&new->tv_orig, NULL);
2465
2466 /* Re-calculate checksum. */
2467 ospf_lsa_checksum (new->data);
2468
68980084 2469 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
718e3744 2470
2471 /* Flood LSA through AS. */
68980084 2472 ospf_flood_through_as (ospf, NULL, new);
718e3744 2473
718e3744 2474 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
d4a53d58 2475 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
68980084 2476 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
718e3744 2477
d4a53d58 2478 /* Register self-originated LSA to refresh queue.
2479 * Translated LSAs should not be registered, but refreshed upon
2480 * refresh of the Type-7
2481 */
2482 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2483 ospf_refresher_register_lsa (ospf, new);
718e3744 2484
2485 /* Debug logging. */
2486 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2487 {
e588f21f 2488 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
d4a53d58 2489 new->data->type, inet_ntoa (new->data->id));
718e3744 2490 ospf_lsa_header_dump (new->data);
2491 }
2492
2493 return;
2494}
2495
2496\f
2497/* LSA installation functions. */
2498
2499/* Install router-LSA to an area. */
4dadc291 2500static struct ospf_lsa *
68980084 2501ospf_router_lsa_install (struct ospf *ospf,
2502 struct ospf_lsa *new, int rt_recalc)
718e3744 2503{
2504 struct ospf_area *area = new->area;
2505
2506 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2507 The entire routing table must be recalculated, starting with
2508 the shortest path calculations for each area (not just the
2509 area whose link-state database has changed).
2510 */
2511 if (rt_recalc)
68980084 2512 ospf_spf_calculate_schedule (ospf);
718e3744 2513
2514 if (IS_LSA_SELF (new))
2515 {
2516 /* Set router-LSA refresh timer. */
2517 OSPF_TIMER_OFF (area->t_router_lsa_self);
2518 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
d4a53d58 2519 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
718e3744 2520
2521 /* Set self-originated router-LSA. */
2522 ospf_lsa_unlock (area->router_lsa_self);
2523 area->router_lsa_self = ospf_lsa_lock (new);
2524
2525 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
e588f21f 2526 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
0c2be26c 2527 new->data->type, inet_ntoa (new->data->id),
2528 ntohl(new->data->ls_seqnum));
718e3744 2529 }
2530
2531 return new;
2532}
2533
2534#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2535 if (!(T)) \
2536 (T) = thread_add_timer (master, (F), oi, (V))
2537
2538/* Install network-LSA to an area. */
4dadc291 2539static struct ospf_lsa *
68980084 2540ospf_network_lsa_install (struct ospf *ospf,
2541 struct ospf_interface *oi,
718e3744 2542 struct ospf_lsa *new,
2543 int rt_recalc)
2544{
2545
2546 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2547 The entire routing table must be recalculated, starting with
2548 the shortest path calculations for each area (not just the
2549 area whose link-state database has changed).
2550 */
2551 if (rt_recalc)
68980084 2552 ospf_spf_calculate_schedule (ospf);
718e3744 2553
2554 /* We supposed that when LSA is originated by us, we pass the int
2555 for which it was originated. If LSA was received by flooding,
2556 the RECEIVED flag is set, so we do not link the LSA to the int. */
2557 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2558 {
2559 /* Set LSRefresh timer. */
2560 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2561
2562 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2563 ospf_network_lsa_refresh_timer,
2564 OSPF_LS_REFRESH_TIME);
2565
2566 ospf_lsa_unlock (oi->network_lsa_self);
2567 oi->network_lsa_self = ospf_lsa_lock (new);
2568 }
2569
2570 return new;
2571}
2572
2573/* Install summary-LSA to an area. */
4dadc291 2574static struct ospf_lsa *
68980084 2575ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2576 int rt_recalc)
718e3744 2577{
718e3744 2578 if (rt_recalc && !IS_LSA_SELF (new))
2579 {
2580 /* RFC 2328 Section 13.2 Summary-LSAs
2581 The best route to the destination described by the summary-
2582 LSA must be recalculated (see Section 16.5). If this
2583 destination is an AS boundary router, it may also be
2584 necessary to re-examine all the AS-external-LSAs.
2585 */
2586
2587#if 0
2588 /* This doesn't exist yet... */
2589 ospf_summary_incremental_update(new); */
2590#else /* #if 0 */
68980084 2591 ospf_spf_calculate_schedule (ospf);
718e3744 2592#endif /* #if 0 */
2593
2594 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
e588f21f 2595 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
718e3744 2596 }
2597
2598 if (IS_LSA_SELF (new))
68980084 2599 ospf_refresher_register_lsa (ospf, new);
718e3744 2600
2601 return new;
2602}
2603
2604/* Install ASBR-summary-LSA to an area. */
4dadc291 2605static struct ospf_lsa *
68980084 2606ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2607 int rt_recalc)
718e3744 2608{
2609 if (rt_recalc && !IS_LSA_SELF (new))
2610 {
2611 /* RFC 2328 Section 13.2 Summary-LSAs
2612 The best route to the destination described by the summary-
2613 LSA must be recalculated (see Section 16.5). If this
2614 destination is an AS boundary router, it may also be
2615 necessary to re-examine all the AS-external-LSAs.
2616 */
2617#if 0
2618 /* These don't exist yet... */
2619 ospf_summary_incremental_update(new);
2620 /* Isn't this done by the above call?
2621 - RFC 2328 Section 16.5 implies it should be */
2622 /* ospf_ase_calculate_schedule(); */
2623#else /* #if 0 */
68980084 2624 ospf_spf_calculate_schedule (ospf);
718e3744 2625#endif /* #if 0 */
2626 }
2627
2628 /* register LSA to refresh-list. */
2629 if (IS_LSA_SELF (new))
68980084 2630 ospf_refresher_register_lsa (ospf, new);
718e3744 2631
2632 return new;
2633}
2634
2635/* Install AS-external-LSA. */
4dadc291 2636static struct ospf_lsa *
68980084 2637ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2638 int rt_recalc)
718e3744 2639{
68980084 2640 ospf_ase_register_external_lsa (new, ospf);
718e3744 2641 /* If LSA is not self-originated, calculate an external route. */
2642 if (rt_recalc)
2643 {
2644 /* RFC 2328 Section 13.2 AS-external-LSAs
2645 The best route to the destination described by the AS-
2646 external-LSA must be recalculated (see Section 16.6).
2647 */
2648
2649 if (!IS_LSA_SELF (new))
d4a53d58 2650 ospf_ase_incremental_update (ospf, new);
718e3744 2651 }
2652
d4a53d58 2653 if (new->data->type == OSPF_AS_NSSA_LSA)
2654 {
2655 /* There is no point to register selforiginate Type-7 LSA for
2656 * refreshing. We rely on refreshing Type-5 LSA's
2657 */
2658 if (IS_LSA_SELF (new))
2659 return new;
2660 else
2661 {
2662 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2663 * New translations will be taken care of by the abr_task.
2664 */
2665 ospf_translated_nssa_refresh (ospf, new, NULL);
2666 }
2667 }
d748032f 2668
d4a53d58 2669 /* Register self-originated LSA to refresh queue.
8fc0f64b 2670 * Leave Translated LSAs alone if NSSA is enabled
d4a53d58 2671 */
beebba75 2672 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
68980084 2673 ospf_refresher_register_lsa (ospf, new);
718e3744 2674
2675 return new;
2676}
2677
2678void
68980084 2679ospf_discard_from_db (struct ospf *ospf,
2680 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
718e3744 2681{
2682 struct ospf_lsa *old;
2683
2684 old = ospf_lsdb_lookup (lsdb, lsa);
2685
2686 if (!old)
2687 return;
2688
2689 if (old->refresh_list >= 0)
68980084 2690 ospf_refresher_unregister_lsa (ospf, old);
718e3744 2691
2692 switch (old->data->type)
2693 {
2694 case OSPF_AS_EXTERNAL_LSA:
69310a67 2695 ospf_ase_unregister_external_lsa (old, ospf);
2696 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2697 break;
718e3744 2698#ifdef HAVE_OPAQUE_LSA
2699 case OSPF_OPAQUE_AS_LSA:
68980084 2700 ospf_ls_retransmit_delete_nbr_as (ospf, old);
718e3744 2701 break;
69310a67 2702#endif /* HAVE_OPAQUE_LSA */
d748032f 2703 case OSPF_AS_NSSA_LSA:
2704 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2705 ospf_ase_unregister_external_lsa (old, ospf);
beebba75 2706 break;
718e3744 2707 default:
68980084 2708 ospf_ls_retransmit_delete_nbr_area (old->area, old);
718e3744 2709 break;
2710 }
2711
68980084 2712 ospf_lsa_maxage_delete (ospf, old);
718e3744 2713 ospf_lsa_discard (old);
2714}
2715
718e3744 2716struct ospf_lsa *
68980084 2717ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2718 struct ospf_lsa *lsa)
718e3744 2719{
2720 struct ospf_lsa *new = NULL;
2721 struct ospf_lsa *old = NULL;
2722 struct ospf_lsdb *lsdb = NULL;
2723 int rt_recalc;
2724
2725 /* Set LSDB. */
2726 switch (lsa->data->type)
2727 {
f2c80652 2728 /* kevinm */
2729 case OSPF_AS_NSSA_LSA:
2730 if (lsa->area)
2731 lsdb = lsa->area->lsdb;
2732 else
68980084 2733 lsdb = ospf->lsdb;
f2c80652 2734 break;
718e3744 2735 case OSPF_AS_EXTERNAL_LSA:
2736#ifdef HAVE_OPAQUE_LSA
2737 case OSPF_OPAQUE_AS_LSA:
2738#endif /* HAVE_OPAQUE_LSA */
68980084 2739 lsdb = ospf->lsdb;
718e3744 2740 break;
2741 default:
2742 lsdb = lsa->area->lsdb;
2743 break;
2744 }
2745
718e3744 2746 assert (lsdb);
2747
2748 /* RFC 2328 13.2. Installing LSAs in the database
2749
2750 Installing a new LSA in the database, either as the result of
2751 flooding or a newly self-originated LSA, may cause the OSPF
2752 routing table structure to be recalculated. The contents of the
2753 new LSA should be compared to the old instance, if present. If
2754 there is no difference, there is no need to recalculate the
2755 routing table. When comparing an LSA to its previous instance,
2756 the following are all considered to be differences in contents:
2757
2758 o The LSA's Options field has changed.
2759
2760 o One of the LSA instances has LS age set to MaxAge, and
2761 the other does not.
2762
2763 o The length field in the LSA header has changed.
2764
2765 o The body of the LSA (i.e., anything outside the 20-byte
2766 LSA header) has changed. Note that this excludes changes
2767 in LS Sequence Number and LS Checksum.
2768
2769 */
2770 /* Look up old LSA and determine if any SPF calculation or incremental
2771 update is needed */
2772 old = ospf_lsdb_lookup (lsdb, lsa);
2773
2774 /* Do comparision and record if recalc needed. */
2775 rt_recalc = 0;
2776 if ( old == NULL || ospf_lsa_different(old, lsa))
2777 rt_recalc = 1;
2778
7ddf1d6e 2779 /*
2780 Sequence number check (Section 14.1 of rfc 2328)
2781 "Premature aging is used when it is time for a self-originated
2782 LSA's sequence number field to wrap. At this point, the current
2783 LSA instance (having LS sequence number MaxSequenceNumber) must
2784 be prematurely aged and flushed from the routing domain before a
2785 new instance with sequence number equal to InitialSequenceNumber
2786 can be originated. "
2787 */
2788
c2b478d7 2789 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
7ddf1d6e 2790 {
2791 if (ospf_lsa_is_self_originated(ospf, lsa))
2792 {
0c2be26c 2793 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2794
2795 if (!IS_LSA_MAXAGE(lsa))
7ddf1d6e 2796 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2797 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2798
2799 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2800 {
e588f21f 2801 zlog_debug ("ospf_lsa_install() Premature Aging "
7ddf1d6e 2802 "lsa 0x%lx", (u_long)lsa);
2803 ospf_lsa_header_dump (lsa->data);
2804 }
2805 }
2806 else
2807 {
2808 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2809 {
e588f21f 2810 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
7ddf1d6e 2811 "that was not self originated. Ignoring\n");
2812 ospf_lsa_header_dump (lsa->data);
2813 }
2814 return old;
2815 }
2816 }
2817
718e3744 2818 /* discard old LSA from LSDB */
2819 if (old != NULL)
68980084 2820 ospf_discard_from_db (ospf, lsdb, lsa);
718e3744 2821
718e3744 2822 /* Calculate Checksum if self-originated?. */
2823 if (IS_LSA_SELF (lsa))
2824 ospf_lsa_checksum (lsa->data);
2825
fe71a97d 2826 /* Insert LSA to LSDB. */
2827 ospf_lsdb_add (lsdb, lsa);
2828 lsa->lsdb = lsdb;
2829
718e3744 2830 /* Do LSA specific installation process. */
2831 switch (lsa->data->type)
2832 {
2833 case OSPF_ROUTER_LSA:
68980084 2834 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
718e3744 2835 break;
2836 case OSPF_NETWORK_LSA:
2837 assert (oi);
68980084 2838 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
718e3744 2839 break;
2840 case OSPF_SUMMARY_LSA:
68980084 2841 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
718e3744 2842 break;
2843 case OSPF_ASBR_SUMMARY_LSA:
68980084 2844 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
718e3744 2845 break;
2846 case OSPF_AS_EXTERNAL_LSA:
68980084 2847 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
718e3744 2848 break;
2849#ifdef HAVE_OPAQUE_LSA
2850 case OSPF_OPAQUE_LINK_LSA:
09e4efdc 2851 if (IS_LSA_SELF (lsa))
68980084 2852 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
09e4efdc 2853 else
68980084 2854 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
09e4efdc 2855 /* Fallthrough */
718e3744 2856 case OSPF_OPAQUE_AREA_LSA:
2857 case OSPF_OPAQUE_AS_LSA:
2858 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2859 break;
2860#endif /* HAVE_OPAQUE_LSA */
d4a53d58 2861 case OSPF_AS_NSSA_LSA:
68980084 2862 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
d4a53d58 2863 default: /* type-6,8,9....nothing special */
718e3744 2864 break;
2865 }
2866
2867 if (new == NULL)
2868 return new; /* Installation failed, cannot proceed further -- endo. */
2869
2870 /* Debug logs. */
2871 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2872 {
2873 char area_str[INET_ADDRSTRLEN];
2874
2875 switch (lsa->data->type)
2876 {
2877 case OSPF_AS_EXTERNAL_LSA:
2878#ifdef HAVE_OPAQUE_LSA
2879 case OSPF_OPAQUE_AS_LSA:
2880#endif /* HAVE_OPAQUE_LSA */
beebba75 2881 case OSPF_AS_NSSA_LSA:
e588f21f 2882 zlog_debug ("LSA[%s]: Install %s",
718e3744 2883 dump_lsa_key (new),
2884 LOOKUP (ospf_lsa_type_msg, new->data->type));
2885 break;
2886 default:
2887 strcpy (area_str, inet_ntoa (new->area->area_id));
e588f21f 2888 zlog_debug ("LSA[%s]: Install %s to Area %s",
718e3744 2889 dump_lsa_key (new),
2890 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2891 break;
2892 }
2893 }
2894
7ddf1d6e 2895 /*
2896 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2897 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2898 */
2899 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2900 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
718e3744 2901 {
7ddf1d6e 2902 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
e588f21f 2903 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
0c2be26c 2904 new->data->type,
2905 inet_ntoa (new->data->id),
2906 lsa);
68980084 2907 ospf_lsa_maxage (ospf, lsa);
718e3744 2908 }
2909
2910 return new;
2911}
2912
2913\f
4dadc291 2914static int
68980084 2915ospf_check_nbr_status (struct ospf *ospf)
718e3744 2916{
1eb8ef25 2917 struct listnode *node, *nnode;
2918 struct ospf_interface *oi;
2919
2920 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
718e3744 2921 {
718e3744 2922 struct route_node *rn;
2923 struct ospf_neighbor *nbr;
2924
2925 if (ospf_if_is_enable (oi))
2926 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2927 if ((nbr = rn->info) != NULL)
2928 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2929 {
2930 route_unlock_node (rn);
2931 return 0;
2932 }
2933 }
2934
2935 return 1;
2936}
2937
2938\f
2939#ifdef ORIGINAL_CODING
2940/* This function flood the maxaged LSA to DR. */
2941void
2942ospf_maxage_flood (struct ospf_lsa *lsa)
2943{
2944 switch (lsa->data->type)
2945 {
2946 case OSPF_ROUTER_LSA:
2947 case OSPF_NETWORK_LSA:
2948 case OSPF_SUMMARY_LSA:
2949 case OSPF_ASBR_SUMMARY_LSA:
718e3744 2950 case OSPF_AS_NSSA_LSA:
718e3744 2951#ifdef HAVE_OPAQUE_LSA
2952 case OSPF_OPAQUE_LINK_LSA:
2953 case OSPF_OPAQUE_AREA_LSA:
2954#endif /* HAVE_OPAQUE_LSA */
2955 ospf_flood_through_area (lsa->area, NULL, lsa);
2956 break;
2957 case OSPF_AS_EXTERNAL_LSA:
2958#ifdef HAVE_OPAQUE_LSA
2959 case OSPF_OPAQUE_AS_LSA:
2960#endif /* HAVE_OPAQUE_LSA */
2961 ospf_flood_through_as (NULL, lsa);
2962 break;
2963 default:
2964 break;
2965 }
2966}
2967#endif /* ORIGINAL_CODING */
2968
4dadc291 2969static int
718e3744 2970ospf_maxage_lsa_remover (struct thread *thread)
2971{
68980084 2972 struct ospf *ospf = THREAD_ARG (thread);
1eb8ef25 2973 struct ospf_lsa *lsa;
2974 struct listnode *node, *nnode;
718e3744 2975 int reschedule = 0;
2976
68980084 2977 ospf->t_maxage = NULL;
718e3744 2978
2979 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2980 zlog_debug ("LSA[MaxAge]: remover Start");
718e3744 2981
68980084 2982 reschedule = !ospf_check_nbr_status (ospf);
718e3744 2983
2984 if (!reschedule)
1eb8ef25 2985 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
718e3744 2986 {
718e3744 2987 if (lsa->retransmit_counter > 0)
2988 {
2989 reschedule = 1;
2990 continue;
2991 }
2992
2993 /* Remove LSA from the LSDB */
2994 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2995 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2996 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
7ddf1d6e 2997 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
718e3744 2998
2999 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 3000 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
718e3744 3001 lsa->data->type, inet_ntoa (lsa->data->id));
3002
3003 /* Flood max age LSA. */
3004#ifdef ORIGINAL_CODING
3005 ospf_maxage_flood (lsa);
3006#else /* ORIGINAL_CODING */
68980084 3007 ospf_flood_through (ospf, NULL, lsa);
718e3744 3008#endif /* ORIGINAL_CODING */
3009
7ddf1d6e 3010 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3011 {
3012 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 3013 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
7ddf1d6e 3014 (u_long)lsa);
3015 ospf_router_lsa_originate(lsa->area);
3016 }
3017
718e3744 3018 /* Remove from lsdb. */
68980084 3019 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
718e3744 3020 ospf_lsdb_delete (lsa->lsdb, lsa);
3021 }
3022
3023 /* A MaxAge LSA must be removed immediately from the router's link
3024 state database as soon as both a) it is no longer contained on any
3025 neighbor Link state retransmission lists and b) none of the router's
3026 neighbors are in states Exchange or Loading. */
3027 if (reschedule)
68980084 3028 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
718e3744 3029
3030 return 0;
3031}
3032
4dadc291 3033static int
68980084 3034ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
718e3744 3035{
52dc7ee6 3036 struct listnode *node;
1eb8ef25 3037 struct ospf_lsa *lsa;
3038
3039 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3040 if (lsa == new)
718e3744 3041 return 1;
3042
3043 return 0;
3044}
3045
3046void
68980084 3047ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3048{
52dc7ee6 3049 struct listnode *n;
718e3744 3050
68980084 3051 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
718e3744 3052 {
68980084 3053 list_delete_node (ospf->maxage_lsa, n);
718e3744 3054 ospf_lsa_unlock (lsa);
3055 }
3056}
3057
3058void
68980084 3059ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3060{
3061 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3062 and schedule the MaxAge LSA remover. */
68980084 3063 if (ospf_lsa_maxage_exist (ospf, lsa))
718e3744 3064 {
3065 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 3066 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
718e3744 3067 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3068 return;
3069 }
3070
68980084 3071 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
718e3744 3072
3073 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 3074 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
718e3744 3075
68980084 3076 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
718e3744 3077}
3078
4dadc291 3079static int
68980084 3080ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3081{
718e3744 3082 /* Stay away from any Local Translated Type-7 LSAs */
3083 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3084 return 0;
718e3744 3085
3086 if (IS_LSA_MAXAGE (lsa))
3087 /* Self-originated LSAs should NOT time-out instead,
3088 they're flushed and submitted to the max_age list explicitly. */
68980084 3089 if (!ospf_lsa_is_self_originated (ospf, lsa))
718e3744 3090 {
3091 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 3092 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
718e3744 3093
3094 switch (lsa->data->type)
3095 {
718e3744 3096#ifdef HAVE_OPAQUE_LSA
37163d6d 3097 case OSPF_OPAQUE_LINK_LSA:
3098 case OSPF_OPAQUE_AREA_LSA:
718e3744 3099 case OSPF_OPAQUE_AS_LSA:
09e4efdc 3100 /*
3101 * As a general rule, whenever network topology has changed
3102 * (due to an LSA removal in this case), routing recalculation
3103 * should be triggered. However, this is not true for opaque
3104 * LSAs. Even if an opaque LSA instance is going to be removed
3105 * from the routing domain, it does not mean a change in network
3106 * topology, and thus, routing recalculation is not needed here.
3107 */
3108 break;
718e3744 3109#endif /* HAVE_OPAQUE_LSA */
09e4efdc 3110 case OSPF_AS_EXTERNAL_LSA:
beebba75 3111 case OSPF_AS_NSSA_LSA:
68980084 3112 ospf_ase_incremental_update (ospf, lsa);
3113 break;
718e3744 3114 default:
68980084 3115 ospf_spf_calculate_schedule (ospf);
3116 break;
718e3744 3117 }
68980084 3118 ospf_lsa_maxage (ospf, lsa);
718e3744 3119 }
3120
3121 return 0;
3122}
3123
3124/* Periodical check of MaxAge LSA. */
3125int
68980084 3126ospf_lsa_maxage_walker (struct thread *thread)
718e3744 3127{
68980084 3128 struct ospf *ospf = THREAD_ARG (thread);
3129 struct route_node *rn;
3130 struct ospf_lsa *lsa;
1eb8ef25 3131 struct ospf_area *area;
3132 struct listnode *node, *nnode;
718e3744 3133
68980084 3134 ospf->t_maxage_walker = NULL;
718e3744 3135
1eb8ef25 3136 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 3137 {
68980084 3138 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3139 ospf_lsa_maxage_walker_remover (ospf, lsa);
3140 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3141 ospf_lsa_maxage_walker_remover (ospf, lsa);
3142 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3143 ospf_lsa_maxage_walker_remover (ospf, lsa);
3144 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3145 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3146#ifdef HAVE_OPAQUE_LSA
68980084 3147 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3148 ospf_lsa_maxage_walker_remover (ospf, lsa);
3149 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3150 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3151#endif /* HAVE_OPAQUE_LSA */
4fb949e3 3152 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3153 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3154 }
3155
4fb949e3 3156 /* for AS-external-LSAs. */
68980084 3157 if (ospf->lsdb)
3158 {
3159 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3160 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3161#ifdef HAVE_OPAQUE_LSA
68980084 3162 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3163 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3164#endif /* HAVE_OPAQUE_LSA */
68980084 3165 }
718e3744 3166
68980084 3167 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3168 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
718e3744 3169 return 0;
3170}
3171
68980084 3172struct ospf_lsa *
3173ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3174 struct prefix_ipv4 *p, struct in_addr router_id)
718e3744 3175{
68980084 3176 struct ospf_lsa *lsa;
3177 struct in_addr mask, id;
3178 struct lsa_header_mask
3179 {
3180 struct lsa_header header;
3181 struct in_addr mask;
3182 } *hmask;
718e3744 3183
68980084 3184 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3185 if (lsa == NULL)
3186 return NULL;
718e3744 3187
68980084 3188 masklen2ip (p->prefixlen, &mask);
718e3744 3189
68980084 3190 hmask = (struct lsa_header_mask *) lsa->data;
718e3744 3191
68980084 3192 if (mask.s_addr != hmask->mask.s_addr)
3193 {
3194 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3195 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3196 if (!lsa)
3197 return NULL;
3198 }
718e3744 3199
68980084 3200 return lsa;
718e3744 3201}
3202
3203struct ospf_lsa *
3204ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3205 struct in_addr id, struct in_addr adv_router)
3206{
e05fba43 3207 struct ospf *ospf = ospf_lookup();
3208 assert(ospf);
3209
718e3744 3210 switch (type)
3211 {
3212 case OSPF_ROUTER_LSA:
3213 case OSPF_NETWORK_LSA:
3214 case OSPF_SUMMARY_LSA:
3215 case OSPF_ASBR_SUMMARY_LSA:
718e3744 3216 case OSPF_AS_NSSA_LSA:
718e3744 3217#ifdef HAVE_OPAQUE_LSA
3218 case OSPF_OPAQUE_LINK_LSA:
3219 case OSPF_OPAQUE_AREA_LSA:
3220#endif /* HAVE_OPAQUE_LSA */
3221 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
718e3744 3222 case OSPF_AS_EXTERNAL_LSA:
3223#ifdef HAVE_OPAQUE_LSA
3224 case OSPF_OPAQUE_AS_LSA:
3225#endif /* HAVE_OPAQUE_LSA */
e05fba43 3226 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
718e3744 3227 default:
3228 break;
3229 }
3230
3231 return NULL;
3232}
3233
3234struct ospf_lsa *
3235ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3236 struct in_addr id)
3237{
3238 struct ospf_lsa *lsa;
3239 struct route_node *rn;
3240
3241 switch (type)
3242 {
3243 case OSPF_ROUTER_LSA:
3244 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
718e3744 3245 case OSPF_NETWORK_LSA:
3246 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3247 if ((lsa = rn->info))
3248 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3249 {
3250 route_unlock_node (rn);
3251 return lsa;
3252 }
3253 break;
3254 case OSPF_SUMMARY_LSA:
3255 case OSPF_ASBR_SUMMARY_LSA:
3256 /* Currently not used. */
3257 assert (1);
3258 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
718e3744 3259 case OSPF_AS_EXTERNAL_LSA:
d4a53d58 3260 case OSPF_AS_NSSA_LSA:
718e3744 3261#ifdef HAVE_OPAQUE_LSA
3262 case OSPF_OPAQUE_LINK_LSA:
3263 case OSPF_OPAQUE_AREA_LSA:
3264 case OSPF_OPAQUE_AS_LSA:
3265 /* Currently not used. */
3266 break;
3267#endif /* HAVE_OPAQUE_LSA */
3268 default:
3269 break;
3270 }
3271
3272 return NULL;
3273}
3274
3275struct ospf_lsa *
3276ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3277{
3278 struct ospf_lsa *match;
3279
3280#ifdef HAVE_OPAQUE_LSA
3281 /*
3282 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3283 * is redefined to have two subfields; opaque-type and opaque-id.
3284 * However, it is harmless to treat the two sub fields together, as if
3285 * they two were forming a unique LSA-ID.
3286 */
3287#endif /* HAVE_OPAQUE_LSA */
3288
3289 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3290
3291 if (match == NULL)
3292 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
e588f21f 3293 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
718e3744 3294 lsah->type, inet_ntoa (lsah->id));
3295
3296 return match;
3297}
3298
3299/* return +n, l1 is more recent.
3300 return -n, l2 is more recent.
3301 return 0, l1 and l2 is identical. */
3302int
3303ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3304{
3305 int r;
3306 int x, y;
3307
3308 if (l1 == NULL && l2 == NULL)
3309 return 0;
3310 if (l1 == NULL)
3311 return -1;
3312 if (l2 == NULL)
3313 return 1;
3314
3315 /* compare LS sequence number. */
3316 x = (int) ntohl (l1->data->ls_seqnum);
3317 y = (int) ntohl (l2->data->ls_seqnum);
3318 if (x > y)
3319 return 1;
3320 if (x < y)
3321 return -1;
3322
3323 /* compare LS checksum. */
3324 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3325 if (r)
3326 return r;
3327
3328 /* compare LS age. */
3329 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3330 return 1;
3331 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3332 return -1;
3333
3334 /* compare LS age with MaxAgeDiff. */
3335 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3336 return -1;
3337 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3338 return 1;
3339
3340 /* LSAs are identical. */
3341 return 0;
3342}
3343
3344/* If two LSAs are different, return 1, otherwise return 0. */
3345int
3346ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3347{
3348 char *p1, *p2;
3349 assert (l1);
3350 assert (l2);
3351 assert (l1->data);
3352 assert (l2->data);
3353
3354 if (l1->data->options != l2->data->options)
3355 return 1;
3356
3357 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3358 return 1;
3359
3360 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3361 return 1;
3362
3363 if (l1->data->length != l2->data->length)
3364 return 1;
3365
3366 if (l1->data->length == 0)
3367 return 1;
3368
d1825830 3369 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
718e3744 3370
3371 p1 = (char *) l1->data;
3372 p2 = (char *) l2->data;
3373
3374 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3375 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3376 return 1;
3377
3378 return 0;
3379}
3380
3381#ifdef ORIGINAL_CODING
3382void
3383ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3384 struct ospf_lsa *self,
3385 struct ospf_lsa *new)
3386{
3387 u_int32_t seqnum;
3388
3389 /* Adjust LS Sequence Number. */
3390 seqnum = ntohl (new->data->ls_seqnum) + 1;
3391 self->data->ls_seqnum = htonl (seqnum);
3392
3393 /* Recalculate LSA checksum. */
3394 ospf_lsa_checksum (self->data);
3395
3396 /* Reflooding LSA. */
3397 /* RFC2328 Section 13.3
3398 On non-broadcast networks, separate Link State Update
3399 packets must be sent, as unicasts, to each adjacent neighbor
3400 (i.e., those in state Exchange or greater). The destination
3401 IP addresses for these packets are the neighbors' IP
3402 addresses. */
3403 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3404 {
3405 struct route_node *rn;
3406 struct ospf_neighbor *onbr;
3407
3408 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3409 if ((onbr = rn->info) != NULL)
3410 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3411 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3412 }
3413 else
3414 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3415
3416 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 3417 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
718e3744 3418 self->data->type, inet_ntoa (self->data->id));
3419}
3420#else /* ORIGINAL_CODING */
3421static int
68980084 3422ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3423{
3424 if (lsa == NULL || !IS_LSA_SELF (lsa))
3425 return 0;
3426
3427 if (IS_DEBUG_OSPF_EVENT)
e588f21f 3428 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 3429
3430 /* Force given lsa's age to MaxAge. */
3431 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3432
3433 switch (lsa->data->type)
3434 {
3435#ifdef HAVE_OPAQUE_LSA
3436 case OSPF_OPAQUE_LINK_LSA:
3437 case OSPF_OPAQUE_AREA_LSA:
3438 case OSPF_OPAQUE_AS_LSA:
3439 ospf_opaque_lsa_refresh (lsa);
3440 break;
3441#endif /* HAVE_OPAQUE_LSA */
3442 default:
68980084 3443 ospf_lsa_maxage (ospf, lsa);
718e3744 3444 break;
3445 }
3446
3447 return 0;
3448}
3449
3450void
68980084 3451ospf_flush_self_originated_lsas_now (struct ospf *ospf)
718e3744 3452{
1eb8ef25 3453 struct listnode *node, *nnode;
3454 struct listnode *node2, *nnode2;
718e3744 3455 struct ospf_area *area;
3456 struct ospf_interface *oi;
3457 struct ospf_lsa *lsa;
68980084 3458 struct route_node *rn;
718e3744 3459 int need_to_flush_ase = 0;
3460
1eb8ef25 3461 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 3462 {
718e3744 3463 if ((lsa = area->router_lsa_self) != NULL)
3464 {
3465 if (IS_DEBUG_OSPF_EVENT)
e588f21f 3466 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 3467
3468 ospf_lsa_flush_area (lsa, area);
3469 ospf_lsa_unlock (area->router_lsa_self);
3470 area->router_lsa_self = NULL;
3471 OSPF_TIMER_OFF (area->t_router_lsa_self);
3472 }
3473
1eb8ef25 3474 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
718e3744 3475 {
718e3744 3476 if ((lsa = oi->network_lsa_self) != NULL
1eb8ef25 3477 && oi->state == ISM_DR
3478 && oi->full_nbrs > 0)
718e3744 3479 {
3480 if (IS_DEBUG_OSPF_EVENT)
e588f21f 3481 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 3482
3483 ospf_lsa_flush_area (oi->network_lsa_self, area);
3484 ospf_lsa_unlock (oi->network_lsa_self);
3485 oi->network_lsa_self = NULL;
3486 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3487 }
3488
3489 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3490 && area->external_routing == OSPF_AREA_DEFAULT)
3491 need_to_flush_ase = 1;
3492 }
3493
68980084 3494 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3495 ospf_lsa_flush_schedule (ospf, lsa);
3496 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3497 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3498#ifdef HAVE_OPAQUE_LSA
68980084 3499 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3500 ospf_lsa_flush_schedule (ospf, lsa);
3501 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3502 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3503#endif /* HAVE_OPAQUE_LSA */
3504 }
3505
3506 if (need_to_flush_ase)
3507 {
68980084 3508 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3509 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3510#ifdef HAVE_OPAQUE_LSA
68980084 3511 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3512 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3513#endif /* HAVE_OPAQUE_LSA */
3514 }
3515
3516 /*
3517 * Make sure that the MaxAge LSA remover is executed immediately,
3518 * without conflicting to other threads.
3519 */
68980084 3520 if (ospf->t_maxage != NULL)
718e3744 3521 {
68980084 3522 OSPF_TIMER_OFF (ospf->t_maxage);
3523 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
718e3744 3524 }
3525
3526 return;
3527}
3528#endif /* ORIGINAL_CODING */
3529
3530/* If there is self-originated LSA, then return 1, otherwise return 0. */
3531/* An interface-independent version of ospf_lsa_is_self_originated */
3532int
68980084 3533ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3534{
52dc7ee6 3535 struct listnode *node;
1eb8ef25 3536 struct ospf_interface *oi;
718e3744 3537
3538 /* This LSA is already checked. */
3539 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3540 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3541
3542 /* Make sure LSA is self-checked. */
3543 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3544
3545 /* AdvRouter and Router ID is the same. */
68980084 3546 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
718e3744 3547 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3548
3549 /* LSA is router-LSA. */
3550 else if (lsa->data->type == OSPF_ROUTER_LSA &&
68980084 3551 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
718e3744 3552 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3553
3554 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3555 else if (lsa->data->type == OSPF_NETWORK_LSA)
1eb8ef25 3556 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
718e3744 3557 {
718e3744 3558 /* Ignore virtual link. */
3559 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3560 if (oi->address->family == AF_INET)
3561 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3562 {
3563 /* to make it easier later */
3564 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3565 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3566 }
3567 }
3568
3569 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3570}
3571
3572/* Get unique Link State ID. */
3573struct in_addr
68980084 3574ospf_lsa_unique_id (struct ospf *ospf,
3575 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
718e3744 3576{
3577 struct ospf_lsa *lsa;
3578 struct in_addr mask, id;
3579
3580 id = p->prefix;
3581
3582 /* Check existence of LSA instance. */
68980084 3583 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
718e3744 3584 if (lsa)
3585 {
3586 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3587 if (ip_masklen (al->mask) == p->prefixlen)
3588 {
3589 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 3590 zlog_debug ("ospf_lsa_unique_id(): "
718e3744 3591 "Can't get Link State ID for %s/%d",
3592 inet_ntoa (p->prefix), p->prefixlen);
3593 /* id.s_addr = 0; */
3594 id.s_addr = 0xffffffff;
3595 return id;
3596 }
3597 /* Masklen differs, then apply wildcard mask to Link State ID. */
3598 else
3599 {
3600 masklen2ip (p->prefixlen, &mask);
3601
3602 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
68980084 3603 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3604 id, ospf->router_id);
718e3744 3605 if (lsa)
3606 {
3607 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 3608 zlog_debug ("ospf_lsa_unique_id(): "
718e3744 3609 "Can't get Link State ID for %s/%d",
3610 inet_ntoa (p->prefix), p->prefixlen);
3611 /* id.s_addr = 0; */
3612 id.s_addr = 0xffffffff;
3613 return id;
3614 }
3615 }
3616 }
3617
3618 return id;
3619}
3620
3621\f
3622#define LSA_ACTION_ORIGN_RTR 1
3623#define LSA_ACTION_ORIGN_NET 2
3624#define LSA_ACTION_FLOOD_AREA 3
3625#define LSA_ACTION_FLOOD_AS 4
3626#define LSA_ACTION_FLUSH_AREA 5
3627#define LSA_ACTION_FLUSH_AS 6
3628
3629struct lsa_action
3630{
3631 u_char action;
3632 struct ospf_area *area;
3633 struct ospf_interface *oi;
3634 struct ospf_lsa *lsa;
3635};
3636
4dadc291 3637static int
718e3744 3638ospf_lsa_action (struct thread *t)
3639{
3640 struct lsa_action *data;
020709f9 3641 struct ospf *ospf;
3642
3643 ospf = ospf_lookup ();
718e3744 3644
3645 data = THREAD_ARG (t);
3646
3647 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
e588f21f 3648 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
718e3744 3649 data->action);
3650
3651 switch (data->action)
3652 {
3653 case LSA_ACTION_ORIGN_RTR:
3654 ospf_router_lsa_refresh (data->area->router_lsa_self);
3655 break;
3656 case LSA_ACTION_ORIGN_NET:
3657 ospf_network_lsa_originate (data->oi);
3658 break;
3659 case LSA_ACTION_FLOOD_AREA:
3660 ospf_flood_through_area (data->area, NULL, data->lsa);
3661 break;
3662 case LSA_ACTION_FLOOD_AS:
68980084 3663 ospf_flood_through_as (ospf, NULL, data->lsa);
718e3744 3664 break;
3665 case LSA_ACTION_FLUSH_AREA:
3666 ospf_lsa_flush_area (data->lsa, data->area);
3667 break;
3668 case LSA_ACTION_FLUSH_AS:
68980084 3669 ospf_lsa_flush_as (ospf, data->lsa);
718e3744 3670 break;
3671 }
3672
3673 ospf_lsa_unlock (data->lsa);
3674 XFREE (MTYPE_OSPF_MESSAGE, data);
3675 return 0;
3676}
3677
3678void
3679ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3680{
3681 struct lsa_action *data;
3682
3683 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3684 memset (data, 0, sizeof (struct lsa_action));
3685
3686 data->action = LSA_ACTION_FLOOD_AREA;
3687 data->area = area;
3688 data->lsa = ospf_lsa_lock (lsa);
3689
3690 thread_add_event (master, ospf_lsa_action, data, 0);
3691}
3692
3693void
3694ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3695{
3696 struct lsa_action *data;
3697
3698 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3699 memset (data, 0, sizeof (struct lsa_action));
3700
3701 data->action = LSA_ACTION_FLUSH_AREA;
3702 data->area = area;
3703 data->lsa = ospf_lsa_lock (lsa);
3704
3705 thread_add_event (master, ospf_lsa_action, data, 0);
3706}
3707
3708\f
3709/* LSA Refreshment functions. */
4dadc291 3710static void
68980084 3711ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3712{
3713 struct external_info *ei;
3714 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3715
3716 switch (lsa->data->type)
3717 {
3718 /* Router and Network LSAs are processed differently. */
3719 case OSPF_ROUTER_LSA:
3720 case OSPF_NETWORK_LSA:
3721 break;
3722 case OSPF_SUMMARY_LSA:
68980084 3723 ospf_summary_lsa_refresh (ospf, lsa);
718e3744 3724 break;
3725 case OSPF_ASBR_SUMMARY_LSA:
68980084 3726 ospf_summary_asbr_lsa_refresh (ospf, lsa);
718e3744 3727 break;
3728 case OSPF_AS_EXTERNAL_LSA:
d4a53d58 3729 /* Translated from NSSA Type-5s are refreshed when
3730 * from refresh of Type-7 - do not refresh these directly.
3731 */
3732 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3733 break;
718e3744 3734 ei = ospf_external_info_check (lsa);
3735 if (ei)
d4a53d58 3736 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
718e3744 3737 else
d4a53d58 3738 ospf_lsa_flush_as (ospf, lsa);
718e3744 3739 break;
3740#ifdef HAVE_OPAQUE_LSA
3741 case OSPF_OPAQUE_LINK_LSA:
3742 case OSPF_OPAQUE_AREA_LSA:
3743 case OSPF_OPAQUE_AS_LSA:
3744 ospf_opaque_lsa_refresh (lsa);
3745 break;
d748032f 3746#endif /* HAVE_OPAQUE_LSA */
718e3744 3747 default:
3748 break;
718e3744 3749 }
3750}
3751
3752void
68980084 3753ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3754{
3755 u_int16_t index, current_index;
3756
3757 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3758
3759 if (lsa->refresh_list < 0)
3760 {
3761 int delay;
3762
3763 if (LS_AGE (lsa) == 0 &&
3764 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3765 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3766 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3767 else
3768 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3769 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3770 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3771
3772 if (delay < 0)
3773 delay = 0;
3774
68980084 3775 current_index = ospf->lsa_refresh_queue.index +
3776 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
718e3744 3777
3778 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3779 % (OSPF_LSA_REFRESHER_SLOTS);
3780
3781 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3782 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
d4a53d58 3783 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
68980084 3784 if (!ospf->lsa_refresh_queue.qs[index])
3785 ospf->lsa_refresh_queue.qs[index] = list_new ();
3786 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
718e3744 3787 lsa->refresh_list = index;
f2c80652 3788 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3789 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
d4a53d58 3790 "setting refresh_list on lsa %p (slod %d)",
3791 inet_ntoa (lsa->data->id), lsa, index);
718e3744 3792 }
3793}
3794
3795void
68980084 3796ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3797{
3798 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3799 if (lsa->refresh_list >= 0)
3800 {
52dc7ee6 3801 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
718e3744 3802 listnode_delete (refresh_list, lsa);
3803 if (!listcount (refresh_list))
3804 {
3805 list_free (refresh_list);
68980084 3806 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
718e3744 3807 }
3808 ospf_lsa_unlock (lsa);
3809 lsa->refresh_list = -1;
3810 }
3811}
3812
3813int
3814ospf_lsa_refresh_walker (struct thread *t)
3815{
52dc7ee6 3816 struct list *refresh_list;
1eb8ef25 3817 struct listnode *node, *nnode;
68980084 3818 struct ospf *ospf = THREAD_ARG (t);
1eb8ef25 3819 struct ospf_lsa *lsa;
718e3744 3820 int i;
52dc7ee6 3821 struct list *lsa_to_refresh = list_new ();
718e3744 3822
3823 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3824 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
718e3744 3825
3826
68980084 3827 i = ospf->lsa_refresh_queue.index;
718e3744 3828
9dbc7972 3829 /* Note: if clock has jumped backwards, then time change could be negative,
3830 so we are careful to cast the expression to unsigned before taking
3831 modulus. */
68980084 3832 ospf->lsa_refresh_queue.index =
9dbc7972 3833 ((unsigned long)(ospf->lsa_refresh_queue.index +
3834 (time (NULL) - ospf->lsa_refresher_started) /
3835 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
718e3744 3836
3837 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3838 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
68980084 3839 ospf->lsa_refresh_queue.index);
718e3744 3840
68980084 3841 for (;i != ospf->lsa_refresh_queue.index;
718e3744 3842 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3843 {
3844 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3845 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
d4a53d58 3846 "refresh index %d", i);
718e3744 3847
68980084 3848 refresh_list = ospf->lsa_refresh_queue.qs [i];
718e3744 3849
68980084 3850 ospf->lsa_refresh_queue.qs [i] = NULL;
3851
718e3744 3852 if (refresh_list)
3853 {
1eb8ef25 3854 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
718e3744 3855 {
718e3744 3856 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3857 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
d4a53d58 3858 "refresh lsa %p (slot %d)",
3859 inet_ntoa (lsa->data->id), lsa, i);
718e3744 3860
3861 list_delete_node (refresh_list, node);
3862 ospf_lsa_unlock (lsa);
3863 lsa->refresh_list = -1;
3864 listnode_add (lsa_to_refresh, lsa);
718e3744 3865 }
3866 list_free (refresh_list);
3867 }
3868 }
3869
68980084 3870 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3871 ospf, ospf->lsa_refresh_interval);
3872 ospf->lsa_refresher_started = time (NULL);
718e3744 3873
1eb8ef25 3874 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3875 ospf_lsa_refresh (ospf, lsa);
718e3744 3876
3877 list_delete (lsa_to_refresh);
3878
3879 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3880 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
718e3744 3881
3882 return 0;
3883}
3884