Skip to content

Commit

Permalink
nexthop: Use enum to encode notification type
Browse files Browse the repository at this point in the history
Currently there are only two types of in-kernel nexthop notification.
The two are distinguished by the 'is_grp' boolean field in 'struct
nh_notifier_info'.

As more notification types are introduced for more next-hop group types, a
boolean is not an easily extensible interface. Instead, convert it to an
enum.

Signed-off-by: Ido Schimmel <[email protected]>
Reviewed-by: Petr Machata <[email protected]>
Signed-off-by: Petr Machata <[email protected]>
Reviewed-by: David Ahern <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
idosch authored and kuba-moo committed Jan 29, 2021
1 parent 720ccd9 commit 09ad6be
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 29 deletions.
54 changes: 41 additions & 13 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -4309,25 +4309,36 @@ static int mlxsw_sp_nexthop_obj_validate(struct mlxsw_sp *mlxsw_sp,
if (event != NEXTHOP_EVENT_REPLACE)
return 0;

if (!info->is_grp)
switch (info->type) {
case NH_NOTIFIER_INFO_TYPE_SINGLE:
return mlxsw_sp_nexthop_obj_single_validate(mlxsw_sp, info->nh,
info->extack);
return mlxsw_sp_nexthop_obj_group_validate(mlxsw_sp, info->nh_grp,
info->extack);
case NH_NOTIFIER_INFO_TYPE_GRP:
return mlxsw_sp_nexthop_obj_group_validate(mlxsw_sp,
info->nh_grp,
info->extack);
default:
NL_SET_ERR_MSG_MOD(info->extack, "Unsupported nexthop type");
return -EOPNOTSUPP;
}
}

static bool mlxsw_sp_nexthop_obj_is_gateway(struct mlxsw_sp *mlxsw_sp,
const struct nh_notifier_info *info)
{
const struct net_device *dev;

if (info->is_grp)
switch (info->type) {
case NH_NOTIFIER_INFO_TYPE_SINGLE:
dev = info->nh->dev;
return info->nh->gw_family || info->nh->is_reject ||
mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL);
case NH_NOTIFIER_INFO_TYPE_GRP:
/* Already validated earlier. */
return true;

dev = info->nh->dev;
return info->nh->gw_family || info->nh->is_reject ||
mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL);
default:
return false;
}
}

static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp,
Expand Down Expand Up @@ -4410,11 +4421,22 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp,
struct nh_notifier_info *info)
{
unsigned int nhs = info->is_grp ? info->nh_grp->num_nh : 1;
struct mlxsw_sp_nexthop_group_info *nhgi;
struct mlxsw_sp_nexthop *nh;
unsigned int nhs;
int err, i;

switch (info->type) {
case NH_NOTIFIER_INFO_TYPE_SINGLE:
nhs = 1;
break;
case NH_NOTIFIER_INFO_TYPE_GRP:
nhs = info->nh_grp->num_nh;
break;
default:
return -EINVAL;
}

nhgi = kzalloc(struct_size(nhgi, nexthops, nhs), GFP_KERNEL);
if (!nhgi)
return -ENOMEM;
Expand All @@ -4427,12 +4449,18 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
int weight;

nh = &nhgi->nexthops[i];
if (info->is_grp) {
nh_obj = &info->nh_grp->nh_entries[i].nh;
weight = info->nh_grp->nh_entries[i].weight;
} else {
switch (info->type) {
case NH_NOTIFIER_INFO_TYPE_SINGLE:
nh_obj = info->nh;
weight = 1;
break;
case NH_NOTIFIER_INFO_TYPE_GRP:
nh_obj = &info->nh_grp->nh_entries[i].nh;
weight = info->nh_grp->nh_entries[i].weight;
break;
default:
err = -EINVAL;
goto err_nexthop_obj_init;
}
err = mlxsw_sp_nexthop_obj_init(mlxsw_sp, nh_grp, nh, nh_obj,
weight);
Expand Down
23 changes: 14 additions & 9 deletions drivers/net/netdevsim/fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,23 +860,28 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data,

nexthop = kzalloc(sizeof(*nexthop), GFP_KERNEL);
if (!nexthop)
return NULL;
return ERR_PTR(-ENOMEM);

nexthop->id = info->id;

/* Determine the number of nexthop entries the new nexthop will
* occupy.
*/

if (!info->is_grp) {
switch (info->type) {
case NH_NOTIFIER_INFO_TYPE_SINGLE:
occ = 1;
goto out;
break;
case NH_NOTIFIER_INFO_TYPE_GRP:
for (i = 0; i < info->nh_grp->num_nh; i++)
occ += info->nh_grp->nh_entries[i].weight;
break;
default:
NL_SET_ERR_MSG_MOD(info->extack, "Unsupported nexthop type");
kfree(nexthop);
return ERR_PTR(-EOPNOTSUPP);
}

for (i = 0; i < info->nh_grp->num_nh; i++)
occ += info->nh_grp->nh_entries[i].weight;

out:
nexthop->occ = occ;
return nexthop;
}
Expand Down Expand Up @@ -972,8 +977,8 @@ static int nsim_nexthop_insert(struct nsim_fib_data *data,
int err;

nexthop = nsim_nexthop_create(data, info);
if (!nexthop)
return -ENOMEM;
if (IS_ERR(nexthop))
return PTR_ERR(nexthop);

nexthop_old = rhashtable_lookup_fast(&data->nexthop_ht, &info->id,
nsim_nexthop_ht_params);
Expand Down
7 changes: 6 additions & 1 deletion include/net/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ enum nexthop_event_type {
NEXTHOP_EVENT_REPLACE,
};

enum nh_notifier_info_type {
NH_NOTIFIER_INFO_TYPE_SINGLE,
NH_NOTIFIER_INFO_TYPE_GRP,
};

struct nh_notifier_single_info {
struct net_device *dev;
u8 gw_family;
Expand Down Expand Up @@ -142,7 +147,7 @@ struct nh_notifier_info {
struct net *net;
struct netlink_ext_ack *extack;
u32 id;
bool is_grp;
enum nh_notifier_info_type type;
union {
struct nh_notifier_single_info *nh;
struct nh_notifier_grp_info *nh_grp;
Expand Down
14 changes: 8 additions & 6 deletions net/ipv4/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ __nh_notifier_single_info_init(struct nh_notifier_single_info *nh_info,
static int nh_notifier_single_info_init(struct nh_notifier_info *info,
const struct nexthop *nh)
{
info->type = NH_NOTIFIER_INFO_TYPE_SINGLE;
info->nh = kzalloc(sizeof(*info->nh), GFP_KERNEL);
if (!info->nh)
return -ENOMEM;
Expand All @@ -92,6 +93,7 @@ static int nh_notifier_grp_info_init(struct nh_notifier_info *info,
u16 num_nh = nhg->num_nh;
int i;

info->type = NH_NOTIFIER_INFO_TYPE_GRP;
info->nh_grp = kzalloc(struct_size(info->nh_grp, nh_entries, num_nh),
GFP_KERNEL);
if (!info->nh_grp)
Expand Down Expand Up @@ -121,17 +123,17 @@ static int nh_notifier_info_init(struct nh_notifier_info *info,
const struct nexthop *nh)
{
info->id = nh->id;
info->is_grp = nh->is_group;

if (info->is_grp)
if (nh->is_group)
return nh_notifier_grp_info_init(info, nh);
else
return nh_notifier_single_info_init(info, nh);
}

static void nh_notifier_info_fini(struct nh_notifier_info *info)
static void nh_notifier_info_fini(struct nh_notifier_info *info,
const struct nexthop *nh)
{
if (info->is_grp)
if (nh->is_group)
nh_notifier_grp_info_fini(info);
else
nh_notifier_single_info_fini(info);
Expand Down Expand Up @@ -161,7 +163,7 @@ static int call_nexthop_notifiers(struct net *net,

err = blocking_notifier_call_chain(&net->nexthop.notifier_chain,
event_type, &info);
nh_notifier_info_fini(&info);
nh_notifier_info_fini(&info, nh);

return notifier_to_errno(err);
}
Expand All @@ -182,7 +184,7 @@ static int call_nexthop_notifier(struct notifier_block *nb, struct net *net,
return err;

err = nb->notifier_call(nb, event_type, &info);
nh_notifier_info_fini(&info);
nh_notifier_info_fini(&info, nh);

return notifier_to_errno(err);
}
Expand Down

0 comments on commit 09ad6be

Please sign in to comment.