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