]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospfd: fix counting of "ip ospf area" commands
authorIgor Ryzhov <iryzhov@nfware.com>
Mon, 29 Mar 2021 11:47:43 +0000 (14:47 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 30 Mar 2021 08:51:21 +0000 (11:51 +0300)
Instead of trying to maintain if_ospf_cli_count, let's directly count
the number of configured interfaces when it is needed. Current approach
sometimes leads to an incorrect counter.

Fixes #8321.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
ospfd/ospf_interface.c
ospfd/ospf_interface.h
ospfd/ospf_vty.c
ospfd/ospfd.c
ospfd/ospfd.h

index d494f0fbce5dacb271fec9d51c60a8b86f2b5946..6829c4a347cc25243fbad736f491ce81930133c5 100644 (file)
@@ -1272,12 +1272,27 @@ void ospf_if_interface(struct interface *ifp)
        hook_call(ospf_if_update, ifp);
 }
 
-static int ospf_ifp_create(struct interface *ifp)
+uint32_t ospf_if_count_area_params(struct interface *ifp)
 {
-       struct ospf *ospf = NULL;
        struct ospf_if_params *params;
        struct route_node *rn;
        uint32_t count = 0;
+
+       params = IF_DEF_PARAMS(ifp);
+       if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+               count++;
+
+       for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
+               if ((params = rn->info)
+                   && OSPF_IF_PARAM_CONFIGURED(params, if_area))
+                       count++;
+
+       return count;
+}
+
+static int ospf_ifp_create(struct interface *ifp)
+{
+       struct ospf *ospf = NULL;
        struct ospf_if_info *oii;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
@@ -1303,18 +1318,8 @@ static int ospf_ifp_create(struct interface *ifp)
        if (!ospf)
                return 0;
 
-       params = IF_DEF_PARAMS(ifp);
-       if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
-               count++;
-
-       for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
-               if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
-                       count++;
-
-       if (count > 0) {
-               ospf->if_ospf_cli_count += count;
+       if (ospf_if_count_area_params(ifp) > 0)
                ospf_interface_area_set(ospf, ifp);
-       }
 
        ospf_if_recalculate_output_cost(ifp);
 
@@ -1382,9 +1387,7 @@ static int ospf_ifp_down(struct interface *ifp)
 static int ospf_ifp_destroy(struct interface *ifp)
 {
        struct ospf *ospf;
-       struct ospf_if_params *params;
        struct route_node *rn;
-       uint32_t count = 0;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
                zlog_debug(
@@ -1397,18 +1400,8 @@ static int ospf_ifp_destroy(struct interface *ifp)
 
        ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
        if (ospf) {
-               params = IF_DEF_PARAMS(ifp);
-               if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
-                       count++;
-
-               for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
-                       if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
-                               count++;
-
-               if (count > 0) {
-                       ospf->if_ospf_cli_count -= count;
+               if (ospf_if_count_area_params(ifp) > 0)
                        ospf_interface_area_unset(ospf, ifp);
-               }
        }
 
        for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
index a9534f543d53a5845eceee76ca6573b50320dde2..e2d732738169a2032330419532011c19c7be13f6 100644 (file)
@@ -338,6 +338,8 @@ extern void ospf_if_set_multicast(struct ospf_interface *);
 
 extern void ospf_if_interface(struct interface *ifp);
 
+extern uint32_t ospf_if_count_area_params(struct interface *ifp);
+
 DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd));
 DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd));
 
index e6835ffc72060bec936a9629847585d1e521251e..f7bef89b307fdcbc8964ef47f6bf6245a60c6969 100644 (file)
@@ -577,6 +577,7 @@ DEFUN (ospf_network_area,
        struct prefix_ipv4 p;
        struct in_addr area_id;
        int ret, format;
+       uint32_t count;
 
        if (ospf->instance) {
                vty_out(vty,
@@ -584,14 +585,15 @@ DEFUN (ospf_network_area,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       if (ospf->if_ospf_cli_count > 0) {
+       count = ospf_count_area_params(ospf);
+       if (count > 0) {
                vty_out(vty,
                        "Please remove all ip ospf area x.x.x.x commands first.\n");
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
                                "%s ospf vrf %s num of %u ip ospf area x config",
                                __func__, ospf->name ? ospf->name : "NIL",
-                               ospf->if_ospf_cli_count);
+                               count);
                return CMD_WARNING_CONFIG_FAILED;
        }
 
@@ -8821,10 +8823,8 @@ DEFUN (ip_ospf_area,
 
                if (count > 0) {
                        ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
-                       if (ospf) {
+                       if (ospf)
                                ospf_interface_area_unset(ospf, ifp);
-                               ospf->if_ospf_cli_count -= count;
-                       }
                }
 
                return CMD_NOT_MY_INSTANCE;
@@ -8882,10 +8882,8 @@ DEFUN (ip_ospf_area,
                params->if_area_id_fmt = format;
        }
 
-       if (ospf) {
+       if (ospf)
                ospf_interface_area_set(ospf, ifp);
-               ospf->if_ospf_cli_count++;
-       }
 
        return CMD_SUCCESS;
 }
@@ -8951,7 +8949,6 @@ DEFUN (no_ip_ospf_area,
 
        if (ospf) {
                ospf_interface_area_unset(ospf, ifp);
-               ospf->if_ospf_cli_count--;
                ospf_area_check_free(ospf, area_id);
        }
 
index 9856e601305fc42d562c85feb55c77d780af5886..077d7c0fb0bfe288cee52d5d76f1c9d5dc8d7107 100644 (file)
@@ -476,41 +476,11 @@ struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
 
 static void ospf_init(struct ospf *ospf)
 {
-       struct vrf *vrf;
-       struct interface *ifp;
-
        ospf_opaque_type11_lsa_init(ospf);
 
        if (ospf->vrf_id != VRF_UNKNOWN)
                ospf->oi_running = 1;
 
-       /* Activate 'ip ospf area x' configured interfaces for given
-        * vrf. Activate area on vrf x aware interfaces.
-        * vrf_enable callback calls router_id_update which
-        * internally will call ospf_if_update to trigger
-        * network_run_state
-        */
-       vrf = vrf_lookup_by_id(ospf->vrf_id);
-
-       FOR_ALL_INTERFACES (vrf, ifp) {
-               struct ospf_if_params *params;
-               struct route_node *rn;
-               uint32_t count = 0;
-
-               params = IF_DEF_PARAMS(ifp);
-               if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
-                       count++;
-
-               for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
-                       if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
-                               count++;
-
-               if (count > 0) {
-                       ospf_interface_area_set(ospf, ifp);
-                       ospf->if_ospf_cli_count += count;
-               }
-       }
-
        ospf_router_id_update(ospf);
 }
 
@@ -554,6 +524,23 @@ struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
        return (vrf->info) ? (struct ospf *)vrf->info : NULL;
 }
 
+uint32_t ospf_count_area_params(struct ospf *ospf)
+{
+       struct vrf *vrf;
+       struct interface *ifp;
+       uint32_t count = 0;
+
+       if (ospf->vrf_id != VRF_UNKNOWN) {
+               vrf = vrf_lookup_by_id(ospf->vrf_id);
+
+               FOR_ALL_INTERFACES (vrf, ifp) {
+                       count += ospf_if_count_area_params(ifp);
+               }
+       }
+
+       return count;
+}
+
 /* It should only be used when processing incoming info update from zebra.
  * Other situations, it is not sufficient to lookup the ospf instance by
  * vrf_name only without using the instance number.
index 5d64ee9ba21fa1da21a102297f6e9fe840a4f5c1..6bf7f4e9fb2368efe333a3b9a4a3d5c108e4add2 100644 (file)
@@ -310,11 +310,6 @@ struct ospf {
        /* Statistics for LSA used for new instantiation. */
        uint32_t rx_lsa_count;
 
-       /* Counter of "ip ospf area x.x.x.x" used
-        * for mutual exclusion of network command under
-        * router ospf or ip ospf area x under interface. */
-       uint32_t if_ospf_cli_count;
-
        struct route_table *distance_table;
 
        /* Used during ospf instance going down send LSDB
@@ -650,6 +645,7 @@ extern struct ospf *ospf_new_alloc(unsigned short instance, const char *name);
 extern struct ospf *ospf_lookup_by_inst_name(unsigned short instance,
                                             const char *name);
 extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
+extern uint32_t ospf_count_area_params(struct ospf *ospf);
 extern void ospf_finish(struct ospf *);
 extern void ospf_process_refresh_data(struct ospf *ospf, bool reset);
 extern void ospf_router_id_update(struct ospf *ospf);