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