OSDN Git Service

net: switchdev: merge switchdev_handle_fdb_{add,del}_to_device
authorVladimir Oltean <vladimir.oltean@nxp.com>
Tue, 26 Oct 2021 14:27:43 +0000 (17:27 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 27 Oct 2021 13:54:02 +0000 (14:54 +0100)
To reduce code churn, the same patch makes multiple changes, since they
all touch the same lines:

1. The implementations for these two are identical, just with different
   function pointers. Reduce duplications and name the function pointers
   "mod_cb" instead of "add_cb" and "del_cb". Pass the event as argument.

2. Drop the "const" attribute from "orig_dev". If the driver needs to
   check whether orig_dev belongs to itself and then
   call_switchdev_notifiers(orig_dev, SWITCHDEV_FDB_OFFLOADED), it
   can't, because call_switchdev_notifiers takes a non-const struct
   net_device *.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/switchdev.h
net/dsa/slave.c
net/switchdev/switchdev.c

index 60d806b..d353793 100644 (file)
@@ -299,28 +299,16 @@ void switchdev_port_fwd_mark_set(struct net_device *dev,
                                 struct net_device *group_dev,
                                 bool joining);
 
-int switchdev_handle_fdb_add_to_device(struct net_device *dev,
+int switchdev_handle_fdb_event_to_device(struct net_device *dev, unsigned long event,
                const struct switchdev_notifier_fdb_info *fdb_info,
                bool (*check_cb)(const struct net_device *dev),
                bool (*foreign_dev_check_cb)(const struct net_device *dev,
                                             const struct net_device *foreign_dev),
-               int (*add_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
+               int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                             unsigned long event, const void *ctx,
                              const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_add_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
-                                 const struct switchdev_notifier_fdb_info *fdb_info));
-
-int switchdev_handle_fdb_del_to_device(struct net_device *dev,
-               const struct switchdev_notifier_fdb_info *fdb_info,
-               bool (*check_cb)(const struct net_device *dev),
-               bool (*foreign_dev_check_cb)(const struct net_device *dev,
-                                            const struct net_device *foreign_dev),
-               int (*del_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
-                             const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_del_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
+               int (*lag_mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                                 unsigned long event, const void *ctx,
                                  const struct switchdev_notifier_fdb_info *fdb_info));
 
 int switchdev_handle_port_obj_add(struct net_device *dev,
@@ -426,32 +414,16 @@ call_switchdev_blocking_notifiers(unsigned long val,
 }
 
 static inline int
-switchdev_handle_fdb_add_to_device(struct net_device *dev,
-               const struct switchdev_notifier_fdb_info *fdb_info,
-               bool (*check_cb)(const struct net_device *dev),
-               bool (*foreign_dev_check_cb)(const struct net_device *dev,
-                                            const struct net_device *foreign_dev),
-               int (*add_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
-                             const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_add_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
-                                 const struct switchdev_notifier_fdb_info *fdb_info))
-{
-       return 0;
-}
-
-static inline int
-switchdev_handle_fdb_del_to_device(struct net_device *dev,
+switchdev_handle_fdb_event_to_device(struct net_device *dev, unsigned long event,
                const struct switchdev_notifier_fdb_info *fdb_info,
                bool (*check_cb)(const struct net_device *dev),
                bool (*foreign_dev_check_cb)(const struct net_device *dev,
                                             const struct net_device *foreign_dev),
-               int (*del_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
+               int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                             unsigned long event, const void *ctx,
                              const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_del_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
+               int (*lag_mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                                 unsigned long event, const void *ctx,
                                  const struct switchdev_notifier_fdb_info *fdb_info))
 {
        return 0;
index dbda0e0..db066f0 100644 (file)
@@ -2468,10 +2468,9 @@ static bool dsa_foreign_dev_check(const struct net_device *dev,
 }
 
 static int dsa_slave_fdb_event(struct net_device *dev,
-                              const struct net_device *orig_dev,
-                              const void *ctx,
-                              const struct switchdev_notifier_fdb_info *fdb_info,
-                              unsigned long event)
+                              struct net_device *orig_dev,
+                              unsigned long event, const void *ctx,
+                              const struct switchdev_notifier_fdb_info *fdb_info)
 {
        struct dsa_switchdev_event_work *switchdev_work;
        struct dsa_port *dp = dsa_slave_to_port(dev);
@@ -2525,24 +2524,6 @@ static int dsa_slave_fdb_event(struct net_device *dev,
        return 0;
 }
 
-static int
-dsa_slave_fdb_add_to_device(struct net_device *dev,
-                           const struct net_device *orig_dev, const void *ctx,
-                           const struct switchdev_notifier_fdb_info *fdb_info)
-{
-       return dsa_slave_fdb_event(dev, orig_dev, ctx, fdb_info,
-                                  SWITCHDEV_FDB_ADD_TO_DEVICE);
-}
-
-static int
-dsa_slave_fdb_del_to_device(struct net_device *dev,
-                           const struct net_device *orig_dev, const void *ctx,
-                           const struct switchdev_notifier_fdb_info *fdb_info)
-{
-       return dsa_slave_fdb_event(dev, orig_dev, ctx, fdb_info,
-                                  SWITCHDEV_FDB_DEL_TO_DEVICE);
-}
-
 /* Called under rcu_read_lock() */
 static int dsa_slave_switchdev_event(struct notifier_block *unused,
                                     unsigned long event, void *ptr)
@@ -2557,18 +2538,12 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
                                                     dsa_slave_port_attr_set);
                return notifier_from_errno(err);
        case SWITCHDEV_FDB_ADD_TO_DEVICE:
-               err = switchdev_handle_fdb_add_to_device(dev, ptr,
-                                                        dsa_slave_dev_check,
-                                                        dsa_foreign_dev_check,
-                                                        dsa_slave_fdb_add_to_device,
-                                                        NULL);
-               return notifier_from_errno(err);
        case SWITCHDEV_FDB_DEL_TO_DEVICE:
-               err = switchdev_handle_fdb_del_to_device(dev, ptr,
-                                                        dsa_slave_dev_check,
-                                                        dsa_foreign_dev_check,
-                                                        dsa_slave_fdb_del_to_device,
-                                                        NULL);
+               err = switchdev_handle_fdb_event_to_device(dev, event, ptr,
+                                                          dsa_slave_dev_check,
+                                                          dsa_foreign_dev_check,
+                                                          dsa_slave_fdb_event,
+                                                          NULL);
                return notifier_from_errno(err);
        default:
                return NOTIFY_DONE;
index 0b2c18e..8346047 100644 (file)
@@ -428,17 +428,17 @@ switchdev_lower_dev_find(struct net_device *dev,
        return switchdev_priv.lower_dev;
 }
 
-static int __switchdev_handle_fdb_add_to_device(struct net_device *dev,
-               const struct net_device *orig_dev,
+static int __switchdev_handle_fdb_event_to_device(struct net_device *dev,
+               struct net_device *orig_dev, unsigned long event,
                const struct switchdev_notifier_fdb_info *fdb_info,
                bool (*check_cb)(const struct net_device *dev),
                bool (*foreign_dev_check_cb)(const struct net_device *dev,
                                             const struct net_device *foreign_dev),
-               int (*add_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
+               int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                             unsigned long event, const void *ctx,
                              const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_add_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
+               int (*lag_mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                                 unsigned long event, const void *ctx,
                                  const struct switchdev_notifier_fdb_info *fdb_info))
 {
        const struct switchdev_notifier_info *info = &fdb_info->info;
@@ -447,17 +447,17 @@ static int __switchdev_handle_fdb_add_to_device(struct net_device *dev,
        int err = -EOPNOTSUPP;
 
        if (check_cb(dev))
-               return add_cb(dev, orig_dev, info->ctx, fdb_info);
+               return mod_cb(dev, orig_dev, event, info->ctx, fdb_info);
 
        if (netif_is_lag_master(dev)) {
                if (!switchdev_lower_dev_find(dev, check_cb, foreign_dev_check_cb))
                        goto maybe_bridged_with_us;
 
                /* This is a LAG interface that we offload */
-               if (!lag_add_cb)
+               if (!lag_mod_cb)
                        return -EOPNOTSUPP;
 
-               return lag_add_cb(dev, orig_dev, info->ctx, fdb_info);
+               return lag_mod_cb(dev, orig_dev, event, info->ctx, fdb_info);
        }
 
        /* Recurse through lower interfaces in case the FDB entry is pointing
@@ -481,10 +481,10 @@ static int __switchdev_handle_fdb_add_to_device(struct net_device *dev,
                                                      foreign_dev_check_cb))
                                continue;
 
-                       err = __switchdev_handle_fdb_add_to_device(lower_dev, orig_dev,
-                                                                  fdb_info, check_cb,
-                                                                  foreign_dev_check_cb,
-                                                                  add_cb, lag_add_cb);
+                       err = __switchdev_handle_fdb_event_to_device(lower_dev, orig_dev,
+                                                                    event, fdb_info, check_cb,
+                                                                    foreign_dev_check_cb,
+                                                                    mod_cb, lag_mod_cb);
                        if (err && err != -EOPNOTSUPP)
                                return err;
                }
@@ -503,140 +503,34 @@ maybe_bridged_with_us:
        if (!switchdev_lower_dev_find(br, check_cb, foreign_dev_check_cb))
                return 0;
 
-       return __switchdev_handle_fdb_add_to_device(br, orig_dev, fdb_info,
-                                                   check_cb, foreign_dev_check_cb,
-                                                   add_cb, lag_add_cb);
+       return __switchdev_handle_fdb_event_to_device(br, orig_dev, event, fdb_info,
+                                                     check_cb, foreign_dev_check_cb,
+                                                     mod_cb, lag_mod_cb);
 }
 
-int switchdev_handle_fdb_add_to_device(struct net_device *dev,
+int switchdev_handle_fdb_event_to_device(struct net_device *dev, unsigned long event,
                const struct switchdev_notifier_fdb_info *fdb_info,
                bool (*check_cb)(const struct net_device *dev),
                bool (*foreign_dev_check_cb)(const struct net_device *dev,
                                             const struct net_device *foreign_dev),
-               int (*add_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
+               int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                             unsigned long event, const void *ctx,
                              const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_add_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
+               int (*lag_mod_cb)(struct net_device *dev, struct net_device *orig_dev,
+                                 unsigned long event, const void *ctx,
                                  const struct switchdev_notifier_fdb_info *fdb_info))
 {
        int err;
 
-       err = __switchdev_handle_fdb_add_to_device(dev, dev, fdb_info,
-                                                  check_cb,
-                                                  foreign_dev_check_cb,
-                                                  add_cb, lag_add_cb);
+       err = __switchdev_handle_fdb_event_to_device(dev, dev, event, fdb_info,
+                                                    check_cb, foreign_dev_check_cb,
+                                                    mod_cb, lag_mod_cb);
        if (err == -EOPNOTSUPP)
                err = 0;
 
        return err;
 }
-EXPORT_SYMBOL_GPL(switchdev_handle_fdb_add_to_device);
-
-static int __switchdev_handle_fdb_del_to_device(struct net_device *dev,
-               const struct net_device *orig_dev,
-               const struct switchdev_notifier_fdb_info *fdb_info,
-               bool (*check_cb)(const struct net_device *dev),
-               bool (*foreign_dev_check_cb)(const struct net_device *dev,
-                                            const struct net_device *foreign_dev),
-               int (*del_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
-                             const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_del_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
-                                 const struct switchdev_notifier_fdb_info *fdb_info))
-{
-       const struct switchdev_notifier_info *info = &fdb_info->info;
-       struct net_device *br, *lower_dev;
-       struct list_head *iter;
-       int err = -EOPNOTSUPP;
-
-       if (check_cb(dev))
-               return del_cb(dev, orig_dev, info->ctx, fdb_info);
-
-       if (netif_is_lag_master(dev)) {
-               if (!switchdev_lower_dev_find(dev, check_cb, foreign_dev_check_cb))
-                       goto maybe_bridged_with_us;
-
-               /* This is a LAG interface that we offload */
-               if (!lag_del_cb)
-                       return -EOPNOTSUPP;
-
-               return lag_del_cb(dev, orig_dev, info->ctx, fdb_info);
-       }
-
-       /* Recurse through lower interfaces in case the FDB entry is pointing
-        * towards a bridge device.
-        */
-       if (netif_is_bridge_master(dev)) {
-               if (!switchdev_lower_dev_find(dev, check_cb, foreign_dev_check_cb))
-                       return 0;
-
-               /* This is a bridge interface that we offload */
-               netdev_for_each_lower_dev(dev, lower_dev, iter) {
-                       /* Do not propagate FDB entries across bridges */
-                       if (netif_is_bridge_master(lower_dev))
-                               continue;
-
-                       /* Bridge ports might be either us, or LAG interfaces
-                        * that we offload.
-                        */
-                       if (!check_cb(lower_dev) &&
-                           !switchdev_lower_dev_find(lower_dev, check_cb,
-                                                     foreign_dev_check_cb))
-                               continue;
-
-                       err = __switchdev_handle_fdb_del_to_device(lower_dev, orig_dev,
-                                                                  fdb_info, check_cb,
-                                                                  foreign_dev_check_cb,
-                                                                  del_cb, lag_del_cb);
-                       if (err && err != -EOPNOTSUPP)
-                               return err;
-               }
-
-               return 0;
-       }
-
-maybe_bridged_with_us:
-       /* Event is neither on a bridge nor a LAG. Check whether it is on an
-        * interface that is in a bridge with us.
-        */
-       br = netdev_master_upper_dev_get_rcu(dev);
-       if (!br || !netif_is_bridge_master(br))
-               return 0;
-
-       if (!switchdev_lower_dev_find(br, check_cb, foreign_dev_check_cb))
-               return 0;
-
-       return __switchdev_handle_fdb_del_to_device(br, orig_dev, fdb_info,
-                                                   check_cb, foreign_dev_check_cb,
-                                                   del_cb, lag_del_cb);
-}
-
-int switchdev_handle_fdb_del_to_device(struct net_device *dev,
-               const struct switchdev_notifier_fdb_info *fdb_info,
-               bool (*check_cb)(const struct net_device *dev),
-               bool (*foreign_dev_check_cb)(const struct net_device *dev,
-                                            const struct net_device *foreign_dev),
-               int (*del_cb)(struct net_device *dev,
-                             const struct net_device *orig_dev, const void *ctx,
-                             const struct switchdev_notifier_fdb_info *fdb_info),
-               int (*lag_del_cb)(struct net_device *dev,
-                                 const struct net_device *orig_dev, const void *ctx,
-                                 const struct switchdev_notifier_fdb_info *fdb_info))
-{
-       int err;
-
-       err = __switchdev_handle_fdb_del_to_device(dev, dev, fdb_info,
-                                                  check_cb,
-                                                  foreign_dev_check_cb,
-                                                  del_cb, lag_del_cb);
-       if (err == -EOPNOTSUPP)
-               err = 0;
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(switchdev_handle_fdb_del_to_device);
+EXPORT_SYMBOL_GPL(switchdev_handle_fdb_event_to_device);
 
 static int __switchdev_handle_port_obj_add(struct net_device *dev,
                        struct switchdev_notifier_port_obj_info *port_obj_info,