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

Commit fc4a7489 authored by Patrick Mullaney's avatar Patrick Mullaney Committed by David S. Miller
Browse files

netdevice: provide common routine for macvlan and vlan operstate management



Provide common routine for the transition of operational state for a leaf
device during a root device transition.

Signed-off-by: default avatarPatrick Mullaney <pmullaney@novell.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 012093f6
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -582,25 +582,6 @@ static void macvlan_port_destroy(struct net_device *dev)
	kfree(port);
}

static void macvlan_transfer_operstate(struct net_device *dev)
{
	struct macvlan_dev *vlan = netdev_priv(dev);
	const struct net_device *lowerdev = vlan->lowerdev;

	if (lowerdev->operstate == IF_OPER_DORMANT)
		netif_dormant_on(dev);
	else
		netif_dormant_off(dev);

	if (netif_carrier_ok(lowerdev)) {
		if (!netif_carrier_ok(dev))
			netif_carrier_on(dev);
	} else {
		if (netif_carrier_ok(dev))
			netif_carrier_off(dev);
	}
}

static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
{
	if (tb[IFLA_ADDRESS]) {
@@ -693,7 +674,7 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,
		return err;

	list_add_tail(&vlan->list, &port->vlans);
	macvlan_transfer_operstate(dev);
	netif_stacked_transfer_operstate(lowerdev, dev);
	return 0;
}

@@ -768,7 +749,8 @@ static int macvlan_device_event(struct notifier_block *unused,
	switch (event) {
	case NETDEV_CHANGE:
		list_for_each_entry(vlan, &port->vlans, list)
			macvlan_transfer_operstate(vlan->dev);
			netif_stacked_transfer_operstate(vlan->lowerdev,
							 vlan->dev);
		break;
	case NETDEV_FEAT_CHANGE:
		list_for_each_entry(vlan, &port->vlans, list) {
+3 −0
Original line number Diff line number Diff line
@@ -1981,6 +1981,9 @@ unsigned long netdev_increment_features(unsigned long all, unsigned long one,
					unsigned long mask);
unsigned long netdev_fix_features(unsigned long features, const char *name);

void netif_stacked_transfer_operstate(const struct net_device *rootdev,
					struct net_device *dev);

static inline int net_gso_ok(int features, int gso_type)
{
	int feature = gso_type << NETIF_F_GSO_SHIFT;
+4 −25
Original line number Diff line number Diff line
@@ -184,27 +184,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
	dev_put(real_dev);
}

static void vlan_transfer_operstate(const struct net_device *dev,
				    struct net_device *vlandev)
{
	/* Have to respect userspace enforced dormant state
	 * of real device, also must allow supplicant running
	 * on VLAN device
	 */
	if (dev->operstate == IF_OPER_DORMANT)
		netif_dormant_on(vlandev);
	else
		netif_dormant_off(vlandev);

	if (netif_carrier_ok(dev)) {
		if (!netif_carrier_ok(vlandev))
			netif_carrier_on(vlandev);
	} else {
		if (netif_carrier_ok(vlandev))
			netif_carrier_off(vlandev);
	}
}

int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
{
	const char *name = real_dev->name;
@@ -262,7 +241,7 @@ int register_vlan_dev(struct net_device *dev)
	/* Account for reference in struct vlan_dev_info */
	dev_hold(real_dev);

	vlan_transfer_operstate(real_dev, dev);
	netif_stacked_transfer_operstate(real_dev, dev);
	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */

	/* So, got the sucker initialized, now lets place
@@ -453,7 +432,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
			if (!vlandev)
				continue;

			vlan_transfer_operstate(dev, vlandev);
			netif_stacked_transfer_operstate(dev, vlandev);
		}
		break;

@@ -511,7 +490,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
			vlan = vlan_dev_info(vlandev);
			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
				dev_change_flags(vlandev, flgs & ~IFF_UP);
			vlan_transfer_operstate(dev, vlandev);
			netif_stacked_transfer_operstate(dev, vlandev);
		}
		break;

@@ -529,7 +508,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
			vlan = vlan_dev_info(vlandev);
			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
				dev_change_flags(vlandev, flgs | IFF_UP);
			vlan_transfer_operstate(dev, vlandev);
			netif_stacked_transfer_operstate(dev, vlandev);
		}
		break;

+27 −0
Original line number Diff line number Diff line
@@ -4900,6 +4900,33 @@ unsigned long netdev_fix_features(unsigned long features, const char *name)
}
EXPORT_SYMBOL(netdev_fix_features);

/**
 *	netif_stacked_transfer_operstate -	transfer operstate
 *	@rootdev: the root or lower level device to transfer state from
 *	@dev: the device to transfer operstate to
 *
 *	Transfer operational state from root to device. This is normally
 *	called when a stacking relationship exists between the root
 *	device and the device(a leaf device).
 */
void netif_stacked_transfer_operstate(const struct net_device *rootdev,
					struct net_device *dev)
{
	if (rootdev->operstate == IF_OPER_DORMANT)
		netif_dormant_on(dev);
	else
		netif_dormant_off(dev);

	if (netif_carrier_ok(rootdev)) {
		if (!netif_carrier_ok(dev))
			netif_carrier_on(dev);
	} else {
		if (netif_carrier_ok(dev))
			netif_carrier_off(dev);
	}
}
EXPORT_SYMBOL(netif_stacked_transfer_operstate);

/**
 *	register_netdevice	- register a network device
 *	@dev: device to register