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