back to topotato report
topotato coverage report
Current view: top level - ospfd - ospf_lsa.c (source / functions) Hit Total Coverage
Test: test_ospf_topo1.py::OSPFTopo1Test Lines: 950 1818 52.3 %
Date: 2023-02-24 18:38:32 Functions: 72 105 68.6 %

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

Generated by: LCOV version v1.16-topotato