]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - net/dsa/switch.c
net: dsa: let drivers state that they need VLAN filtering while standalone
[mirror_ubuntu-jammy-kernel.git] / net / dsa / switch.c
index dd042fd7f800afb41fc54df19b28452a7c12c872..1c797ec8e2c2b805a890df560c80b4f0eb45d4da 100644 (file)
@@ -116,9 +116,10 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds,
 static int dsa_switch_bridge_leave(struct dsa_switch *ds,
                                   struct dsa_notifier_bridge_info *info)
 {
-       bool unset_vlan_filtering = br_vlan_enabled(info->br);
        struct dsa_switch_tree *dst = ds->dst;
        struct netlink_ext_ack extack = {0};
+       bool change_vlan_filtering = false;
+       bool vlan_filtering;
        int err, port;
 
        if (dst->index == info->tree_index && ds->index == info->sw_index &&
@@ -131,6 +132,15 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
                                                info->sw_index, info->port,
                                                info->br);
 
+       if (ds->needs_standalone_vlan_filtering && !br_vlan_enabled(info->br)) {
+               change_vlan_filtering = true;
+               vlan_filtering = true;
+       } else if (!ds->needs_standalone_vlan_filtering &&
+                  br_vlan_enabled(info->br)) {
+               change_vlan_filtering = true;
+               vlan_filtering = false;
+       }
+
        /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
         * event for changing vlan_filtering setting upon slave ports leaving
         * it. That is a good thing, because that lets us handle it and also
@@ -139,21 +149,22 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
         * vlan_filtering callback is only when the last port leaves the last
         * VLAN-aware bridge.
         */
-       if (unset_vlan_filtering && ds->vlan_filtering_is_global) {
+       if (change_vlan_filtering && ds->vlan_filtering_is_global) {
                for (port = 0; port < ds->num_ports; port++) {
                        struct net_device *bridge_dev;
 
                        bridge_dev = dsa_to_port(ds, port)->bridge_dev;
 
                        if (bridge_dev && br_vlan_enabled(bridge_dev)) {
-                               unset_vlan_filtering = false;
+                               change_vlan_filtering = false;
                                break;
                        }
                }
        }
-       if (unset_vlan_filtering) {
+
+       if (change_vlan_filtering) {
                err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
-                                             false, &extack);
+                                             vlan_filtering, &extack);
                if (extack._msg)
                        dev_err(ds->dev, "port %d: %s\n", info->port,
                                extack._msg);