drivers/net/bonding/bond_main.c

Source file repositories/reference/linux-study-clean/drivers/net/bonding/bond_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/bonding/bond_main.c
Extension
.c
Size
183957 bytes
Lines
6680
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
	struct slave *new_slave = NULL, *prev_slave;
	struct sockaddr_storage ss;
	int res = 0, i;

	if (slave_dev->type == ARPHRD_CAN) {
		BOND_NL_ERR(bond_dev, extack,
			    "CAN devices cannot be enslaved");
		return -EPERM;
	}

	if (slave_dev->flags & IFF_MASTER &&
	    !netif_is_bond_master(slave_dev)) {
		BOND_NL_ERR(bond_dev, extack,
			    "Device type (master device) cannot be enslaved");
		return -EPERM;
	}

	/* already in-use? */
	if (netdev_is_rx_handler_busy(slave_dev)) {
		SLAVE_NL_ERR(bond_dev, slave_dev, extack,
			     "Device is in use and cannot be enslaved");
		return -EBUSY;
	}

	if (bond_dev == slave_dev) {
		BOND_NL_ERR(bond_dev, extack, "Cannot enslave bond to itself.");
		return -EPERM;
	}

	/* vlan challenged mutual exclusion */
	/* no need to lock since we're protected by rtnl_lock */
	if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
		slave_dbg(bond_dev, slave_dev, "is NETIF_F_VLAN_CHALLENGED\n");
		if (vlan_uses_dev(bond_dev)) {
			SLAVE_NL_ERR(bond_dev, slave_dev, extack,
				     "Can not enslave VLAN challenged device to VLAN enabled bond");
			return -EPERM;
		} else {
			slave_warn(bond_dev, slave_dev, "enslaved VLAN challenged slave. Adding VLANs will be blocked as long as it is part of bond.\n");
		}
	} else {
		slave_dbg(bond_dev, slave_dev, "is !NETIF_F_VLAN_CHALLENGED\n");
	}

	if (slave_dev->features & NETIF_F_HW_ESP)
		slave_dbg(bond_dev, slave_dev, "is esp-hw-offload capable\n");

	/* Old ifenslave binaries are no longer supported.  These can
	 * be identified with moderate accuracy by the state of the slave:
	 * the current ifenslave will set the interface down prior to
	 * enslaving it; the old ifenslave will not.
	 */
	if (slave_dev->flags & IFF_UP) {
		SLAVE_NL_ERR(bond_dev, slave_dev, extack,
			     "Device can not be enslaved while up");
		return -EPERM;
	}

	/* set bonding device ether type by slave - bonding netdevices are
	 * created with ether_setup, so when the slave type is not ARPHRD_ETHER
	 * there is a need to override some of the type dependent attribs/funcs.
	 *
	 * bond ether type mutual exclusion - don't allow slaves of dissimilar
	 * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond
	 */
	if (!bond_has_slaves(bond)) {
		if (bond_dev->type != slave_dev->type) {
			if (slave_dev->type != ARPHRD_ETHER &&
			    BOND_MODE(bond) == BOND_MODE_8023AD) {
				SLAVE_NL_ERR(bond_dev, slave_dev, extack,
					     "8023AD mode requires Ethernet devices");
				return -EINVAL;
			}
			slave_dbg(bond_dev, slave_dev, "change device type from %d to %d\n",
				  bond_dev->type, slave_dev->type);

			res = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE,
						       bond_dev);
			res = notifier_to_errno(res);
			if (res) {
				slave_err(bond_dev, slave_dev, "refused to change device type\n");
				return -EBUSY;
			}

			/* Flush unicast and multicast addresses */
			dev_uc_flush(bond_dev);
			dev_mc_flush(bond_dev);

			if (slave_dev->type != ARPHRD_ETHER)

Annotation

Implementation Notes