nexthop: Use enum to encode notification type
authorIdo Schimmel <idosch@nvidia.com>
Thu, 28 Jan 2021 12:49:17 +0000 (13:49 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 29 Jan 2021 04:49:52 +0000 (20:49 -0800)
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>
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/netdevsim/fib.c
include/net/nexthop.h
net/ipv4/nexthop.c

index 41424ee..0ac7014 100644 (file)
@@ -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);
index 45d8a77..f140bbc 100644 (file)
@@ -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);
index d0e245b..7bc057a 100644 (file)
@@ -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;
index c09b823..12f812b 100644 (file)
@@ -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);
 }