mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 02:37:00 +00:00
ospfd: fix counting of "ip ospf area" commands
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>
This commit is contained in:
parent
45af60f0bb
commit
cbf32f74ef
@ -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))
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user