]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
switchdev: Add fdb.added_by_user to switchdev notifications
authorPetr Machata <petrm@mellanox.com>
Thu, 3 May 2018 12:43:46 +0000 (14:43 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 May 2018 17:46:47 +0000 (13:46 -0400)
The following patch enables sending notifications also for events on FDB
entries that weren't added by the user. Give the drivers the information
necessary to distinguish between the two origins of FDB entries.

To maintain the current behavior, have switchdev-implementing drivers
bail out on notifications about non-user-added FDB entries. In case of
mlxsw driver, allow a call to mlxsw_sp_span_respin() so that SPAN over
bridge catches up with the changed FDB.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Acked-by: Ivan Vecera <ivecera@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/rocker/rocker_main.c
include/net/switchdev.h
net/bridge/br_switchdev.c
net/dsa/slave.c

index 1af99fe5fd320c51915958ed4e5f3b66ee957671..3973d90cc90807174877eede65c9ef0c08a0a58f 100644 (file)
@@ -2270,6 +2270,8 @@ static void mlxsw_sp_switchdev_event_work(struct work_struct *work)
        switch (switchdev_work->event) {
        case SWITCHDEV_FDB_ADD_TO_DEVICE:
                fdb_info = &switchdev_work->fdb_info;
+               if (!fdb_info->added_by_user)
+                       break;
                err = mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, true);
                if (err)
                        break;
@@ -2279,6 +2281,8 @@ static void mlxsw_sp_switchdev_event_work(struct work_struct *work)
                break;
        case SWITCHDEV_FDB_DEL_TO_DEVICE:
                fdb_info = &switchdev_work->fdb_info;
+               if (!fdb_info->added_by_user)
+                       break;
                mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, false);
                break;
        case SWITCHDEV_FDB_ADD_TO_BRIDGE: /* fall through */
index 056cb60936303563ac835a8a450e29566cd2bb86..152d6948611cf5e0706565438278c22aaa1fca7f 100644 (file)
@@ -2783,6 +2783,8 @@ static int rocker_switchdev_event(struct notifier_block *unused,
        switch (event) {
        case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
        case SWITCHDEV_FDB_DEL_TO_DEVICE:
+               if (!fdb_info->added_by_user)
+                       break;
                memcpy(&switchdev_work->fdb_info, ptr,
                       sizeof(switchdev_work->fdb_info));
                switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
index 39bc855d7fee6644ade78f0273ab672cf204265a..d574ce63bf220d1069d2d2a5fa7177496984d92f 100644 (file)
@@ -155,6 +155,7 @@ struct switchdev_notifier_fdb_info {
        struct switchdev_notifier_info info; /* must be first */
        const unsigned char *addr;
        u16 vid;
+       bool added_by_user;
 };
 
 static inline struct net_device *
index ee775f4ff76c222fea3ffa2ad322eb9bd4013706..71a03c487c4b5381d825301a896632c9131bec26 100644 (file)
@@ -102,13 +102,15 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
 
 static void
 br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
-                               u16 vid, struct net_device *dev)
+                               u16 vid, struct net_device *dev,
+                               bool added_by_user)
 {
        struct switchdev_notifier_fdb_info info;
        unsigned long notifier_type;
 
        info.addr = mac;
        info.vid = vid;
+       info.added_by_user = added_by_user;
        notifier_type = adding ? SWITCHDEV_FDB_ADD_TO_DEVICE : SWITCHDEV_FDB_DEL_TO_DEVICE;
        call_switchdev_notifiers(notifier_type, dev, &info.info);
 }
@@ -123,12 +125,14 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
        case RTM_DELNEIGH:
                br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr,
                                                fdb->key.vlan_id,
-                                               fdb->dst->dev);
+                                               fdb->dst->dev,
+                                               fdb->added_by_user);
                break;
        case RTM_NEWNEIGH:
                br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr,
                                                fdb->key.vlan_id,
-                                               fdb->dst->dev);
+                                               fdb->dst->dev,
+                                               fdb->added_by_user);
                break;
        }
 }
index f3fb3a0880b17f1735ddc417ce493615c10e2c87..c287f1ef964cbf209baacbb7379278c1f19e2c69 100644 (file)
@@ -1441,6 +1441,7 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
                                     unsigned long event, void *ptr)
 {
        struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+       struct switchdev_notifier_fdb_info *fdb_info = ptr;
        struct dsa_switchdev_event_work *switchdev_work;
 
        if (!dsa_slave_dev_check(dev))
@@ -1458,8 +1459,10 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
        switch (event) {
        case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
        case SWITCHDEV_FDB_DEL_TO_DEVICE:
+               if (!fdb_info->added_by_user)
+                       break;
                if (dsa_slave_switchdev_fdb_work_init(switchdev_work,
-                                                     ptr))
+                                                     fdb_info))
                        goto err_fdb_work_init;
                dev_hold(dev);
                break;