Commit 09ad6bec authored by Ido Schimmel's avatar Ido Schimmel Committed by Jakub Kicinski

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: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 720ccd9a
...@@ -4309,11 +4309,18 @@ static int mlxsw_sp_nexthop_obj_validate(struct mlxsw_sp *mlxsw_sp, ...@@ -4309,11 +4309,18 @@ static int mlxsw_sp_nexthop_obj_validate(struct mlxsw_sp *mlxsw_sp,
if (event != NEXTHOP_EVENT_REPLACE) if (event != NEXTHOP_EVENT_REPLACE)
return 0; 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, return mlxsw_sp_nexthop_obj_single_validate(mlxsw_sp, info->nh,
info->extack); info->extack);
return mlxsw_sp_nexthop_obj_group_validate(mlxsw_sp, info->nh_grp, case NH_NOTIFIER_INFO_TYPE_GRP:
info->extack); 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, 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, ...@@ -4321,13 +4328,17 @@ static bool mlxsw_sp_nexthop_obj_is_gateway(struct mlxsw_sp *mlxsw_sp,
{ {
const struct net_device *dev; 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. */ /* Already validated earlier. */
return true; return true;
default:
dev = info->nh->dev; return false;
return info->nh->gw_family || info->nh->is_reject || }
mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL);
} }
static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp, 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, ...@@ -4410,11 +4421,22 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp, struct mlxsw_sp_nexthop_group *nh_grp,
struct nh_notifier_info *info) 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_group_info *nhgi;
struct mlxsw_sp_nexthop *nh; struct mlxsw_sp_nexthop *nh;
unsigned int nhs;
int err, i; 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); nhgi = kzalloc(struct_size(nhgi, nexthops, nhs), GFP_KERNEL);
if (!nhgi) if (!nhgi)
return -ENOMEM; return -ENOMEM;
...@@ -4427,12 +4449,18 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp, ...@@ -4427,12 +4449,18 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
int weight; int weight;
nh = &nhgi->nexthops[i]; nh = &nhgi->nexthops[i];
if (info->is_grp) { switch (info->type) {
nh_obj = &info->nh_grp->nh_entries[i].nh; case NH_NOTIFIER_INFO_TYPE_SINGLE:
weight = info->nh_grp->nh_entries[i].weight;
} else {
nh_obj = info->nh; nh_obj = info->nh;
weight = 1; 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, err = mlxsw_sp_nexthop_obj_init(mlxsw_sp, nh_grp, nh, nh_obj,
weight); weight);
......
...@@ -860,7 +860,7 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data, ...@@ -860,7 +860,7 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data,
nexthop = kzalloc(sizeof(*nexthop), GFP_KERNEL); nexthop = kzalloc(sizeof(*nexthop), GFP_KERNEL);
if (!nexthop) if (!nexthop)
return NULL; return ERR_PTR(-ENOMEM);
nexthop->id = info->id; nexthop->id = info->id;
...@@ -868,15 +868,20 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data, ...@@ -868,15 +868,20 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data,
* occupy. * occupy.
*/ */
if (!info->is_grp) { switch (info->type) {
case NH_NOTIFIER_INFO_TYPE_SINGLE:
occ = 1; 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; nexthop->occ = occ;
return nexthop; return nexthop;
} }
...@@ -972,8 +977,8 @@ static int nsim_nexthop_insert(struct nsim_fib_data *data, ...@@ -972,8 +977,8 @@ static int nsim_nexthop_insert(struct nsim_fib_data *data,
int err; int err;
nexthop = nsim_nexthop_create(data, info); nexthop = nsim_nexthop_create(data, info);
if (!nexthop) if (IS_ERR(nexthop))
return -ENOMEM; return PTR_ERR(nexthop);
nexthop_old = rhashtable_lookup_fast(&data->nexthop_ht, &info->id, nexthop_old = rhashtable_lookup_fast(&data->nexthop_ht, &info->id,
nsim_nexthop_ht_params); nsim_nexthop_ht_params);
......
...@@ -114,6 +114,11 @@ enum nexthop_event_type { ...@@ -114,6 +114,11 @@ enum nexthop_event_type {
NEXTHOP_EVENT_REPLACE, NEXTHOP_EVENT_REPLACE,
}; };
enum nh_notifier_info_type {
NH_NOTIFIER_INFO_TYPE_SINGLE,
NH_NOTIFIER_INFO_TYPE_GRP,
};
struct nh_notifier_single_info { struct nh_notifier_single_info {
struct net_device *dev; struct net_device *dev;
u8 gw_family; u8 gw_family;
...@@ -142,7 +147,7 @@ struct nh_notifier_info { ...@@ -142,7 +147,7 @@ struct nh_notifier_info {
struct net *net; struct net *net;
struct netlink_ext_ack *extack; struct netlink_ext_ack *extack;
u32 id; u32 id;
bool is_grp; enum nh_notifier_info_type type;
union { union {
struct nh_notifier_single_info *nh; struct nh_notifier_single_info *nh;
struct nh_notifier_grp_info *nh_grp; struct nh_notifier_grp_info *nh_grp;
......
...@@ -71,6 +71,7 @@ __nh_notifier_single_info_init(struct nh_notifier_single_info *nh_info, ...@@ -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, static int nh_notifier_single_info_init(struct nh_notifier_info *info,
const struct nexthop *nh) const struct nexthop *nh)
{ {
info->type = NH_NOTIFIER_INFO_TYPE_SINGLE;
info->nh = kzalloc(sizeof(*info->nh), GFP_KERNEL); info->nh = kzalloc(sizeof(*info->nh), GFP_KERNEL);
if (!info->nh) if (!info->nh)
return -ENOMEM; return -ENOMEM;
...@@ -92,6 +93,7 @@ static int nh_notifier_grp_info_init(struct nh_notifier_info *info, ...@@ -92,6 +93,7 @@ static int nh_notifier_grp_info_init(struct nh_notifier_info *info,
u16 num_nh = nhg->num_nh; u16 num_nh = nhg->num_nh;
int i; int i;
info->type = NH_NOTIFIER_INFO_TYPE_GRP;
info->nh_grp = kzalloc(struct_size(info->nh_grp, nh_entries, num_nh), info->nh_grp = kzalloc(struct_size(info->nh_grp, nh_entries, num_nh),
GFP_KERNEL); GFP_KERNEL);
if (!info->nh_grp) if (!info->nh_grp)
...@@ -121,17 +123,17 @@ static int nh_notifier_info_init(struct nh_notifier_info *info, ...@@ -121,17 +123,17 @@ static int nh_notifier_info_init(struct nh_notifier_info *info,
const struct nexthop *nh) const struct nexthop *nh)
{ {
info->id = nh->id; 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); return nh_notifier_grp_info_init(info, nh);
else else
return nh_notifier_single_info_init(info, nh); 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); nh_notifier_grp_info_fini(info);
else else
nh_notifier_single_info_fini(info); nh_notifier_single_info_fini(info);
...@@ -161,7 +163,7 @@ static int call_nexthop_notifiers(struct net *net, ...@@ -161,7 +163,7 @@ static int call_nexthop_notifiers(struct net *net,
err = blocking_notifier_call_chain(&net->nexthop.notifier_chain, err = blocking_notifier_call_chain(&net->nexthop.notifier_chain,
event_type, &info); event_type, &info);
nh_notifier_info_fini(&info); nh_notifier_info_fini(&info, nh);
return notifier_to_errno(err); return notifier_to_errno(err);
} }
...@@ -182,7 +184,7 @@ static int call_nexthop_notifier(struct notifier_block *nb, struct net *net, ...@@ -182,7 +184,7 @@ static int call_nexthop_notifier(struct notifier_block *nb, struct net *net,
return err; return err;
err = nb->notifier_call(nb, event_type, &info); err = nb->notifier_call(nb, event_type, &info);
nh_notifier_info_fini(&info); nh_notifier_info_fini(&info, nh);
return notifier_to_errno(err); return notifier_to_errno(err);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment