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

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
Loading
Loading
Loading
Loading
+41 −13
Original line number Diff line number Diff line
@@ -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,
	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)
		/* Already validated earlier. */
		return true;

	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;
	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);
+14 −9
Original line number Diff line number Diff line
@@ -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);
	}

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);
+6 −1
Original line number Diff line number Diff line
@@ -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;
+8 −6
Original line number Diff line number Diff line
@@ -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);
}