Skip to content

Commit

Permalink
bonding: initialization rework
Browse files Browse the repository at this point in the history
Need to rework how bonding devices are initialized to make it more
amenable to creating bonding devices via netlink.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jun 14, 2009
1 parent 5c5129b commit 181470f
Showing 1 changed file with 30 additions and 37 deletions.
67 changes: 30 additions & 37 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 -----------------------------*/
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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;

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -5077,34 +5084,20 @@ 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);
res = -ENOMEM;
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;
Expand Down

0 comments on commit 181470f

Please sign in to comment.