diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2008-08-28 15:38:41 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-24 18:49:01 -0400 |
commit | 2d1ea19da0e84117d3ebbad981e4664bef03152e (patch) | |
tree | 0b073f7b68399b35bc122487ee8dcfc5d6492901 /drivers/net/bonding/bond_alb.c | |
parent | f382a0a8e9403c6d7f8b2cfa21e41fefb5d0c9bd (diff) |
bonding: Do not tx-balance some IPv6 packets on ALB/TLB bonds
IPv6 all-node-multicasts and DAD probes should not be tx-balanced
on ALB/TLB bonds. The all-node-multicast is an equivalent to IPv4
broadcasts. DAD probes have to be sent only on the primary so that
we don't get false-positive detections.
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 3d39278a63e3..ade5f3f6693b 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/in.h> | 38 | #include <linux/in.h> |
39 | #include <net/ipx.h> | 39 | #include <net/ipx.h> |
40 | #include <net/arp.h> | 40 | #include <net/arp.h> |
41 | #include <net/ipv6.h> | ||
41 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
42 | #include "bonding.h" | 43 | #include "bonding.h" |
43 | #include "bond_alb.h" | 44 | #include "bond_alb.h" |
@@ -81,6 +82,7 @@ | |||
81 | #define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC | 82 | #define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC |
82 | 83 | ||
83 | static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; | 84 | static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; |
85 | static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01}; | ||
84 | static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC; | 86 | static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC; |
85 | 87 | ||
86 | #pragma pack(1) | 88 | #pragma pack(1) |
@@ -1290,6 +1292,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1290 | u32 hash_index = 0; | 1292 | u32 hash_index = 0; |
1291 | const u8 *hash_start = NULL; | 1293 | const u8 *hash_start = NULL; |
1292 | int res = 1; | 1294 | int res = 1; |
1295 | struct ipv6hdr *ip6hdr; | ||
1293 | 1296 | ||
1294 | skb_reset_mac_header(skb); | 1297 | skb_reset_mac_header(skb); |
1295 | eth_data = eth_hdr(skb); | 1298 | eth_data = eth_hdr(skb); |
@@ -1319,11 +1322,32 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1319 | } | 1322 | } |
1320 | break; | 1323 | break; |
1321 | case ETH_P_IPV6: | 1324 | case ETH_P_IPV6: |
1325 | /* IPv6 doesn't really use broadcast mac address, but leave | ||
1326 | * that here just in case. | ||
1327 | */ | ||
1322 | if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) { | 1328 | if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) { |
1323 | do_tx_balance = 0; | 1329 | do_tx_balance = 0; |
1324 | break; | 1330 | break; |
1325 | } | 1331 | } |
1326 | 1332 | ||
1333 | /* IPv6 uses all-nodes multicast as an equivalent to | ||
1334 | * broadcasts in IPv4. | ||
1335 | */ | ||
1336 | if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) { | ||
1337 | do_tx_balance = 0; | ||
1338 | break; | ||
1339 | } | ||
1340 | |||
1341 | /* Additianally, DAD probes should not be tx-balanced as that | ||
1342 | * will lead to false positives for duplicate addresses and | ||
1343 | * prevent address configuration from working. | ||
1344 | */ | ||
1345 | ip6hdr = ipv6_hdr(skb); | ||
1346 | if (ipv6_addr_any(&ip6hdr->saddr)) { | ||
1347 | do_tx_balance = 0; | ||
1348 | break; | ||
1349 | } | ||
1350 | |||
1327 | hash_start = (char *)&(ipv6_hdr(skb)->daddr); | 1351 | hash_start = (char *)&(ipv6_hdr(skb)->daddr); |
1328 | hash_size = sizeof(ipv6_hdr(skb)->daddr); | 1352 | hash_size = sizeof(ipv6_hdr(skb)->daddr); |
1329 | break; | 1353 | break; |