aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r--drivers/net/bonding/bond_alb.c24
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
83static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; 84static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
85static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01};
84static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC; 86static 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;