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