Skip to content

Commit

Permalink
Merge pull request FRRouting#8362 from idryzhov/fix-ospf-cli-count
Browse files Browse the repository at this point in the history
ospfd: fix counting of "ip ospf area" commands
  • Loading branch information
Mark Stapp authored Mar 30, 2021
2 parents 9b25636 + cbf32f7 commit 5c9254b
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 70 deletions.
45 changes: 19 additions & 26 deletions ospfd/ospf_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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);

Expand Down Expand Up @@ -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(
Expand All @@ -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))
Expand Down
2 changes: 2 additions & 0 deletions ospfd/ospf_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
15 changes: 6 additions & 9 deletions ospfd/ospf_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,21 +577,23 @@ 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,
"The network command is not supported in multi-instance ospf\n");
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;
}

Expand Down Expand Up @@ -8873,10 +8875,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;
Expand Down Expand Up @@ -8934,10 +8934,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;
}
Expand Down Expand Up @@ -9003,7 +9001,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);
}

Expand Down
47 changes: 17 additions & 30 deletions ospfd/ospfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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.
Expand Down
6 changes: 1 addition & 5 deletions ospfd/ospfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 5c9254b

Please sign in to comment.