Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: bridge: propagate extack through switchdev_port_attr_set

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>

authored by

Vladimir Oltean and committed by
David S. Miller
dcbdf135 9e781401

+35 -25
+2 -1
include/net/switchdev.h
··· 247 247 248 248 void switchdev_deferred_process(void); 249 249 int switchdev_port_attr_set(struct net_device *dev, 250 - const struct switchdev_attr *attr); 250 + const struct switchdev_attr *attr, 251 + struct netlink_ext_ack *extack); 251 252 int switchdev_port_obj_add(struct net_device *dev, 252 253 const struct switchdev_obj *obj, 253 254 struct netlink_ext_ack *extack);
+2 -2
net/bridge/br_mrp_switchdev.c
··· 178 178 }; 179 179 int err; 180 180 181 - err = switchdev_port_attr_set(p->dev, &attr); 181 + err = switchdev_port_attr_set(p->dev, &attr, NULL); 182 182 if (err && err != -EOPNOTSUPP) 183 183 br_warn(p->br, "error setting offload MRP state on port %u(%s)\n", 184 184 (unsigned int)p->port_no, p->dev->name); ··· 196 196 }; 197 197 int err; 198 198 199 - err = switchdev_port_attr_set(p->dev, &attr); 199 + err = switchdev_port_attr_set(p->dev, &attr, NULL); 200 200 if (err && err != -EOPNOTSUPP) 201 201 return err; 202 202
+3 -3
net/bridge/br_multicast.c
··· 1381 1381 .u.mrouter = is_mc_router, 1382 1382 }; 1383 1383 1384 - switchdev_port_attr_set(p->dev, &attr); 1384 + switchdev_port_attr_set(p->dev, &attr, NULL); 1385 1385 } 1386 1386 1387 1387 static void br_multicast_local_router_expired(struct timer_list *t) ··· 1602 1602 .u.mc_disabled = !value, 1603 1603 }; 1604 1604 1605 - switchdev_port_attr_set(dev, &attr); 1605 + switchdev_port_attr_set(dev, &attr, NULL); 1606 1606 } 1607 1607 1608 1608 int br_multicast_add_port(struct net_bridge_port *port) ··· 2645 2645 .u.mrouter = is_mc_router, 2646 2646 }; 2647 2647 2648 - switchdev_port_attr_set(p->dev, &attr); 2648 + switchdev_port_attr_set(p->dev, &attr, NULL); 2649 2649 } 2650 2650 2651 2651 /*
+1 -1
net/bridge/br_netlink.c
··· 1221 1221 if (data[IFLA_BR_VLAN_PROTOCOL]) { 1222 1222 __be16 vlan_proto = nla_get_be16(data[IFLA_BR_VLAN_PROTOCOL]); 1223 1223 1224 - err = __br_vlan_set_proto(br, vlan_proto); 1224 + err = __br_vlan_set_proto(br, vlan_proto, extack); 1225 1225 if (err) 1226 1226 return err; 1227 1227 }
+2 -1
net/bridge/br_private.h
··· 1087 1087 void br_recalculate_fwd_mask(struct net_bridge *br); 1088 1088 int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val, 1089 1089 struct netlink_ext_ack *extack); 1090 - int __br_vlan_set_proto(struct net_bridge *br, __be16 proto); 1090 + int __br_vlan_set_proto(struct net_bridge *br, __be16 proto, 1091 + struct netlink_ext_ack *extack); 1091 1092 int br_vlan_set_proto(struct net_bridge *br, unsigned long val, 1092 1093 struct netlink_ext_ack *extack); 1093 1094 int br_vlan_set_stats(struct net_bridge *br, unsigned long val);
+2 -2
net/bridge/br_stp.c
··· 43 43 return; 44 44 45 45 p->state = state; 46 - err = switchdev_port_attr_set(p->dev, &attr); 46 + err = switchdev_port_attr_set(p->dev, &attr, NULL); 47 47 if (err && err != -EOPNOTSUPP) 48 48 br_warn(p->br, "error setting offload STP state on port %u(%s)\n", 49 49 (unsigned int) p->port_no, p->dev->name); ··· 591 591 }; 592 592 int err; 593 593 594 - err = switchdev_port_attr_set(dev, &attr); 594 + err = switchdev_port_attr_set(dev, &attr, NULL); 595 595 if (err && err != -EOPNOTSUPP) 596 596 return err; 597 597
+4 -2
net/bridge/br_switchdev.c
··· 96 96 attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS; 97 97 attr.flags = SWITCHDEV_F_DEFER; 98 98 99 - err = switchdev_port_attr_set(p->dev, &attr); 99 + err = switchdev_port_attr_set(p->dev, &attr, extack); 100 100 if (err) { 101 - NL_SET_ERR_MSG_MOD(extack, "error setting offload flag on port"); 101 + if (extack && !extack->_msg) 102 + NL_SET_ERR_MSG_MOD(extack, 103 + "error setting offload flag on port"); 102 104 return err; 103 105 } 104 106
+7 -6
net/bridge/br_vlan.c
··· 820 820 if (br_opt_get(br, BROPT_VLAN_ENABLED) == !!val) 821 821 return 0; 822 822 823 - err = switchdev_port_attr_set(br->dev, &attr); 823 + err = switchdev_port_attr_set(br->dev, &attr, extack); 824 824 if (err && err != -EOPNOTSUPP) 825 825 return err; 826 826 ··· 850 850 } 851 851 EXPORT_SYMBOL_GPL(br_vlan_get_proto); 852 852 853 - int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) 853 + int __br_vlan_set_proto(struct net_bridge *br, __be16 proto, 854 + struct netlink_ext_ack *extack) 854 855 { 855 856 struct switchdev_attr attr = { 856 857 .orig_dev = br->dev, ··· 868 867 if (br->vlan_proto == proto) 869 868 return 0; 870 869 871 - err = switchdev_port_attr_set(br->dev, &attr); 870 + err = switchdev_port_attr_set(br->dev, &attr, extack); 872 871 if (err && err != -EOPNOTSUPP) 873 872 return err; 874 873 ··· 898 897 899 898 err_filt: 900 899 attr.u.vlan_protocol = ntohs(oldproto); 901 - switchdev_port_attr_set(br->dev, &attr); 900 + switchdev_port_attr_set(br->dev, &attr, NULL); 902 901 903 902 list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) 904 903 vlan_vid_del(p->dev, proto, vlan->vid); ··· 918 917 if (!eth_type_vlan(htons(val))) 919 918 return -EPROTONOSUPPORT; 920 919 921 - return __br_vlan_set_proto(br, htons(val)); 920 + return __br_vlan_set_proto(br, htons(val), extack); 922 921 } 923 922 924 923 int br_vlan_set_stats(struct net_bridge *br, unsigned long val) ··· 1166 1165 if (!vg) 1167 1166 goto out; 1168 1167 1169 - ret = switchdev_port_attr_set(p->dev, &attr); 1168 + ret = switchdev_port_attr_set(p->dev, &attr, extack); 1170 1169 if (ret && ret != -EOPNOTSUPP) 1171 1170 goto err_vlan_enabled; 1172 1171
+12 -7
net/switchdev/switchdev.c
··· 100 100 101 101 static int switchdev_port_attr_notify(enum switchdev_notifier_type nt, 102 102 struct net_device *dev, 103 - const struct switchdev_attr *attr) 103 + const struct switchdev_attr *attr, 104 + struct netlink_ext_ack *extack) 104 105 { 105 106 int err; 106 107 int rc; ··· 112 111 }; 113 112 114 113 rc = call_switchdev_blocking_notifiers(nt, dev, 115 - &attr_info.info, NULL); 114 + &attr_info.info, extack); 116 115 err = notifier_to_errno(rc); 117 116 if (err) { 118 117 WARN_ON(!attr_info.handled); ··· 126 125 } 127 126 128 127 static int switchdev_port_attr_set_now(struct net_device *dev, 129 - const struct switchdev_attr *attr) 128 + const struct switchdev_attr *attr, 129 + struct netlink_ext_ack *extack) 130 130 { 131 - return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr); 131 + return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr, 132 + extack); 132 133 } 133 134 134 135 static void switchdev_port_attr_set_deferred(struct net_device *dev, ··· 139 136 const struct switchdev_attr *attr = data; 140 137 int err; 141 138 142 - err = switchdev_port_attr_set_now(dev, attr); 139 + err = switchdev_port_attr_set_now(dev, attr, NULL); 143 140 if (err && err != -EOPNOTSUPP) 144 141 netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", 145 142 err, attr->id); ··· 159 156 * 160 157 * @dev: port device 161 158 * @attr: attribute to set 159 + * @extack: netlink extended ack, for error message propagation 162 160 * 163 161 * rtnl_lock must be held and must not be in atomic section, 164 162 * in case SWITCHDEV_F_DEFER flag is not set. 165 163 */ 166 164 int switchdev_port_attr_set(struct net_device *dev, 167 - const struct switchdev_attr *attr) 165 + const struct switchdev_attr *attr, 166 + struct netlink_ext_ack *extack) 168 167 { 169 168 if (attr->flags & SWITCHDEV_F_DEFER) 170 169 return switchdev_port_attr_set_defer(dev, attr); 171 170 ASSERT_RTNL(); 172 - return switchdev_port_attr_set_now(dev, attr); 171 + return switchdev_port_attr_set_now(dev, attr, extack); 173 172 } 174 173 EXPORT_SYMBOL_GPL(switchdev_port_attr_set); 175 174