nexthop: Use enum to encode notification type
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 <idosch@nvidia.com> Reviewed-by: Petr Machata <petrm@nvidia.com> Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
720ccd9a72
commit
09ad6becf5
@ -4309,11 +4309,18 @@ 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,
|
||||
@ -4321,13 +4328,17 @@ static bool mlxsw_sp_nexthop_obj_is_gateway(struct mlxsw_sp *mlxsw_sp,
|
||||
{
|
||||
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,
|
||||
@ -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;
|
||||
@ -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);
|
||||
|
@ -860,7 +860,7 @@ 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;
|
||||
|
||||
@ -868,15 +868,20 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data,
|
||||
* 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;
|
||||
}
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
@ -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)
|
||||
@ -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);
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user