aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2009-06-12 15:02:52 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-14 02:29:04 -0400
commit181470fcf3f8ecc16625bc45a5f6f678e57bfb22 (patch)
tree903835cc78e6ff87f3db38508933676c48510bdd /drivers
parent5c5129b54f2f346c86cd23fea67e71b45f7f84ff (diff)
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: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c67
1 files changed, 30 insertions, 37 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a6e789172727..d927f71af8a3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -210,6 +210,7 @@ struct bond_parm_tbl ad_select_tbl[] = {
210/*-------------------------- Forward declarations ---------------------------*/ 210/*-------------------------- Forward declarations ---------------------------*/
211 211
212static void bond_send_gratuitous_arp(struct bonding *bond); 212static void bond_send_gratuitous_arp(struct bonding *bond);
213static int bond_init(struct net_device *bond_dev);
213static void bond_deinit(struct net_device *bond_dev); 214static void bond_deinit(struct net_device *bond_dev);
214 215
215/*---------------------------- General routines -----------------------------*/ 216/*---------------------------- General routines -----------------------------*/
@@ -4518,6 +4519,7 @@ static const struct ethtool_ops bond_ethtool_ops = {
4518}; 4519};
4519 4520
4520static const struct net_device_ops bond_netdev_ops = { 4521static const struct net_device_ops bond_netdev_ops = {
4522 .ndo_init = bond_init,
4521 .ndo_uninit = bond_uninit, 4523 .ndo_uninit = bond_uninit,
4522 .ndo_open = bond_open, 4524 .ndo_open = bond_open,
4523 .ndo_stop = bond_close, 4525 .ndo_stop = bond_close,
@@ -4533,38 +4535,22 @@ static const struct net_device_ops bond_netdev_ops = {
4533 .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, 4535 .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
4534}; 4536};
4535 4537
4536/* 4538static void bond_setup(struct net_device *bond_dev)
4537 * Does not allocate but creates a /proc entry.
4538 * Allowed to fail.
4539 */
4540static int bond_init(struct net_device *bond_dev)
4541{ 4539{
4542 struct bonding *bond = netdev_priv(bond_dev); 4540 struct bonding *bond = netdev_priv(bond_dev);
4543 4541
4544 pr_debug("Begin bond_init for %s\n", bond_dev->name);
4545
4546 /* initialize rwlocks */ 4542 /* initialize rwlocks */
4547 rwlock_init(&bond->lock); 4543 rwlock_init(&bond->lock);
4548 rwlock_init(&bond->curr_slave_lock); 4544 rwlock_init(&bond->curr_slave_lock);
4549 4545
4550 bond->params = bonding_defaults; 4546 bond->params = bonding_defaults;
4551 4547
4552 bond->wq = create_singlethread_workqueue(bond_dev->name);
4553 if (!bond->wq)
4554 return -ENOMEM;
4555
4556 /* Initialize pointers */ 4548 /* Initialize pointers */
4557 bond->first_slave = NULL;
4558 bond->curr_active_slave = NULL;
4559 bond->current_arp_slave = NULL;
4560 bond->primary_slave = NULL;
4561 bond->dev = bond_dev; 4549 bond->dev = bond_dev;
4562 bond->send_grat_arp = 0;
4563 bond->send_unsol_na = 0;
4564 bond->setup_by_slave = 0;
4565 INIT_LIST_HEAD(&bond->vlan_list); 4550 INIT_LIST_HEAD(&bond->vlan_list);
4566 4551
4567 /* Initialize the device entry points */ 4552 /* Initialize the device entry points */
4553 ether_setup(bond_dev);
4568 bond_dev->netdev_ops = &bond_netdev_ops; 4554 bond_dev->netdev_ops = &bond_netdev_ops;
4569 bond_dev->ethtool_ops = &bond_ethtool_ops; 4555 bond_dev->ethtool_ops = &bond_ethtool_ops;
4570 bond_set_mode_ops(bond, bond->params.mode); 4556 bond_set_mode_ops(bond, bond->params.mode);
@@ -4575,6 +4561,8 @@ static int bond_init(struct net_device *bond_dev)
4575 bond_dev->tx_queue_len = 0; 4561 bond_dev->tx_queue_len = 0;
4576 bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; 4562 bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
4577 bond_dev->priv_flags |= IFF_BONDING; 4563 bond_dev->priv_flags |= IFF_BONDING;
4564 bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
4565
4578 if (bond->params.arp_interval) 4566 if (bond->params.arp_interval)
4579 bond_dev->priv_flags |= IFF_MASTER_ARPMON; 4567 bond_dev->priv_flags |= IFF_MASTER_ARPMON;
4580 4568
@@ -4599,10 +4587,6 @@ static int bond_init(struct net_device *bond_dev)
4599 NETIF_F_HW_VLAN_RX | 4587 NETIF_F_HW_VLAN_RX |
4600 NETIF_F_HW_VLAN_FILTER); 4588 NETIF_F_HW_VLAN_FILTER);
4601 4589
4602 bond_create_proc_entry(bond);
4603 list_add_tail(&bond->bond_list, &bond_dev_list);
4604
4605 return 0;
4606} 4590}
4607 4591
4608static void bond_work_cancel_all(struct bonding *bond) 4592static void bond_work_cancel_all(struct bonding *bond)
@@ -5056,6 +5040,29 @@ static void bond_set_lockdep_class(struct net_device *dev)
5056 netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL); 5040 netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
5057} 5041}
5058 5042
5043/*
5044 * Called from registration process
5045 */
5046static int bond_init(struct net_device *bond_dev)
5047{
5048 struct bonding *bond = netdev_priv(bond_dev);
5049
5050 pr_debug("Begin bond_init for %s\n", bond_dev->name);
5051
5052 bond->wq = create_singlethread_workqueue(bond_dev->name);
5053 if (!bond->wq)
5054 return -ENOMEM;
5055
5056 bond_set_lockdep_class(bond_dev);
5057
5058 netif_carrier_off(bond_dev);
5059
5060 bond_create_proc_entry(bond);
5061 list_add_tail(&bond->bond_list, &bond_dev_list);
5062
5063 return 0;
5064}
5065
5059/* Create a new bond based on the specified name and bonding parameters. 5066/* Create a new bond based on the specified name and bonding parameters.
5060 * If name is NULL, obtain a suitable "bond%d" name for us. 5067 * If name is NULL, obtain a suitable "bond%d" name for us.
5061 * Caller must NOT hold rtnl_lock; we need to release it here before we 5068 * Caller must NOT hold rtnl_lock; we need to release it here before we
@@ -5077,7 +5084,7 @@ int bond_create(const char *name)
5077 } 5084 }
5078 5085
5079 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", 5086 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
5080 ether_setup); 5087 bond_setup);
5081 if (!bond_dev) { 5088 if (!bond_dev) {
5082 pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n", 5089 pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n",
5083 name); 5090 name);
@@ -5085,26 +5092,12 @@ int bond_create(const char *name)
5085 goto out_rtnl; 5092 goto out_rtnl;
5086 } 5093 }
5087 5094
5088 bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
5089 if (!name) { 5095 if (!name) {
5090 res = dev_alloc_name(bond_dev, "bond%d"); 5096 res = dev_alloc_name(bond_dev, "bond%d");
5091 if (res < 0) 5097 if (res < 0)
5092 goto out_netdev; 5098 goto out_netdev;
5093 } 5099 }
5094 5100
5095 /* bond_init() must be called after dev_alloc_name() (for the
5096 * /proc files), but before register_netdevice(), because we
5097 * need to set function pointers.
5098 */
5099
5100 res = bond_init(bond_dev);
5101 if (res < 0)
5102 goto out_netdev;
5103
5104 bond_set_lockdep_class(bond_dev);
5105
5106 netif_carrier_off(bond_dev);
5107
5108 res = register_netdevice(bond_dev); 5101 res = register_netdevice(bond_dev);
5109 if (res < 0) 5102 if (res < 0)
5110 goto out_bond; 5103 goto out_bond;