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