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

Commit 471cb5a3 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

bonding: remove usage of dev->master



Benefit from new upper dev list and free bonding from dev->master usage.

Signed-off-by: default avatarJiri Pirko <jiri@resnulli.us>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7f6e7101
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -1127,7 +1127,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
				// INFO_RECEIVED_LOOPBACK_FRAMES
				pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
				       "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
				       port->slave->dev->master->name, port->slave->dev->name);
				       port->slave->bond->dev->name, port->slave->dev->name);
				return;
			}
			__update_selected(lacpdu, port);
@@ -1306,7 +1306,7 @@ static void ad_port_selection_logic(struct port *port)
		}
		if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
			pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
				   port->slave->dev->master->name,
				   port->slave->bond->dev->name,
				   port->actor_port_number,
				   port->slave->dev->name,
				   port->aggregator->aggregator_identifier);
@@ -1386,7 +1386,7 @@ static void ad_port_selection_logic(struct port *port)
				 port->aggregator->aggregator_identifier);
		} else {
			pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n",
			       port->slave->dev->master->name,
			       port->slave->bond->dev->name,
			       port->actor_port_number, port->slave->dev->name);
		}
	}
@@ -1463,7 +1463,7 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best,

	default:
		pr_warning("%s: Impossible agg select mode %d\n",
			   curr->slave->dev->master->name,
			   curr->slave->bond->dev->name,
			   __get_agg_selection_mode(curr->lag_ports));
		break;
	}
@@ -1571,7 +1571,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
		// check if any partner replys
		if (best->is_individual) {
			pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
				   best->slave ? best->slave->dev->master->name : "NULL");
				   best->slave ? best->slave->bond->dev->name : "NULL");
		}

		best->is_active = 1;
@@ -1898,7 +1898,7 @@ int bond_3ad_bind_slave(struct slave *slave)

	if (bond == NULL) {
		pr_err("%s: The slave %s is not attached to its bond\n",
		       slave->dev->master->name, slave->dev->name);
		       slave->bond->dev->name, slave->dev->name);
		return -1;
	}

@@ -1973,7 +1973,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
	// if slave is null, the whole port is not initialized
	if (!port->slave) {
		pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n",
			   slave->dev->master->name, slave->dev->name);
			   slave->bond->dev->name, slave->dev->name);
		return;
	}

@@ -2009,7 +2009,7 @@ void bond_3ad_unbind_slave(struct slave *slave)

				if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
					pr_info("%s: Removing an active aggregator\n",
						aggregator->slave->dev->master->name);
						aggregator->slave->bond->dev->name);
					// select new active aggregator
					 select_new_active_agg = 1;
				}
@@ -2040,7 +2040,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
					ad_agg_selection_logic(__get_first_agg(port));
			} else {
				pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
					   slave->dev->master->name);
					   slave->bond->dev->name);
			}
		} else { // in case that the only port related to this aggregator is the one we want to remove
			select_new_active_agg = aggregator->is_active;
@@ -2048,7 +2048,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
			ad_clear_agg(aggregator);
			if (select_new_active_agg) {
				pr_info("%s: Removing an active aggregator\n",
					slave->dev->master->name);
					slave->bond->dev->name);
				// select new active aggregator
				ad_agg_selection_logic(__get_first_agg(port));
			}
@@ -2076,7 +2076,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
					ad_clear_agg(temp_aggregator);
					if (select_new_active_agg) {
						pr_info("%s: Removing an active aggregator\n",
							slave->dev->master->name);
							slave->bond->dev->name);
						// select new active aggregator
						ad_agg_selection_logic(__get_first_agg(port));
					}
@@ -2184,7 +2184,7 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1

		if (!port->slave) {
			pr_warning("%s: Warning: port of slave %s is uninitialized\n",
				   slave->dev->name, slave->dev->master->name);
				   slave->dev->name, slave->bond->dev->name);
			return ret;
		}

@@ -2240,7 +2240,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
	// if slave is null, the whole port is not initialized
	if (!port->slave) {
		pr_warning("Warning: %s: speed changed for uninitialized port on %s\n",
			   slave->dev->master->name, slave->dev->name);
			   slave->bond->dev->name, slave->dev->name);
		return;
	}

@@ -2268,7 +2268,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
	// if slave is null, the whole port is not initialized
	if (!port->slave) {
		pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n",
			   slave->dev->master->name, slave->dev->name);
			   slave->bond->dev->name, slave->dev->name);
		return;
	}

@@ -2297,7 +2297,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
	// if slave is null, the whole port is not initialized
	if (!port->slave) {
		pr_warning("Warning: %s: link status changed for uninitialized port on %s\n",
			   slave->dev->master->name, slave->dev->name);
			   slave->bond->dev->name, slave->dev->name);
		return;
	}

+3 −3
Original line number Diff line number Diff line
@@ -507,7 +507,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
				 client_info->mac_dst);
		if (!skb) {
			pr_err("%s: Error: failed to create an ARP packet\n",
			       client_info->slave->dev->master->name);
			       client_info->slave->bond->dev->name);
			continue;
		}

@@ -517,7 +517,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
			skb = vlan_put_tag(skb, client_info->vlan_id);
			if (!skb) {
				pr_err("%s: Error: failed to insert VLAN tag\n",
				       client_info->slave->dev->master->name);
				       client_info->slave->bond->dev->name);
				continue;
			}
		}
@@ -1043,7 +1043,7 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
	if (dev_set_mac_address(dev, &s_addr)) {
		pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n"
		       "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
		       dev->master->name, dev->name);
		       slave->bond->dev->name, dev->name);
		return -EOPNOTSUPP;
	}
	return 0;
+55 −39
Original line number Diff line number Diff line
@@ -746,11 +746,9 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
{
	struct in_device *in_dev;

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(dev);
	if (in_dev)
		ip_mc_rejoin_groups(in_dev);
	rcu_read_unlock();
}

/*
@@ -760,9 +758,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
 */
static void bond_resend_igmp_join_requests(struct bonding *bond)
{
	struct net_device *bond_dev, *vlan_dev, *master_dev;
	struct net_device *bond_dev, *vlan_dev, *upper_dev;
	struct vlan_entry *vlan;

	rcu_read_lock();
	read_lock(&bond->lock);

	bond_dev = bond->dev;
@@ -774,18 +773,14 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
	 * if bond is enslaved to a bridge,
	 * then rejoin all groups on its master
	 */
	master_dev = bond_dev->master;
	if (master_dev)
		if ((master_dev->priv_flags & IFF_EBRIDGE)
			&& (bond_dev->priv_flags & IFF_BRIDGE_PORT))
			__bond_resend_igmp_join_requests(master_dev);
	upper_dev = netdev_master_upper_dev_get_rcu(bond_dev);
	if (upper_dev && upper_dev->priv_flags & IFF_EBRIDGE)
		__bond_resend_igmp_join_requests(upper_dev);

	/* rejoin all groups on vlan devices */
	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
		rcu_read_lock();
		vlan_dev = __vlan_find_dev_deep(bond_dev,
						vlan->vlan_id);
		rcu_read_unlock();
		if (vlan_dev)
			__bond_resend_igmp_join_requests(vlan_dev);
	}
@@ -794,13 +789,16 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
		queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);

	read_unlock(&bond->lock);
	rcu_read_unlock();
}

static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
{
	struct bonding *bond = container_of(work, struct bonding,
					    mcast_work.work);
	rcu_read_lock();
	bond_resend_igmp_join_requests(bond);
	rcu_read_unlock();
}

/*
@@ -1493,6 +1491,27 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
	return ret;
}

static int bond_master_upper_dev_link(struct net_device *bond_dev,
				      struct net_device *slave_dev)
{
	int err;

	err = netdev_master_upper_dev_link(slave_dev, bond_dev);
	if (err)
		return err;
	slave_dev->flags |= IFF_SLAVE;
	rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE);
	return 0;
}

static void bond_upper_dev_unlink(struct net_device *bond_dev,
				  struct net_device *slave_dev)
{
	netdev_upper_dev_unlink(slave_dev, bond_dev);
	slave_dev->flags &= ~IFF_SLAVE;
	rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE);
}

/* enslave device <slave> to bond device <master> */
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
@@ -1655,9 +1674,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
		}
	}

	res = netdev_set_bond_master(slave_dev, bond_dev);
	res = bond_master_upper_dev_link(bond_dev, slave_dev);
	if (res) {
		pr_debug("Error %d calling netdev_set_bond_master\n", res);
		pr_debug("Error %d calling bond_master_upper_dev_link\n", res);
		goto err_restore_mac;
	}

@@ -1891,7 +1910,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
	dev_close(slave_dev);

err_unset_master:
	netdev_set_bond_master(slave_dev, NULL);
	bond_upper_dev_unlink(bond_dev, slave_dev);

err_restore_mac:
	if (!bond->params.fail_over_mac) {
@@ -1936,7 +1955,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)

	/* slave is not a slave or master is not master of this slave */
	if (!(slave_dev->flags & IFF_SLAVE) ||
	    (slave_dev->master != bond_dev)) {
	    !netdev_has_upper_dev(slave_dev, bond_dev)) {
		pr_err("%s: Error: cannot release %s.\n",
		       bond_dev->name, slave_dev->name);
		return -EINVAL;
@@ -2080,7 +2099,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
		netif_addr_unlock_bh(bond_dev);
	}

	netdev_set_bond_master(slave_dev, NULL);
	bond_upper_dev_unlink(bond_dev, slave_dev);

	slave_disable_netpoll(slave);

@@ -2195,7 +2214,7 @@ static int bond_release_all(struct net_device *bond_dev)
			netif_addr_unlock_bh(bond_dev);
		}

		netdev_set_bond_master(slave_dev, NULL);
		bond_upper_dev_unlink(bond_dev, slave_dev);

		slave_disable_netpoll(slave);

@@ -2259,8 +2278,9 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
	if (!USES_PRIMARY(bond->params.mode))
		return -EINVAL;

	/* Verify that master_dev is indeed the master of slave_dev */
	if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev))
	/* Verify that bond_dev is indeed the master of slave_dev */
	if (!(slave_dev->flags & IFF_SLAVE) ||
	    !netdev_has_upper_dev(slave_dev, bond_dev))
		return -EINVAL;

	read_lock(&bond->lock);
@@ -3258,25 +3278,23 @@ static int bond_master_netdev_event(unsigned long event,
static int bond_slave_netdev_event(unsigned long event,
				   struct net_device *slave_dev)
{
	struct net_device *bond_dev = slave_dev->master;
	struct bonding *bond = netdev_priv(bond_dev);
	struct slave *slave = NULL;
	struct slave *slave = bond_slave_get_rtnl(slave_dev);
	struct bonding *bond = slave->bond;
	struct net_device *bond_dev = slave->bond->dev;
	u32 old_speed;
	u8 old_duplex;

	switch (event) {
	case NETDEV_UNREGISTER:
		if (bond_dev) {
		if (bond->setup_by_slave)
			bond_release_and_destroy(bond_dev, slave_dev);
		else
			bond_release(bond_dev, slave_dev);
		}
		break;
	case NETDEV_UP:
	case NETDEV_CHANGE:
		slave = bond_get_slave_by_dev(bond, slave_dev);
		if (slave) {
			u32 old_speed = slave->speed;
			u8  old_duplex = slave->duplex;
		old_speed = slave->speed;
		old_duplex = slave->duplex;

		bond_update_speed_duplex(slave);

@@ -3286,8 +3304,6 @@ static int bond_slave_netdev_event(unsigned long event,
			if (old_duplex != slave->duplex)
				bond_3ad_adapter_duplex_changed(slave);
		}
		}

		break;
	case NETDEV_DOWN:
		/*
+7 −7
Original line number Diff line number Diff line
@@ -258,6 +258,9 @@ static inline bool bond_vlan_used(struct bonding *bond)
#define bond_slave_get_rcu(dev) \
	((struct slave *) rcu_dereference(dev->rx_handler_data))

#define bond_slave_get_rtnl(dev) \
	((struct slave *) rtnl_dereference(dev->rx_handler_data))

/**
 * Returns NULL if the net_device does not belong to any of the bond's slaves
 *
@@ -280,11 +283,9 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,

static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
{
	if (!slave || !slave->dev->master) {
	if (!slave || !slave->bond)
		return NULL;
	}

	return netdev_priv(slave->dev->master);
	return slave->bond;
}

static inline bool bond_is_lb(const struct bonding *bond)
@@ -360,10 +361,9 @@ static inline void bond_netpoll_send_skb(const struct slave *slave,

static inline void bond_set_slave_inactive_flags(struct slave *slave)
{
	struct bonding *bond = netdev_priv(slave->dev->master);
	if (!bond_is_lb(bond))
	if (!bond_is_lb(slave->bond))
		bond_set_backup_slave(slave);
	if (!bond->params.all_slaves_active)
	if (!slave->bond->params.all_slaves_active)
		slave->inactive = 1;
}

+1 −0
Original line number Diff line number Diff line
@@ -1987,6 +1987,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
	if (err < 0)
		rtnl_set_sk_err(net, RTNLGRP_LINK, err);
}
EXPORT_SYMBOL(rtmsg_ifinfo);

static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
				   struct net_device *dev,