back to topotato report
topotato coverage report
Current view: top level - ospfd - ospfd.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 545 1146 47.6 %
Date: 2023-02-24 14:41:08 Functions: 41 92 44.6 %

          Line data    Source code
       1             : /* OSPF version 2 daemon program.
       2             :  * Copyright (C) 1999, 2000 Toshiaki Takada
       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 "thread.h"
      24             : #include "vty.h"
      25             : #include "command.h"
      26             : #include "linklist.h"
      27             : #include "prefix.h"
      28             : #include "table.h"
      29             : #include "if.h"
      30             : #include "memory.h"
      31             : #include "stream.h"
      32             : #include "log.h"
      33             : #include "sockunion.h" /* for inet_aton () */
      34             : #include "zclient.h"
      35             : #include "routemap.h"
      36             : #include "plist.h"
      37             : #include "sockopt.h"
      38             : #include "bfd.h"
      39             : #include "libfrr.h"
      40             : #include "defaults.h"
      41             : #include "lib_errors.h"
      42             : #include "ldp_sync.h"
      43             : 
      44             : #include "ospfd/ospfd.h"
      45             : #include "ospfd/ospf_bfd.h"
      46             : #include "ospfd/ospf_network.h"
      47             : #include "ospfd/ospf_interface.h"
      48             : #include "ospfd/ospf_ism.h"
      49             : #include "ospfd/ospf_asbr.h"
      50             : #include "ospfd/ospf_lsa.h"
      51             : #include "ospfd/ospf_lsdb.h"
      52             : #include "ospfd/ospf_neighbor.h"
      53             : #include "ospfd/ospf_nsm.h"
      54             : #include "ospfd/ospf_spf.h"
      55             : #include "ospfd/ospf_packet.h"
      56             : #include "ospfd/ospf_dump.h"
      57             : #include "ospfd/ospf_route.h"
      58             : #include "ospfd/ospf_zebra.h"
      59             : #include "ospfd/ospf_abr.h"
      60             : #include "ospfd/ospf_flood.h"
      61             : #include "ospfd/ospf_ase.h"
      62             : #include "ospfd/ospf_ldp_sync.h"
      63             : #include "ospfd/ospf_gr.h"
      64             : #include "ospfd/ospf_apiserver.h"
      65             : 
      66             : 
      67             : DEFINE_QOBJ_TYPE(ospf);
      68             : 
      69             : /* OSPF process wide configuration. */
      70             : static struct ospf_master ospf_master;
      71             : 
      72             : /* OSPF process wide configuration pointer to export. */
      73             : struct ospf_master *om;
      74             : 
      75             : unsigned short ospf_instance;
      76             : 
      77             : extern struct zclient *zclient;
      78             : 
      79             : 
      80             : static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
      81             : static void ospf_network_free(struct ospf *, struct ospf_network *);
      82             : static void ospf_area_free(struct ospf_area *);
      83             : static void ospf_network_run(struct prefix *, struct ospf_area *);
      84             : static void ospf_network_run_interface(struct ospf *, struct interface *,
      85             :                                        struct prefix *, struct ospf_area *);
      86             : static void ospf_network_run_subnet(struct ospf *, struct connected *,
      87             :                                     struct prefix *, struct ospf_area *);
      88             : static int ospf_network_match_iface(const struct connected *,
      89             :                                     const struct prefix *);
      90             : static void ospf_finish_final(struct ospf *);
      91             : 
      92             : /* API to clean refresh queues and LSAs */
      93           4 : static void ospf_free_refresh_queue(struct ospf *ospf)
      94             : {
      95        1088 :         for (int i = 0; i < OSPF_LSA_REFRESHER_SLOTS; i++) {
      96        1084 :                 struct list *list = ospf->lsa_refresh_queue.qs[i];
      97        1084 :                 struct listnode *node, *nnode;
      98        1084 :                 struct ospf_lsa *lsa;
      99             : 
     100        1084 :                 if (list) {
     101           0 :                         for (ALL_LIST_ELEMENTS(list, node, nnode, lsa)) {
     102           0 :                                 listnode_delete(list, lsa);
     103           0 :                                 lsa->refresh_list = -1;
     104           0 :                                 ospf_lsa_unlock(&lsa);
     105             :                         }
     106           0 :                         list_delete(&list);
     107           0 :                         ospf->lsa_refresh_queue.qs[i] = NULL;
     108             :                 }
     109             :         }
     110           4 : }
     111             : #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
     112             : 
     113           0 : int p_spaces_compare_func(const struct p_space *a, const struct p_space *b)
     114             : {
     115           0 :         if (a->protected_resource->type == OSPF_TI_LFA_LINK_PROTECTION
     116           0 :             && b->protected_resource->type == OSPF_TI_LFA_LINK_PROTECTION)
     117           0 :                 return (a->protected_resource->link->link_id.s_addr
     118           0 :                         - b->protected_resource->link->link_id.s_addr);
     119             : 
     120           0 :         if (a->protected_resource->type == OSPF_TI_LFA_NODE_PROTECTION
     121           0 :             && b->protected_resource->type == OSPF_TI_LFA_NODE_PROTECTION)
     122           0 :                 return (a->protected_resource->router_id.s_addr
     123           0 :                         - b->protected_resource->router_id.s_addr);
     124             : 
     125             :         /* This should not happen */
     126             :         return 0;
     127             : }
     128             : 
     129           0 : int q_spaces_compare_func(const struct q_space *a, const struct q_space *b)
     130             : {
     131           0 :         return (a->root->id.s_addr - b->root->id.s_addr);
     132             : }
     133             : 
     134             : DECLARE_RBTREE_UNIQ(p_spaces, struct p_space, p_spaces_item,
     135             :                     p_spaces_compare_func);
     136             : 
     137          16 : void ospf_process_refresh_data(struct ospf *ospf, bool reset)
     138             : {
     139          16 :         struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
     140          16 :         struct in_addr router_id, router_id_old;
     141          16 :         struct ospf_interface *oi;
     142          16 :         struct interface *ifp;
     143          16 :         struct listnode *node, *nnode;
     144          16 :         struct ospf_area *area;
     145          16 :         bool rid_change = false;
     146             : 
     147          16 :         if (!ospf->oi_running) {
     148           0 :                 if (IS_DEBUG_OSPF_EVENT)
     149           0 :                         zlog_debug(
     150             :                                 "Router ospf not configured -- Router-ID update postponed");
     151           0 :                 return;
     152             :         }
     153             : 
     154          16 :         if (IS_DEBUG_OSPF_EVENT)
     155          16 :                 zlog_debug("Router-ID[OLD:%pI4]: Update",
     156             :                            &ospf->router_id);
     157             : 
     158          16 :         router_id_old = ospf->router_id;
     159             : 
     160             :         /* Select the router ID based on these priorities:
     161             :              1. Statically assigned router ID is always the first choice.
     162             :              2. If there is no statically assigned router ID, then try to stick
     163             :                 with the most recent value, since changing router ID's is very
     164             :                 disruptive.
     165             :              3. Last choice: just go with whatever the zebra daemon recommends.
     166             :         */
     167          16 :         if (ospf->router_id_static.s_addr != INADDR_ANY)
     168          12 :                 router_id = ospf->router_id_static;
     169           4 :         else if (ospf->router_id.s_addr != INADDR_ANY)
     170           0 :                 router_id = ospf->router_id;
     171             :         else
     172           4 :                 router_id = ospf->router_id_zebra;
     173             : 
     174          16 :         if (IS_DEBUG_OSPF_EVENT)
     175          16 :                 zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4",
     176             :                            &ospf->router_id, &router_id);
     177             : 
     178          16 :         rid_change = !(IPV4_ADDR_SAME(&router_id_old, &router_id));
     179          16 :         if (rid_change || (reset)) {
     180           8 :                 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
     181             :                         /* Some nbrs are identified by router_id, these needs
     182             :                          * to be rebuilt. Possible optimization would be to do
     183             :                          * oi->nbr_self->router_id = router_id for
     184             :                          * !(virtual | ptop) links
     185             :                          */
     186           0 :                         ospf_nbr_self_reset(oi, router_id);
     187             : 
     188             :                         /*
     189             :                          * If the old router id was not set, but now it
     190             :                          * is and the interface is operative and the
     191             :                          * state is ISM_Down we should kick the state
     192             :                          * machine as that we processed the interfaces
     193             :                          * based upon the network statement( or intf config )
     194             :                          * but could not start it at that time.
     195             :                          */
     196           0 :                         if (if_is_operative(oi->ifp) && oi->state == ISM_Down
     197           0 :                             && router_id_old.s_addr == INADDR_ANY)
     198           0 :                                 ospf_if_up(oi);
     199             :                 }
     200             : 
     201             :                 /* Flush (inline) all the self originated LSAs */
     202           4 :                 ospf_flush_self_originated_lsas_now(ospf);
     203             : 
     204           4 :                 ospf->router_id = router_id;
     205           4 :                 if (IS_DEBUG_OSPF_EVENT)
     206           4 :                         zlog_debug("Router-ID[NEW:%pI4]: Update",
     207             :                                    &ospf->router_id);
     208             : 
     209             :                 /* Flush (inline) all external LSAs which now match the new
     210             :                    router-id,
     211             :                    need to adjust the OSPF_LSA_SELF flag, so the flush doesn't
     212             :                    hit
     213             :                    asserts in ospf_refresher_unregister_lsa(). This step is
     214             :                    needed
     215             :                    because the current frr code does look-up for
     216             :                    self-originated LSAs
     217             :                    based on the self router-id alone but expects OSPF_LSA_SELF
     218             :                    to be
     219             :                    properly set */
     220           4 :                 if (ospf->lsdb) {
     221           4 :                         struct route_node *rn;
     222           4 :                         struct ospf_lsa *lsa;
     223             : 
     224           4 :                         LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
     225             :                                 /* AdvRouter and Router ID is the same. */
     226           0 :                                 if (IPV4_ADDR_SAME(&lsa->data->adv_router,
     227           0 :                                         &ospf->router_id) && rid_change) {
     228           0 :                                         SET_FLAG(lsa->flags,
     229             :                                                  OSPF_LSA_SELF_CHECKED);
     230           0 :                                         SET_FLAG(lsa->flags, OSPF_LSA_SELF);
     231           0 :                                         ospf_lsa_flush_schedule(ospf, lsa);
     232             :                                 }
     233             :                                 /* The above flush will send immediately
     234             :                                  * So discard the LSA to originate new
     235             :                                  */
     236           0 :                                 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
     237             :                         }
     238             : 
     239           4 :                         LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
     240           0 :                                 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
     241             : 
     242           4 :                         ospf_lsdb_delete_all(ospf->lsdb);
     243             :                 }
     244             : 
     245             :                 /* Since the LSAs are deleted, need reset the aggr flag */
     246           4 :                 ospf_unset_all_aggr_flag(ospf);
     247             : 
     248             :                 /* Delete the LSDB */
     249           8 :                 for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
     250           0 :                         ospf_area_lsdb_discard_delete(area);
     251             : 
     252             :                 /* update router-lsa's for each area */
     253           4 :                 ospf_router_lsa_update(ospf);
     254             : 
     255             :                 /* update ospf_interface's */
     256          17 :                 FOR_ALL_INTERFACES (vrf, ifp) {
     257           9 :                         if (reset)
     258           0 :                                 ospf_if_reset(ifp);
     259             :                         else
     260           9 :                                 ospf_if_update(ospf, ifp);
     261             :                 }
     262             : 
     263           4 :                 ospf_external_lsa_rid_change(ospf);
     264             : 
     265             : #ifdef SUPPORT_OSPF_API
     266           4 :                 ospf_apiserver_clients_notify_router_id_change(router_id);
     267             : #endif
     268             :         }
     269             : 
     270          16 :         ospf->inst_shutdown = 0;
     271             : }
     272             : 
     273          16 : void ospf_router_id_update(struct ospf *ospf)
     274             : {
     275          12 :         ospf_process_refresh_data(ospf, false);
     276           0 : }
     277             : 
     278           0 : void ospf_process_reset(struct ospf *ospf)
     279             : {
     280           0 :         ospf_process_refresh_data(ospf, true);
     281           0 : }
     282             : 
     283           0 : void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
     284             :                         const char *nbr_str)
     285             : {
     286           0 :         struct route_node *rn;
     287           0 :         struct ospf_neighbor *nbr;
     288           0 :         struct ospf_interface *oi;
     289           0 :         struct listnode *node;
     290             : 
     291             :         /* Clear only a particular nbr with nbr router id as nbr_id */
     292           0 :         if (nbr_str != NULL) {
     293           0 :                 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
     294           0 :                         nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &nbr_id);
     295           0 :                         if (nbr)
     296           0 :                                 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
     297             :                 }
     298             :                 return;
     299             :         }
     300             : 
     301             :         /* send Neighbor event KillNbr to all associated neighbors. */
     302           0 :         for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
     303           0 :                 for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
     304           0 :                         nbr = rn->info;
     305           0 :                         if (nbr && (nbr != oi->nbr_self))
     306           0 :                                 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
     307             :                 }
     308             :         }
     309             : }
     310             : 
     311             : /* For OSPF area sort by area id. */
     312           1 : static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2)
     313             : {
     314           1 :         if (ntohl(a1->area_id.s_addr) > ntohl(a2->area_id.s_addr))
     315             :                 return 1;
     316           0 :         if (ntohl(a1->area_id.s_addr) < ntohl(a2->area_id.s_addr))
     317           0 :                 return -1;
     318             :         return 0;
     319             : }
     320             : 
     321           4 : static void ospf_add(struct ospf *ospf)
     322             : {
     323           4 :         listnode_add(om->ospf, ospf);
     324             : }
     325             : 
     326           4 : static void ospf_delete(struct ospf *ospf)
     327             : {
     328           4 :         listnode_delete(om->ospf, ospf);
     329             : }
     330             : 
     331           4 : struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
     332             : {
     333           4 :         int i;
     334           4 :         struct vrf *vrf = NULL;
     335             : 
     336           4 :         struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
     337             : 
     338           4 :         new->instance = instance;
     339           4 :         new->router_id.s_addr = htonl(0);
     340           4 :         new->router_id_static.s_addr = htonl(0);
     341             : 
     342           4 :         vrf = vrf_lookup_by_name(name);
     343           4 :         if (vrf)
     344           4 :                 new->vrf_id = vrf->vrf_id;
     345             :         else
     346           0 :                 new->vrf_id = VRF_UNKNOWN;
     347             : 
     348             :         /* Freed in ospf_finish_final */
     349           4 :         new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
     350           4 :         if (IS_DEBUG_OSPF_EVENT)
     351           4 :                 zlog_debug(
     352             :                         "%s: Create new ospf instance with vrf_name %s vrf_id %u",
     353             :                         __func__, name, new->vrf_id);
     354             : 
     355           4 :         if (vrf)
     356           8 :                 ospf_vrf_link(new, vrf);
     357             : 
     358           4 :         ospf_zebra_vrf_register(new);
     359             : 
     360           4 :         new->abr_type = OSPF_ABR_DEFAULT;
     361           4 :         new->oiflist = list_new();
     362           4 :         new->vlinks = list_new();
     363           4 :         new->areas = list_new();
     364           4 :         new->areas->cmp = (int (*)(void *, void *))ospf_area_id_cmp;
     365           4 :         new->networks = route_table_init();
     366           4 :         new->nbr_nbma = route_table_init();
     367             : 
     368           4 :         new->lsdb = ospf_lsdb_new();
     369             : 
     370           4 :         new->default_originate = DEFAULT_ORIGINATE_NONE;
     371             : 
     372           4 :         new->passive_interface_default = OSPF_IF_ACTIVE;
     373             : 
     374           4 :         new->new_external_route = route_table_init();
     375           4 :         new->old_external_route = route_table_init();
     376           4 :         new->external_lsas = route_table_init();
     377             : 
     378           4 :         new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
     379           4 :         new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
     380           4 :         new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
     381             : 
     382             :         /* Distribute parameter init. */
     383         132 :         for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
     384         128 :                 new->dtag[i] = 0;
     385             :         }
     386           4 :         new->default_metric = -1;
     387           4 :         new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
     388             : 
     389             :         /* LSA timers */
     390           4 :         new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
     391           4 :         new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
     392             : 
     393             :         /* SPF timer value init. */
     394           4 :         new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
     395           4 :         new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
     396           4 :         new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
     397           4 :         new->spf_hold_multiplier = 1;
     398             : 
     399             :         /* MaxAge init. */
     400           4 :         new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
     401           4 :         new->maxage_lsa = route_table_init();
     402           4 :         new->t_maxage_walker = NULL;
     403           4 :         thread_add_timer(master, ospf_lsa_maxage_walker, new,
     404             :                          OSPF_LSA_MAXAGE_CHECK_INTERVAL, &new->t_maxage_walker);
     405             : 
     406             :         /* Max paths initialization */
     407           4 :         new->max_multipath = MULTIPATH_NUM;
     408             : 
     409             :         /* Distance table init. */
     410           4 :         new->distance_table = route_table_init();
     411             : 
     412           4 :         new->lsa_refresh_queue.index = 0;
     413           4 :         new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
     414           4 :         new->lsa_refresh_timer = OSPF_LS_REFRESH_TIME;
     415           4 :         new->t_lsa_refresher = NULL;
     416           4 :         thread_add_timer(master, ospf_lsa_refresh_walker, new,
     417             :                          new->lsa_refresh_interval, &new->t_lsa_refresher);
     418           4 :         new->lsa_refresher_started = monotime(NULL);
     419             : 
     420           4 :         new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1);
     421             : 
     422           4 :         new->t_read = NULL;
     423           4 :         new->oi_write_q = list_new();
     424           4 :         new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
     425             : 
     426           4 :         new->proactive_arp = OSPF_PROACTIVE_ARP_DEFAULT;
     427             : 
     428           4 :         ospf_gr_helper_instance_init(new);
     429             : 
     430           4 :         ospf_asbr_external_aggregator_init(new);
     431             : 
     432           4 :         ospf_opaque_type11_lsa_init(new);
     433             : 
     434           4 :         QOBJ_REG(new, ospf);
     435             : 
     436           4 :         new->fd = -1;
     437             : 
     438           4 :         return new;
     439             : }
     440             : 
     441             : /* Allocate new ospf structure. */
     442           4 : static struct ospf *ospf_new(unsigned short instance, const char *name)
     443             : {
     444           4 :         struct ospf *new;
     445             : 
     446           4 :         new = ospf_new_alloc(instance, name);
     447           4 :         ospf_add(new);
     448             : 
     449           4 :         if (new->vrf_id == VRF_UNKNOWN)
     450             :                 return new;
     451             : 
     452           4 :         if ((ospf_sock_init(new)) < 0) {
     453           0 :                 flog_err(EC_LIB_SOCKET,
     454             :                          "%s: ospf_sock_init is unable to open a socket",
     455             :                          __func__);
     456           0 :                 return new;
     457             :         }
     458             : 
     459           4 :         thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
     460             : 
     461           4 :         new->oi_running = 1;
     462           4 :         ospf_router_id_update(new);
     463             : 
     464             :         /*
     465             :          * Read from non-volatile memory whether this instance is performing a
     466             :          * graceful restart or not.
     467             :          */
     468           4 :         ospf_gr_nvm_read(new);
     469             : 
     470           4 :         return new;
     471             : }
     472             : 
     473           0 : struct ospf *ospf_lookup_instance(unsigned short instance)
     474             : {
     475           0 :         struct ospf *ospf;
     476           0 :         struct listnode *node, *nnode;
     477             : 
     478           0 :         if (listcount(om->ospf) == 0)
     479             :                 return NULL;
     480             : 
     481           0 :         for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
     482           0 :                 if ((ospf->instance == 0 && instance == 0)
     483           0 :                     || (ospf->instance && instance
     484           0 :                         && ospf->instance == instance))
     485           0 :                         return ospf;
     486             : 
     487             :         return NULL;
     488             : }
     489             : 
     490         144 : static int ospf_is_ready(struct ospf *ospf)
     491             : {
     492             :         /* OSPF must be on and Router-ID must be configured. */
     493         144 :         if (!ospf || ospf->router_id.s_addr == INADDR_ANY)
     494             :                 return 0;
     495             : 
     496             :         return 1;
     497             : }
     498             : 
     499           4 : struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
     500             : {
     501           4 :         struct ospf *ospf = NULL;
     502           4 :         struct listnode *node, *nnode;
     503             : 
     504           8 :         for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
     505           0 :                 if ((ospf->instance == instance)
     506           0 :                     && ((ospf->name == NULL && name == NULL)
     507           0 :                         || (ospf->name && name
     508           0 :                             && strcmp(ospf->name, name) == 0)))
     509           0 :                         return ospf;
     510             :         }
     511             :         return NULL;
     512             : }
     513             : 
     514           4 : struct ospf *ospf_lookup(unsigned short instance, const char *name)
     515             : {
     516           4 :         struct ospf *ospf;
     517             : 
     518           4 :         if (ospf_instance) {
     519           0 :                 ospf = ospf_lookup_instance(instance);
     520             :         } else {
     521           4 :                 ospf = ospf_lookup_by_inst_name(instance, name);
     522             :         }
     523             : 
     524           4 :         return ospf;
     525             : }
     526             : 
     527           4 : struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
     528             : {
     529           4 :         struct ospf *ospf;
     530             : 
     531           4 :         ospf = ospf_lookup(instance, name);
     532             : 
     533           4 :         *created = (ospf == NULL);
     534           4 :         if (ospf == NULL)
     535           4 :                 ospf = ospf_new(instance, name);
     536             : 
     537           4 :         return ospf;
     538             : }
     539             : 
     540         271 : struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
     541             : {
     542         271 :         struct vrf *vrf = NULL;
     543             : 
     544         271 :         vrf = vrf_lookup_by_id(vrf_id);
     545         271 :         if (!vrf)
     546             :                 return NULL;
     547         271 :         return (vrf->info) ? (struct ospf *)vrf->info : NULL;
     548             : }
     549             : 
     550           6 : uint32_t ospf_count_area_params(struct ospf *ospf)
     551             : {
     552           6 :         struct vrf *vrf;
     553           6 :         struct interface *ifp;
     554           6 :         uint32_t count = 0;
     555             : 
     556           6 :         if (ospf->vrf_id != VRF_UNKNOWN) {
     557           6 :                 vrf = vrf_lookup_by_id(ospf->vrf_id);
     558             : 
     559          27 :                 FOR_ALL_INTERFACES (vrf, ifp) {
     560          15 :                         count += ospf_if_count_area_params(ifp);
     561             :                 }
     562             :         }
     563             : 
     564           6 :         return count;
     565             : }
     566             : 
     567             : /* It should only be used when processing incoming info update from zebra.
     568             :  * Other situations, it is not sufficient to lookup the ospf instance by
     569             :  * vrf_name only without using the instance number.
     570             :  */
     571           4 : static struct ospf *ospf_lookup_by_name(const char *vrf_name)
     572             : {
     573           4 :         struct ospf *ospf = NULL;
     574           4 :         struct listnode *node, *nnode;
     575             : 
     576           8 :         for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
     577           0 :                 if ((ospf->name == NULL && vrf_name == NULL)
     578           0 :                     || (ospf->name && vrf_name
     579           0 :                         && strcmp(ospf->name, vrf_name) == 0))
     580           0 :                         return ospf;
     581             :         return NULL;
     582             : }
     583             : 
     584             : /* Handle the second half of deferred shutdown. This is called either
     585             :  * from the deferred-shutdown timer thread, or directly through
     586             :  * ospf_deferred_shutdown_check.
     587             :  *
     588             :  * Function is to cleanup G-R state, if required then call ospf_finish_final
     589             :  * to complete shutdown of this ospf instance. Possibly exit if the
     590             :  * whole process is being shutdown and this was the last OSPF instance.
     591             :  */
     592           4 : static void ospf_deferred_shutdown_finish(struct ospf *ospf)
     593             : {
     594           4 :         ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
     595           4 :         THREAD_OFF(ospf->t_deferred_shutdown);
     596             : 
     597           4 :         ospf_finish_final(ospf);
     598             : 
     599             :         /* *ospf is now invalid */
     600             : 
     601             :         /* ospfd being shut-down? If so, was this the last ospf instance? */
     602           4 :         if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)
     603           4 :             && (listcount(om->ospf) == 0)) {
     604           4 :                 frr_fini();
     605           4 :                 exit(0);
     606             :         }
     607             : 
     608           0 :         return;
     609             : }
     610             : 
     611             : /* Timer thread for G-R */
     612           0 : static void ospf_deferred_shutdown_timer(struct thread *t)
     613             : {
     614           0 :         struct ospf *ospf = THREAD_ARG(t);
     615             : 
     616           0 :         ospf_deferred_shutdown_finish(ospf);
     617           0 : }
     618             : 
     619             : /* Check whether deferred-shutdown must be scheduled, otherwise call
     620             :  * down directly into second-half of instance shutdown.
     621             :  */
     622           4 : static void ospf_deferred_shutdown_check(struct ospf *ospf)
     623             : {
     624           4 :         unsigned long timeout;
     625           4 :         struct listnode *ln;
     626           4 :         struct ospf_area *area;
     627             : 
     628             :         /* deferred shutdown already running? */
     629           4 :         if (ospf->t_deferred_shutdown)
     630             :                 return;
     631             : 
     632             :         /* Should we try push out max-metric LSAs? */
     633           4 :         if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) {
     634           0 :                 for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
     635           0 :                         SET_FLAG(area->stub_router_state,
     636             :                                  OSPF_AREA_ADMIN_STUB_ROUTED);
     637             : 
     638           0 :                         if (!CHECK_FLAG(area->stub_router_state,
     639             :                                         OSPF_AREA_IS_STUB_ROUTED))
     640           0 :                                 ospf_router_lsa_update_area(area);
     641             :                 }
     642           0 :                 timeout = ospf->stub_router_shutdown_time;
     643             :         } else {
     644             :                 /* No timer needed */
     645           4 :                 ospf_deferred_shutdown_finish(ospf);
     646           4 :                 return;
     647             :         }
     648             : 
     649           0 :         OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
     650             :                       timeout);
     651           0 :         return;
     652             : }
     653             : 
     654             : /* Shut down the entire process */
     655           4 : void ospf_terminate(void)
     656             : {
     657           4 :         struct ospf *ospf;
     658           4 :         struct listnode *node, *nnode;
     659             : 
     660             :         /* shutdown already in progress */
     661           4 :         if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
     662             :                 return;
     663             : 
     664           4 :         SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN);
     665             : 
     666             :         /* Skip some steps if OSPF not actually running */
     667           4 :         if (listcount(om->ospf) == 0)
     668           0 :                 goto done;
     669             : 
     670           4 :         for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
     671           4 :                 ospf_finish(ospf);
     672             : 
     673             :         /* Cleanup GR */
     674           0 :         ospf_gr_helper_stop();
     675             : 
     676             :         /* Cleanup route maps */
     677           0 :         route_map_finish();
     678             : 
     679             :         /* reverse prefix_list_init */
     680           0 :         prefix_list_add_hook(NULL);
     681           0 :         prefix_list_delete_hook(NULL);
     682           0 :         prefix_list_reset();
     683             : 
     684             :         /* Cleanup vrf info */
     685           0 :         ospf_vrf_terminate();
     686             : 
     687             :         /* Deliberately go back up, hopefully to thread scheduler, as
     688             :          * One or more ospf_finish()'s may have deferred shutdown to a timer
     689             :          * thread
     690             :          */
     691           0 :         zclient_stop(zclient);
     692           0 :         zclient_free(zclient);
     693             : 
     694           0 : done:
     695           0 :         frr_fini();
     696             : }
     697             : 
     698           4 : void ospf_finish(struct ospf *ospf)
     699             : {
     700             :         /* let deferred shutdown decide */
     701           0 :         ospf_deferred_shutdown_check(ospf);
     702             : 
     703             :         /* if ospf_deferred_shutdown returns, then ospf_finish_final is
     704             :          * deferred to expiry of G-S timer thread. Return back up, hopefully
     705             :          * to thread scheduler.
     706             :          */
     707           4 :         return;
     708             : }
     709             : 
     710             : /* Final cleanup of ospf instance */
     711           4 : static void ospf_finish_final(struct ospf *ospf)
     712             : {
     713           4 :         struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
     714           4 :         struct route_node *rn;
     715           4 :         struct ospf_nbr_nbma *nbr_nbma;
     716           4 :         struct ospf_lsa *lsa;
     717           4 :         struct ospf_interface *oi;
     718           4 :         struct ospf_area *area;
     719           4 :         struct ospf_vl_data *vl_data;
     720           4 :         struct listnode *node, *nnode;
     721           4 :         struct ospf_redist *red;
     722           4 :         int i;
     723             : 
     724           4 :         QOBJ_UNREG(ospf);
     725             : 
     726           4 :         ospf_opaque_type11_lsa_term(ospf);
     727             : 
     728           4 :         ospf_opaque_finish();
     729             : 
     730           4 :         if (!ospf->gr_info.prepare_in_progress)
     731           4 :                 ospf_flush_self_originated_lsas_now(ospf);
     732             : 
     733             :         /* Unregister redistribution */
     734         128 :         for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
     735         124 :                 struct list *red_list;
     736             : 
     737         124 :                 red_list = ospf->redist[i];
     738         124 :                 if (!red_list)
     739         120 :                         continue;
     740             : 
     741           8 :                 for (ALL_LIST_ELEMENTS(red_list, node, nnode, red)) {
     742           4 :                         ospf_redistribute_unset(ospf, i, red->instance);
     743           4 :                         ospf_redist_del(ospf, i, red->instance);
     744             :                 }
     745             :         }
     746           4 :         red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
     747           4 :         if (red) {
     748           0 :                 ospf_routemap_unset(red);
     749           0 :                 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
     750           0 :                 ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE, 0, 0);
     751             :         }
     752             : 
     753          13 :         for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
     754           5 :                 ospf_remove_vls_through_area(ospf, area);
     755             : 
     756           8 :         for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
     757           0 :                 ospf_vl_delete(ospf, vl_data);
     758             : 
     759           4 :         list_delete(&ospf->vlinks);
     760             : 
     761             :         /* shutdown LDP-Sync */
     762           4 :         if (ospf->vrf_id == VRF_DEFAULT)
     763           4 :                 ospf_ldp_sync_gbl_exit(ospf, true);
     764             : 
     765             :         /* Reset interface. */
     766          16 :         for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
     767           8 :                 ospf_if_free(oi);
     768           4 :         list_delete(&ospf->oiflist);
     769           4 :         ospf->oi_running = 0;
     770             : 
     771             :         /* De-Register VRF */
     772           4 :         ospf_zebra_vrf_deregister(ospf);
     773             : 
     774             :         /* Clear static neighbors */
     775           4 :         for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
     776           0 :                 if ((nbr_nbma = rn->info)) {
     777           0 :                         THREAD_OFF(nbr_nbma->t_poll);
     778             : 
     779           0 :                         if (nbr_nbma->nbr) {
     780           0 :                                 nbr_nbma->nbr->nbr_nbma = NULL;
     781           0 :                                 nbr_nbma->nbr = NULL;
     782             :                         }
     783             : 
     784           0 :                         if (nbr_nbma->oi) {
     785           0 :                                 listnode_delete(nbr_nbma->oi->nbr_nbma,
     786             :                                                 nbr_nbma);
     787           0 :                                 nbr_nbma->oi = NULL;
     788             :                         }
     789             : 
     790           0 :                         XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
     791             :                 }
     792             : 
     793           4 :         route_table_finish(ospf->nbr_nbma);
     794             : 
     795             :         /* Clear networks and Areas. */
     796          12 :         for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
     797           8 :                 struct ospf_network *network;
     798             : 
     799           8 :                 if ((network = rn->info) != NULL) {
     800           6 :                         ospf_network_free(ospf, network);
     801           6 :                         rn->info = NULL;
     802           6 :                         route_unlock_node(rn);
     803             :                 }
     804             :         }
     805           4 :         route_table_finish(ospf->networks);
     806             : 
     807           8 :         for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
     808           0 :                 listnode_delete(ospf->areas, area);
     809           0 :                 ospf_area_free(area);
     810             :         }
     811             : 
     812             :         /* Cancel all timers. */
     813           4 :         THREAD_OFF(ospf->t_read);
     814           4 :         THREAD_OFF(ospf->t_write);
     815           4 :         THREAD_OFF(ospf->t_spf_calc);
     816           4 :         THREAD_OFF(ospf->t_ase_calc);
     817           4 :         THREAD_OFF(ospf->t_maxage);
     818           4 :         THREAD_OFF(ospf->t_maxage_walker);
     819           4 :         THREAD_OFF(ospf->t_abr_task);
     820           4 :         THREAD_OFF(ospf->t_asbr_check);
     821           4 :         THREAD_OFF(ospf->t_asbr_nssa_redist_update);
     822           4 :         THREAD_OFF(ospf->t_distribute_update);
     823           4 :         THREAD_OFF(ospf->t_lsa_refresher);
     824           4 :         THREAD_OFF(ospf->t_opaque_lsa_self);
     825           4 :         THREAD_OFF(ospf->t_sr_update);
     826           4 :         THREAD_OFF(ospf->t_default_routemap_timer);
     827           4 :         THREAD_OFF(ospf->t_external_aggr);
     828           4 :         THREAD_OFF(ospf->gr_info.t_grace_period);
     829             : 
     830           4 :         LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
     831           0 :                 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
     832          28 :         LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
     833          14 :                 ospf_discard_from_db(ospf, ospf->lsdb, lsa);
     834             : 
     835           4 :         ospf_lsdb_delete_all(ospf->lsdb);
     836           4 :         ospf_lsdb_free(ospf->lsdb);
     837             : 
     838           4 :         for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
     839           0 :                 if ((lsa = rn->info) != NULL) {
     840           0 :                         ospf_lsa_unlock(&lsa);
     841           0 :                         rn->info = NULL;
     842           0 :                         route_unlock_node(rn);
     843             :                 }
     844             :         }
     845           4 :         route_table_finish(ospf->maxage_lsa);
     846             : 
     847           4 :         if (ospf->old_table)
     848           4 :                 ospf_route_table_free(ospf->old_table);
     849           4 :         if (ospf->new_table) {
     850           4 :                 if (!ospf->gr_info.prepare_in_progress)
     851           4 :                         ospf_route_delete(ospf, ospf->new_table);
     852           4 :                 ospf_route_table_free(ospf->new_table);
     853             :         }
     854           4 :         if (ospf->oall_rtrs)
     855           0 :                 ospf_rtrs_free(ospf->oall_rtrs);
     856           4 :         if (ospf->all_rtrs)
     857           0 :                 ospf_rtrs_free(ospf->all_rtrs);
     858           4 :         if (ospf->old_rtrs)
     859           4 :                 ospf_rtrs_free(ospf->old_rtrs);
     860           4 :         if (ospf->new_rtrs)
     861           4 :                 ospf_rtrs_free(ospf->new_rtrs);
     862           4 :         if (ospf->new_external_route) {
     863           4 :                 if (!ospf->gr_info.prepare_in_progress)
     864           4 :                         ospf_route_delete(ospf, ospf->new_external_route);
     865           4 :                 ospf_route_table_free(ospf->new_external_route);
     866             :         }
     867           4 :         if (ospf->old_external_route) {
     868           4 :                 if (!ospf->gr_info.prepare_in_progress)
     869           4 :                         ospf_route_delete(ospf, ospf->old_external_route);
     870           4 :                 ospf_route_table_free(ospf->old_external_route);
     871             :         }
     872           4 :         if (ospf->external_lsas) {
     873           4 :                 ospf_ase_external_lsas_finish(ospf->external_lsas);
     874             :         }
     875             : 
     876         132 :         for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
     877         128 :                 struct list *ext_list;
     878         128 :                 struct ospf_external *ext;
     879             : 
     880         128 :                 ext_list = ospf->external[i];
     881         128 :                 if (!ext_list)
     882         128 :                         continue;
     883             : 
     884           0 :                 for (ALL_LIST_ELEMENTS(ext_list, node, nnode, ext)) {
     885           0 :                         if (ext->external_info)
     886           0 :                                 for (rn = route_top(ext->external_info); rn;
     887           0 :                                      rn = route_next(rn)) {
     888           0 :                                         if (rn->info == NULL)
     889           0 :                                                 continue;
     890             : 
     891           0 :                                         XFREE(MTYPE_OSPF_EXTERNAL_INFO,
     892             :                                               rn->info);
     893           0 :                                         rn->info = NULL;
     894           0 :                                         route_unlock_node(rn);
     895             :                                 }
     896             : 
     897           0 :                         ospf_external_del(ospf, i, ext->instance);
     898             :                 }
     899             :         }
     900             : 
     901           4 :         ospf_distance_reset(ospf);
     902           4 :         route_table_finish(ospf->distance_table);
     903             : 
     904             :         /* Release extrenal Aggregator table */
     905           4 :         for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
     906           0 :                 struct ospf_external_aggr_rt *aggr;
     907             : 
     908           0 :                 aggr = rn->info;
     909             : 
     910           0 :                 if (aggr) {
     911           0 :                         ospf_external_aggregator_free(aggr);
     912           0 :                         rn->info = NULL;
     913           0 :                         route_unlock_node(rn);
     914             :                 }
     915             :         }
     916             : 
     917           4 :         route_table_finish(ospf->rt_aggr_tbl);
     918             : 
     919             : 
     920           4 :         ospf_free_refresh_queue(ospf);
     921             : 
     922           4 :         list_delete(&ospf->areas);
     923           4 :         list_delete(&ospf->oi_write_q);
     924             : 
     925             :         /* Reset GR helper data structers */
     926           4 :         ospf_gr_helper_instance_stop(ospf);
     927             : 
     928           4 :         close(ospf->fd);
     929           4 :         stream_free(ospf->ibuf);
     930           4 :         ospf->fd = -1;
     931           4 :         ospf->max_multipath = MULTIPATH_NUM;
     932           4 :         ospf_delete(ospf);
     933             : 
     934           4 :         if (vrf)
     935           8 :                 ospf_vrf_unlink(ospf, vrf);
     936             : 
     937           4 :         XFREE(MTYPE_OSPF_TOP, ospf->name);
     938           4 :         XFREE(MTYPE_OSPF_TOP, ospf);
     939           4 : }
     940             : 
     941             : 
     942             : /* allocate new OSPF Area object */
     943          11 : struct ospf_area *ospf_area_new(struct ospf *ospf, struct in_addr area_id)
     944             : {
     945          11 :         struct ospf_area *new;
     946             : 
     947             :         /* Allocate new config_network. */
     948          11 :         new = XCALLOC(MTYPE_OSPF_AREA, sizeof(struct ospf_area));
     949             : 
     950          11 :         new->ospf = ospf;
     951             : 
     952          11 :         new->area_id = area_id;
     953          11 :         new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
     954             : 
     955          11 :         new->external_routing = OSPF_AREA_DEFAULT;
     956          11 :         new->default_cost = 1;
     957          11 :         new->auth_type = OSPF_AUTH_NULL;
     958             : 
     959             :         /* New LSDB init. */
     960          11 :         new->lsdb = ospf_lsdb_new();
     961             : 
     962             :         /* Self-originated LSAs initialize. */
     963          11 :         new->router_lsa_self = NULL;
     964             : 
     965          11 :         ospf_opaque_type10_lsa_init(new);
     966             : 
     967          11 :         new->oiflist = list_new();
     968          11 :         new->ranges = route_table_init();
     969             : 
     970          11 :         if (area_id.s_addr == OSPF_AREA_BACKBONE)
     971           7 :                 ospf->backbone = new;
     972             : 
     973          11 :         return new;
     974             : }
     975             : 
     976          11 : void ospf_area_lsdb_discard_delete(struct ospf_area *area)
     977             : {
     978          11 :         struct route_node *rn;
     979          11 :         struct ospf_lsa *lsa;
     980             : 
     981          28 :         LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
     982          11 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     983          23 :         LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
     984           8 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     985          24 :         LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
     986           8 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     987          16 :         LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
     988           4 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     989             : 
     990          11 :         LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
     991           0 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     992          11 :         LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
     993           0 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     994          11 :         LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
     995           0 :                 ospf_discard_from_db(area->ospf, area->lsdb, lsa);
     996             : 
     997          11 :         ospf_lsdb_delete_all(area->lsdb);
     998          11 : }
     999             : 
    1000          11 : static void ospf_area_free(struct ospf_area *area)
    1001             : {
    1002          11 :         ospf_opaque_type10_lsa_term(area);
    1003             : 
    1004             :         /* Free LSDBs. */
    1005          11 :         ospf_area_lsdb_discard_delete(area);
    1006             : 
    1007          11 :         ospf_lsdb_free(area->lsdb);
    1008             : 
    1009          11 :         ospf_lsa_unlock(&area->router_lsa_self);
    1010             : 
    1011          11 :         route_table_finish(area->ranges);
    1012          11 :         list_delete(&area->oiflist);
    1013             : 
    1014          11 :         if (EXPORT_NAME(area))
    1015           0 :                 free(EXPORT_NAME(area));
    1016             : 
    1017          11 :         if (IMPORT_NAME(area))
    1018           0 :                 free(IMPORT_NAME(area));
    1019             : 
    1020             :         /* Cancel timer. */
    1021          11 :         THREAD_OFF(area->t_stub_router);
    1022          11 :         THREAD_OFF(area->t_opaque_lsa_self);
    1023             : 
    1024          11 :         if (OSPF_IS_AREA_BACKBONE(area))
    1025           7 :                 area->ospf->backbone = NULL;
    1026             : 
    1027          11 :         XFREE(MTYPE_OSPF_AREA, area);
    1028          11 : }
    1029             : 
    1030          12 : void ospf_area_check_free(struct ospf *ospf, struct in_addr area_id)
    1031             : {
    1032          12 :         struct ospf_area *area;
    1033             : 
    1034          12 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1035          12 :         if (area && listcount(area->oiflist) == 0 && area->ranges->top == NULL
    1036          11 :             && !ospf_vl_count(ospf, area)
    1037          11 :             && area->shortcut_configured == OSPF_SHORTCUT_DEFAULT
    1038             :             && area->external_routing == OSPF_AREA_DEFAULT
    1039          11 :             && area->no_summary == 0 && area->default_cost == 1
    1040          11 :             && EXPORT_NAME(area) == NULL && IMPORT_NAME(area) == NULL
    1041          11 :             && area->auth_type == OSPF_AUTH_NULL) {
    1042          11 :                 listnode_delete(ospf->areas, area);
    1043          11 :                 ospf_area_free(area);
    1044             :         }
    1045          12 : }
    1046             : 
    1047          96 : struct ospf_area *ospf_area_get(struct ospf *ospf, struct in_addr area_id)
    1048             : {
    1049          96 :         struct ospf_area *area;
    1050             : 
    1051          96 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1052          96 :         if (!area) {
    1053          11 :                 area = ospf_area_new(ospf, area_id);
    1054          11 :                 listnode_add_sort(ospf->areas, area);
    1055          11 :                 ospf_check_abr_status(ospf);
    1056          11 :                 if (ospf->stub_router_admin_set
    1057             :                     == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) {
    1058           0 :                         SET_FLAG(area->stub_router_state,
    1059             :                                  OSPF_AREA_ADMIN_STUB_ROUTED);
    1060             :                 }
    1061             :         }
    1062             : 
    1063          96 :         return area;
    1064             : }
    1065             : 
    1066         223 : struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *ospf,
    1067             :                                               struct in_addr area_id)
    1068             : {
    1069         223 :         struct ospf_area *area;
    1070         223 :         struct listnode *node;
    1071             : 
    1072         491 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
    1073         256 :                 if (IPV4_ADDR_SAME(&area->area_id, &area_id))
    1074         211 :                         return area;
    1075             : 
    1076             :         return NULL;
    1077             : }
    1078             : 
    1079          17 : void ospf_area_add_if(struct ospf_area *area, struct ospf_interface *oi)
    1080             : {
    1081           0 :         listnode_add(area->oiflist, oi);
    1082           0 : }
    1083             : 
    1084           0 : void ospf_area_del_if(struct ospf_area *area, struct ospf_interface *oi)
    1085             : {
    1086           0 :         listnode_delete(area->oiflist, oi);
    1087           0 : }
    1088             : 
    1089             : 
    1090          17 : struct ospf_interface *add_ospf_interface(struct connected *co,
    1091             :                                           struct ospf_area *area)
    1092             : {
    1093          17 :         struct ospf_interface *oi;
    1094             : 
    1095          17 :         oi = ospf_if_new(area->ospf, co->ifp, co->address);
    1096          17 :         oi->connected = co;
    1097             : 
    1098          17 :         oi->area = area;
    1099             : 
    1100          17 :         oi->params = ospf_lookup_if_params(co->ifp, oi->address->u.prefix4);
    1101          17 :         oi->output_cost = ospf_if_get_output_cost(oi);
    1102             : 
    1103             :         /* Relate ospf interface to ospf instance. */
    1104          17 :         oi->ospf = area->ospf;
    1105             : 
    1106             :         /* update network type as interface flag */
    1107             :         /* If network type is specified previously,
    1108             :            skip network type setting. */
    1109          17 :         oi->type = IF_DEF_PARAMS(co->ifp)->type;
    1110          17 :         oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn;
    1111             : 
    1112             :         /* Add pseudo neighbor. */
    1113          17 :         ospf_nbr_self_reset(oi, oi->ospf->router_id);
    1114             : 
    1115          17 :         ospf_area_add_if(oi->area, oi);
    1116             : 
    1117             :         /* if LDP-IGP Sync is configured globally inherit config */
    1118          17 :         ospf_ldp_sync_if_init(oi);
    1119             : 
    1120             :         /*
    1121             :          * if router_id is not configured, don't bring up
    1122             :          * interfaces.
    1123             :          * ospf_router_id_update() will call ospf_if_update
    1124             :          * whenever r-id is configured instead.
    1125             :          */
    1126          17 :         if ((area->ospf->router_id.s_addr != INADDR_ANY)
    1127          17 :             && if_is_operative(co->ifp))
    1128          17 :                 ospf_if_up(oi);
    1129             : 
    1130          17 :         return oi;
    1131             : }
    1132             : 
    1133         150 : static void update_redistributed(struct ospf *ospf, int add_to_ospf)
    1134             : {
    1135         150 :         struct route_node *rn;
    1136         150 :         struct external_info *ei;
    1137         150 :         struct ospf_external *ext;
    1138             : 
    1139         150 :         if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) {
    1140         141 :                 ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0);
    1141         141 :                 if ((ext) && EXTERNAL_INFO(ext)) {
    1142         207 :                         for (rn = route_top(EXTERNAL_INFO(ext)); rn;
    1143          66 :                              rn = route_next(rn)) {
    1144          66 :                                 ei = rn->info;
    1145          66 :                                 if (ei == NULL)
    1146          21 :                                         continue;
    1147             : 
    1148          45 :                                 if (add_to_ospf) {
    1149          45 :                                         if (ospf_external_info_find_lsa(ospf,
    1150             :                                                                         &ei->p))
    1151          24 :                                                 if (!ospf_redistribute_check(
    1152             :                                                             ospf, ei, NULL))
    1153           0 :                                                         ospf_external_lsa_flush(
    1154           0 :                                                                 ospf, ei->type,
    1155             :                                                                 &ei->p,
    1156             :                                                                 ei->ifindex /*, ei->nexthop */);
    1157             :                                 } else {
    1158           0 :                                         if (!ospf_external_info_find_lsa(
    1159             :                                                     ospf, &ei->p))
    1160           0 :                                                 if (ospf_redistribute_check(
    1161             :                                                             ospf, ei, NULL))
    1162           0 :                                                         ospf_external_lsa_originate(
    1163             :                                                                 ospf, ei);
    1164             :                                 }
    1165             :                         }
    1166             :                 }
    1167             :         }
    1168         150 : }
    1169             : 
    1170             : /* Config network statement related functions. */
    1171           6 : static struct ospf_network *ospf_network_new(struct in_addr area_id)
    1172             : {
    1173           6 :         struct ospf_network *new;
    1174           6 :         new = XCALLOC(MTYPE_OSPF_NETWORK, sizeof(struct ospf_network));
    1175             : 
    1176           6 :         new->area_id = area_id;
    1177           6 :         new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
    1178             : 
    1179           6 :         return new;
    1180             : }
    1181             : 
    1182           6 : static void ospf_network_free(struct ospf *ospf, struct ospf_network *network)
    1183             : {
    1184           6 :         ospf_area_check_free(ospf, network->area_id);
    1185           6 :         ospf_schedule_abr_task(ospf);
    1186           6 :         XFREE(MTYPE_OSPF_NETWORK, network);
    1187           6 : }
    1188             : 
    1189           6 : int ospf_network_set(struct ospf *ospf, struct prefix_ipv4 *p,
    1190             :                      struct in_addr area_id, int df)
    1191             : {
    1192           6 :         struct ospf_network *network;
    1193           6 :         struct ospf_area *area;
    1194           6 :         struct route_node *rn;
    1195             : 
    1196           6 :         rn = route_node_get(ospf->networks, (struct prefix *)p);
    1197           6 :         if (rn->info) {
    1198           0 :                 network = rn->info;
    1199           0 :                 route_unlock_node(rn);
    1200             : 
    1201           0 :                 if (IPV4_ADDR_SAME(&area_id, &network->area_id)) {
    1202             :                         return 1;
    1203             :                 } else {
    1204             :                         /* There is already same network statement. */
    1205             :                         return 0;
    1206             :                 }
    1207             :         }
    1208             : 
    1209           6 :         rn->info = network = ospf_network_new(area_id);
    1210           6 :         network->area_id_fmt = df;
    1211           6 :         area = ospf_area_get(ospf, area_id);
    1212           6 :         ospf_area_display_format_set(ospf, area, df);
    1213             : 
    1214             :         /* Run network config now. */
    1215           6 :         ospf_network_run((struct prefix *)p, area);
    1216             : 
    1217             :         /* Update connected redistribute. */
    1218           6 :         update_redistributed(ospf, 1); /* interfaces possibly added */
    1219             : 
    1220           6 :         ospf_area_check_free(ospf, area_id);
    1221             : 
    1222           6 :         return 1;
    1223             : }
    1224             : 
    1225           0 : int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
    1226             :                        struct in_addr area_id)
    1227             : {
    1228           0 :         struct route_node *rn;
    1229           0 :         struct ospf_network *network;
    1230           0 :         struct listnode *node, *nnode;
    1231           0 :         struct ospf_interface *oi;
    1232             : 
    1233           0 :         rn = route_node_lookup(ospf->networks, (struct prefix *)p);
    1234           0 :         if (rn == NULL)
    1235             :                 return 0;
    1236             : 
    1237           0 :         network = rn->info;
    1238           0 :         route_unlock_node(rn);
    1239           0 :         if (!IPV4_ADDR_SAME(&area_id, &network->area_id))
    1240             :                 return 0;
    1241             : 
    1242           0 :         ospf_network_free(ospf, rn->info);
    1243           0 :         rn->info = NULL;
    1244           0 :         route_unlock_node(rn); /* initial reference */
    1245             : 
    1246             :         /* Find interfaces that are not configured already.  */
    1247           0 :         for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
    1248             : 
    1249           0 :                 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
    1250           0 :                         continue;
    1251             : 
    1252           0 :                 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
    1253             :         }
    1254             : 
    1255             :         /* Update connected redistribute. */
    1256           0 :         update_redistributed(ospf, 0); /* interfaces possibly removed */
    1257           0 :         ospf_area_check_free(ospf, area_id);
    1258             : 
    1259           0 :         return 1;
    1260             : }
    1261             : 
    1262             : /* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means
    1263             :  * there might not be any 'router ospf' config.
    1264             :  *
    1265             :  * Otherwise, doesn't do anything different to ospf_if_update for now
    1266             :  */
    1267           0 : void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
    1268             : {
    1269           0 :         if (!ospf)
    1270             :                 return;
    1271             : 
    1272           0 :         ospf_if_update(ospf, ifp);
    1273             :         /* if_update does a update_redistributed */
    1274             : 
    1275           0 :         return;
    1276             : }
    1277             : 
    1278           0 : void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
    1279             : {
    1280           0 :         struct route_node *rn_oi;
    1281             : 
    1282           0 :         if (!ospf)
    1283             :                 return; /* Ospf not ready yet */
    1284             : 
    1285             :         /* Find interfaces that may need to be removed. */
    1286           0 :         for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
    1287           0 :              rn_oi = route_next(rn_oi)) {
    1288           0 :                 struct ospf_interface *oi = NULL;
    1289             : 
    1290           0 :                 if ((oi = rn_oi->info) == NULL)
    1291           0 :                         continue;
    1292             : 
    1293           0 :                 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
    1294           0 :                         continue;
    1295             : 
    1296           0 :                 ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
    1297             :         }
    1298             : 
    1299             :         /* Update connected redistribute. */
    1300           0 :         update_redistributed(ospf, 0); /* interfaces possibly removed */
    1301             : }
    1302             : 
    1303             : /* Check whether interface matches given network
    1304             :  * returns: 1, true. 0, false
    1305             :  */
    1306         194 : static int ospf_network_match_iface(const struct connected *co,
    1307             :                                     const struct prefix *net)
    1308             : {
    1309             :         /* new approach: more elegant and conceptually clean */
    1310         194 :         return prefix_match_network_statement(net, CONNECTED_PREFIX(co));
    1311             : }
    1312             : 
    1313          90 : static void ospf_update_interface_area(struct connected *co,
    1314             :                                        struct ospf_area *area)
    1315             : {
    1316          90 :         struct ospf_interface *oi = ospf_if_table_lookup(co->ifp, co->address);
    1317             : 
    1318             :         /* nothing to be done case */
    1319          90 :         if (oi && oi->area == area) {
    1320             :                 return;
    1321             :         }
    1322             : 
    1323           0 :         if (oi)
    1324           0 :                 ospf_if_free(oi);
    1325             : 
    1326          17 :         add_ospf_interface(co, area);
    1327             : }
    1328             : 
    1329             : /* Run OSPF for the given subnet, taking into account the following
    1330             :  * possible sources of area configuration, in the given order of preference:
    1331             :  *
    1332             :  * - Whether there is interface+address specific area configuration
    1333             :  * - Whether there is a default area for the interface
    1334             :  * - Whether there is an area given as a parameter.
    1335             :  * - If no specific network prefix/area is supplied, whether there's
    1336             :  *   a matching network configured.
    1337             :  */
    1338         222 : static void ospf_network_run_subnet(struct ospf *ospf, struct connected *co,
    1339             :                                     struct prefix *p,
    1340             :                                     struct ospf_area *given_area)
    1341             : {
    1342         222 :         struct ospf_interface *oi;
    1343         222 :         struct ospf_if_params *params;
    1344         222 :         struct ospf_area *area = NULL;
    1345         222 :         struct route_node *rn;
    1346         222 :         int configed = 0;
    1347             : 
    1348         222 :         if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
    1349             :                 return;
    1350             : 
    1351         222 :         if (co->address->family != AF_INET)
    1352             :                 return;
    1353             : 
    1354             :         /* Try determine the appropriate area for this interface + address
    1355             :          * Start by checking interface config
    1356             :          */
    1357         122 :         params = ospf_lookup_if_params(co->ifp, co->address->u.prefix4);
    1358         122 :         if (params && OSPF_IF_PARAM_CONFIGURED(params, if_area))
    1359           0 :                 area = ospf_area_get(ospf, params->if_area);
    1360             :         else {
    1361         122 :                 params = IF_DEF_PARAMS(co->ifp);
    1362         122 :                 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
    1363           0 :                         area = ospf_area_get(ospf, params->if_area);
    1364             :         }
    1365             : 
    1366             :         /* If we've found an interface and/or addr specific area, then we're
    1367             :          * done
    1368             :          */
    1369           0 :         if (area) {
    1370           0 :                 ospf_update_interface_area(co, area);
    1371           0 :                 return;
    1372             :         }
    1373             : 
    1374             :         /* Otherwise, only remaining possibility is a matching network statement
    1375             :          */
    1376         122 :         if (p) {
    1377           0 :                 assert(given_area != NULL);
    1378             : 
    1379             :                 /* Which either was supplied as a parameter.. (e.g. cause a new
    1380             :                  * network/area was just added)..
    1381             :                  */
    1382           0 :                 if (p->family == co->address->family
    1383           0 :                     && ospf_network_match_iface(co, p))
    1384           0 :                         ospf_update_interface_area(co, given_area);
    1385             : 
    1386           0 :                 return;
    1387             :         }
    1388             : 
    1389             :         /* Else we have to search the existing network/area config to see
    1390             :          * if any match..
    1391             :          */
    1392         388 :         for (rn = route_top(ospf->networks); rn; rn = route_next(rn))
    1393         266 :                 if (rn->info != NULL && ospf_network_match_iface(co, &rn->p)) {
    1394          90 :                         struct ospf_network *network =
    1395             :                                 (struct ospf_network *)rn->info;
    1396          90 :                         area = ospf_area_get(ospf, network->area_id);
    1397          90 :                         ospf_update_interface_area(co, area);
    1398          90 :                         configed = 1;
    1399             :                 }
    1400             : 
    1401             :         /* If the subnet isn't in any area, deconfigure */
    1402         122 :         if (!configed && (oi = ospf_if_table_lookup(co->ifp, co->address)))
    1403           0 :                 ospf_if_free(oi);
    1404             : }
    1405             : 
    1406         159 : static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp,
    1407             :                                        struct prefix *p,
    1408             :                                        struct ospf_area *given_area)
    1409             : {
    1410         159 :         struct listnode *cnode;
    1411         159 :         struct connected *co;
    1412             : 
    1413         159 :         if (memcmp(ifp->name, "VLINK", 5) == 0)
    1414             :                 return;
    1415             : 
    1416             :         /* Network prefix without area is nonsensical */
    1417         159 :         if (p)
    1418          15 :                 assert(given_area != NULL);
    1419             : 
    1420             :         /* if interface prefix is match specified prefix,
    1421             :            then create socket and join multicast group. */
    1422         540 :         for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co))
    1423         222 :                 ospf_network_run_subnet(ospf, co, p, given_area);
    1424             : }
    1425             : 
    1426           6 : static void ospf_network_run(struct prefix *p, struct ospf_area *area)
    1427             : {
    1428           6 :         struct vrf *vrf = vrf_lookup_by_id(area->ospf->vrf_id);
    1429           6 :         struct interface *ifp;
    1430             : 
    1431             :         /* Schedule Router ID Update. */
    1432           6 :         if (area->ospf->router_id.s_addr == INADDR_ANY)
    1433           0 :                 ospf_router_id_update(area->ospf);
    1434             : 
    1435             :         /* Get target interface. */
    1436          27 :         FOR_ALL_INTERFACES (vrf, ifp)
    1437          15 :                 ospf_network_run_interface(area->ospf, ifp, p, area);
    1438           6 : }
    1439             : 
    1440          26 : void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
    1441             : {
    1442          26 :         struct route_node *rn;
    1443          26 :         struct listnode *node, *nnode;
    1444          26 :         struct list *lst;
    1445          26 :         struct ospf_lsa *lsa;
    1446             : 
    1447             :         /* empty ls update queue */
    1448          32 :         for (rn = route_top(oi->ls_upd_queue); rn; rn = route_next(rn))
    1449           6 :                 if ((lst = (struct list *)rn->info)) {
    1450          13 :                         for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa))
    1451           8 :                                 ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */
    1452           5 :                         list_delete(&lst);
    1453           5 :                         rn->info = NULL;
    1454             :                 }
    1455             : 
    1456             :         /* remove update event */
    1457          26 :         THREAD_OFF(oi->t_ls_upd_event);
    1458          26 : }
    1459             : 
    1460         144 : void ospf_if_update(struct ospf *ospf, struct interface *ifp)
    1461             : {
    1462             : 
    1463         144 :         if (!ospf)
    1464             :                 return;
    1465             : 
    1466         144 :         if (IS_DEBUG_OSPF_EVENT)
    1467         144 :                 zlog_debug(
    1468             :                         "%s: interface %s vrf %s(%u) ospf vrf %s vrf_id %u router_id %pI4",
    1469             :                         __func__, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
    1470             :                         ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
    1471             :                         &ospf->router_id);
    1472             : 
    1473             :         /* OSPF must be ready. */
    1474         144 :         if (!ospf_is_ready(ospf))
    1475             :                 return;
    1476             : 
    1477         144 :         ospf_network_run_interface(ospf, ifp, NULL, NULL);
    1478             : 
    1479             :         /* Update connected redistribute. */
    1480         144 :         update_redistributed(ospf, 1);
    1481             : 
    1482             : }
    1483             : 
    1484           5 : void ospf_remove_vls_through_area(struct ospf *ospf, struct ospf_area *area)
    1485             : {
    1486           5 :         struct listnode *node, *nnode;
    1487           5 :         struct ospf_vl_data *vl_data;
    1488             : 
    1489          10 :         for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
    1490           0 :                 if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
    1491           0 :                         ospf_vl_delete(ospf, vl_data);
    1492           5 : }
    1493             : 
    1494             : 
    1495             : static const struct message ospf_area_type_msg[] = {
    1496             :         {OSPF_AREA_DEFAULT, "Default"},
    1497             :         {OSPF_AREA_STUB, "Stub"},
    1498             :         {OSPF_AREA_NSSA, "NSSA"},
    1499             :         {0}};
    1500             : 
    1501           0 : static void ospf_area_type_set(struct ospf_area *area, int type)
    1502             : {
    1503           0 :         struct listnode *node;
    1504           0 :         struct ospf_interface *oi;
    1505             : 
    1506           0 :         if (area->external_routing == type) {
    1507           0 :                 if (IS_DEBUG_OSPF_EVENT)
    1508           0 :                         zlog_debug("Area[%pI4]: Types are the same, ignored.",
    1509             :                                    &area->area_id);
    1510           0 :                 return;
    1511             :         }
    1512             : 
    1513           0 :         area->external_routing = type;
    1514             : 
    1515           0 :         if (IS_DEBUG_OSPF_EVENT)
    1516           0 :                 zlog_debug("Area[%pI4]: Configured as %s",
    1517             :                            &area->area_id,
    1518             :                            lookup_msg(ospf_area_type_msg, type, NULL));
    1519             : 
    1520           0 :         switch (area->external_routing) {
    1521           0 :         case OSPF_AREA_DEFAULT:
    1522           0 :                 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
    1523           0 :                         if (oi->nbr_self != NULL) {
    1524           0 :                                 UNSET_FLAG(oi->nbr_self->options,
    1525             :                                            OSPF_OPTION_NP);
    1526           0 :                                 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
    1527             :                         }
    1528             :                 break;
    1529           0 :         case OSPF_AREA_STUB:
    1530           0 :                 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
    1531           0 :                         if (oi->nbr_self != NULL) {
    1532           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1533           0 :                                         zlog_debug(
    1534             :                                                 "setting options on %s accordingly",
    1535             :                                                 IF_NAME(oi));
    1536           0 :                                 UNSET_FLAG(oi->nbr_self->options,
    1537             :                                            OSPF_OPTION_NP);
    1538           0 :                                 UNSET_FLAG(oi->nbr_self->options,
    1539             :                                            OSPF_OPTION_E);
    1540           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1541           0 :                                         zlog_debug("options set on %s: %x",
    1542             :                                                    IF_NAME(oi), OPTIONS(oi));
    1543             :                         }
    1544             :                 break;
    1545           0 :         case OSPF_AREA_NSSA:
    1546           0 :                 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi))
    1547           0 :                         if (oi->nbr_self != NULL) {
    1548           0 :                                 zlog_debug(
    1549             :                                         "setting nssa options on %s accordingly",
    1550             :                                         IF_NAME(oi));
    1551           0 :                                 UNSET_FLAG(oi->nbr_self->options,
    1552             :                                            OSPF_OPTION_E);
    1553           0 :                                 SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP);
    1554           0 :                                 zlog_debug("options set on %s: %x", IF_NAME(oi),
    1555             :                                            OPTIONS(oi));
    1556             :                         }
    1557             :                 break;
    1558             :         default:
    1559             :                 break;
    1560             :         }
    1561             : 
    1562           0 :         ospf_router_lsa_update_area(area);
    1563           0 :         ospf_schedule_abr_task(area->ospf);
    1564             : }
    1565             : 
    1566           0 : int ospf_area_shortcut_set(struct ospf *ospf, struct ospf_area *area, int mode)
    1567             : {
    1568           0 :         if (area->shortcut_configured == mode)
    1569             :                 return 0;
    1570             : 
    1571           0 :         area->shortcut_configured = mode;
    1572           0 :         ospf_router_lsa_update_area(area);
    1573           0 :         ospf_schedule_abr_task(ospf);
    1574             : 
    1575           0 :         ospf_area_check_free(ospf, area->area_id);
    1576             : 
    1577           0 :         return 1;
    1578             : }
    1579             : 
    1580           0 : int ospf_area_shortcut_unset(struct ospf *ospf, struct ospf_area *area)
    1581             : {
    1582           0 :         area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
    1583           0 :         ospf_router_lsa_update_area(area);
    1584           0 :         ospf_area_check_free(ospf, area->area_id);
    1585           0 :         ospf_schedule_abr_task(ospf);
    1586             : 
    1587           0 :         return 1;
    1588             : }
    1589             : 
    1590           0 : static int ospf_area_vlink_count(struct ospf *ospf, struct ospf_area *area)
    1591             : {
    1592           0 :         struct ospf_vl_data *vl;
    1593           0 :         struct listnode *node;
    1594           0 :         int count = 0;
    1595             : 
    1596           0 :         for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl))
    1597           0 :                 if (IPV4_ADDR_SAME(&vl->vl_area_id, &area->area_id))
    1598           0 :                         count++;
    1599             : 
    1600           0 :         return count;
    1601             : }
    1602             : 
    1603           6 : int ospf_area_display_format_set(struct ospf *ospf, struct ospf_area *area,
    1604             :                                  int df)
    1605             : {
    1606           6 :         area->area_id_fmt = df;
    1607             : 
    1608           6 :         return 1;
    1609             : }
    1610             : 
    1611           0 : int ospf_area_stub_set(struct ospf *ospf, struct in_addr area_id)
    1612             : {
    1613           0 :         struct ospf_area *area;
    1614             : 
    1615           0 :         area = ospf_area_get(ospf, area_id);
    1616           0 :         if (ospf_area_vlink_count(ospf, area))
    1617             :                 return 0;
    1618             : 
    1619           0 :         if (area->external_routing != OSPF_AREA_STUB)
    1620           0 :                 ospf_area_type_set(area, OSPF_AREA_STUB);
    1621             : 
    1622             :         return 1;
    1623             : }
    1624             : 
    1625           0 : int ospf_area_stub_unset(struct ospf *ospf, struct in_addr area_id)
    1626             : {
    1627           0 :         struct ospf_area *area;
    1628             : 
    1629           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1630           0 :         if (area == NULL)
    1631             :                 return 1;
    1632             : 
    1633           0 :         if (area->external_routing == OSPF_AREA_STUB)
    1634           0 :                 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
    1635             : 
    1636           0 :         ospf_area_check_free(ospf, area_id);
    1637             : 
    1638           0 :         return 1;
    1639             : }
    1640             : 
    1641           0 : int ospf_area_no_summary_set(struct ospf *ospf, struct in_addr area_id)
    1642             : {
    1643           0 :         struct ospf_area *area;
    1644             : 
    1645           0 :         area = ospf_area_get(ospf, area_id);
    1646           0 :         area->no_summary = 1;
    1647             : 
    1648           0 :         return 1;
    1649             : }
    1650             : 
    1651           0 : int ospf_area_no_summary_unset(struct ospf *ospf, struct in_addr area_id)
    1652             : {
    1653           0 :         struct ospf_area *area;
    1654             : 
    1655           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1656           0 :         if (area == NULL)
    1657             :                 return 0;
    1658             : 
    1659           0 :         area->no_summary = 0;
    1660           0 :         ospf_area_check_free(ospf, area_id);
    1661             : 
    1662           0 :         return 1;
    1663             : }
    1664             : 
    1665           0 : int ospf_area_nssa_no_summary_set(struct ospf *ospf, struct in_addr area_id)
    1666             : {
    1667           0 :         struct ospf_area *area;
    1668             : 
    1669           0 :         area = ospf_area_get(ospf, area_id);
    1670           0 :         if (ospf_area_vlink_count(ospf, area))
    1671             :                 return 0;
    1672             : 
    1673           0 :         if (area->external_routing != OSPF_AREA_NSSA) {
    1674           0 :                 ospf_area_type_set(area, OSPF_AREA_NSSA);
    1675           0 :                 ospf->anyNSSA++;
    1676           0 :                 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
    1677             :         }
    1678             : 
    1679           0 :         ospf_area_no_summary_set(ospf, area_id);
    1680             : 
    1681           0 :         return 1;
    1682             : }
    1683             : 
    1684           0 : int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id)
    1685             : {
    1686           0 :         struct ospf_area *area;
    1687             : 
    1688           0 :         area = ospf_area_get(ospf, area_id);
    1689           0 :         if (ospf_area_vlink_count(ospf, area))
    1690             :                 return 0;
    1691             : 
    1692           0 :         if (area->external_routing != OSPF_AREA_NSSA) {
    1693           0 :                 ospf_area_type_set(area, OSPF_AREA_NSSA);
    1694           0 :                 ospf->anyNSSA++;
    1695             : 
    1696             :                 /* set NSSA area defaults */
    1697           0 :                 area->no_summary = 0;
    1698           0 :                 area->suppress_fa = 0;
    1699           0 :                 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
    1700           0 :                 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
    1701           0 :                 area->NSSATranslatorStabilityInterval =
    1702             :                         OSPF_NSSA_TRANS_STABLE_DEFAULT;
    1703             :         }
    1704             :         return 1;
    1705             : }
    1706             : 
    1707           0 : int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
    1708             : {
    1709           0 :         struct ospf_area *area;
    1710             : 
    1711           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1712           0 :         if (area == NULL)
    1713             :                 return 0;
    1714             : 
    1715             :         /* argc < 5 -> 'no area x nssa' */
    1716           0 :         if (argc < 5 && area->external_routing == OSPF_AREA_NSSA) {
    1717           0 :                 ospf->anyNSSA--;
    1718             :                 /* set NSSA area defaults */
    1719           0 :                 area->no_summary = 0;
    1720           0 :                 area->suppress_fa = 0;
    1721           0 :                 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
    1722           0 :                 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
    1723           0 :                 area->NSSATranslatorStabilityInterval =
    1724             :                         OSPF_NSSA_TRANS_STABLE_DEFAULT;
    1725           0 :                 ospf_area_type_set(area, OSPF_AREA_DEFAULT);
    1726             :         } else {
    1727           0 :                 ospf_area_nssa_translator_role_set(ospf, area_id,
    1728             :                                                    OSPF_NSSA_ROLE_CANDIDATE);
    1729             :         }
    1730             : 
    1731           0 :         ospf_area_check_free(ospf, area_id);
    1732             : 
    1733           0 :         return 1;
    1734             : }
    1735             : 
    1736           0 : int ospf_area_nssa_suppress_fa_set(struct ospf *ospf, struct in_addr area_id)
    1737             : {
    1738           0 :         struct ospf_area *area;
    1739             : 
    1740           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1741           0 :         if (area == NULL)
    1742             :                 return 0;
    1743             : 
    1744           0 :         area->suppress_fa = 1;
    1745             : 
    1746           0 :         return 1;
    1747             : }
    1748             : 
    1749           0 : int ospf_area_nssa_suppress_fa_unset(struct ospf *ospf, struct in_addr area_id)
    1750             : {
    1751           0 :         struct ospf_area *area;
    1752             : 
    1753           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1754           0 :         if (area == NULL)
    1755             :                 return 0;
    1756             : 
    1757           0 :         area->suppress_fa = 0;
    1758             : 
    1759           0 :         return 1;
    1760             : }
    1761             : 
    1762           0 : int ospf_area_nssa_translator_role_set(struct ospf *ospf,
    1763             :                                        struct in_addr area_id, int role)
    1764             : {
    1765           0 :         struct ospf_area *area;
    1766             : 
    1767           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
    1768           0 :         if (area == NULL)
    1769             :                 return 0;
    1770             : 
    1771           0 :         if (role != area->NSSATranslatorRole) {
    1772           0 :                 if ((area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)
    1773           0 :                     || (role == OSPF_NSSA_ROLE_ALWAYS)) {
    1774             :                         /* RFC 3101 3.1
    1775             :                          * if new role is OSPF_NSSA_ROLE_ALWAYS we need to set
    1776             :                          * Nt bit, if the role was OSPF_NSSA_ROLE_ALWAYS we need
    1777             :                          * to clear Nt bit
    1778             :                          */
    1779           0 :                         area->NSSATranslatorRole = role;
    1780           0 :                         ospf_router_lsa_update_area(area);
    1781             :                 } else
    1782           0 :                         area->NSSATranslatorRole = role;
    1783             :         }
    1784             : 
    1785             :         return 1;
    1786             : }
    1787             : 
    1788           0 : int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area,
    1789             :                               const char *list_name)
    1790             : {
    1791           0 :         struct access_list *list;
    1792           0 :         list = access_list_lookup(AFI_IP, list_name);
    1793             : 
    1794           0 :         EXPORT_LIST(area) = list;
    1795             : 
    1796           0 :         if (EXPORT_NAME(area))
    1797           0 :                 free(EXPORT_NAME(area));
    1798             : 
    1799           0 :         EXPORT_NAME(area) = strdup(list_name);
    1800           0 :         ospf_schedule_abr_task(ospf);
    1801             : 
    1802           0 :         return 1;
    1803             : }
    1804             : 
    1805           0 : int ospf_area_export_list_unset(struct ospf *ospf, struct ospf_area *area)
    1806             : {
    1807             : 
    1808           0 :         EXPORT_LIST(area) = 0;
    1809             : 
    1810           0 :         if (EXPORT_NAME(area))
    1811           0 :                 free(EXPORT_NAME(area));
    1812             : 
    1813           0 :         EXPORT_NAME(area) = NULL;
    1814             : 
    1815           0 :         ospf_area_check_free(ospf, area->area_id);
    1816             : 
    1817           0 :         ospf_schedule_abr_task(ospf);
    1818             : 
    1819           0 :         return 1;
    1820             : }
    1821             : 
    1822           0 : int ospf_area_import_list_set(struct ospf *ospf, struct ospf_area *area,
    1823             :                               const char *name)
    1824             : {
    1825           0 :         struct access_list *list;
    1826           0 :         list = access_list_lookup(AFI_IP, name);
    1827             : 
    1828           0 :         IMPORT_LIST(area) = list;
    1829             : 
    1830           0 :         if (IMPORT_NAME(area))
    1831           0 :                 free(IMPORT_NAME(area));
    1832             : 
    1833           0 :         IMPORT_NAME(area) = strdup(name);
    1834           0 :         ospf_schedule_abr_task(ospf);
    1835             : 
    1836           0 :         return 1;
    1837             : }
    1838             : 
    1839           0 : int ospf_area_import_list_unset(struct ospf *ospf, struct ospf_area *area)
    1840             : {
    1841           0 :         IMPORT_LIST(area) = 0;
    1842             : 
    1843           0 :         if (IMPORT_NAME(area))
    1844           0 :                 free(IMPORT_NAME(area));
    1845             : 
    1846           0 :         IMPORT_NAME(area) = NULL;
    1847           0 :         ospf_area_check_free(ospf, area->area_id);
    1848             : 
    1849           0 :         ospf_schedule_abr_task(ospf);
    1850             : 
    1851           0 :         return 1;
    1852             : }
    1853             : 
    1854           0 : int ospf_timers_refresh_set(struct ospf *ospf, int interval)
    1855             : {
    1856           0 :         int time_left;
    1857             : 
    1858           0 :         if (ospf->lsa_refresh_interval == interval)
    1859             :                 return 1;
    1860             : 
    1861           0 :         time_left = ospf->lsa_refresh_interval
    1862           0 :                     - (monotime(NULL) - ospf->lsa_refresher_started);
    1863             : 
    1864           0 :         if (time_left > interval) {
    1865           0 :                 THREAD_OFF(ospf->t_lsa_refresher);
    1866           0 :                 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
    1867             :                                  interval, &ospf->t_lsa_refresher);
    1868             :         }
    1869           0 :         ospf->lsa_refresh_interval = interval;
    1870             : 
    1871           0 :         return 1;
    1872             : }
    1873             : 
    1874           0 : int ospf_timers_refresh_unset(struct ospf *ospf)
    1875             : {
    1876           0 :         int time_left;
    1877             : 
    1878           0 :         time_left = ospf->lsa_refresh_interval
    1879           0 :                     - (monotime(NULL) - ospf->lsa_refresher_started);
    1880             : 
    1881           0 :         if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) {
    1882           0 :                 THREAD_OFF(ospf->t_lsa_refresher);
    1883           0 :                 ospf->t_lsa_refresher = NULL;
    1884           0 :                 thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
    1885             :                                  OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
    1886             :                                  &ospf->t_lsa_refresher);
    1887             :         }
    1888             : 
    1889           0 :         ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
    1890             : 
    1891           0 :         return 1;
    1892             : }
    1893             : 
    1894             : 
    1895           0 : static struct ospf_nbr_nbma *ospf_nbr_nbma_new(void)
    1896             : {
    1897           0 :         struct ospf_nbr_nbma *nbr_nbma;
    1898             : 
    1899           0 :         nbr_nbma = XCALLOC(MTYPE_OSPF_NEIGHBOR_STATIC,
    1900             :                            sizeof(struct ospf_nbr_nbma));
    1901             : 
    1902           0 :         nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
    1903           0 :         nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
    1904             : 
    1905           0 :         return nbr_nbma;
    1906             : }
    1907             : 
    1908           0 : static void ospf_nbr_nbma_free(struct ospf_nbr_nbma *nbr_nbma)
    1909             : {
    1910           0 :         XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
    1911             : }
    1912             : 
    1913           0 : static void ospf_nbr_nbma_delete(struct ospf *ospf,
    1914             :                                  struct ospf_nbr_nbma *nbr_nbma)
    1915             : {
    1916           0 :         struct route_node *rn;
    1917           0 :         struct prefix_ipv4 p;
    1918             : 
    1919           0 :         p.family = AF_INET;
    1920           0 :         p.prefix = nbr_nbma->addr;
    1921           0 :         p.prefixlen = IPV4_MAX_BITLEN;
    1922             : 
    1923           0 :         rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
    1924           0 :         if (rn) {
    1925           0 :                 ospf_nbr_nbma_free(rn->info);
    1926           0 :                 rn->info = NULL;
    1927           0 :                 route_unlock_node(rn);
    1928           0 :                 route_unlock_node(rn);
    1929             :         }
    1930           0 : }
    1931             : 
    1932           0 : static void ospf_nbr_nbma_down(struct ospf_nbr_nbma *nbr_nbma)
    1933             : {
    1934           0 :         THREAD_OFF(nbr_nbma->t_poll);
    1935             : 
    1936           0 :         if (nbr_nbma->nbr) {
    1937           0 :                 nbr_nbma->nbr->nbr_nbma = NULL;
    1938           0 :                 OSPF_NSM_EVENT_EXECUTE(nbr_nbma->nbr, NSM_KillNbr);
    1939             :         }
    1940             : 
    1941           0 :         if (nbr_nbma->oi)
    1942           0 :                 listnode_delete(nbr_nbma->oi->nbr_nbma, nbr_nbma);
    1943           0 : }
    1944             : 
    1945           0 : static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma,
    1946             :                               struct ospf_interface *oi)
    1947             : {
    1948           0 :         struct ospf_neighbor *nbr;
    1949           0 :         struct route_node *rn;
    1950           0 :         struct prefix p;
    1951             : 
    1952           0 :         if (oi->type != OSPF_IFTYPE_NBMA)
    1953           0 :                 return;
    1954             : 
    1955           0 :         if (nbr_nbma->nbr != NULL)
    1956             :                 return;
    1957             : 
    1958           0 :         if (IPV4_ADDR_SAME(&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
    1959             :                 return;
    1960             : 
    1961           0 :         nbr_nbma->oi = oi;
    1962           0 :         listnode_add(oi->nbr_nbma, nbr_nbma);
    1963             : 
    1964             :         /* Get neighbor information from table. */
    1965           0 :         p.family = AF_INET;
    1966           0 :         p.prefixlen = IPV4_MAX_BITLEN;
    1967           0 :         p.u.prefix4 = nbr_nbma->addr;
    1968             : 
    1969           0 :         rn = route_node_get(oi->nbrs, &p);
    1970           0 :         if (rn->info) {
    1971           0 :                 nbr = rn->info;
    1972           0 :                 nbr->nbr_nbma = nbr_nbma;
    1973           0 :                 nbr_nbma->nbr = nbr;
    1974             : 
    1975           0 :                 route_unlock_node(rn);
    1976             :         } else {
    1977           0 :                 nbr = rn->info = ospf_nbr_new(oi);
    1978           0 :                 nbr->state = NSM_Down;
    1979           0 :                 nbr->src = nbr_nbma->addr;
    1980           0 :                 nbr->nbr_nbma = nbr_nbma;
    1981           0 :                 nbr->priority = nbr_nbma->priority;
    1982           0 :                 nbr->address = p;
    1983             : 
    1984           0 :                 nbr_nbma->nbr = nbr;
    1985             : 
    1986             :                 /* Configure BFD if interface has it. */
    1987           0 :                 ospf_neighbor_bfd_apply(nbr);
    1988             : 
    1989           0 :                 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start);
    1990             :         }
    1991             : }
    1992             : 
    1993           0 : void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi)
    1994             : {
    1995           0 :         struct ospf_nbr_nbma *nbr_nbma;
    1996           0 :         struct route_node *rn;
    1997           0 :         struct prefix_ipv4 p;
    1998             : 
    1999           0 :         if (oi->type != OSPF_IFTYPE_NBMA)
    2000           0 :                 return;
    2001             : 
    2002           0 :         for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
    2003           0 :                 if ((nbr_nbma = rn->info))
    2004           0 :                         if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL) {
    2005           0 :                                 p.family = AF_INET;
    2006           0 :                                 p.prefix = nbr_nbma->addr;
    2007           0 :                                 p.prefixlen = IPV4_MAX_BITLEN;
    2008             : 
    2009           0 :                                 if (prefix_match(oi->address,
    2010             :                                                  (struct prefix *)&p))
    2011           0 :                                         ospf_nbr_nbma_add(nbr_nbma, oi);
    2012             :                         }
    2013             : }
    2014             : 
    2015           0 : struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *ospf,
    2016             :                                            struct in_addr nbr_addr)
    2017             : {
    2018           0 :         struct route_node *rn;
    2019           0 :         struct prefix_ipv4 p;
    2020             : 
    2021           0 :         p.family = AF_INET;
    2022           0 :         p.prefix = nbr_addr;
    2023           0 :         p.prefixlen = IPV4_MAX_BITLEN;
    2024             : 
    2025           0 :         rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p);
    2026           0 :         if (rn) {
    2027           0 :                 route_unlock_node(rn);
    2028           0 :                 return rn->info;
    2029             :         }
    2030             :         return NULL;
    2031             : }
    2032             : 
    2033           0 : int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr)
    2034             : {
    2035           0 :         struct ospf_nbr_nbma *nbr_nbma;
    2036           0 :         struct ospf_interface *oi;
    2037           0 :         struct prefix_ipv4 p;
    2038           0 :         struct route_node *rn;
    2039           0 :         struct listnode *node;
    2040             : 
    2041           0 :         nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
    2042           0 :         if (nbr_nbma)
    2043             :                 return 0;
    2044             : 
    2045           0 :         nbr_nbma = ospf_nbr_nbma_new();
    2046           0 :         nbr_nbma->addr = nbr_addr;
    2047             : 
    2048           0 :         p.family = AF_INET;
    2049           0 :         p.prefix = nbr_addr;
    2050           0 :         p.prefixlen = IPV4_MAX_BITLEN;
    2051             : 
    2052           0 :         rn = route_node_get(ospf->nbr_nbma, (struct prefix *)&p);
    2053           0 :         if (rn->info)
    2054           0 :                 route_unlock_node(rn);
    2055           0 :         rn->info = nbr_nbma;
    2056             : 
    2057           0 :         for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
    2058           0 :                 if (oi->type == OSPF_IFTYPE_NBMA)
    2059           0 :                         if (prefix_match(oi->address, (struct prefix *)&p)) {
    2060           0 :                                 ospf_nbr_nbma_add(nbr_nbma, oi);
    2061           0 :                                 break;
    2062             :                         }
    2063             :         }
    2064             : 
    2065             :         return 1;
    2066             : }
    2067             : 
    2068           0 : int ospf_nbr_nbma_unset(struct ospf *ospf, struct in_addr nbr_addr)
    2069             : {
    2070           0 :         struct ospf_nbr_nbma *nbr_nbma;
    2071             : 
    2072           0 :         nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
    2073           0 :         if (nbr_nbma == NULL)
    2074             :                 return 0;
    2075             : 
    2076           0 :         ospf_nbr_nbma_down(nbr_nbma);
    2077           0 :         ospf_nbr_nbma_delete(ospf, nbr_nbma);
    2078             : 
    2079           0 :         return 1;
    2080             : }
    2081             : 
    2082           0 : int ospf_nbr_nbma_priority_set(struct ospf *ospf, struct in_addr nbr_addr,
    2083             :                                uint8_t priority)
    2084             : {
    2085           0 :         struct ospf_nbr_nbma *nbr_nbma;
    2086             : 
    2087           0 :         nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
    2088           0 :         if (nbr_nbma == NULL)
    2089             :                 return 0;
    2090             : 
    2091           0 :         if (nbr_nbma->priority != priority)
    2092           0 :                 nbr_nbma->priority = priority;
    2093             : 
    2094             :         return 1;
    2095             : }
    2096             : 
    2097           0 : int ospf_nbr_nbma_priority_unset(struct ospf *ospf, struct in_addr nbr_addr)
    2098             : {
    2099           0 :         struct ospf_nbr_nbma *nbr_nbma;
    2100             : 
    2101           0 :         nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
    2102           0 :         if (nbr_nbma == NULL)
    2103             :                 return 0;
    2104             : 
    2105           0 :         if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
    2106           0 :                 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
    2107             : 
    2108           0 :         return 1;
    2109             : }
    2110             : 
    2111           0 : int ospf_nbr_nbma_poll_interval_set(struct ospf *ospf, struct in_addr nbr_addr,
    2112             :                                     unsigned int interval)
    2113             : {
    2114           0 :         struct ospf_nbr_nbma *nbr_nbma;
    2115             : 
    2116           0 :         nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr);
    2117           0 :         if (nbr_nbma == NULL)
    2118             :                 return 0;
    2119             : 
    2120           0 :         if (nbr_nbma->v_poll != interval) {
    2121           0 :                 nbr_nbma->v_poll = interval;
    2122           0 :                 if (nbr_nbma->oi && ospf_if_is_up(nbr_nbma->oi)) {
    2123           0 :                         THREAD_OFF(nbr_nbma->t_poll);
    2124           0 :                         OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer,
    2125             :                                            nbr_nbma->v_poll);
    2126             :                 }
    2127             :         }
    2128             : 
    2129             :         return 1;
    2130             : }
    2131             : 
    2132           0 : int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
    2133             : {
    2134           0 :         struct ospf_nbr_nbma *nbr_nbma;
    2135             : 
    2136           0 :         nbr_nbma = ospf_nbr_nbma_lookup(ospf, addr);
    2137           0 :         if (nbr_nbma == NULL)
    2138             :                 return 0;
    2139             : 
    2140           0 :         if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
    2141           0 :                 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
    2142             : 
    2143             :         return 1;
    2144             : }
    2145             : 
    2146           4 : void ospf_master_init(struct thread_master *master)
    2147             : {
    2148           4 :         memset(&ospf_master, 0, sizeof(ospf_master));
    2149             : 
    2150           4 :         om = &ospf_master;
    2151           4 :         om->ospf = list_new();
    2152           4 :         om->master = master;
    2153           4 : }
    2154             : 
    2155             : /* Link OSPF instance to VRF. */
    2156           4 : void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
    2157             : {
    2158           4 :         ospf->vrf_id = vrf->vrf_id;
    2159           4 :         if (vrf->info != (void *)ospf)
    2160           4 :                 vrf->info = (void *)ospf;
    2161           0 : }
    2162             : 
    2163             : /* Unlink OSPF instance from VRF. */
    2164           4 : void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
    2165             : {
    2166           4 :         if (vrf->info == (void *)ospf)
    2167           4 :                 vrf->info = NULL;
    2168           4 :         ospf->vrf_id = VRF_UNKNOWN;
    2169           4 : }
    2170             : 
    2171             : /* This is hook function for vrf create called as part of vrf_init */
    2172           4 : static int ospf_vrf_new(struct vrf *vrf)
    2173             : {
    2174           4 :         if (IS_DEBUG_OSPF_EVENT)
    2175           0 :                 zlog_debug("%s: VRF Created: %s(%u)", __func__, vrf->name,
    2176             :                            vrf->vrf_id);
    2177             : 
    2178           4 :         return 0;
    2179             : }
    2180             : 
    2181             : /* This is hook function for vrf delete call as part of vrf_init */
    2182           0 : static int ospf_vrf_delete(struct vrf *vrf)
    2183             : {
    2184           0 :         if (IS_DEBUG_OSPF_EVENT)
    2185           0 :                 zlog_debug("%s: VRF Deletion: %s(%u)", __func__, vrf->name,
    2186             :                            vrf->vrf_id);
    2187             : 
    2188           0 :         return 0;
    2189             : }
    2190             : 
    2191           0 : static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf, bool set)
    2192             : {
    2193           0 :         int type;
    2194           0 :         struct list *red_list;
    2195             : 
    2196           0 :         for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
    2197           0 :                 red_list = ospf->redist[type];
    2198           0 :                 if (!red_list)
    2199           0 :                         continue;
    2200           0 :                 if (IS_DEBUG_OSPF_EVENT)
    2201           0 :                         zlog_debug(
    2202             :                                 "%s: setting redist vrf %d bitmap for type %d",
    2203             :                                 __func__, ospf->vrf_id, type);
    2204           0 :                 if (set)
    2205           0 :                         vrf_bitmap_set(zclient->redist[AFI_IP][type],
    2206             :                                        ospf->vrf_id);
    2207             :                 else
    2208           0 :                         vrf_bitmap_unset(zclient->redist[AFI_IP][type],
    2209             :                                          ospf->vrf_id);
    2210             :         }
    2211             : 
    2212           0 :         red_list = ospf->redist[DEFAULT_ROUTE];
    2213           0 :         if (red_list) {
    2214           0 :                 if (set)
    2215           0 :                         vrf_bitmap_set(zclient->default_information[AFI_IP],
    2216             :                                        ospf->vrf_id);
    2217             :                 else
    2218           0 :                         vrf_bitmap_unset(zclient->default_information[AFI_IP],
    2219             :                                          ospf->vrf_id);
    2220             :         }
    2221           0 : }
    2222             : 
    2223             : /* Enable OSPF VRF instance */
    2224           4 : static int ospf_vrf_enable(struct vrf *vrf)
    2225             : {
    2226           4 :         struct ospf *ospf = NULL;
    2227           4 :         vrf_id_t old_vrf_id;
    2228           4 :         int ret = 0;
    2229             : 
    2230           4 :         if (IS_DEBUG_OSPF_EVENT)
    2231           0 :                 zlog_debug("%s: VRF %s id %u enabled", __func__, vrf->name,
    2232             :                            vrf->vrf_id);
    2233             : 
    2234           4 :         ospf = ospf_lookup_by_name(vrf->name);
    2235           4 :         if (ospf) {
    2236           0 :                 old_vrf_id = ospf->vrf_id;
    2237             :                 /* We have instance configured, link to VRF and make it "up". */
    2238           0 :                 ospf_vrf_link(ospf, vrf);
    2239           0 :                 if (IS_DEBUG_OSPF_EVENT)
    2240           0 :                         zlog_debug(
    2241             :                                 "%s: ospf linked to vrf %s vrf_id %u (old id %u)",
    2242             :                                 __func__, vrf->name, ospf->vrf_id, old_vrf_id);
    2243             : 
    2244           0 :                 if (old_vrf_id != ospf->vrf_id) {
    2245           0 :                         ospf_set_redist_vrf_bitmaps(ospf, true);
    2246             : 
    2247             :                         /* start zebra redist to us for new vrf */
    2248           0 :                         ospf_zebra_vrf_register(ospf);
    2249             : 
    2250           0 :                         ret = ospf_sock_init(ospf);
    2251           0 :                         if (ret < 0 || ospf->fd <= 0)
    2252             :                                 return 0;
    2253           0 :                         thread_add_read(master, ospf_read, ospf, ospf->fd,
    2254             :                                         &ospf->t_read);
    2255           0 :                         ospf->oi_running = 1;
    2256           0 :                         ospf_router_id_update(ospf);
    2257             :                 }
    2258             :         }
    2259             : 
    2260             :         return 0;
    2261             : }
    2262             : 
    2263             : /* Disable OSPF VRF instance */
    2264           0 : static int ospf_vrf_disable(struct vrf *vrf)
    2265             : {
    2266           0 :         struct ospf *ospf = NULL;
    2267           0 :         vrf_id_t old_vrf_id = VRF_UNKNOWN;
    2268             : 
    2269           0 :         if (vrf->vrf_id == VRF_DEFAULT)
    2270             :                 return 0;
    2271             : 
    2272           0 :         if (IS_DEBUG_OSPF_EVENT)
    2273           0 :                 zlog_debug("%s: VRF %s id %d disabled.", __func__, vrf->name,
    2274             :                            vrf->vrf_id);
    2275             : 
    2276           0 :         ospf = ospf_lookup_by_name(vrf->name);
    2277           0 :         if (ospf) {
    2278           0 :                 old_vrf_id = ospf->vrf_id;
    2279             : 
    2280           0 :                 ospf_zebra_vrf_deregister(ospf);
    2281             : 
    2282           0 :                 ospf_set_redist_vrf_bitmaps(ospf, false);
    2283             : 
    2284             :                 /* We have instance configured, unlink
    2285             :                  * from VRF and make it "down".
    2286             :                  */
    2287           0 :                 ospf_vrf_unlink(ospf, vrf);
    2288           0 :                 ospf->oi_running = 0;
    2289           0 :                 if (IS_DEBUG_OSPF_EVENT)
    2290           0 :                         zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__,
    2291             :                                    old_vrf_id);
    2292           0 :                 THREAD_OFF(ospf->t_read);
    2293           0 :                 close(ospf->fd);
    2294           0 :                 ospf->fd = -1;
    2295             :         }
    2296             : 
    2297             :         /* Note: This is a callback, the VRF will be deleted by the caller. */
    2298             :         return 0;
    2299             : }
    2300             : 
    2301           4 : void ospf_vrf_init(void)
    2302             : {
    2303           4 :         vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
    2304             :                  ospf_vrf_delete);
    2305           4 : }
    2306             : 
    2307           0 : void ospf_vrf_terminate(void)
    2308             : {
    2309           0 :         vrf_terminate();
    2310           0 : }
    2311             : 
    2312         277 : const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
    2313             : {
    2314         277 :         struct vrf *vrf = vrf_lookup_by_id(vrf_id);
    2315             : 
    2316         277 :         return vrf ? vrf->name : "NIL";
    2317             : }
    2318             : 
    2319         977 : const char *ospf_get_name(const struct ospf *ospf)
    2320             : {
    2321         977 :         if (ospf->name)
    2322             :                 return ospf->name;
    2323             :         else
    2324           0 :                 return VRF_DEFAULT_NAME;
    2325             : }

Generated by: LCOV version v1.16-topotato