]> err.no Git - linux-2.6/blobdiff - drivers/net/bonding/bond_alb.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireles...
[linux-2.6] / drivers / net / bonding / bond_alb.c
index 6db5d763f6b612c02685e076b37b0b1d180e2fb0..5a673725471cd55430be7642ceb71d4ff88d2b6e 100644 (file)
@@ -345,7 +345,7 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
        struct arp_pkt *arp = (struct arp_pkt *)skb->data;
        int res = NET_RX_DROP;
 
-       if (bond_dev->nd_net != &init_net)
+       if (dev_net(bond_dev) != &init_net)
                goto out;
 
        if (!(bond_dev->flags & IFF_MASTER))
@@ -678,12 +678,8 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
                }
 
                if (!list_empty(&bond->vlan_list)) {
-                       unsigned short vlan_id;
-                       int res = vlan_get_tag(skb, &vlan_id);
-                       if (!res) {
+                       if (!vlan_get_tag(skb, &client_info->vlan_id))
                                client_info->tag = 1;
-                               client_info->vlan_id = vlan_id;
-                       }
                }
 
                if (!client_info->assigned) {
@@ -979,7 +975,7 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
 /*
  * Send learning packets after MAC address swap.
  *
- * Called with RTNL and bond->lock held for read.
+ * Called with RTNL and no other locks
  */
 static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
                                struct slave *slave2)
@@ -987,6 +983,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
        int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
        struct slave *disabled_slave = NULL;
 
+       ASSERT_RTNL();
+
        /* fasten the change in the switch */
        if (SLAVE_IS_OK(slave1)) {
                alb_send_learning_packets(slave1, slave1->dev->dev_addr);
@@ -1031,7 +1029,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
  * a slave that has @slave's permanet address as its current address.
  * We'll make sure that that slave no longer uses @slave's permanent address.
  *
- * Caller must hold bond lock
+ * Caller must hold RTNL and no other locks
  */
 static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
 {
@@ -1455,16 +1453,16 @@ void bond_alb_monitor(struct work_struct *work)
 
        /* handle rlb stuff */
        if (bond_info->rlb_enabled) {
-               /* the following code changes the promiscuity of the
-                * the curr_active_slave. It needs to be locked with a
-                * write lock to protect from other code that also
-                * sets the promiscuity.
-                */
-               write_lock_bh(&bond->curr_slave_lock);
-
                if (bond_info->primary_is_promisc &&
                    (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
 
+                       /*
+                        * dev_set_promiscuity requires rtnl and
+                        * nothing else.
+                        */
+                       read_unlock(&bond->lock);
+                       rtnl_lock();
+
                        bond_info->rlb_promisc_timeout_counter = 0;
 
                        /* If the primary was set to promiscuous mode
@@ -1473,9 +1471,10 @@ void bond_alb_monitor(struct work_struct *work)
                         */
                        dev_set_promiscuity(bond->curr_active_slave->dev, -1);
                        bond_info->primary_is_promisc = 0;
-               }
 
-               write_unlock_bh(&bond->curr_slave_lock);
+                       rtnl_unlock();
+                       read_lock(&bond->lock);
+               }
 
                if (bond_info->rlb_rebalance) {
                        bond_info->rlb_rebalance = 0;
@@ -1541,7 +1540,12 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
        return 0;
 }
 
-/* Caller must hold bond lock for write */
+/*
+ * Remove slave from tlb and rlb hash tables, and fix up MAC addresses
+ * if necessary.
+ *
+ * Caller must hold RTNL and no other locks
+ */
 void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
 {
        if (bond->slave_cnt > 1) {
@@ -1600,9 +1604,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
        struct slave *swap_slave;
        int i;
 
-       if (new_slave)
-               ASSERT_RTNL();
-
        if (bond->curr_active_slave == new_slave) {
                return;
        }
@@ -1648,6 +1649,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
        write_unlock_bh(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
 
+       ASSERT_RTNL();
+
        /* curr_active_slave must be set before calling alb_swap_mac_addr */
        if (swap_slave) {
                /* swap mac address */
@@ -1658,12 +1661,11 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
                                       bond->alb_info.rlb_enabled);
        }
 
-       read_lock(&bond->lock);
-
        if (swap_slave) {
                alb_fasten_mac_swap(bond, swap_slave, new_slave);
+               read_lock(&bond->lock);
        } else {
-               /* fasten bond mac on new current slave */
+               read_lock(&bond->lock);
                alb_send_learning_packets(new_slave, bond->dev->dev_addr);
        }