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

Commit 181470fc authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller
Browse files

bonding: initialization rework



Need to rework how bonding devices are initialized to make it more
amenable to creating bonding devices via netlink.

Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5c5129b5
Loading
Loading
Loading
Loading
+30 −37
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ struct bond_parm_tbl ad_select_tbl[] = {
/*-------------------------- Forward declarations ---------------------------*/

static void bond_send_gratuitous_arp(struct bonding *bond);
static int bond_init(struct net_device *bond_dev);
static void bond_deinit(struct net_device *bond_dev);

/*---------------------------- General routines -----------------------------*/
@@ -4518,6 +4519,7 @@ static const struct ethtool_ops bond_ethtool_ops = {
};

static const struct net_device_ops bond_netdev_ops = {
	.ndo_init		= bond_init,
	.ndo_uninit		= bond_uninit,
	.ndo_open		= bond_open,
	.ndo_stop		= bond_close,
@@ -4533,38 +4535,22 @@ static const struct net_device_ops bond_netdev_ops = {
	.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,
};

/*
 * Does not allocate but creates a /proc entry.
 * Allowed to fail.
 */
static int bond_init(struct net_device *bond_dev)
static void bond_setup(struct net_device *bond_dev)
{
	struct bonding *bond = netdev_priv(bond_dev);

	pr_debug("Begin bond_init for %s\n", bond_dev->name);

	/* initialize rwlocks */
	rwlock_init(&bond->lock);
	rwlock_init(&bond->curr_slave_lock);

	bond->params = bonding_defaults;

	bond->wq = create_singlethread_workqueue(bond_dev->name);
	if (!bond->wq)
		return -ENOMEM;

	/* Initialize pointers */
	bond->first_slave = NULL;
	bond->curr_active_slave = NULL;
	bond->current_arp_slave = NULL;
	bond->primary_slave = NULL;
	bond->dev = bond_dev;
	bond->send_grat_arp = 0;
	bond->send_unsol_na = 0;
	bond->setup_by_slave = 0;
	INIT_LIST_HEAD(&bond->vlan_list);

	/* Initialize the device entry points */
	ether_setup(bond_dev);
	bond_dev->netdev_ops = &bond_netdev_ops;
	bond_dev->ethtool_ops = &bond_ethtool_ops;
	bond_set_mode_ops(bond, bond->params.mode);
@@ -4575,6 +4561,8 @@ static int bond_init(struct net_device *bond_dev)
	bond_dev->tx_queue_len = 0;
	bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
	bond_dev->priv_flags |= IFF_BONDING;
	bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;

	if (bond->params.arp_interval)
		bond_dev->priv_flags |= IFF_MASTER_ARPMON;

@@ -4599,10 +4587,6 @@ static int bond_init(struct net_device *bond_dev)
			       NETIF_F_HW_VLAN_RX |
			       NETIF_F_HW_VLAN_FILTER);

	bond_create_proc_entry(bond);
	list_add_tail(&bond->bond_list, &bond_dev_list);

	return 0;
}

static void bond_work_cancel_all(struct bonding *bond)
@@ -5056,6 +5040,29 @@ static void bond_set_lockdep_class(struct net_device *dev)
	netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
}

/*
 * Called from registration process
 */
static int bond_init(struct net_device *bond_dev)
{
	struct bonding *bond = netdev_priv(bond_dev);

	pr_debug("Begin bond_init for %s\n", bond_dev->name);

	bond->wq = create_singlethread_workqueue(bond_dev->name);
	if (!bond->wq)
		return -ENOMEM;

	bond_set_lockdep_class(bond_dev);

	netif_carrier_off(bond_dev);

	bond_create_proc_entry(bond);
	list_add_tail(&bond->bond_list, &bond_dev_list);

	return 0;
}

/* Create a new bond based on the specified name and bonding parameters.
 * If name is NULL, obtain a suitable "bond%d" name for us.
 * Caller must NOT hold rtnl_lock; we need to release it here before we
@@ -5077,7 +5084,7 @@ int bond_create(const char *name)
	}

	bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
				ether_setup);
				bond_setup);
	if (!bond_dev) {
		pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n",
		       name);
@@ -5085,26 +5092,12 @@ int bond_create(const char *name)
		goto out_rtnl;
	}

	bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
	if (!name) {
		res = dev_alloc_name(bond_dev, "bond%d");
		if (res < 0)
			goto out_netdev;
	}

	/* bond_init() must be called after dev_alloc_name() (for the
	 * /proc files), but before register_netdevice(), because we
	 * need to set function pointers.
	 */

	res = bond_init(bond_dev);
	if (res < 0)
		goto out_netdev;

	bond_set_lockdep_class(bond_dev);

	netif_carrier_off(bond_dev);

	res = register_netdevice(bond_dev);
	if (res < 0)
		goto out_bond;