summaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@gmail.com>2019-06-14 13:49:22 -0400
committerDavid S. Miller <davem@davemloft.net>2019-06-14 23:20:07 -0400
commit79b139f4bc4659016854115b9104cfb9ef598b31 (patch)
treee172a8546806917545ec7371c428d28532974e15 /net/dsa
parentf3b78049d4629b4fc565e225dda4e3ffdf907a84 (diff)
net: dsa: use switchdev handle helpers
Get rid of the dsa_slave_switchdev_port_{attr_set,obj}_event functions in favor of the switchdev_handle_port_{attr_set,obj_add,obj_del} helpers which recurse into the lower devices of the target interface. This has the benefit of being aware of the operations made on the bridge device itself, where orig_dev is the bridge, and dev is the slave. This can be used later to configure the hardware switches. Only VLAN and (port) MDB objects not directly targeting the slave device are unsupported at the moment, so skip this case in their respective case statements. Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/slave.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index cb436a05c9a8..99673f6b07f6 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -311,7 +311,8 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
311 311
312static int dsa_slave_port_obj_add(struct net_device *dev, 312static int dsa_slave_port_obj_add(struct net_device *dev,
313 const struct switchdev_obj *obj, 313 const struct switchdev_obj *obj,
314 struct switchdev_trans *trans) 314 struct switchdev_trans *trans,
315 struct netlink_ext_ack *extack)
315{ 316{
316 struct dsa_port *dp = dsa_slave_to_port(dev); 317 struct dsa_port *dp = dsa_slave_to_port(dev);
317 int err; 318 int err;
@@ -323,6 +324,8 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
323 324
324 switch (obj->id) { 325 switch (obj->id) {
325 case SWITCHDEV_OBJ_ID_PORT_MDB: 326 case SWITCHDEV_OBJ_ID_PORT_MDB:
327 if (obj->orig_dev != dev)
328 return -EOPNOTSUPP;
326 err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj), trans); 329 err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj), trans);
327 break; 330 break;
328 case SWITCHDEV_OBJ_ID_HOST_MDB: 331 case SWITCHDEV_OBJ_ID_HOST_MDB:
@@ -333,6 +336,8 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
333 trans); 336 trans);
334 break; 337 break;
335 case SWITCHDEV_OBJ_ID_PORT_VLAN: 338 case SWITCHDEV_OBJ_ID_PORT_VLAN:
339 if (obj->orig_dev != dev)
340 return -EOPNOTSUPP;
336 err = dsa_port_vlan_add(dp, SWITCHDEV_OBJ_PORT_VLAN(obj), 341 err = dsa_port_vlan_add(dp, SWITCHDEV_OBJ_PORT_VLAN(obj),
337 trans); 342 trans);
338 break; 343 break;
@@ -352,6 +357,8 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
352 357
353 switch (obj->id) { 358 switch (obj->id) {
354 case SWITCHDEV_OBJ_ID_PORT_MDB: 359 case SWITCHDEV_OBJ_ID_PORT_MDB:
360 if (obj->orig_dev != dev)
361 return -EOPNOTSUPP;
355 err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); 362 err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
356 break; 363 break;
357 case SWITCHDEV_OBJ_ID_HOST_MDB: 364 case SWITCHDEV_OBJ_ID_HOST_MDB:
@@ -361,6 +368,8 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
361 err = dsa_port_mdb_del(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj)); 368 err = dsa_port_mdb_del(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj));
362 break; 369 break;
363 case SWITCHDEV_OBJ_ID_PORT_VLAN: 370 case SWITCHDEV_OBJ_ID_PORT_VLAN:
371 if (obj->orig_dev != dev)
372 return -EOPNOTSUPP;
364 err = dsa_port_vlan_del(dp, SWITCHDEV_OBJ_PORT_VLAN(obj)); 373 err = dsa_port_vlan_del(dp, SWITCHDEV_OBJ_PORT_VLAN(obj));
365 break; 374 break;
366 default: 375 default:
@@ -1479,19 +1488,6 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb,
1479 return NOTIFY_DONE; 1488 return NOTIFY_DONE;
1480} 1489}
1481 1490
1482static int
1483dsa_slave_switchdev_port_attr_set_event(struct net_device *netdev,
1484 struct switchdev_notifier_port_attr_info *port_attr_info)
1485{
1486 int err;
1487
1488 err = dsa_slave_port_attr_set(netdev, port_attr_info->attr,
1489 port_attr_info->trans);
1490
1491 port_attr_info->handled = true;
1492 return notifier_from_errno(err);
1493}
1494
1495struct dsa_switchdev_event_work { 1491struct dsa_switchdev_event_work {
1496 struct work_struct work; 1492 struct work_struct work;
1497 struct switchdev_notifier_fdb_info fdb_info; 1493 struct switchdev_notifier_fdb_info fdb_info;
@@ -1566,13 +1562,18 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
1566{ 1562{
1567 struct net_device *dev = switchdev_notifier_info_to_dev(ptr); 1563 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1568 struct dsa_switchdev_event_work *switchdev_work; 1564 struct dsa_switchdev_event_work *switchdev_work;
1565 int err;
1566
1567 if (event == SWITCHDEV_PORT_ATTR_SET) {
1568 err = switchdev_handle_port_attr_set(dev, ptr,
1569 dsa_slave_dev_check,
1570 dsa_slave_port_attr_set);
1571 return notifier_from_errno(err);
1572 }
1569 1573
1570 if (!dsa_slave_dev_check(dev)) 1574 if (!dsa_slave_dev_check(dev))
1571 return NOTIFY_DONE; 1575 return NOTIFY_DONE;
1572 1576
1573 if (event == SWITCHDEV_PORT_ATTR_SET)
1574 return dsa_slave_switchdev_port_attr_set_event(dev, ptr);
1575
1576 switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); 1577 switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
1577 if (!switchdev_work) 1578 if (!switchdev_work)
1578 return NOTIFY_BAD; 1579 return NOTIFY_BAD;
@@ -1602,41 +1603,28 @@ err_fdb_work_init:
1602 return NOTIFY_BAD; 1603 return NOTIFY_BAD;
1603} 1604}
1604 1605
1605static int
1606dsa_slave_switchdev_port_obj_event(unsigned long event,
1607 struct net_device *netdev,
1608 struct switchdev_notifier_port_obj_info *port_obj_info)
1609{
1610 int err = -EOPNOTSUPP;
1611
1612 switch (event) {
1613 case SWITCHDEV_PORT_OBJ_ADD:
1614 err = dsa_slave_port_obj_add(netdev, port_obj_info->obj,
1615 port_obj_info->trans);
1616 break;
1617 case SWITCHDEV_PORT_OBJ_DEL:
1618 err = dsa_slave_port_obj_del(netdev, port_obj_info->obj);
1619 break;
1620 }
1621
1622 port_obj_info->handled = true;
1623 return notifier_from_errno(err);
1624}
1625
1626static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused, 1606static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
1627 unsigned long event, void *ptr) 1607 unsigned long event, void *ptr)
1628{ 1608{
1629 struct net_device *dev = switchdev_notifier_info_to_dev(ptr); 1609 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1630 1610 int err;
1631 if (!dsa_slave_dev_check(dev))
1632 return NOTIFY_DONE;
1633 1611
1634 switch (event) { 1612 switch (event) {
1635 case SWITCHDEV_PORT_OBJ_ADD: /* fall through */ 1613 case SWITCHDEV_PORT_OBJ_ADD:
1614 err = switchdev_handle_port_obj_add(dev, ptr,
1615 dsa_slave_dev_check,
1616 dsa_slave_port_obj_add);
1617 return notifier_from_errno(err);
1636 case SWITCHDEV_PORT_OBJ_DEL: 1618 case SWITCHDEV_PORT_OBJ_DEL:
1637 return dsa_slave_switchdev_port_obj_event(event, dev, ptr); 1619 err = switchdev_handle_port_obj_del(dev, ptr,
1620 dsa_slave_dev_check,
1621 dsa_slave_port_obj_del);
1622 return notifier_from_errno(err);
1638 case SWITCHDEV_PORT_ATTR_SET: 1623 case SWITCHDEV_PORT_ATTR_SET:
1639 return dsa_slave_switchdev_port_attr_set_event(dev, ptr); 1624 err = switchdev_handle_port_attr_set(dev, ptr,
1625 dsa_slave_dev_check,
1626 dsa_slave_port_attr_set);
1627 return notifier_from_errno(err);
1640 } 1628 }
1641 1629
1642 return NOTIFY_DONE; 1630 return NOTIFY_DONE;