]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: bridge: propagate extack through switchdev_port_attr_set
authorVladimir Oltean <vladimir.oltean@nxp.com>
Sat, 13 Feb 2021 20:43:17 +0000 (22:43 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Feb 2021 01:38:11 +0000 (17:38 -0800)
The benefit is the ability to propagate errors from switchdev drivers
for the SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING and
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL attributes.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/switchdev.h
net/bridge/br_mrp_switchdev.c
net/bridge/br_multicast.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/bridge/br_stp.c
net/bridge/br_switchdev.c
net/bridge/br_vlan.c
net/switchdev/switchdev.c

index 25d9e45709344de850bdbb1c3b4992c58f70aa56..195f62672cc419c8646e3f86ea794928b2e554ff 100644 (file)
@@ -247,7 +247,8 @@ switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
 
 void switchdev_deferred_process(void);
 int switchdev_port_attr_set(struct net_device *dev,
-                           const struct switchdev_attr *attr);
+                           const struct switchdev_attr *attr,
+                           struct netlink_ext_ack *extack);
 int switchdev_port_obj_add(struct net_device *dev,
                           const struct switchdev_obj *obj,
                           struct netlink_ext_ack *extack);
index 75a7e8d0a26853a2f5f167f89b4255915b0c26f3..3c9a4abcf4eea46b8abfae97a65265b8b26ce7e5 100644 (file)
@@ -178,7 +178,7 @@ int br_mrp_port_switchdev_set_state(struct net_bridge_port *p, u32 state)
        };
        int err;
 
-       err = switchdev_port_attr_set(p->dev, &attr);
+       err = switchdev_port_attr_set(p->dev, &attr, NULL);
        if (err && err != -EOPNOTSUPP)
                br_warn(p->br, "error setting offload MRP state on port %u(%s)\n",
                        (unsigned int)p->port_no, p->dev->name);
@@ -196,7 +196,7 @@ int br_mrp_port_switchdev_set_role(struct net_bridge_port *p,
        };
        int err;
 
-       err = switchdev_port_attr_set(p->dev, &attr);
+       err = switchdev_port_attr_set(p->dev, &attr, NULL);
        if (err && err != -EOPNOTSUPP)
                return err;
 
index bf10ef5bbcd980c6c905c2e1c5a8706f875fb758..9d265447d6540536c089511fd2408f83286e6459 100644 (file)
@@ -1381,7 +1381,7 @@ static void br_mc_router_state_change(struct net_bridge *p,
                .u.mrouter = is_mc_router,
        };
 
-       switchdev_port_attr_set(p->dev, &attr);
+       switchdev_port_attr_set(p->dev, &attr, NULL);
 }
 
 static void br_multicast_local_router_expired(struct timer_list *t)
@@ -1602,7 +1602,7 @@ static void br_mc_disabled_update(struct net_device *dev, bool value)
                .u.mc_disabled = !value,
        };
 
-       switchdev_port_attr_set(dev, &attr);
+       switchdev_port_attr_set(dev, &attr, NULL);
 }
 
 int br_multicast_add_port(struct net_bridge_port *port)
@@ -2645,7 +2645,7 @@ static void br_port_mc_router_state_change(struct net_bridge_port *p,
                .u.mrouter = is_mc_router,
        };
 
-       switchdev_port_attr_set(p->dev, &attr);
+       switchdev_port_attr_set(p->dev, &attr, NULL);
 }
 
 /*
index 3f5dc6fcc980c589ed2381098cf6b1708b2f06b6..f2b1343f8332a1c42c097612ebf734a848ec8a99 100644 (file)
@@ -1221,7 +1221,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
        if (data[IFLA_BR_VLAN_PROTOCOL]) {
                __be16 vlan_proto = nla_get_be16(data[IFLA_BR_VLAN_PROTOCOL]);
 
-               err = __br_vlan_set_proto(br, vlan_proto);
+               err = __br_vlan_set_proto(br, vlan_proto, extack);
                if (err)
                        return err;
        }
index a8d483325476f9f298f876c22266de6a07601dbc..da71e71fcddc49b862a09b9baacfdcd58f6be188 100644 (file)
@@ -1087,7 +1087,8 @@ struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid);
 void br_recalculate_fwd_mask(struct net_bridge *br);
 int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val,
                          struct netlink_ext_ack *extack);
-int __br_vlan_set_proto(struct net_bridge *br, __be16 proto);
+int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
+                       struct netlink_ext_ack *extack);
 int br_vlan_set_proto(struct net_bridge *br, unsigned long val,
                      struct netlink_ext_ack *extack);
 int br_vlan_set_stats(struct net_bridge *br, unsigned long val);
index a3a5745660dd94ce9c4324b47dbc68c3b27cc87c..21c6781906aa78d42e6aa3959e87d081e2247092 100644 (file)
@@ -43,7 +43,7 @@ void br_set_state(struct net_bridge_port *p, unsigned int state)
                return;
 
        p->state = state;
-       err = switchdev_port_attr_set(p->dev, &attr);
+       err = switchdev_port_attr_set(p->dev, &attr, NULL);
        if (err && err != -EOPNOTSUPP)
                br_warn(p->br, "error setting offload STP state on port %u(%s)\n",
                                (unsigned int) p->port_no, p->dev->name);
@@ -591,7 +591,7 @@ int __set_ageing_time(struct net_device *dev, unsigned long t)
        };
        int err;
 
-       err = switchdev_port_attr_set(dev, &attr);
+       err = switchdev_port_attr_set(dev, &attr, NULL);
        if (err && err != -EOPNOTSUPP)
                return err;
 
index 184cf4c8b06d93210727b4eebff29842fe87448c..b89503832fcca8b4317e4bab4b0ecad94dbc8464 100644 (file)
@@ -96,9 +96,11 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
        attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
        attr.flags = SWITCHDEV_F_DEFER;
 
-       err = switchdev_port_attr_set(p->dev, &attr);
+       err = switchdev_port_attr_set(p->dev, &attr, extack);
        if (err) {
-               NL_SET_ERR_MSG_MOD(extack, "error setting offload flag on port");
+               if (extack && !extack->_msg)
+                       NL_SET_ERR_MSG_MOD(extack,
+                                          "error setting offload flag on port");
                return err;
        }
 
index c4a51095850a94e4b99adf9e0b9cb7c43be2b4d6..8829f621b8ec25f6a562f1272b32b37a5c242d4b 100644 (file)
@@ -820,7 +820,7 @@ int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val,
        if (br_opt_get(br, BROPT_VLAN_ENABLED) == !!val)
                return 0;
 
-       err = switchdev_port_attr_set(br->dev, &attr);
+       err = switchdev_port_attr_set(br->dev, &attr, extack);
        if (err && err != -EOPNOTSUPP)
                return err;
 
@@ -850,7 +850,8 @@ int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto)
 }
 EXPORT_SYMBOL_GPL(br_vlan_get_proto);
 
-int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
+int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
+                       struct netlink_ext_ack *extack)
 {
        struct switchdev_attr attr = {
                .orig_dev = br->dev,
@@ -867,7 +868,7 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
        if (br->vlan_proto == proto)
                return 0;
 
-       err = switchdev_port_attr_set(br->dev, &attr);
+       err = switchdev_port_attr_set(br->dev, &attr, extack);
        if (err && err != -EOPNOTSUPP)
                return err;
 
@@ -897,7 +898,7 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
 
 err_filt:
        attr.u.vlan_protocol = ntohs(oldproto);
-       switchdev_port_attr_set(br->dev, &attr);
+       switchdev_port_attr_set(br->dev, &attr, NULL);
 
        list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist)
                vlan_vid_del(p->dev, proto, vlan->vid);
@@ -917,7 +918,7 @@ int br_vlan_set_proto(struct net_bridge *br, unsigned long val,
        if (!eth_type_vlan(htons(val)))
                return -EPROTONOSUPPORT;
 
-       return __br_vlan_set_proto(br, htons(val));
+       return __br_vlan_set_proto(br, htons(val), extack);
 }
 
 int br_vlan_set_stats(struct net_bridge *br, unsigned long val)
@@ -1165,7 +1166,7 @@ int nbp_vlan_init(struct net_bridge_port *p, struct netlink_ext_ack *extack)
        if (!vg)
                goto out;
 
-       ret = switchdev_port_attr_set(p->dev, &attr);
+       ret = switchdev_port_attr_set(p->dev, &attr, extack);
        if (ret && ret != -EOPNOTSUPP)
                goto err_vlan_enabled;
 
index 0b84f076591e52a6449e538f33e7a761127c4d8f..89a36db47ab4648d717e2cd20130486e7db92f3c 100644 (file)
@@ -100,7 +100,8 @@ static int switchdev_deferred_enqueue(struct net_device *dev,
 
 static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
                                      struct net_device *dev,
-                                     const struct switchdev_attr *attr)
+                                     const struct switchdev_attr *attr,
+                                     struct netlink_ext_ack *extack)
 {
        int err;
        int rc;
@@ -111,7 +112,7 @@ static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
        };
 
        rc = call_switchdev_blocking_notifiers(nt, dev,
-                                              &attr_info.info, NULL);
+                                              &attr_info.info, extack);
        err = notifier_to_errno(rc);
        if (err) {
                WARN_ON(!attr_info.handled);
@@ -125,9 +126,11 @@ static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
 }
 
 static int switchdev_port_attr_set_now(struct net_device *dev,
-                                      const struct switchdev_attr *attr)
+                                      const struct switchdev_attr *attr,
+                                      struct netlink_ext_ack *extack)
 {
-       return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr);
+       return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr,
+                                         extack);
 }
 
 static void switchdev_port_attr_set_deferred(struct net_device *dev,
@@ -136,7 +139,7 @@ static void switchdev_port_attr_set_deferred(struct net_device *dev,
        const struct switchdev_attr *attr = data;
        int err;
 
-       err = switchdev_port_attr_set_now(dev, attr);
+       err = switchdev_port_attr_set_now(dev, attr, NULL);
        if (err && err != -EOPNOTSUPP)
                netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n",
                           err, attr->id);
@@ -156,17 +159,19 @@ static int switchdev_port_attr_set_defer(struct net_device *dev,
  *
  *     @dev: port device
  *     @attr: attribute to set
+ *     @extack: netlink extended ack, for error message propagation
  *
  *     rtnl_lock must be held and must not be in atomic section,
  *     in case SWITCHDEV_F_DEFER flag is not set.
  */
 int switchdev_port_attr_set(struct net_device *dev,
-                           const struct switchdev_attr *attr)
+                           const struct switchdev_attr *attr,
+                           struct netlink_ext_ack *extack)
 {
        if (attr->flags & SWITCHDEV_F_DEFER)
                return switchdev_port_attr_set_defer(dev, attr);
        ASSERT_RTNL();
-       return switchdev_port_attr_set_now(dev, attr);
+       return switchdev_port_attr_set_now(dev, attr, extack);
 }
 EXPORT_SYMBOL_GPL(switchdev_port_attr_set);