aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2016-02-26 13:16:00 -0500
committerDavid S. Miller <davem@davemloft.net>2016-03-01 16:24:51 -0500
commitfb2dabad69f099fb9c03a44276778911da50ba29 (patch)
tree07dd9149cfb77ba1cc114da5f104b618574ae64d
parent7f66ee41566d00f80ed15c0cec0b237f7af8ac0f (diff)
net: dsa: support VLAN filtering switchdev attr
When a user explicitly requests VLAN filtering with something like: # echo 1 > /sys/class/net/<bridge>/bridge/vlan_filtering Switchdev propagates a SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING port attribute. Add support for it in the DSA layer with a new port_vlan_filtering function to let drivers toggle 802.1Q filtering on user demand. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/dsa.h2
-rw-r--r--net/dsa/slave.c21
2 files changed, 23 insertions, 0 deletions
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 3dd54867174a..26c0a3fa009a 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -305,6 +305,8 @@ struct dsa_switch_driver {
305 /* 305 /*
306 * VLAN support 306 * VLAN support
307 */ 307 */
308 int (*port_vlan_filtering)(struct dsa_switch *ds, int port,
309 bool vlan_filtering);
308 int (*port_vlan_prepare)(struct dsa_switch *ds, int port, 310 int (*port_vlan_prepare)(struct dsa_switch *ds, int port,
309 const struct switchdev_obj_port_vlan *vlan, 311 const struct switchdev_obj_port_vlan *vlan,
310 struct switchdev_trans *trans); 312 struct switchdev_trans *trans);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index cde29239b60d..27bf03d11670 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -317,6 +317,24 @@ static int dsa_slave_stp_update(struct net_device *dev, u8 state)
317 return ret; 317 return ret;
318} 318}
319 319
320static int dsa_slave_vlan_filtering(struct net_device *dev,
321 const struct switchdev_attr *attr,
322 struct switchdev_trans *trans)
323{
324 struct dsa_slave_priv *p = netdev_priv(dev);
325 struct dsa_switch *ds = p->parent;
326
327 /* bridge skips -EOPNOTSUPP, so skip the prepare phase */
328 if (switchdev_trans_ph_prepare(trans))
329 return 0;
330
331 if (ds->drv->port_vlan_filtering)
332 return ds->drv->port_vlan_filtering(ds, p->port,
333 attr->u.vlan_filtering);
334
335 return 0;
336}
337
320static int dsa_slave_port_attr_set(struct net_device *dev, 338static int dsa_slave_port_attr_set(struct net_device *dev,
321 const struct switchdev_attr *attr, 339 const struct switchdev_attr *attr,
322 struct switchdev_trans *trans) 340 struct switchdev_trans *trans)
@@ -333,6 +351,9 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
333 ret = ds->drv->port_stp_update(ds, p->port, 351 ret = ds->drv->port_stp_update(ds, p->port,
334 attr->u.stp_state); 352 attr->u.stp_state);
335 break; 353 break;
354 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
355 ret = dsa_slave_vlan_filtering(dev, attr, trans);
356 break;
336 default: 357 default:
337 ret = -EOPNOTSUPP; 358 ret = -EOPNOTSUPP;
338 break; 359 break;