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