Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a44dbb2 authored by Roopa Prabhu's avatar Roopa Prabhu Committed by David S. Miller
Browse files

swdevice: add new apis to set and del bridge port attributes



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: default avatarRoopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent add511b3
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -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_ */
+110 −0
Original line number Diff line number Diff line
@@ -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);