diff options
| author | David S. Miller <davem@davemloft.net> | 2013-04-22 20:32:51 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-04-22 20:32:51 -0400 |
| commit | 6e0895c2ea326cc4bb11e8fa2f654628d5754c31 (patch) | |
| tree | 7089303ac11a12edc43a8c4fa1b23974e10937ea /drivers/net/bonding | |
| parent | 55fbbe46e9eb3cbe6c335503f5550855a1128dce (diff) | |
| parent | 60d509fa6a9c4653a86ad830e4c4b30360b23f0e (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
include/net/scm.h
net/batman-adv/routing.c
net/ipv4/tcp_input.c
The e{uid,gid} --> {uid,gid} credentials fix conflicted with the
cleanup in net-next to now pass cred structs around.
The be2net driver had a bug fix in 'net' that overlapped with the VLAN
interface changes by Patrick McHardy in net-next.
An IGB conflict existed because in 'net' the build_skb() support was
reverted, and in 'net-next' there was a comment style fix within that
code.
Several batman-adv conflicts were resolved by making sure that all
calls to batadv_is_my_mac() are changed to have a new bat_priv first
argument.
Eric Dumazet's TS ECR fix in TCP in 'net' conflicted with the F-RTO
rewrite in 'net-next', mostly overlapping changes.
Thanks to Stephen Rothwell and Antonio Quartulli for help with several
of these merge resolutions.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 101 |
1 files changed, 73 insertions, 28 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5e22126c7a26..532153db1f9c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -848,8 +848,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, | |||
| 848 | if (bond->dev->flags & IFF_ALLMULTI) | 848 | if (bond->dev->flags & IFF_ALLMULTI) |
| 849 | dev_set_allmulti(old_active->dev, -1); | 849 | dev_set_allmulti(old_active->dev, -1); |
| 850 | 850 | ||
| 851 | netif_addr_lock_bh(bond->dev); | ||
| 851 | netdev_for_each_mc_addr(ha, bond->dev) | 852 | netdev_for_each_mc_addr(ha, bond->dev) |
| 852 | dev_mc_del(old_active->dev, ha->addr); | 853 | dev_mc_del(old_active->dev, ha->addr); |
| 854 | netif_addr_unlock_bh(bond->dev); | ||
| 853 | } | 855 | } |
| 854 | 856 | ||
| 855 | if (new_active) { | 857 | if (new_active) { |
| @@ -860,8 +862,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, | |||
| 860 | if (bond->dev->flags & IFF_ALLMULTI) | 862 | if (bond->dev->flags & IFF_ALLMULTI) |
| 861 | dev_set_allmulti(new_active->dev, 1); | 863 | dev_set_allmulti(new_active->dev, 1); |
| 862 | 864 | ||
| 865 | netif_addr_lock_bh(bond->dev); | ||
| 863 | netdev_for_each_mc_addr(ha, bond->dev) | 866 | netdev_for_each_mc_addr(ha, bond->dev) |
| 864 | dev_mc_add(new_active->dev, ha->addr); | 867 | dev_mc_add(new_active->dev, ha->addr); |
| 868 | netif_addr_unlock_bh(bond->dev); | ||
| 865 | } | 869 | } |
| 866 | } | 870 | } |
| 867 | 871 | ||
| @@ -1903,11 +1907,29 @@ err_dest_symlinks: | |||
| 1903 | bond_destroy_slave_symlinks(bond_dev, slave_dev); | 1907 | bond_destroy_slave_symlinks(bond_dev, slave_dev); |
| 1904 | 1908 | ||
| 1905 | err_detach: | 1909 | err_detach: |
| 1910 | if (!USES_PRIMARY(bond->params.mode)) { | ||
| 1911 | netif_addr_lock_bh(bond_dev); | ||
| 1912 | bond_mc_list_flush(bond_dev, slave_dev); | ||
| 1913 | netif_addr_unlock_bh(bond_dev); | ||
| 1914 | } | ||
| 1915 | bond_del_vlans_from_slave(bond, slave_dev); | ||
| 1906 | write_lock_bh(&bond->lock); | 1916 | write_lock_bh(&bond->lock); |
| 1907 | bond_detach_slave(bond, new_slave); | 1917 | bond_detach_slave(bond, new_slave); |
| 1918 | if (bond->primary_slave == new_slave) | ||
| 1919 | bond->primary_slave = NULL; | ||
| 1908 | write_unlock_bh(&bond->lock); | 1920 | write_unlock_bh(&bond->lock); |
| 1921 | if (bond->curr_active_slave == new_slave) { | ||
| 1922 | read_lock(&bond->lock); | ||
| 1923 | write_lock_bh(&bond->curr_slave_lock); | ||
| 1924 | bond_change_active_slave(bond, NULL); | ||
| 1925 | bond_select_active_slave(bond); | ||
| 1926 | write_unlock_bh(&bond->curr_slave_lock); | ||
| 1927 | read_unlock(&bond->lock); | ||
| 1928 | } | ||
| 1929 | slave_disable_netpoll(new_slave); | ||
| 1909 | 1930 | ||
| 1910 | err_close: | 1931 | err_close: |
| 1932 | slave_dev->priv_flags &= ~IFF_BONDING; | ||
| 1911 | dev_close(slave_dev); | 1933 | dev_close(slave_dev); |
| 1912 | 1934 | ||
| 1913 | err_unset_master: | 1935 | err_unset_master: |
| @@ -3172,11 +3194,20 @@ static int bond_slave_netdev_event(unsigned long event, | |||
| 3172 | struct net_device *slave_dev) | 3194 | struct net_device *slave_dev) |
| 3173 | { | 3195 | { |
| 3174 | struct slave *slave = bond_slave_get_rtnl(slave_dev); | 3196 | struct slave *slave = bond_slave_get_rtnl(slave_dev); |
| 3175 | struct bonding *bond = slave->bond; | 3197 | struct bonding *bond; |
| 3176 | struct net_device *bond_dev = slave->bond->dev; | 3198 | struct net_device *bond_dev; |
| 3177 | u32 old_speed; | 3199 | u32 old_speed; |
| 3178 | u8 old_duplex; | 3200 | u8 old_duplex; |
| 3179 | 3201 | ||
| 3202 | /* A netdev event can be generated while enslaving a device | ||
| 3203 | * before netdev_rx_handler_register is called in which case | ||
| 3204 | * slave will be NULL | ||
| 3205 | */ | ||
| 3206 | if (!slave) | ||
| 3207 | return NOTIFY_DONE; | ||
| 3208 | bond_dev = slave->bond->dev; | ||
| 3209 | bond = slave->bond; | ||
| 3210 | |||
| 3180 | switch (event) { | 3211 | switch (event) { |
| 3181 | case NETDEV_UNREGISTER: | 3212 | case NETDEV_UNREGISTER: |
| 3182 | if (bond->setup_by_slave) | 3213 | if (bond->setup_by_slave) |
| @@ -3290,20 +3321,22 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count) | |||
| 3290 | */ | 3321 | */ |
| 3291 | static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) | 3322 | static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) |
| 3292 | { | 3323 | { |
| 3293 | struct ethhdr *data = (struct ethhdr *)skb->data; | 3324 | const struct ethhdr *data; |
| 3294 | struct iphdr *iph; | 3325 | const struct iphdr *iph; |
| 3295 | struct ipv6hdr *ipv6h; | 3326 | const struct ipv6hdr *ipv6h; |
| 3296 | u32 v6hash; | 3327 | u32 v6hash; |
| 3297 | __be32 *s, *d; | 3328 | const __be32 *s, *d; |
| 3298 | 3329 | ||
| 3299 | if (skb->protocol == htons(ETH_P_IP) && | 3330 | if (skb->protocol == htons(ETH_P_IP) && |
| 3300 | skb_network_header_len(skb) >= sizeof(*iph)) { | 3331 | pskb_network_may_pull(skb, sizeof(*iph))) { |
| 3301 | iph = ip_hdr(skb); | 3332 | iph = ip_hdr(skb); |
| 3333 | data = (struct ethhdr *)skb->data; | ||
| 3302 | return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ | 3334 | return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ |
| 3303 | (data->h_dest[5] ^ data->h_source[5])) % count; | 3335 | (data->h_dest[5] ^ data->h_source[5])) % count; |
| 3304 | } else if (skb->protocol == htons(ETH_P_IPV6) && | 3336 | } else if (skb->protocol == htons(ETH_P_IPV6) && |
| 3305 | skb_network_header_len(skb) >= sizeof(*ipv6h)) { | 3337 | pskb_network_may_pull(skb, sizeof(*ipv6h))) { |
| 3306 | ipv6h = ipv6_hdr(skb); | 3338 | ipv6h = ipv6_hdr(skb); |
| 3339 | data = (struct ethhdr *)skb->data; | ||
| 3307 | s = &ipv6h->saddr.s6_addr32[0]; | 3340 | s = &ipv6h->saddr.s6_addr32[0]; |
| 3308 | d = &ipv6h->daddr.s6_addr32[0]; | 3341 | d = &ipv6h->daddr.s6_addr32[0]; |
| 3309 | v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); | 3342 | v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); |
| @@ -3322,33 +3355,36 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) | |||
| 3322 | static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) | 3355 | static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) |
| 3323 | { | 3356 | { |
| 3324 | u32 layer4_xor = 0; | 3357 | u32 layer4_xor = 0; |
| 3325 | struct iphdr *iph; | 3358 | const struct iphdr *iph; |
| 3326 | struct ipv6hdr *ipv6h; | 3359 | const struct ipv6hdr *ipv6h; |
| 3327 | __be32 *s, *d; | 3360 | const __be32 *s, *d; |
| 3328 | __be16 *layer4hdr; | 3361 | const __be16 *l4 = NULL; |
| 3362 | __be16 _l4[2]; | ||
| 3363 | int noff = skb_network_offset(skb); | ||
| 3364 | int poff; | ||
| 3329 | 3365 | ||
| 3330 | if (skb->protocol == htons(ETH_P_IP) && | 3366 | if (skb->protocol == htons(ETH_P_IP) && |
| 3331 | skb_network_header_len(skb) >= sizeof(*iph)) { | 3367 | pskb_may_pull(skb, noff + sizeof(*iph))) { |
| 3332 | iph = ip_hdr(skb); | 3368 | iph = ip_hdr(skb); |
| 3333 | if (!ip_is_fragment(iph) && | 3369 | poff = proto_ports_offset(iph->protocol); |
| 3334 | (iph->protocol == IPPROTO_TCP || | 3370 | |
| 3335 | iph->protocol == IPPROTO_UDP) && | 3371 | if (!ip_is_fragment(iph) && poff >= 0) { |
| 3336 | (skb_headlen(skb) - skb_network_offset(skb) >= | 3372 | l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff, |
| 3337 | iph->ihl * sizeof(u32) + sizeof(*layer4hdr) * 2)) { | 3373 | sizeof(_l4), &_l4); |
| 3338 | layer4hdr = (__be16 *)((u32 *)iph + iph->ihl); | 3374 | if (l4) |
| 3339 | layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); | 3375 | layer4_xor = ntohs(l4[0] ^ l4[1]); |
| 3340 | } | 3376 | } |
| 3341 | return (layer4_xor ^ | 3377 | return (layer4_xor ^ |
| 3342 | ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; | 3378 | ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; |
| 3343 | } else if (skb->protocol == htons(ETH_P_IPV6) && | 3379 | } else if (skb->protocol == htons(ETH_P_IPV6) && |
| 3344 | skb_network_header_len(skb) >= sizeof(*ipv6h)) { | 3380 | pskb_ |
