swdevice: add new apis to set and del bridge port attributes
authorRoopa Prabhu <roopa@cumulusnetworks.com>
Fri, 30 Jan 2015 06:40:13 +0000 (22:40 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Feb 2015 07:16:34 +0000 (23:16 -0800)
This patch adds two new api's netdev_switch_port_bridge_setlink
and netdev_switch_port_bridge_dellink to offload bridge port attributes
to switch port

(The names of the apis look odd with 'switch_port_bridge',
but am more inclined to change the prefix of the api to something else.
Will take any suggestions).

The api's look at the NETIF_F_HW_SWITCH_OFFLOAD feature flag to
pass bridge port attributes to the port device.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/switchdev.h
net/switchdev/switchdev.c

index 205e63698da9f9412d65aa702135c6c98d9abf8d..cfcdac2e5d253ef431bc18709cc5e7edd0e47e6f 100644 (file)
@@ -43,7 +43,14 @@ int register_netdev_switch_notifier(struct notifier_block *nb);
 int unregister_netdev_switch_notifier(struct notifier_block *nb);
 int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev,
                                 struct netdev_switch_notifier_info *info);
-
+int netdev_switch_port_bridge_setlink(struct net_device *dev,
+                               struct nlmsghdr *nlh, u16 flags);
+int netdev_switch_port_bridge_dellink(struct net_device *dev,
+                               struct nlmsghdr *nlh, u16 flags);
+int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev,
+                                              struct nlmsghdr *nlh, u16 flags);
+int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev,
+                                              struct nlmsghdr *nlh, u16 flags);
 #else
 
 static inline int netdev_switch_parent_id_get(struct net_device *dev,
@@ -74,6 +81,34 @@ static inline int call_netdev_switch_notifiers(unsigned long val, struct net_dev
        return NOTIFY_DONE;
 }
 
+static inline int netdev_switch_port_bridge_setlink(struct net_device *dev,
+                                                   struct nlmsghdr *nlh,
+                                                   u16 flags)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int netdev_switch_port_bridge_dellink(struct net_device *dev,
+                                                   struct nlmsghdr *nlh,
+                                                   u16 flags)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev,
+                                                       struct nlmsghdr *nlh,
+                                                       u16 flags)
+{
+       return 0;
+}
+
+static inline int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev,
+                                                       struct nlmsghdr *nlh,
+                                                       u16 flags)
+{
+       return 0;
+}
+
 #endif
 
 #endif /* _LINUX_SWITCHDEV_H_ */
index 22e02f4edd99bf318ce2944b7ebd3804425ffd27..8c1e558db11893b7f70eaa5e5201da07a3df8812 100644 (file)
@@ -115,3 +115,113 @@ int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev,
        return err;
 }
 EXPORT_SYMBOL(call_netdev_switch_notifiers);
+
+/**
+ *     netdev_switch_port_bridge_setlink - Notify switch device port of bridge
+ *     port attributes
+ *
+ *     @dev: port device
+ *     @nlh: netlink msg with bridge port attributes
+ *     @flags: bridge setlink flags
+ *
+ *     Notify switch device port of bridge port attributes
+ */
+int netdev_switch_port_bridge_setlink(struct net_device *dev,
+                                     struct nlmsghdr *nlh, u16 flags)
+{
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD))
+               return 0;
+
+       if (!ops->ndo_bridge_setlink)
+               return -EOPNOTSUPP;
+
+       return ops->ndo_bridge_setlink(dev, nlh, flags);
+}
+EXPORT_SYMBOL(netdev_switch_port_bridge_setlink);
+
+/**
+ *     netdev_switch_port_bridge_dellink - Notify switch device port of bridge
+ *     port attribute delete
+ *
+ *     @dev: port device
+ *     @nlh: netlink msg with bridge port attributes
+ *     @flags: bridge setlink flags
+ *
+ *     Notify switch device port of bridge port attribute delete
+ */
+int netdev_switch_port_bridge_dellink(struct net_device *dev,
+                                     struct nlmsghdr *nlh, u16 flags)
+{
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD))
+               return 0;
+
+       if (!ops->ndo_bridge_dellink)
+               return -EOPNOTSUPP;
+
+       return ops->ndo_bridge_dellink(dev, nlh, flags);
+}
+EXPORT_SYMBOL(netdev_switch_port_bridge_dellink);
+
+/**
+ *     ndo_dflt_netdev_switch_port_bridge_setlink - default ndo bridge setlink
+ *                                                  op for master devices
+ *
+ *     @dev: port device
+ *     @nlh: netlink msg with bridge port attributes
+ *     @flags: bridge setlink flags
+ *
+ *     Notify master device slaves of bridge port attributes
+ */
+int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev,
+                                              struct nlmsghdr *nlh, u16 flags)
+{
+       struct net_device *lower_dev;
+       struct list_head *iter;
+       int ret = 0, err = 0;
+
+       if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD))
+               return ret;
+
+       netdev_for_each_lower_dev(dev, lower_dev, iter) {
+               err = netdev_switch_port_bridge_setlink(lower_dev, nlh, flags);
+               if (err && err != -EOPNOTSUPP)
+                       ret = err;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_setlink);
+
+/**
+ *     ndo_dflt_netdev_switch_port_bridge_dellink - default ndo bridge dellink
+ *                                                  op for master devices
+ *
+ *     @dev: port device
+ *     @nlh: netlink msg with bridge port attributes
+ *     @flags: bridge dellink flags
+ *
+ *     Notify master device slaves of bridge port attribute deletes
+ */
+int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev,
+                                              struct nlmsghdr *nlh, u16 flags)
+{
+       struct net_device *lower_dev;
+       struct list_head *iter;
+       int ret = 0, err = 0;
+
+       if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD))
+               return ret;
+
+       netdev_for_each_lower_dev(dev, lower_dev, iter) {
+               err = netdev_switch_port_bridge_dellink(lower_dev, nlh, flags);
+               if (err && err != -EOPNOTSUPP)
+                       ret = err;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(ndo_dflt_netdev_switch_port_bridge_dellink);