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