diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 63 |
1 files changed, 18 insertions, 45 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bdb68a600382..3b16c34ed86e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link | |||
| 171 | /*----------------------------- Global variables ----------------------------*/ | 171 | /*----------------------------- Global variables ----------------------------*/ |
| 172 | 172 | ||
| 173 | #ifdef CONFIG_NET_POLL_CONTROLLER | 173 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 174 | cpumask_var_t netpoll_block_tx; | 174 | atomic_t netpoll_block_tx = ATOMIC_INIT(0); |
| 175 | #endif | 175 | #endif |
| 176 | 176 | ||
| 177 | static const char * const version = | 177 | static const char * const version = |
| @@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) | |||
| 418 | * @bond: bond device that got this skb for tx. | 418 | * @bond: bond device that got this skb for tx. |
| 419 | * @skb: hw accel VLAN tagged skb to transmit | 419 | * @skb: hw accel VLAN tagged skb to transmit |
| 420 | * @slave_dev: slave that is supposed to xmit this skbuff | 420 | * @slave_dev: slave that is supposed to xmit this skbuff |
| 421 | * | ||
| 422 | * When the bond gets an skb to transmit that is | ||
| 423 | * already hardware accelerated VLAN tagged, and it | ||
| 424 | * needs to relay this skb to a slave that is not | ||
| 425 | * hw accel capable, the skb needs to be "unaccelerated", | ||
| 426 | * i.e. strip the hwaccel tag and re-insert it as part | ||
| 427 | * of the payload. | ||
| 428 | */ | 421 | */ |
| 429 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, | 422 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, |
| 430 | struct net_device *slave_dev) | 423 | struct net_device *slave_dev) |
| 431 | { | 424 | { |
| 432 | unsigned short uninitialized_var(vlan_id); | 425 | skb->dev = slave_dev; |
| 433 | |||
| 434 | /* Test vlan_list not vlgrp to catch and handle 802.1p tags */ | ||
| 435 | if (!list_empty(&bond->vlan_list) && | ||
| 436 | !(slave_dev->features & NETIF_F_HW_VLAN_TX) && | ||
| 437 | vlan_get_tag(skb, &vlan_id) == 0) { | ||
| 438 | skb->dev = slave_dev; | ||
| 439 | skb = vlan_put_tag(skb, vlan_id); | ||
| 440 | if (!skb) { | ||
| 441 | /* vlan_put_tag() frees the skb in case of error, | ||
| 442 | * so return success here so the calling functions | ||
| 443 | * won't attempt to free is again. | ||
| 444 | */ | ||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | } else { | ||
| 448 | skb->dev = slave_dev; | ||
| 449 | } | ||
| 450 | |||
| 451 | skb->priority = 1; | 426 | skb->priority = 1; |
| 452 | #ifdef CONFIG_NET_POLL_CONTROLLER | 427 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 453 | if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { | 428 | if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { |
| @@ -878,8 +853,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev) | |||
| 878 | rcu_read_lock(); | 853 | rcu_read_lock(); |
| 879 | in_dev = __in_dev_get_rcu(dev); | 854 | in_dev = __in_dev_get_rcu(dev); |
| 880 | if (in_dev) { | 855 | if (in_dev) { |
| 856 | read_lock(&in_dev->mc_list_lock); | ||
| 881 | for (im = in_dev->mc_list; im; im = im->next) | 857 | for (im = in_dev->mc_list; im; im = im->next) |
| 882 | ip_mc_rejoin_group(im); | 858 | ip_mc_rejoin_group(im); |
| 859 | read_unlock(&in_dev->mc_list_lock); | ||
| 883 | } | 860 | } |
| 884 | 861 | ||
| 885 | rcu_read_unlock(); | 862 | rcu_read_unlock(); |
| @@ -1201,11 +1178,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
| 1201 | bond_do_fail_over_mac(bond, new_active, | 1178 | bond_do_fail_over_mac(bond, new_active, |
| 1202 | old_active); | 1179 | old_active); |
| 1203 | 1180 | ||
| 1204 | bond->send_grat_arp = bond->params.num_grat_arp; | 1181 | if (netif_running(bond->dev)) { |
| 1205 | bond_send_gratuitous_arp(bond); | 1182 | bond->send_grat_arp = bond->params.num_grat_arp; |
| 1183 | bond_send_gratuitous_arp(bond); | ||
| 1206 | 1184 | ||
| 1207 | bond->send_unsol_na = bond->params.num_unsol_na; | 1185 | bond->send_unsol_na = bond->params.num_unsol_na; |
| 1208 | bond_send_unsolicited_na(bond); | 1186 | bond_send_unsolicited_na(bond); |
| 1187 | } | ||
| 1209 | 1188 | ||
| 1210 | write_unlock_bh(&bond->curr_slave_lock); | 1189 | write_unlock_bh(&bond->curr_slave_lock); |
| 1211 | read_unlock(&bond->lock); | 1190 | read_unlock(&bond->lock); |
| @@ -1219,8 +1198,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
| 1219 | 1198 | ||
| 1220 | /* resend IGMP joins since active slave has changed or | 1199 | /* resend IGMP joins since active slave has changed or |
| 1221 | * all were sent on curr_active_slave */ | 1200 | * all were sent on curr_active_slave */ |
| 1222 | if ((USES_PRIMARY(bond->params.mode) && new_active) || | 1201 | if (((USES_PRIMARY(bond->params.mode) && new_active) || |
| 1223 | bond->params.mode == BOND_MODE_ROUNDROBIN) { | 1202 | bond->params.mode == BOND_MODE_ROUNDROBIN) && |
| 1203 | netif_running(bond->dev)) { | ||
| 1224 | bond->igmp_retrans = bond->params.resend_igmp; | 1204 | bond->igmp_retrans = bond->params.resend_igmp; |
| 1225 | queue_delayed_work(bond->wq, &bond->mcast_work, 0); | 1205 | queue_delayed_work(bond->wq, &bond->mcast_work, 0); |
| 1226 | } | 1206 | } |
| @@ -1574,7 +1554,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1574 | 1554 | ||
| 1575 | /* If this is the first slave, then we need to set the master's hardware | 1555 | /* If this is the first slave, then we need to set the master's hardware |
| 1576 | * address to be the same as the slave's. */ | 1556 | * address to be the same as the slave's. */ |
| 1577 | if (bond->slave_cnt == 0) | 1557 | if (is_zero_ether_addr(bond->dev->dev_addr)) |
| 1578 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | 1558 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, |
| 1579 | slave_dev->addr_len); | 1559 | slave_dev->addr_len); |
| 1580 | 1560 | ||
| @@ -5297,13 +5277,6 @@ static int __init bonding_init(void) | |||
| 5297 | if (res) | 5277 | if (res) |
| 5298 | goto out; | 5278 | goto out; |
| 5299 | 5279 | ||
| 5300 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 5301 | if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { | ||
| 5302 | res = -ENOMEM; | ||
| 5303 | goto out; | ||
| 5304 | } | ||
| 5305 | #endif | ||
| 5306 | |||
| 5307 | res = register_pernet_subsys(&bond_net_ops); | 5280 | res = register_pernet_subsys(&bond_net_ops); |
| 5308 | if (res) | 5281 | if (res) |
| 5309 | goto out; | 5282 | goto out; |
| @@ -5332,9 +5305,6 @@ err: | |||
| 5332 | rtnl_link_unregister(&bond_link_ops); | 5305 | rtnl_link_unregister(&bond_link_ops); |
| 5333 | err_link: | 5306 | err_link: |
| 5334 | unregister_pernet_subsys(&bond_net_ops); | 5307 | unregister_pernet_subsys(&bond_net_ops); |
| 5335 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 5336 | free_cpumask_var(netpoll_block_tx); | ||
| 5337 | #endif | ||
| 5338 | goto out; | 5308 | goto out; |
| 5339 | 5309 | ||
| 5340 | } | 5310 | } |
| @@ -5351,7 +5321,10 @@ static void __exit bonding_exit(void) | |||
| 5351 | unregister_pernet_subsys(&bond_net_ops); | 5321 | unregister_pernet_subsys(&bond_net_ops); |
| 5352 | 5322 | ||
| 5353 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5323 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 5354 | free_cpumask_var(netpoll_block_tx); | 5324 | /* |
| 5325 | * Make sure we don't have an imbalance on our netpoll blocking | ||
| 5326 | */ | ||
| 5327 | WARN_ON(atomic_read(&netpoll_block_tx)); | ||
| 5355 | #endif | 5328 | #endif |
| 5356 | } | 5329 | } |
| 5357 | 5330 | ||
