back to topotato report
topotato coverage report
Current view: top level - ospf6d - ospf6_flood.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 483 651 74.2 %
Date: 2023-02-24 19:38:44 Functions: 27 30 90.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2003 Yasuhiro Ohara
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "log.h"
      24             : #include "thread.h"
      25             : #include "linklist.h"
      26             : #include "vty.h"
      27             : #include "command.h"
      28             : 
      29             : #include "ospf6d.h"
      30             : #include "ospf6_proto.h"
      31             : #include "ospf6_lsa.h"
      32             : #include "ospf6_lsdb.h"
      33             : #include "ospf6_message.h"
      34             : #include "ospf6_route.h"
      35             : #include "ospf6_spf.h"
      36             : 
      37             : #include "ospf6_top.h"
      38             : #include "ospf6_area.h"
      39             : #include "ospf6_interface.h"
      40             : #include "ospf6_neighbor.h"
      41             : 
      42             : #include "ospf6_flood.h"
      43             : #include "ospf6_vlink.h"
      44             : #include "ospf6_nssa.h"
      45             : #include "ospf6_gr.h"
      46             : 
      47             : unsigned char conf_debug_ospf6_flooding;
      48             : 
      49         957 : struct ospf6_lsdb *ospf6_get_scoped_lsdb(struct ospf6_lsa *lsa)
      50             : {
      51         957 :         struct ospf6_lsdb *lsdb = NULL;
      52         957 :         switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
      53          56 :         case OSPF6_SCOPE_LINKLOCAL:
      54          56 :                 lsdb = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb;
      55          56 :                 break;
      56         722 :         case OSPF6_SCOPE_AREA:
      57         722 :                 lsdb = OSPF6_AREA(lsa->lsdb->data)->lsdb;
      58         722 :                 break;
      59         179 :         case OSPF6_SCOPE_AS:
      60         179 :                 lsdb = OSPF6_PROCESS(lsa->lsdb->data)->lsdb;
      61         179 :                 break;
      62             :         default:
      63           0 :                 assert(0);
      64             :                 break;
      65             :         }
      66         957 :         return lsdb;
      67             : }
      68             : 
      69         237 : struct ospf6_lsdb *ospf6_get_scoped_lsdb_self(struct ospf6_lsa *lsa)
      70             : {
      71         237 :         struct ospf6_lsdb *lsdb_self = NULL;
      72         237 :         switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
      73          33 :         case OSPF6_SCOPE_LINKLOCAL:
      74          33 :                 lsdb_self = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb_self;
      75          33 :                 break;
      76         164 :         case OSPF6_SCOPE_AREA:
      77         164 :                 lsdb_self = OSPF6_AREA(lsa->lsdb->data)->lsdb_self;
      78         164 :                 break;
      79          40 :         case OSPF6_SCOPE_AS:
      80          40 :                 lsdb_self = OSPF6_PROCESS(lsa->lsdb->data)->lsdb_self;
      81          40 :                 break;
      82             :         default:
      83           0 :                 assert(0);
      84             :                 break;
      85             :         }
      86         237 :         return lsdb_self;
      87             : }
      88             : 
      89         361 : void ospf6_lsa_originate(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
      90             : {
      91         361 :         struct ospf6_lsa *old;
      92         361 :         struct ospf6_lsdb *lsdb_self;
      93             : 
      94         361 :         if (lsa->header->adv_router == INADDR_ANY) {
      95           0 :                 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
      96           0 :                         zlog_debug(
      97             :                                 "Refusing to originate LSA (zero router ID): %s",
      98             :                                 lsa->name);
      99             : 
     100           0 :                 ospf6_lsa_delete(lsa);
     101           0 :                 return;
     102             :         }
     103             : 
     104             :         /* find previous LSA */
     105         361 :         old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
     106             :                                 lsa->header->adv_router, lsa->lsdb);
     107             : 
     108             :         /* if the new LSA does not differ from previous,
     109             :            suppress this update of the LSA */
     110         361 :         if (old && !OSPF6_LSA_IS_DIFFER(lsa, old)
     111         199 :             && !ospf6->gr_info.finishing_restart) {
     112         199 :                 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
     113           0 :                         zlog_debug("Suppress updating LSA: %s", lsa->name);
     114         199 :                 ospf6_lsa_delete(lsa);
     115         199 :                 return;
     116             :         }
     117             : 
     118             :         /* store it in the LSDB for self-originated LSAs */
     119         162 :         lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
     120         162 :         ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self);
     121             : 
     122         162 :         THREAD_OFF(lsa->refresh);
     123         162 :         thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
     124             :                          &lsa->refresh);
     125             : 
     126         162 :         if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
     127         162 :             || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) {
     128           0 :                 zlog_debug("LSA Originate:");
     129           0 :                 ospf6_lsa_header_print(lsa);
     130             :         }
     131             : 
     132         162 :         ospf6_install_lsa(lsa);
     133         162 :         ospf6_flood(NULL, lsa);
     134             : }
     135             : 
     136          60 : void ospf6_lsa_originate_process(struct ospf6_lsa *lsa, struct ospf6 *process)
     137             : {
     138          60 :         lsa->lsdb = process->lsdb;
     139          60 :         ospf6_lsa_originate(process, lsa);
     140          60 : }
     141             : 
     142         235 : void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
     143             : {
     144         235 :         lsa->lsdb = oa->lsdb;
     145         235 :         ospf6_lsa_originate(oa->ospf6, lsa);
     146         235 : }
     147             : 
     148          66 : void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa,
     149             :                                    struct ospf6_interface *oi)
     150             : {
     151          66 :         assert(oi->type != OSPF_IFTYPE_VIRTUALLINK);
     152             : 
     153          66 :         lsa->lsdb = oi->lsdb;
     154          66 :         ospf6_lsa_originate(oi->area->ospf6, lsa);
     155          66 : }
     156             : 
     157          20 : void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
     158             : {
     159          20 :         uint32_t id = lsa->header->id;
     160          20 :         struct ospf6_area *oa;
     161          20 :         struct listnode *lnode;
     162             : 
     163          20 :         ospf6_lsa_purge(lsa);
     164             : 
     165             :         /* Delete the corresponding NSSA LSA */
     166          67 :         for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) {
     167          27 :                 lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), id,
     168             :                                         ospf6->router_id, oa->lsdb);
     169          27 :                 if (lsa) {
     170           0 :                         if (IS_OSPF6_DEBUG_NSSA)
     171           0 :                                 zlog_debug("withdraw type 7 lsa, LS ID: %u",
     172             :                                            htonl(id));
     173             : 
     174           0 :                         ospf6_lsa_purge(lsa);
     175             :                 }
     176             :         }
     177          20 : }
     178             : 
     179          75 : void ospf6_lsa_purge(struct ospf6_lsa *lsa)
     180             : {
     181          75 :         struct ospf6_lsa *self;
     182          75 :         struct ospf6_lsdb *lsdb_self;
     183             : 
     184             :         /* remove it from the LSDB for self-originated LSAs */
     185          75 :         lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
     186         150 :         self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
     187          75 :                                  lsa->header->adv_router, lsdb_self);
     188          75 :         if (self) {
     189          65 :                 THREAD_OFF(self->expire);
     190          65 :                 THREAD_OFF(self->refresh);
     191          65 :                 ospf6_lsdb_remove(self, lsdb_self);
     192             :         }
     193             : 
     194          75 :         ospf6_lsa_premature_aging(lsa);
     195          75 : }
     196             : 
     197             : /* Puring Multi Link-State IDs LSAs:
     198             :  * Same Advertising Router with Multiple Link-State IDs
     199             :  * LSAs, purging require to traverse all Link-State IDs
     200             :  */
     201          15 : void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa, struct ospf6_lsa *lsa)
     202             : {
     203          15 :         int ls_id = 0;
     204          15 :         struct ospf6_lsa *lsa_next;
     205          15 :         uint16_t type;
     206             : 
     207          15 :         type = lsa->header->type;
     208             : 
     209          15 :         ospf6_lsa_purge(lsa);
     210             : 
     211          15 :         lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
     212          15 :                                      oa->ospf6->router_id, oa->lsdb);
     213          15 :         while (lsa_next) {
     214           0 :                 ospf6_lsa_purge(lsa_next);
     215           0 :                 lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
     216           0 :                                              oa->ospf6->router_id, oa->lsdb);
     217             :         }
     218          15 : }
     219             : 
     220         490 : void ospf6_increment_retrans_count(struct ospf6_lsa *lsa)
     221             : {
     222             :         /* The LSA must be the original one (see the description
     223             :            in ospf6_decrement_retrans_count () below) */
     224         490 :         lsa->retrans_count++;
     225         490 : }
     226             : 
     227         490 : void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa)
     228             : {
     229         490 :         struct ospf6_lsdb *lsdb;
     230         490 :         struct ospf6_lsa *orig;
     231             : 
     232             :         /* The LSA must be on the retrans-list of a neighbor. It means
     233             :            the "lsa" is a copied one, and we have to decrement the
     234             :            retransmission count of the original one (instead of this "lsa"'s).
     235             :            In order to find the original LSA, first we have to find
     236             :            appropriate LSDB that have the original LSA. */
     237         490 :         lsdb = ospf6_get_scoped_lsdb(lsa);
     238             : 
     239             :         /* Find the original LSA of which the retrans_count should be
     240             :          * decremented */
     241         980 :         orig = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
     242         490 :                                  lsa->header->adv_router, lsdb);
     243         490 :         if (orig) {
     244         490 :                 orig->retrans_count--;
     245         490 :                 assert(orig->retrans_count >= 0);
     246             :         }
     247         490 : }
     248             : 
     249             : /* RFC2328 section 13.2 Installing LSAs in the database */
     250         615 : void ospf6_install_lsa(struct ospf6_lsa *lsa)
     251             : {
     252         615 :         struct ospf6 *ospf6;
     253         615 :         struct timeval now;
     254         615 :         struct ospf6_lsa *old;
     255         615 :         struct ospf6_area *area = NULL;
     256             : 
     257         615 :         ospf6 = ospf6_get_by_lsdb(lsa);
     258         615 :         assert(ospf6);
     259             : 
     260             :         /* Remove the old instance from all neighbors' Link state
     261             :            retransmission list (RFC2328 13.2 last paragraph) */
     262        1230 :         old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
     263         615 :                                 lsa->header->adv_router, lsa->lsdb);
     264         615 :         if (old) {
     265         292 :                 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) {
     266           0 :                         if (IS_OSPF6_DEBUG_NSSA)
     267           0 :                                 zlog_debug("%s : old LSA %s", __func__,
     268             :                                            lsa->name);
     269           0 :                         lsa->external_lsa_id = old->external_lsa_id;
     270             :                 }
     271         292 :                 THREAD_OFF(old->expire);
     272         292 :                 THREAD_OFF(old->refresh);
     273         292 :                 ospf6_flood_clear(old);
     274             :         }
     275             : 
     276         615 :         monotime(&now);
     277         615 :         if (!OSPF6_LSA_IS_MAXAGE(lsa)) {
     278         455 :                 thread_add_timer(master, ospf6_lsa_expire, lsa,
     279             :                                  OSPF_LSA_MAXAGE + lsa->birth.tv_sec
     280             :                                          - now.tv_sec,
     281             :                                  &lsa->expire);
     282             :         } else
     283         160 :                 lsa->expire = NULL;
     284             : 
     285         615 :         if (OSPF6_LSA_IS_SEQWRAP(lsa)
     286             :             && !(CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)
     287             :                  && lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER))) {
     288           0 :                 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
     289           0 :                         zlog_debug("lsa install wrapping: sequence 0x%x",
     290             :                                    ntohl(lsa->header->seqnum));
     291           0 :                 SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
     292             :                 /* in lieu of premature_aging, since we do not want to recreate
     293             :                  * this lsa
     294             :                  * and/or mess with timers etc, we just want to wrap the
     295             :                  * sequence number
     296             :                  * and reflood the lsa before continuing.
     297             :                  * NOTE: Flood needs to be called right after this function
     298             :                  * call, by the
     299             :                  * caller
     300             :                  */
     301           0 :                 lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
     302           0 :                 lsa->header->age = htons(OSPF_LSA_MAXAGE);
     303           0 :                 ospf6_lsa_checksum(lsa->header);
     304             :         }
     305             : 
     306         615 :         if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
     307         615 :             || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
     308           0 :                 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
     309             :                            __func__, lsa->name, ntohs(lsa->header->age),
     310             :                            ntohl(lsa->header->seqnum));
     311             : 
     312             :         /* actually install */
     313         615 :         lsa->installed = now;
     314             : 
     315             :         /* Topo change handling */
     316         615 :         if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa->header->type))
     317         532 :             && !CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)) {
     318             : 
     319             :                 /* check if it is new lsa ? or existing lsa got modified ?*/
     320         477 :                 if (!old || OSPF6_LSA_IS_CHANGED(old, lsa))
     321         391 :                         ospf6_helper_handle_topo_chg(ospf6, lsa);
     322             :         }
     323             : 
     324         615 :         ospf6_lsdb_add(lsa, lsa->lsdb);
     325             : 
     326         615 :         if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
     327           0 :             && lsa->header->adv_router != ospf6->router_id) {
     328           0 :                 area = OSPF6_AREA(lsa->lsdb->data);
     329           0 :                 ospf6_translated_nssa_refresh(area, lsa, NULL);
     330           0 :                 ospf6_schedule_abr_task(area->ospf6);
     331             :         }
     332             : 
     333         615 :         if (ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) {
     334         168 :                 area = OSPF6_AREA(lsa->lsdb->data);
     335         168 :                 if (old == NULL) {
     336          67 :                         if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
     337          67 :                             || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
     338           0 :                                 zlog_debug("%s: New router LSA %s", __func__,
     339             :                                            lsa->name);
     340          67 :                         ospf6_abr_nssa_check_status(area->ospf6);
     341             :                 }
     342             :         }
     343         615 :         return;
     344             : }
     345             : 
     346             : /* RFC2740 section 3.5.2. Sending Link State Update packets */
     347             : /* RFC2328 section 13.3 Next step in the flooding procedure */
     348        1191 : void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
     349             :                            struct ospf6_interface *oi)
     350             : {
     351        1191 :         struct listnode *node, *nnode;
     352        1191 :         struct ospf6_neighbor *on;
     353        1191 :         struct ospf6_lsa *req, *old;
     354        1191 :         int retrans_added = 0;
     355        1191 :         int is_debug = 0;
     356             : 
     357        1191 :         if (IS_OSPF6_DEBUG_FLOODING
     358        1191 :             || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) {
     359           0 :                 is_debug++;
     360           0 :                 zlog_debug("Flooding on %pOI: %s", oi, lsa->name);
     361             :         }
     362             : 
     363             :         /* (1) For each neighbor */
     364        3497 :         for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
     365        1115 :                 if (is_debug)
     366           0 :                         zlog_debug("To neighbor %s", on->name);
     367             : 
     368             :                 /* (a) if neighbor state < Exchange, examin next */
     369        1115 :                 if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
     370         103 :                         if (is_debug)
     371           0 :                                 zlog_debug(
     372             :                                         "Neighbor state less than ExChange, next neighbor");
     373         103 :                         continue;
     374             :                 }
     375             : 
     376             :                 /* (b) if neighbor not yet Full, check request-list */
     377        1012 :                 if (on->state != OSPF6_NEIGHBOR_FULL) {
     378         252 :                         if (is_debug)
     379           0 :                                 zlog_debug("Neighbor not yet Full");
     380             : 
     381         504 :                         req = ospf6_lsdb_lookup(
     382         252 :                                 lsa->header->type, lsa->header->id,
     383         252 :                                 lsa->header->adv_router, on->request_list);
     384         252 :                         if (req == NULL) {
     385         105 :                                 if (is_debug)
     386           0 :                                         zlog_debug(
     387             :                                                 "Not on request-list for this neighbor");
     388             :                                 /* fall through */
     389             :                         } else {
     390             :                                 /* If new LSA less recent, examin next neighbor
     391             :                                  */
     392         147 :                                 if (ospf6_lsa_compare(lsa, req) > 0) {
     393           0 :                                         if (is_debug)
     394           0 :                                                 zlog_debug(
     395             :                                                         "Requesting is older, next neighbor");
     396           0 :                                         continue;
     397             :                                 }
     398             : 
     399             :                                 /* If the same instance, delete from
     400             :                                    request-list and
     401             :                                    examin next neighbor */
     402         147 :                                 if (ospf6_lsa_compare(lsa, req) == 0) {
     403         145 :                                         if (is_debug)
     404           0 :                                                 zlog_debug(
     405             :                                                         "Requesting the same, remove it, next neighbor");
     406         145 :                                         if (req == on->last_ls_req) {
     407             :                                                 /* sanity check refcount */
     408          31 :                                                 assert(req->lock >= 2);
     409          31 :                                                 req = ospf6_lsa_unlock(req);
     410          31 :                                                 on->last_ls_req = NULL;
     411             :                                         }
     412         145 :                                         if (req)
     413         145 :                                                 ospf6_lsdb_remove(
     414             :                                                         req, on->request_list);
     415         145 :                                         ospf6_check_nbr_loading(on);
     416         145 :                                         continue;
     417             :                                 }
     418             : 
     419             :                                 /* If the new LSA is more recent, delete from
     420             :                                  * request-list */
     421           2 :                                 if (ospf6_lsa_compare(lsa, req) < 0) {
     422           2 :                                         if (is_debug)
     423           0 :                                                 zlog_debug(
     424             :                                                         "Received is newer, remove requesting");
     425           2 :                                         if (req == on->last_ls_req) {
     426           1 :                                                 req = ospf6_lsa_unlock(req);
     427           1 :                                                 on->last_ls_req = NULL;
     428             :                                         }
     429           2 :                                         if (req)
     430           2 :                                                 ospf6_lsdb_remove(req,
     431             :                                                         on->request_list);
     432           2 :                                         ospf6_check_nbr_loading(on);
     433             :                                         /* fall through */
     434             :                                 }
     435             :                         }
     436             :                 }
     437             : 
     438             :                 /* (c) If the new LSA was received from this neighbor,
     439             :                    examin next neighbor */
     440         867 :                 if (from == on) {
     441         234 :                         if (is_debug)
     442           0 :                                 zlog_debug(
     443             :                                         "Received is from the neighbor, next neighbor");
     444         234 :                         continue;
     445             :                 }
     446             : 
     447         633 :                 if ((oi->area->ospf6->inst_shutdown)
     448         516 :                     || CHECK_FLAG(lsa->flag, OSPF6_LSA_FLUSH)) {
     449         117 :                         if (is_debug)
     450           0 :                                 zlog_debug(
     451             :                                         "%s: Send LSA %s (age %d) update now",
     452             :                                         __func__, lsa->name,
     453             :                                         ntohs(lsa->header->age));
     454         117 :                         ospf6_lsupdate_send_neighbor_now(on, lsa);
     455         117 :                         continue;
     456             :                 } else {
     457             :                         /* (d) add retrans-list, schedule retransmission */
     458         516 :                         if (is_debug)
     459           0 :                                 zlog_debug("Add retrans-list of neighbor %s ",
     460             :                                            on->name);
     461             : 
     462             :                         /* Do not increment the retrans count if the lsa is
     463             :                          * already present in the retrans list.
     464             :                          */
     465        1032 :                         old = ospf6_lsdb_lookup(
     466         516 :                                 lsa->header->type, lsa->header->id,
     467         516 :                                 lsa->header->adv_router, on->retrans_list);
     468         516 :                         if (!old) {
     469         467 :                                 struct ospf6_lsa *orig;
     470         467 :                                 struct ospf6_lsdb *lsdb;
     471             : 
     472         467 :                                 if (is_debug)
     473           0 :                                         zlog_debug(
     474             :                                                 "Increment %s from retrans_list of %s",
     475             :                                                 lsa->name, on->name);
     476             : 
     477             :                                 /* Increment the retrans count on the original
     478             :                                  * copy of LSA if present, to maintain the
     479             :                                  * counter consistency.
     480             :                                  */
     481             : 
     482         467 :                                 lsdb = ospf6_get_scoped_lsdb(lsa);
     483         934 :                                 orig = ospf6_lsdb_lookup(
     484         467 :                                         lsa->header->type, lsa->header->id,
     485         467 :                                         lsa->header->adv_router, lsdb);
     486         467 :                                 if (orig)
     487         332 :                                         ospf6_increment_retrans_count(orig);
     488             :                                 else
     489         135 :                                         ospf6_increment_retrans_count(lsa);
     490             : 
     491         467 :                                 ospf6_lsdb_add(ospf6_lsa_copy(lsa),
     492             :                                                on->retrans_list);
     493         467 :                                 thread_add_timer(
     494             :                                         master, ospf6_lsupdate_send_neighbor,
     495             :                                         on, on->vlink
     496             :                                         ? on->vlink->retransmit_interval
     497             :                                         : on->ospf6_if->rxmt_interval,
     498             :                                         &on->thread_send_lsupdate);
     499         467 :                                 retrans_added++;
     500             :                         }
     501             :                 }
     502             :         }
     503             : 
     504             :         /* (2) examin next interface if not added to retrans-list */
     505        1191 :         if (retrans_added == 0) {
     506         806 :                 if (is_debug)
     507           0 :                         zlog_debug(
     508             :                                 "No retransmission scheduled, next interface %pOI",
     509             :                                 oi);
     510         806 :                 return;
     511             :         }
     512             : 
     513             :         /* (3) If the new LSA was received on this interface,
     514             :            and it was from DR or BDR, examin next interface */
     515         385 :         if (from && from->ospf6_if == oi
     516         173 :             && (from->router_id == oi->drouter
     517         117 :                 || from->router_id == oi->bdrouter)) {
     518          87 :                 if (is_debug)
     519           0 :                         zlog_debug(
     520             :                                 "Received is from the I/F's DR or BDR, next interface");
     521          87 :                 return;
     522             :         }
     523             : 
     524             :         /* (4) If the new LSA was received on this interface,
     525             :            and the interface state is BDR, examin next interface */
     526         156 :         if (from && from->ospf6_if == oi) {
     527          86 :                 if (oi->state == OSPF6_INTERFACE_BDR) {
     528          19 :                         if (is_debug)
     529           0 :                                 zlog_debug(
     530             :                                         "Received is from the I/F, itself BDR, next interface");
     531          19 :                         return;
     532             :                 }
     533          67 :                 SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
     534             :         }
     535             : 
     536             :         /* (5) flood the LSA out the interface. */
     537         279 :         if (is_debug)
     538           0 :                 zlog_debug("Schedule flooding for the interface");
     539         279 :         if ((oi->type == OSPF_IFTYPE_BROADCAST)
     540         279 :             || (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
     541         207 :                 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list);
     542         207 :                 thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
     543             :                                  &oi->thread_send_lsupdate);
     544             :         } else {
     545             :                 /* reschedule retransmissions to all neighbors */
     546         285 :                 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
     547         141 :                         THREAD_OFF(on->thread_send_lsupdate);
     548         141 :                         thread_add_event(master, ospf6_lsupdate_send_neighbor,
     549             :                                          on, 0, &on->thread_send_lsupdate);
     550             :                 }
     551             :         }
     552             : }
     553             : 
     554         732 : void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
     555             :                       struct ospf6_area *oa)
     556             : {
     557         732 :         struct listnode *node, *nnode;
     558         732 :         struct ospf6_interface *oi;
     559             : 
     560        2680 :         for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
     561        1216 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
     562         178 :                     && oi != OSPF6_INTERFACE(lsa->lsdb->data))
     563          71 :                         continue;
     564        1145 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AS
     565         288 :                     && oi->type == OSPF_IFTYPE_VIRTUALLINK)
     566           0 :                         continue;
     567             : 
     568        1145 :                 ospf6_flood_interface(from, lsa, oi);
     569             :         }
     570         732 : }
     571             : 
     572         696 : static void ospf6_flood_process(struct ospf6_neighbor *from,
     573             :                                 struct ospf6_lsa *lsa, struct ospf6 *process)
     574             : {
     575         696 :         struct listnode *node, *nnode;
     576         696 :         struct ospf6_area *oa;
     577             : 
     578        2296 :         for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
     579             : 
     580             :                 /* If unknown LSA and U-bit clear, treat as link local
     581             :                  * flooding scope
     582             :                  */
     583         904 :                 if (!OSPF6_LSA_IS_KNOWN(lsa->header->type)
     584           0 :                     && !(ntohs(lsa->header->type) & OSPF6_LSTYPE_UBIT_MASK)
     585           0 :                     && (oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)) {
     586             : 
     587           0 :                         if (IS_OSPF6_DEBUG_FLOODING)
     588           0 :                                 zlog_debug("Unknown LSA, do not flood");
     589           0 :                         continue;
     590             :                 }
     591             : 
     592         904 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
     593         602 :                     && oa != OSPF6_AREA(lsa->lsdb->data))
     594         144 :                         continue;
     595         760 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
     596         135 :                     && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
     597          28 :                         continue;
     598             : 
     599         732 :                 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
     600         167 :                     && (IS_AREA_STUB(oa) || IS_AREA_NSSA(oa)))
     601           0 :                         continue;
     602             : 
     603             :                 /* Check for NSSA LSA */
     604         732 :                 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
     605           0 :                     && !IS_AREA_NSSA(oa) && !OSPF6_LSA_IS_MAXAGE(lsa))
     606           0 :                         continue;
     607             : 
     608         732 :                 ospf6_flood_area(from, lsa, oa);
     609             :         }
     610         696 : }
     611             : 
     612         696 : void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
     613             : {
     614         696 :         struct ospf6 *ospf6;
     615             : 
     616         696 :         ospf6 = ospf6_get_by_lsdb(lsa);
     617         696 :         if (ospf6 == NULL)
     618             :                 return;
     619             : 
     620         696 :         ospf6_flood_process(from, lsa, ospf6);
     621             : }
     622             : 
     623         869 : static void ospf6_flood_clear_interface(struct ospf6_lsa *lsa,
     624             :                                         struct ospf6_interface *oi)
     625             : {
     626         869 :         struct listnode *node, *nnode;
     627         869 :         struct ospf6_neighbor *on;
     628         869 :         struct ospf6_lsa *rem;
     629             : 
     630        2576 :         for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
     631        1676 :                 rem = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
     632         838 :                                         lsa->header->adv_router,
     633             :                                         on->retrans_list);
     634         838 :                 if (rem && !ospf6_lsa_compare(rem, lsa)) {
     635          87 :                         if (IS_OSPF6_DEBUG_FLOODING
     636          87 :                             || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
     637           0 :                                 zlog_debug("Remove %s from retrans_list of %s",
     638             :                                            rem->name, on->name);
     639          87 :                         ospf6_decrement_retrans_count(rem);
     640          87 :                         ospf6_lsdb_remove(rem, on->retrans_list);
     641             :                 }
     642             :         }
     643         869 : }
     644             : 
     645         540 : void ospf6_flood_clear_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
     646             : {
     647         540 :         struct listnode *node, *nnode;
     648         540 :         struct ospf6_interface *oi;
     649             : 
     650        1969 :         for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
     651         889 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
     652          57 :                     && oi != OSPF6_INTERFACE(lsa->lsdb->data))
     653          20 :                         continue;
     654         869 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AS
     655         134 :                     && oi->type == OSPF_IFTYPE_VIRTUALLINK)
     656           0 :                         continue;
     657             : 
     658         869 :                 ospf6_flood_clear_interface(lsa, oi);
     659             :         }
     660         540 : }
     661             : 
     662         526 : static void ospf6_flood_clear_process(struct ospf6_lsa *lsa,
     663             :                                       struct ospf6 *process)
     664             : {
     665         526 :         struct listnode *node, *nnode;
     666         526 :         struct ospf6_area *oa;
     667             : 
     668        1735 :         for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
     669         683 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
     670         559 :                     && oa != OSPF6_AREA(lsa->lsdb->data))
     671         134 :                         continue;
     672         549 :                 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
     673          46 :                     && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
     674           9 :                         continue;
     675             : 
     676         540 :                 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
     677          78 :                     && (IS_AREA_STUB(oa) || (IS_AREA_NSSA(oa))))
     678           0 :                         continue;
     679             :                 /* Check for NSSA LSA */
     680         540 :                 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
     681           0 :                     && !IS_AREA_NSSA(oa))
     682           0 :                         continue;
     683             : 
     684         540 :                 ospf6_flood_clear_area(lsa, oa);
     685             :         }
     686         526 : }
     687             : 
     688         526 : void ospf6_flood_clear(struct ospf6_lsa *lsa)
     689             : {
     690         526 :         struct ospf6 *ospf6;
     691             : 
     692         526 :         ospf6 = ospf6_get_by_lsdb(lsa);
     693         526 :         if (ospf6 == NULL)
     694             :                 return;
     695         526 :         ospf6_flood_clear_process(lsa, ospf6);
     696             : }
     697             : 
     698             : 
     699             : /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
     700         284 : static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa *lsa,
     701             :                                            int ismore_recent,
     702             :                                            struct ospf6_neighbor *from)
     703             : {
     704         284 :         struct ospf6_interface *oi;
     705         284 :         int is_debug = 0;
     706             : 
     707         284 :         if (IS_OSPF6_DEBUG_FLOODING
     708         284 :             || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
     709             :                 is_debug++;
     710             : 
     711         284 :         assert(from && from->ospf6_if);
     712         284 :         oi = from->ospf6_if;
     713             : 
     714             :         /* LSA is more recent than database copy, but was not flooded
     715             :            back out receiving interface. Delayed acknowledgement sent
     716             :            if advertisement received from Designated Router,
     717             :            otherwide do nothing. */
     718         284 :         if (ismore_recent < 0) {
     719         154 :                 if (oi->drouter == from->router_id) {
     720         135 :                         if (is_debug)
     721           0 :                                 zlog_debug(
     722             :                                         "Delayed acknowledgement (BDR & MoreRecent & from DR)");
     723             :                         /* Delayed acknowledgement */
     724         135 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
     725         135 :                         thread_add_timer(master, ospf6_lsack_send_interface, oi,
     726             :                                          3, &oi->thread_send_lsack);
     727             :                 } else {
     728          19 :                         if (is_debug)
     729           0 :                                 zlog_debug(
     730             :                                         "No acknowledgement (BDR & MoreRecent & ! from DR)");
     731             :                 }
     732         154 :                 return;
     733             :         }
     734             : 
     735             :         /* LSA is a duplicate, and was treated as an implied acknowledgement.
     736             :            Delayed acknowledgement sent if advertisement received from
     737             :            Designated Router, otherwise do nothing */
     738         130 :         if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
     739             :             && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
     740          33 :                 if (oi->drouter == from->router_id) {
     741          29 :                         if (is_debug)
     742           0 :                                 zlog_debug(
     743             :                                         "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
     744             :                         /* Delayed acknowledgement */
     745          29 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
     746          29 :                         thread_add_timer(master, ospf6_lsack_send_interface, oi,
     747             :                                          3, &oi->thread_send_lsack);
     748             :                 } else {
     749           4 :                         if (is_debug)
     750           0 :                                 zlog_debug(
     751             :                                         "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
     752             :                 }
     753          33 :                 return;
     754             :         }
     755             : 
     756             :         /* LSA is a duplicate, and was not treated as an implied
     757             :            acknowledgement.
     758             :            Direct acknowledgement sent */
     759          97 :         if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
     760             :             && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
     761          97 :                 if (is_debug)
     762           0 :                         zlog_debug("Direct acknowledgement (BDR & Duplicate)");
     763          97 :                 ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
     764          97 :                 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
     765             :                                  &from->thread_send_lsack);
     766          97 :                 return;
     767             :         }
     768             : 
     769             :         /* LSA's LS age is equal to Maxage, and there is no current instance
     770             :            of the LSA in the link state database, and none of router's
     771             :            neighbors are in states Exchange or Loading */
     772             :         /* Direct acknowledgement sent, but this case is handled in
     773             :            early of ospf6_receive_lsa () */
     774             : }
     775             : 
     776         436 : static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa *lsa,
     777             :                                            int ismore_recent,
     778             :                                            struct ospf6_neighbor *from)
     779             : {
     780         436 :         struct ospf6_interface *oi;
     781         436 :         int is_debug = 0;
     782             : 
     783         436 :         if (IS_OSPF6_DEBUG_FLOODING
     784         436 :             || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
     785             :                 is_debug++;
     786             : 
     787         436 :         assert(from && from->ospf6_if);
     788         436 :         oi = from->ospf6_if;
     789             : 
     790             :         /* LSA has been flood back out receiving interface.
     791             :            No acknowledgement sent. */
     792         436 :         if (CHECK_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK)) {
     793          67 :                 if (is_debug)
     794           0 :                         zlog_debug("No acknowledgement (AllOther & FloodBack)");
     795          67 :                 return;
     796             :         }
     797             : 
     798             :         /* LSA is more recent than database copy, but was not flooded
     799             :            back out receiving interface. Delayed acknowledgement sent. */
     800         369 :         if (ismore_recent < 0) {
     801         156 :                 if (is_debug)
     802           0 :                         zlog_debug(
     803             :                                 "Delayed acknowledgement (AllOther & MoreRecent)");
     804             :                 /* Delayed acknowledgement */
     805         156 :                 if (oi->type == OSPF_IFTYPE_VIRTUALLINK) {
     806           0 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
     807           0 :                         thread_add_timer(master, ospf6_lsack_send_neighbor,
     808             :                                          from, 3, &from->thread_send_lsack);
     809             :                 } else {
     810         156 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
     811         156 :                         thread_add_timer(master, ospf6_lsack_send_interface, oi,
     812             :                                          3, &oi->thread_send_lsack);
     813             :                 }
     814         156 :                 return;
     815             :         }
     816             : 
     817             :         /* LSA is a duplicate, and was treated as an implied acknowledgement.
     818             :            No acknowledgement sent. */
     819         213 :         if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
     820             :             && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
     821          70 :                 if (is_debug)
     822           0 :                         zlog_debug(
     823             :                                 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
     824          70 :                 return;
     825             :         }
     826             : 
     827             :         /* LSA is a duplicate, and was not treated as an implied
     828             :            acknowledgement.
     829             :            Direct acknowledgement sent */
     830         143 :         if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
     831             :             && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
     832         143 :                 if (is_debug)
     833           0 :                         zlog_debug(
     834             :                                 "Direct acknowledgement (AllOther & Duplicate)");
     835         143 :                 ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
     836         143 :                 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
     837             :                                  &from->thread_send_lsack);
     838         143 :                 return;
     839             :         }
     840             : 
     841             :         /* LSA's LS age is equal to Maxage, and there is no current instance
     842             :            of the LSA in the link state database, and none of router's
     843             :            neighbors are in states Exchange or Loading */
     844             :         /* Direct acknowledgement sent, but this case is handled in
     845             :            early of ospf6_receive_lsa () */
     846             : }
     847             : 
     848         720 : static void ospf6_acknowledge_lsa(struct ospf6_lsa *lsa, int ismore_recent,
     849             :                                   struct ospf6_neighbor *from)
     850             : {
     851         720 :         struct ospf6_interface *oi;
     852             : 
     853         720 :         assert(from && from->ospf6_if);
     854         720 :         oi = from->ospf6_if;
     855             : 
     856         720 :         if (oi->state == OSPF6_INTERFACE_BDR)
     857         284 :                 ospf6_acknowledge_lsa_bdrouter(lsa, ismore_recent, from);
     858             :         else
     859         436 :                 ospf6_acknowledge_lsa_allother(lsa, ismore_recent, from);
     860         720 : }
     861             : 
     862             : /* RFC2328 section 13 (4):
     863             :    if MaxAge LSA and if we have no instance, and no neighbor
     864             :    is in states Exchange or Loading
     865             :    returns 1 if match this case, else returns 0 */
     866         886 : static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa,
     867             :                                     struct ospf6_neighbor *from)
     868             : {
     869         886 :         struct ospf6_neighbor *on;
     870         886 :         struct ospf6_interface *oi;
     871         886 :         struct ospf6_area *oa;
     872         886 :         struct ospf6 *process = NULL;
     873         886 :         struct listnode *i, *j, *k;
     874         886 :         int count = 0;
     875             : 
     876         886 :         if (!OSPF6_LSA_IS_MAXAGE(lsa))
     877             :                 return 0;
     878             : 
     879         182 :         if (ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
     880         182 :                               lsa->header->adv_router, lsa->lsdb))
     881             :                 return 0;
     882             : 
     883          30 :         process = from->ospf6_if->area->ospf6;
     884             : 
     885          95 :         for (ALL_LIST_ELEMENTS_RO(process->area_list, i, oa))
     886         132 :                 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
     887         179 :                         for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on))
     888          55 :                                 if (on->state == OSPF6_NEIGHBOR_EXCHANGE
     889          55 :                                     || on->state == OSPF6_NEIGHBOR_LOADING)
     890          20 :                                         count++;
     891             : 
     892          30 :         if (count == 0)
     893             :                 return 1;
     894             :         return 0;
     895             : }
     896             : 
     897         310 : static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa *lsa,
     898             :                                         struct ospf6_neighbor *from)
     899             : {
     900         310 :         struct timeval now, res;
     901         310 :         unsigned int time_delta_ms;
     902             : 
     903         310 :         monotime(&now);
     904         310 :         timersub(&now, &lsa->installed, &res);
     905         310 :         time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec / 1000);
     906             : 
     907         310 :         if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) {
     908         300 :                 if (IS_OSPF6_DEBUG_FLOODING ||
     909         150 :                     IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
     910           0 :                         zlog_debug(
     911             :                                 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
     912             :                                 time_delta_ms,
     913             :                                 from->ospf6_if->area->ospf6->lsa_minarrival);
     914         150 :                 return true;
     915             :         }
     916             :         return false;
     917             : }
     918             : 
     919             : /* RFC2328 section 13 The Flooding Procedure */
     920         886 : void ospf6_receive_lsa(struct ospf6_neighbor *from,
     921             :                        struct ospf6_lsa_header *lsa_header)
     922             : {
     923         886 :         struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
     924         886 :         int ismore_recent;
     925         886 :         int is_debug = 0;
     926             : 
     927         886 :         ismore_recent = 1;
     928         886 :         assert(from);
     929             : 
     930             :         /* if we receive a LSA with invalid seqnum drop it */
     931         886 :         if (ntohl(lsa_header->seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER) {
     932           0 :                 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header->type)) {
     933           0 :                         zlog_debug(
     934             :                                 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
     935             :                                 ospf6_lstype_name(lsa_header->type),
     936             :                                 &lsa_header->id, &lsa_header->adv_router,
     937             :                                 ntohl(lsa_header->seqnum));
     938             :                 }
     939           0 :                 return;
     940             :         }
     941             : 
     942             :         /* make lsa structure for received lsa */
     943         886 :         new = ospf6_lsa_create(lsa_header);
     944             : 
     945         886 :         if (IS_OSPF6_DEBUG_FLOODING
     946         886 :             || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header->type)) {
     947           0 :                 is_debug++;
     948           0 :                 zlog_debug("LSA Receive from %s", from->name);
     949           0 :                 ospf6_lsa_header_print(new);
     950             :         }
     951             : 
     952             :         /* (1) LSA Checksum */
     953         886 :         if (!ospf6_lsa_checksum_valid(new->header)) {
     954           0 :                 if (is_debug)
     955           0 :                         zlog_debug("Wrong LSA Checksum, discard");
     956           0 :                 ospf6_lsa_delete(new);
     957           0 :                 return;
     958             :         }
     959             : 
     960             :         /* (2) Examine the LSA's LS type.
     961             :            RFC2470 3.5.1. Receiving Link State Update packets  */
     962         886 :         if (IS_AREA_STUB(from->ospf6_if->area)
     963           0 :             && OSPF6_LSA_SCOPE(new->header->type) == OSPF6_SCOPE_AS) {
     964           0 :                 if (is_debug)
     965           0 :                         zlog_debug(
     966             :                                 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
     967           0 :                 ospf6_lsa_delete(new);
     968           0 :                 return;
     969             :         }
     970             : 
     971         886 :         if (from->vlink
     972           0 :             && OSPF6_LSA_SCOPE(new->header->type) == OSPF6_SCOPE_AS) {
     973           0 :                 if (is_debug)
     974           0 :                         zlog_debug(
     975             :                                 "AS-External-LSA (or AS-scope LSA) over virtual link, discard");
     976           0 :                 ospf6_lsa_delete(new);
     977           0 :                 return;
     978             :         }
     979             : 
     980             :         /* (3) LSA which have reserved scope is discarded
     981             :            RFC2470 3.5.1. Receiving Link State Update packets  */
     982             :         /* Flooding scope check. LSAs with unknown scope are discarded here.
     983             :            Set appropriate LSDB for the LSA */
     984         886 :         switch (OSPF6_LSA_SCOPE(new->header->type)) {
     985          80 :         case OSPF6_SCOPE_LINKLOCAL:
     986          80 :                 if (from->ospf6_if->type == OSPF_IFTYPE_VIRTUALLINK) {
     987           0 :                         if (is_debug)
     988           0 :                                 zlog_debug("Link-scoped LSA on virtual link!");
     989           0 :                         ospf6_lsa_delete(new);
     990           0 :                         return;
     991             :                 }
     992          80 :                 new->lsdb = from->ospf6_if->lsdb;
     993          80 :                 break;
     994         621 :         case OSPF6_SCOPE_AREA:
     995         621 :                 new->lsdb = from->ospf6_if->area->lsdb;
     996         621 :                 break;
     997         185 :         case OSPF6_SCOPE_AS:
     998         185 :                 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
     999         185 :                 break;
    1000           0 :         default:
    1001           0 :                 if (is_debug)
    1002           0 :                         zlog_debug("LSA has reserved scope, discard");
    1003           0 :                 ospf6_lsa_delete(new);
    1004           0 :                 return;
    1005             :         }
    1006             : 
    1007             :         /* (4) if MaxAge LSA and if we have no instance, and no neighbor
    1008             :                is in states Exchange or Loading */
    1009         886 :         if (ospf6_is_maxage_lsa_drop(new, from)) {
    1010             :                 /* log */
    1011          14 :                 if (is_debug)
    1012           0 :                         zlog_debug(
    1013             :                                 "Drop MaxAge LSA with direct acknowledgement.");
    1014             : 
    1015             :                 /* a) Acknowledge back to neighbor (Direct acknowledgement,
    1016             :                  * 13.5) */
    1017          14 :                 ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list);
    1018          14 :                 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
    1019             :                                  &from->thread_send_lsack);
    1020             : 
    1021             :                 /* b) Discard */
    1022          14 :                 ospf6_lsa_delete(new);
    1023          14 :                 return;
    1024             :         }
    1025             : 
    1026             :         /* (5) */
    1027             :         /* lookup the same database copy in lsdb */
    1028        1744 :         old = ospf6_lsdb_lookup(new->header->type, new->header->id,
    1029         872 :                                 new->header->adv_router, new->lsdb);
    1030         872 :         if (old) {
    1031         653 :                 ismore_recent = ospf6_lsa_compare(new, old);
    1032         653 :                 if (ntohl(new->header->seqnum) == ntohl(old->header->seqnum)) {
    1033         435 :                         if (is_debug)
    1034           0 :                                 zlog_debug("Received is duplicated LSA");
    1035         435 :                         SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE);
    1036             :                 }
    1037             :         }
    1038             : 
    1039             :         /* if no database copy or received is more recent */
    1040         872 :         if (old == NULL || ismore_recent < 0) {
    1041         511 :                 bool self_originated;
    1042             : 
    1043             :                 /* in case we have no database copy */
    1044         511 :                 ismore_recent = -1;
    1045             : 
    1046             :                 /* (a) MinLSArrival check */
    1047         511 :                 if (old) {
    1048         292 :                         if (ospf6_lsa_check_min_arrival(old, from)) {
    1049         134 :                                 ospf6_lsa_delete(new);
    1050         134 :                                 return; /* examin next lsa */
    1051             :                         }
    1052             :                 }
    1053             : 
    1054         377 :                 monotime(&new->received);
    1055             : 
    1056         377 :                 if (is_debug)
    1057           0 :                         zlog_debug(
    1058             :                                 "Install, Flood, Possibly acknowledge the received LSA");
    1059             : 
    1060             :                 /* Remove older copies of this LSA from retx lists */
    1061         377 :                 if (old)
    1062         158 :                         ospf6_flood_clear(old);
    1063             : 
    1064         377 :                 self_originated = (new->header->adv_router
    1065         377 :                                    == from->ospf6_if->area->ospf6->router_id);
    1066             : 
    1067             :                 /* Received non-self-originated Grace LSA. */
    1068         377 :                 if (IS_GRACE_LSA(new) && !self_originated) {
    1069           0 :                         struct ospf6 *ospf6;
    1070             : 
    1071           0 :                         ospf6 = ospf6_get_by_lsdb(new);
    1072             : 
    1073           0 :                         assert(ospf6);
    1074             : 
    1075           0 :                         if (OSPF6_LSA_IS_MAXAGE(new)) {
    1076             : 
    1077           0 :                                 if (IS_DEBUG_OSPF6_GR)
    1078           0 :                                         zlog_debug(
    1079             :                                                 "%s, Received a maxage GraceLSA from router %pI4",
    1080             :                                                 __func__,
    1081             :                                                 &new->header->adv_router);
    1082           0 :                                 if (old) {
    1083           0 :                                         ospf6_process_maxage_grace_lsa(
    1084             :                                                 ospf6, new, from);
    1085             :                                 } else {
    1086           0 :                                         if (IS_DEBUG_OSPF6_GR)
    1087           0 :                                                 zlog_debug(
    1088             :                                                         "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
    1089             :                                                         __func__);
    1090           0 :                                         return;
    1091             :                                 }
    1092             :                         } else {
    1093             : 
    1094           0 :                                 if (IS_DEBUG_OSPF6_GR)
    1095           0 :                                         zlog_debug(
    1096             :                                                 "%s, Received a GraceLSA from router %pI4",
    1097             :                                                 __func__,
    1098             :                                                 &new->header->adv_router);
    1099             : 
    1100           0 :                                 if (ospf6_process_grace_lsa(ospf6, new, from)
    1101             :                                     == OSPF6_GR_NOT_HELPER) {
    1102           0 :                                         if (IS_DEBUG_OSPF6_GR)
    1103           0 :                                                 zlog_debug(
    1104             :                                                         "%s, Not moving to HELPER role, So dicarding GraceLSA",
    1105             :                                                         __func__);
    1106           0 :                                         return;
    1107             :                                 }
    1108             :                         }
    1109             :                 }
    1110             : 
    1111             :                 /* (b) immediately flood and (c) remove from all retrans-list */
    1112             :                 /* Prevent self-originated LSA to be flooded. this is to make
    1113             :                  * reoriginated instance of the LSA not to be rejected by other
    1114             :                  * routers due to MinLSArrival.
    1115             :                  */
    1116         377 :                 if (!self_originated)
    1117         377 :                         ospf6_flood(from, new);
    1118             : 
    1119             :                 /* (d), installing lsdb, which may cause routing
    1120             :                         table calculation (replacing database copy) */
    1121         377 :                 ospf6_install_lsa(new);
    1122             : 
    1123         377 :                 if (OSPF6_LSA_IS_MAXAGE(new))
    1124          84 :                         ospf6_maxage_remove(from->ospf6_if->area->ospf6);
    1125             : 
    1126             :                 /* (e) possibly acknowledge */
    1127         377 :                 ospf6_acknowledge_lsa(new, ismore_recent, from);
    1128             : 
    1129             :                 /* (f) Self Originated LSA, section 13.4 */
    1130         377 :                 if (self_originated) {
    1131           0 :                         if (from->ospf6_if->area->ospf6->gr_info
    1132           0 :                                     .restart_in_progress) {
    1133           0 :                                 if (IS_DEBUG_OSPF6_GR)
    1134           0 :                                         zlog_debug(
    1135             :                                                 "Graceful Restart in progress -- not flushing self-originated LSA: %s",
    1136             :                                                 new->name);
    1137           0 :                                 return;
    1138             :                         }
    1139             : 
    1140             :                         /* Self-originated LSA (newer than ours) is received
    1141             :                            from
    1142             :                            another router. We have to make a new instance of the
    1143             :                            LSA
    1144             :                            or have to flush this LSA. */
    1145           0 :                         if (is_debug) {
    1146           0 :                                 zlog_debug(
    1147             :                                         "Newer instance of the self-originated LSA");
    1148           0 :                                 zlog_debug("Schedule reorigination");
    1149             :                         }
    1150           0 :                         thread_add_event(master, ospf6_lsa_refresh, new, 0,
    1151             :                                          &new->refresh);
    1152             :                 }
    1153             : 
    1154         377 :                 struct ospf6 *ospf6 = from->ospf6_if->area->ospf6;
    1155         377 :                 struct ospf6_area *area = from->ospf6_if->area;
    1156         377 :                 if (ospf6->gr_info.restart_in_progress)
    1157           0 :                         ospf6_gr_check_lsdb_consistency(ospf6, area);
    1158             : 
    1159         377 :                 return;
    1160             :         }
    1161             : 
    1162             :         /* (6) if there is instance on sending neighbor's request list */
    1163         361 :         if (ospf6_lsdb_lookup(new->header->type, new->header->id,
    1164         361 :                               new->header->adv_router, from->request_list)) {
    1165             :                 /* if no database copy, should go above state (5) */
    1166           0 :                 assert(old);
    1167             : 
    1168           0 :                 zlog_warn(
    1169             :                         "Received is not newer, on the neighbor %s request-list",
    1170             :                         from->name);
    1171           0 :                 zlog_warn(
    1172             :                         "BadLSReq, discard the received LSA lsa %s send badLSReq",
    1173             :                         new->name);
    1174             : 
    1175             :                 /* BadLSReq */
    1176           0 :                 thread_add_event(master, bad_lsreq, from, 0, NULL);
    1177             : 
    1178           0 :                 ospf6_lsa_delete(new);
    1179           0 :                 return;
    1180             :         }
    1181             : 
    1182             :         /* (7) if neither one is more recent */
    1183         361 :         if (ismore_recent == 0) {
    1184         343 :                 if (is_debug)
    1185           0 :                         zlog_debug(
    1186             :                                 "The same instance as database copy (neither recent)");
    1187             : 
    1188             :                 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
    1189             :                  */
    1190         686 :                 rem = ospf6_lsdb_lookup(new->header->type, new->header->id,
    1191         343 :                                         new->header->adv_router,
    1192             :                                         from->retrans_list);
    1193         343 :                 if (rem) {
    1194         103 :                         if (is_debug) {
    1195           0 :                                 zlog_debug(
    1196             :                                         "It is on the neighbor's retrans-list.");
    1197           0 :                                 zlog_debug(
    1198             :                                         "Treat as an Implied acknowledgement");
    1199             :                         }
    1200         103 :                         SET_FLAG(new->flag, OSPF6_LSA_IMPLIEDACK);
    1201         103 :                         ospf6_decrement_retrans_count(rem);
    1202         103 :                         ospf6_lsdb_remove(rem, from->retrans_list);
    1203             :                 }
    1204             : 
    1205         343 :                 if (is_debug)
    1206           0 :                         zlog_debug("Possibly acknowledge and then discard");
    1207             : 
    1208             :                 /* (b) possibly acknowledge */
    1209         343 :                 ospf6_acknowledge_lsa(new, ismore_recent, from);
    1210             : 
    1211         343 :                 ospf6_lsa_delete(new);
    1212         343 :                 return;
    1213             :         }
    1214             : 
    1215             :         /* (8) previous database copy is more recent */
    1216             :         {
    1217          18 :                 assert(old);
    1218             : 
    1219             :                 /* If database copy is in 'Seqnumber Wrapping',
    1220             :                    simply discard the received LSA */
    1221          18 :                 if (OSPF6_LSA_IS_MAXAGE(old)
    1222           1 :                     && old->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)) {
    1223           0 :                         if (is_debug) {
    1224           0 :                                 zlog_debug("The LSA is in Seqnumber Wrapping");
    1225           0 :                                 zlog_debug("MaxAge & MaxSeqNum, discard");
    1226             :                         }
    1227           0 :                         ospf6_lsa_delete(new);
    1228           0 :                         return;
    1229             :                 }
    1230             : 
    1231             :                 /* Otherwise, Send database copy of this LSA to this neighbor */
    1232             :                 {
    1233          18 :                         if (is_debug) {
    1234           0 :                                 zlog_debug("Database copy is more recent.");
    1235           0 :                                 zlog_debug(
    1236             :                                         "Send back directly and then discard");
    1237             :                         }
    1238             : 
    1239             :                         /* Neighbor router sent recent age for LSA,
    1240             :                          * Router could be restarted while current copy is
    1241             :                          * MAXAGEd and not removed.*/
    1242          18 :                         if (OSPF6_LSA_IS_MAXAGE(old)
    1243           1 :                             && !OSPF6_LSA_IS_MAXAGE(new)) {
    1244           1 :                                 if (new->header->adv_router
    1245           1 :                                     != from->ospf6_if->area->ospf6->router_id) {
    1246           0 :                                         if (is_debug)
    1247           0 :                                                 zlog_debug(
    1248             :                                                         "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
    1249             :                                                         __PRETTY_FUNCTION__, old->name);
    1250           0 :                                         ospf6_lsa_purge(old);
    1251           0 :                                         ospf6_flood(from, new);
    1252           0 :                                         ospf6_install_lsa(new);
    1253           0 :                                         return;
    1254             :                                 }
    1255             :                                 /* For self-originated LSA, only trust
    1256             :                                  * ourselves. Fall through and send
    1257             :                                  * LS Update with our current copy.
    1258             :                                  */
    1259           1 :                                 if (is_debug)
    1260           0 :                                         zlog_debug(
    1261             :                                                 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
    1262             :                                                 __PRETTY_FUNCTION__, old->name);
    1263             :                         }
    1264             : 
    1265             :                         /* MinLSArrival check as per RFC 2328 13 (8) */
    1266          18 :                         if (ospf6_lsa_check_min_arrival(old, from)) {
    1267          16 :                                 ospf6_lsa_delete(new);
    1268          16 :                                 return; /* examin next lsa */
    1269             :                         }
    1270             : 
    1271           2 :                         ospf6_lsdb_add(ospf6_lsa_copy(old),
    1272             :                                        from->lsupdate_list);
    1273           2 :                         thread_add_event(master, ospf6_lsupdate_send_neighbor,
    1274             :                                          from, 0, &from->thread_send_lsupdate);
    1275             : 
    1276           2 :                         ospf6_lsa_delete(new);
    1277           2 :                         return;
    1278             :                 }
    1279             :         }
    1280             : }
    1281             : 
    1282           0 : DEFUN (debug_ospf6_flooding,
    1283             :        debug_ospf6_flooding_cmd,
    1284             :        "debug ospf6 flooding",
    1285             :        DEBUG_STR
    1286             :        OSPF6_STR
    1287             :        "Debug OSPFv3 flooding function\n"
    1288             :       )
    1289             : {
    1290           0 :         OSPF6_DEBUG_FLOODING_ON();
    1291           0 :         return CMD_SUCCESS;
    1292             : }
    1293             : 
    1294           0 : DEFUN (no_debug_ospf6_flooding,
    1295             :        no_debug_ospf6_flooding_cmd,
    1296             :        "no debug ospf6 flooding",
    1297             :        NO_STR
    1298             :        DEBUG_STR
    1299             :        OSPF6_STR
    1300             :        "Debug OSPFv3 flooding function\n"
    1301             :       )
    1302             : {
    1303           0 :         OSPF6_DEBUG_FLOODING_OFF();
    1304           0 :         return CMD_SUCCESS;
    1305             : }
    1306             : 
    1307           0 : int config_write_ospf6_debug_flood(struct vty *vty)
    1308             : {
    1309           0 :         if (IS_OSPF6_DEBUG_FLOODING)
    1310           0 :                 vty_out(vty, "debug ospf6 flooding\n");
    1311           0 :         return 0;
    1312             : }
    1313             : 
    1314          16 : void install_element_ospf6_debug_flood(void)
    1315             : {
    1316          16 :         install_element(ENABLE_NODE, &debug_ospf6_flooding_cmd);
    1317          16 :         install_element(ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
    1318          16 :         install_element(CONFIG_NODE, &debug_ospf6_flooding_cmd);
    1319          16 :         install_element(CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
    1320          16 : }

Generated by: LCOV version v1.16-topotato