Commit 2a78dd22 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-add-iff_no_addrconf-to-prevent-ipv6-addrconf'

Xin Long says:

====================
net: add IFF_NO_ADDRCONF to prevent ipv6 addrconf

This patchset adds IFF_NO_ADDRCONF flag for dev->priv_flags
to prevent ipv6 addrconf, as Jiri Pirko's suggestion.

For Bonding it changes to use this flag instead of IFF_SLAVE
flag in Patch 1, and for Teaming and Net Failover it sets
this flag before calling dev_open() in Patch 2 and 3.
====================

Link: https://lore.kernel.org/r/cover.1670599241.git.lucien.xin@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1280d4b7 cb54d392
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -1632,13 +1632,19 @@ static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave,
{
	struct netdev_lag_upper_info lag_upper_info;
	enum netdev_lag_tx_type type;
	int err;

	type = bond_lag_tx_type(bond);
	lag_upper_info.tx_type = type;
	lag_upper_info.hash_type = bond_lag_hash_type(bond, type);

	return netdev_master_upper_dev_link(slave->dev, bond->dev, slave,
	err = netdev_master_upper_dev_link(slave->dev, bond->dev, slave,
					   &lag_upper_info, extack);
	if (err)
		return err;

	slave->dev->flags |= IFF_SLAVE;
	return 0;
}

static void bond_upper_dev_unlink(struct bonding *bond, struct slave *slave)
@@ -1950,8 +1956,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
		}
	}

	/* set slave flag before open to prevent IPv6 addrconf */
	slave_dev->flags |= IFF_SLAVE;
	/* set no_addrconf flag before open to prevent IPv6 addrconf */
	slave_dev->priv_flags |= IFF_NO_ADDRCONF;

	/* open the slave since the application closed it */
	res = dev_open(slave_dev, extack);
@@ -2254,7 +2260,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
	dev_close(slave_dev);

err_restore_mac:
	slave_dev->flags &= ~IFF_SLAVE;
	slave_dev->priv_flags &= ~IFF_NO_ADDRCONF;
	if (!bond->params.fail_over_mac ||
	    BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
		/* XXX TODO - fom follow mode needs to change master's
@@ -2446,6 +2452,8 @@ static int __bond_release_one(struct net_device *bond_dev,
	/* close slave before restoring its mac address */
	dev_close(slave_dev);

	slave_dev->priv_flags &= ~IFF_NO_ADDRCONF;

	if (bond->params.fail_over_mac != BOND_FOM_ACTIVE ||
	    BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
		/* restore original ("permanent") mac address */
+2 −0
Original line number Diff line number Diff line
@@ -1044,6 +1044,7 @@ static int team_port_enter(struct team *team, struct team_port *port)
			goto err_port_enter;
		}
	}
	port->dev->priv_flags |= IFF_NO_ADDRCONF;

	return 0;

@@ -1057,6 +1058,7 @@ static void team_port_leave(struct team *team, struct team_port *port)
{
	if (team->ops.port_leave)
		team->ops.port_leave(team, port);
	port->dev->priv_flags &= ~IFF_NO_ADDRCONF;
	dev_put(team->dev);
}

+2 −1
Original line number Diff line number Diff line
@@ -1662,6 +1662,7 @@ struct net_device_ops {
 * @IFF_FAILOVER: device is a failover master device
 * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
 * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device
 * @IFF_NO_ADDRCONF: prevent ipv6 addrconf
 * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with
 *	skb_headlen(skb) == 0 (data starts from frag0)
 * @IFF_CHANGE_PROTO_DOWN: device supports setting carrier via IFLA_PROTO_DOWN
@@ -1697,7 +1698,7 @@ enum netdev_priv_flags {
	IFF_FAILOVER			= 1<<27,
	IFF_FAILOVER_SLAVE		= 1<<28,
	IFF_L3MDEV_RX_HANDLER		= 1<<29,
	/* was IFF_LIVE_RENAME_OK */
	IFF_NO_ADDRCONF			= BIT_ULL(30),
	IFF_TX_SKB_NO_LINEAR		= BIT_ULL(31),
	IFF_CHANGE_PROTO_DOWN		= BIT_ULL(32),
};
+3 −3
Original line number Diff line number Diff line
@@ -80,14 +80,14 @@ static int failover_slave_register(struct net_device *slave_dev)
		goto err_upper_link;
	}

	slave_dev->priv_flags |= IFF_FAILOVER_SLAVE;
	slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_NO_ADDRCONF);

	if (fops && fops->slave_register &&
	    !fops->slave_register(slave_dev, failover_dev))
		return NOTIFY_OK;

	netdev_upper_dev_unlink(slave_dev, failover_dev);
	slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
	slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_NO_ADDRCONF);
err_upper_link:
	netdev_rx_handler_unregister(slave_dev);
done:
@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net_device *slave_dev)

	netdev_rx_handler_unregister(slave_dev);
	netdev_upper_dev_unlink(slave_dev, failover_dev);
	slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
	slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_NO_ADDRCONF);

	if (fops && fops->slave_unregister &&
	    !fops->slave_unregister(slave_dev, failover_dev))
+2 −2
Original line number Diff line number Diff line
@@ -3320,7 +3320,7 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
		return;

	/* no link local addresses on devices flagged as slaves */
	if (idev->dev->flags & IFF_SLAVE)
	if (idev->dev->priv_flags & IFF_NO_ADDRCONF)
		return;

	ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
@@ -3560,7 +3560,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
		if (idev && idev->cnf.disable_ipv6)
			break;

		if (dev->flags & IFF_SLAVE) {
		if (dev->priv_flags & IFF_NO_ADDRCONF) {
			if (event == NETDEV_UP && !IS_ERR_OR_NULL(idev) &&
			    dev->flags & IFF_UP && dev->flags & IFF_MULTICAST)
				ipv6_mc_up(idev);