aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-10-03 15:37:10 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-03 15:37:10 -0400
commit99ebe9f2b34368c51ae6d4b09708e240284435bd (patch)
tree726011355fb63db194ee061d8e2e7ab215b167df
parent5080546682bae3d32734b18e281091684f0ebbe4 (diff)
parent7a6afab1de8526d1d6347fc33a7957ea3015ad82 (diff)
Merge branch 'bond_hash'
Nikolay Aleksandrov says: ==================== This is a complete remake of my old patch that modified the bonding hash functions to use skb_flow_dissect which was suggested by Eric Dumazet. This time around I've left the old modes although using a new hash function again suggested by Eric, which is the same for all modes. The only difference is the way the headers are obtained. The old modes obtain them as before in order to address concerns about speed, but the 2 new ones use skb_flow_dissect. The unification of the hash function allows to remove a pointer from struct bonding and also a few extra functions that dealt with it. Two new functions are added which take care of the hashing based on bond->params.xmit_policy only: bond_xmit_hash() - global function, used by XOR and 3ad modes bond_flow_dissect() - used by bond_xmit_hash() to obtain the necessary headers and combine them according to bond->params.xmit_policy. Also factor out the ports extraction from skb_flow_dissect and add a new function - skb_flow_get_ports() which can be re-used. v2: add the flow_dissector patch and use skb_flow_get_ports in patch 02 v3: fix a bug in the flow_dissector patch that caused a different thoff by modifying the thoff argument in skb_flow_get_ports directly, most of the users already do it anyway. Also add the necessary export symbol for skb_flow_get_ports. v4: integrate the thoff bug fix in patch 01 v5: disintegrate the thoff bug fix and re-base on top of Eric's fix ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/bonding.txt66
-rw-r--r--drivers/net/bonding/bond_3ad.c2
-rw-r--r--drivers/net/bonding/bond_main.c197
-rw-r--r--drivers/net/bonding/bond_sysfs.c2
-rw-r--r--drivers/net/bonding/bonding.h3
-rw-r--r--include/net/flow_keys.h1
-rw-r--r--include/uapi/linux/if_bonding.h2
-rw-r--r--net/core/flow_dissector.c39
8 files changed, 137 insertions, 175 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 9b28e714831a..3856ed2c45a9 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -743,21 +743,16 @@ xmit_hash_policy
743 protocol information to generate the hash. 743 protocol information to generate the hash.
744 744
745 Uses XOR of hardware MAC addresses and IP addresses to 745 Uses XOR of hardware MAC addresses and IP addresses to
746 generate the hash. The IPv4 formula is 746 generate the hash. The formula is
747 747
748 (((source IP XOR dest IP) AND 0xffff) XOR 748 hash = source MAC XOR destination MAC
749 ( source MAC XOR destination MAC )) 749 hash = hash XOR source IP XOR destination IP
750 modulo slave count 750 hash = hash XOR (hash RSHIFT 16)
751 hash = hash XOR (hash RSHIFT 8)
752 And then hash is reduced modulo slave count.
751 753
752 The IPv6 formula is 754 If the protocol is IPv6 then the source and destination
753 755 addresses are first hashed using ipv6_addr_hash.
754 hash = (source ip quad 2 XOR dest IP quad 2) XOR
755 (source ip quad 3 XOR dest IP quad 3) XOR
756 (source ip quad 4 XOR dest IP quad 4)
757
758 (((hash >> 24) XOR (hash >> 16) XOR (hash >> 8) XOR hash)
759 XOR (source MAC XOR destination MAC))
760 modulo slave count
761 756
762 This algorithm will place all traffic to a particular 757 This algorithm will place all traffic to a particular
763 network peer on the same slave. For non-IP traffic, 758 network peer on the same slave. For non-IP traffic,
@@ -779,21 +774,16 @@ xmit_hash_policy
779 slaves, although a single connection will not span 774 slaves, although a single connection will not span
780 multiple slaves. 775 multiple slaves.
781 776
782 The formula for unfragmented IPv4 TCP and UDP packets is 777 The formula for unfragmented TCP and UDP packets is
783
784 ((source port XOR dest port) XOR
785 ((source IP XOR dest IP) AND 0xffff)
786 modulo slave count
787 778
788 The formula for unfragmented IPv6 TCP and UDP packets is 779 hash = source port, destination port (as in the header)
780 hash = hash XOR source IP XOR destination IP
781 hash = hash XOR (hash RSHIFT 16)
782 hash = hash XOR (hash RSHIFT 8)
783 And then hash is reduced modulo slave count.
789 784
790 hash = (source port XOR dest port) XOR 785 If the protocol is IPv6 then the source and destination
791 ((source ip quad 2 XOR dest IP quad 2) XOR 786 addresses are first hashed using ipv6_addr_hash.
792 (source ip quad 3 XOR dest IP quad 3) XOR
793 (source ip quad 4 XOR dest IP quad 4))
794
795 ((hash >> 24) XOR (hash >> 16) XOR (hash >> 8) XOR hash)
796 modulo slave count
797 787
798 For fragmented TCP or UDP packets and all other IPv4 and 788 For fragmented TCP or UDP packets and all other IPv4 and
799 IPv6 protocol traffic, the source and destination port 789 IPv6 protocol traffic, the source and destination port
@@ -801,10 +791,6 @@ xmit_hash_policy
801 formula is the same as for the layer2 transmit hash 791 formula is the same as for the layer2 transmit hash
802 policy. 792 policy.
803 793
804 The IPv4 policy is intended to mimic the behavior of
805 certain switches, notably Cisco switches with PFC2 as
806 well as some Foundry and IBM products.
807
808 This algorithm is not fully 802.3ad compliant. A 794 This algorithm is not fully 802.3ad compliant. A
809 single TCP or UDP conversation containing both 795 single TCP or UDP conversation containing both
810 fragmented and unfragmented packets will see packets 796 fragmented and unfragmented packets will see packets
@@ -815,6 +801,26 @@ xmit_hash_policy
815 conversations. Other implementations of 802.3ad may 801 conversations. Other implementations of 802.3ad may
816 or may not tolerate this noncompliance. 802 or may not tolerate this noncompliance.
817 803
804 encap2+3
805
806 This policy uses the same formula as layer2+3 but it
807 relies on skb_flow_dissect to obtain the header fields
808 which might result in the use of inner headers if an
809 encapsulation protocol is used. For example this will
810 improve the performance for tunnel users because the
811 packets will be distributed according to the encapsulated
812 flows.
813
814 encap3+4
815
816 This policy uses the same formula as layer3+4 but it
817 relies on skb_flow_dissect to obtain the header fields
818 which might result in the use of inner headers if an
819 encapsulation protocol is used. For example this will
820 improve the performance for tunnel users because the
821 packets will be distributed according to the encapsulated
822 flows.
823
818 The default value is layer2. This option was added in bonding 824 The default value is layer2. This option was added in bonding
819 version 2.6.3. In earlier versions of bonding, this parameter 825 version 2.6.3. In earlier versions of bonding, this parameter
820 does not exist, and the layer2 policy is the only policy. The 826 does not exist, and the layer2 policy is the only policy. The
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index c62606a67f6a..ea3e64e22e22 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2403,7 +2403,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
2403 goto out; 2403 goto out;
2404 } 2404 }
2405 2405
2406 slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg); 2406 slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg);
2407 first_ok_slave = NULL; 2407 first_ok_slave = NULL;
2408 2408
2409 bond_for_each_slave(bond, slave, iter) { 2409 bond_for_each_slave(bond, slave, iter) {
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index fe8a94f9d7db..dfb4f6dd5de0 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -78,6 +78,7 @@
78#include <net/netns/generic.h> 78#include <net/netns/generic.h>
79#include <net/pkt_sched.h> 79#include <net/pkt_sched.h>
80#include <linux/rculist.h> 80#include <linux/rculist.h>
81#include <net/flow_keys.h>
81#include "bonding.h" 82#include "bonding.h"
82#include "bond_3ad.h" 83#include "bond_3ad.h"
83#include "bond_alb.h" 84#include "bond_alb.h"
@@ -159,7 +160,8 @@ MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on
159module_param(xmit_hash_policy, charp, 0); 160module_param(xmit_hash_policy, charp, 0);
160MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; " 161MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; "
161 "0 for layer 2 (default), 1 for layer 3+4, " 162 "0 for layer 2 (default), 1 for layer 3+4, "
162 "2 for layer 2+3"); 163 "2 for layer 2+3, 3 for encap layer 2+3, "
164 "4 for encap layer 3+4");
163module_param(arp_interval, int, 0); 165module_param(arp_interval, int, 0);
164MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); 166MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
165module_param_array(arp_ip_target, charp, NULL, 0); 167module_param_array(arp_ip_target, charp, NULL, 0);
@@ -217,6 +219,8 @@ const struct bond_parm_tbl xmit_hashtype_tbl[] = {
217{ "layer2", BOND_XMIT_POLICY_LAYER2}, 219{ "layer2", BOND_XMIT_POLICY_LAYER2},
218{ "layer3+4", BOND_XMIT_POLICY_LAYER34}, 220{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
219{ "layer2+3", BOND_XMIT_POLICY_LAYER23}, 221{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
222{ "encap2+3", BOND_XMIT_POLICY_ENCAP23},
223{ "encap3+4", BOND_XMIT_POLICY_ENCAP34},
220{ NULL, -1}, 224{ NULL, -1},
221}; 225};
222 226
@@ -3035,99 +3039,85 @@ static struct notifier_block bond_netdev_notifier = {
3035 3039
3036/*---------------------------- Hashing Policies -----------------------------*/ 3040/*---------------------------- Hashing Policies -----------------------------*/
3037 3041
3038/* 3042/* L2 hash helper */
3039 * Hash for the output device based upon layer 2 data 3043static inline u32 bond_eth_hash(struct sk_buff *skb)
3040 */
3041static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
3042{ 3044{
3043 struct ethhdr *data = (struct ethhdr *)skb->data; 3045 struct ethhdr *data = (struct ethhdr *)skb->data;
3044 3046
3045 if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto)) 3047 if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto))
3046 return (data->h_dest[5] ^ data->h_source[5]) % count; 3048 return data->h_dest[5] ^ data->h_source[5];
3047 3049
3048 return 0; 3050 return 0;
3049} 3051}
3050 3052
3051/* 3053/* Extract the appropriate headers based on bond's xmit policy */
3052 * Hash for the output device based upon layer 2 and layer 3 data. If 3054static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
3053 * the packet is not IP, fall back on bond_xmit_hash_policy_l2() 3055 struct flow_keys *fk)
3054 */
3055static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
3056{ 3056{
3057 const struct ethhdr *data; 3057 const struct ipv6hdr *iph6;
3058 const struct iphdr *iph; 3058 const struct iphdr *iph;
3059 const struct ipv6hdr *ipv6h; 3059 int noff, proto = -1;
3060 u32 v6hash;
3061 const __be32 *s, *d;
3062 3060
3063 if (skb->protocol == htons(ETH_P_IP) && 3061 if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23)
3064 pskb_network_may_pull(skb, sizeof(*iph))) { 3062 return skb_flow_dissect(skb, fk);
3063
3064 fk->ports = 0;
3065 noff = skb_network_offset(skb);
3066 if (skb->protocol == htons(ETH_P_IP)) {
3067 if (!pskb_may_pull(skb, noff + sizeof(*iph)))
3068 return false;
3065 iph = ip_hdr(skb); 3069 iph = ip_hdr(skb);
3066 data = (struct ethhdr *)skb->data; 3070 fk->src = iph->saddr;
3067 return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ 3071 fk->dst = iph->daddr;
3068 (data->h_dest[5] ^ data->h_source[5])) % count; 3072 noff += iph->ihl << 2;
3069 } else if (skb->protocol == htons(ETH_P_IPV6) && 3073 if (!ip_is_fragment(iph))
3070 pskb_network_may_pull(skb, sizeof(*ipv6h))) { 3074 proto = iph->protocol;
3071 ipv6h = ipv6_hdr(skb); 3075 } else if (skb->protocol == htons(ETH_P_IPV6)) {
3072 data = (struct ethhdr *)skb->data; 3076 if (!pskb_may_pull(skb, noff + sizeof(*iph6)))
3073 s = &ipv6h->saddr.s6_addr32[0]; 3077 return false;
3074 d = &ipv6h->daddr.s6_addr32[0]; 3078 iph6 = ipv6_hdr(skb);
3075 v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); 3079 fk->src = (__force __be32)ipv6_addr_hash(&iph6->saddr);
3076 v6hash ^= (v6hash >> 24) ^ (v6hash >> 16) ^ (v6hash >> 8); 3080 fk->dst = (__force __be32)ipv6_addr_hash(&iph6->daddr);
3077 return (v6hash ^ data->h_dest[5] ^ data->h_source[5]) % count; 3081 noff += sizeof(*iph6);
3078 } 3082 proto = iph6->nexthdr;
3079 3083 } else {
3080 return bond_xmit_hash_policy_l2(skb, count); 3084 return false;
3085 }
3086 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34 && proto >= 0)
3087 fk->ports = skb_flow_get_ports(skb, noff, proto);
3088
3089 return true;
3081} 3090}
3082 3091
3083/* 3092/**
3084 * Hash for the output device based upon layer 3 and layer 4 data. If 3093 * bond_xmit_hash - generate a hash value based on the xmit policy
3085 * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is 3094 * @bond: bonding device
3086 * altogether not IP, fall back on bond_xmit_hash_policy_l2() 3095 * @skb: buffer to use for headers
3096 * @count: modulo value
3097 *
3098 * This function will extract the necessary headers from the skb buffer and use
3099 * them to generate a hash based on the xmit_policy set in the bonding device
3100 * which will be reduced modulo count before returning.
3087 */ 3101 */
3088static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) 3102int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count)
3089{ 3103{
3090 u32 layer4_xor = 0; 3104 struct flow_keys flow;
3091 const struct iphdr *iph; 3105 u32 hash;
3092 const struct ipv6hdr *ipv6h;
3093 const __be32 *s, *d;
3094 const __be16 *l4 = NULL;
3095 __be16 _l4[2];
3096 int noff = skb_network_offset(skb);
3097 int poff;
3098
3099 if (skb->protocol == htons(ETH_P_IP) &&
3100 pskb_may_pull(skb, noff + sizeof(*iph))) {
3101 iph = ip_hdr(skb);
3102 poff = proto_ports_offset(iph->protocol);
3103 3106
3104 if (!ip_is_fragment(iph) && poff >= 0) { 3107 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 ||
3105 l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff, 3108 !bond_flow_dissect(bond, skb, &flow))
3106 sizeof(_l4), &_l4); 3109 return bond_eth_hash(skb) % count;
3107 if (l4) 3110
3108 layer4_xor = ntohs(l4[0] ^ l4[1]); 3111 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23 ||
3109 } 3112 bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP23)
3110 return (layer4_xor ^ 3113 hash = bond_eth_hash(skb);
3111 ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; 3114 else
3112 } else if (skb->protocol == htons(ETH_P_IPV6) && 3115 hash = (__force u32)flow.ports;
3113 pskb_may_pull(skb, noff + sizeof(*ipv6h))) { 3116 hash ^= (__force u32)flow.dst ^ (__force u32)flow.src;
3114 ipv6h = ipv6_hdr(skb); 3117 hash ^= (hash >> 16);
3115 poff = proto_ports_offset(ipv6h->nexthdr); 3118 hash ^= (hash >> 8);
3116 if (poff >= 0) {
3117 l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff,
3118 sizeof(_l4), &_l4);
3119 if (l4)
3120 layer4_xor = ntohs(l4[0] ^ l4[1]);
3121 }
3122 s = &ipv6h->saddr.s6_addr32[0];
3123 d = &ipv6h->daddr.s6_addr32[0];
3124 layer4_xor ^= (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]);
3125 layer4_xor ^= (layer4_xor >> 24) ^ (layer4_xor >> 16) ^
3126 (layer4_xor >> 8);
3127 return layer4_xor % count;
3128 }
3129 3119
3130 return bond_xmit_hash_policy_l2(skb, count); 3120 return hash % count;
3131} 3121}
3132 3122
3133/*-------------------------- Device entry points ----------------------------*/ 3123/*-------------------------- Device entry points ----------------------------*/
@@ -3721,8 +3711,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
3721 return NETDEV_TX_OK; 3711 return NETDEV_TX_OK;
3722} 3712}
3723 3713
3724/* 3714/* In bond_xmit_xor() , we determine the output device by using a pre-
3725 * In bond_xmit_xor() , we determine the output device by using a pre-
3726 * determined xmit_hash_policy(), If the selected device is not enabled, 3715 * determined xmit_hash_policy(), If the selected device is not enabled,
3727 * find the next active slave. 3716 * find the next active slave.
3728 */ 3717 */
@@ -3730,8 +3719,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
3730{ 3719{
3731 struct bonding *bond = netdev_priv(bond_dev); 3720 struct bonding *bond = netdev_priv(bond_dev);
3732 3721
3733 bond_xmit_slave_id(bond, skb, 3722 bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb, bond->slave_cnt));
3734 bond->xmit_hash_policy(skb, bond->slave_cnt));
3735 3723
3736 return NETDEV_TX_OK; 3724 return NETDEV_TX_OK;
3737} 3725}
@@ -3768,22 +3756,6 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
3768 3756
3769/*------------------------- Device initialization ---------------------------*/ 3757/*------------------------- Device initialization ---------------------------*/
3770 3758
3771static void bond_set_xmit_hash_policy(struct bonding *bond)
3772{
3773 switch (bond->params.xmit_policy) {
3774 case BOND_XMIT_POLICY_LAYER23:
3775 bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
3776 break;
3777 case BOND_XMIT_POLICY_LAYER34:
3778 bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
3779 break;
3780 case BOND_XMIT_POLICY_LAYER2:
3781 default:
3782 bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
3783 break;
3784 }
3785}
3786
3787/* 3759/*
3788 * Lookup the slave that corresponds to a qid 3760 * Lookup the slave that corresponds to a qid
3789 */ 3761 */
@@ -3894,38 +3866,6 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
3894 return ret; 3866 return ret;
3895} 3867}
3896 3868
3897/*
3898 * set bond mode specific net device operations
3899 */
3900void bond_set_mode_ops(struct bonding *bond, int mode)
3901{
3902 struct net_device *bond_dev = bond->dev;
3903
3904 switch (mode) {
3905 case BOND_MODE_ROUNDROBIN:
3906 break;
3907 case BOND_MODE_ACTIVEBACKUP:
3908 break;
3909 case BOND_MODE_XOR:
3910 bond_set_xmit_hash_policy(bond);
3911 break;
3912 case BOND_MODE_BROADCAST:
3913 break;
3914 case BOND_MODE_8023AD:
3915 bond_set_xmit_hash_policy(bond);
3916 break;
3917 case BOND_MODE_ALB:
3918 /* FALLTHRU */
3919 case BOND_MODE_TLB:
3920 break;
3921 default:
3922 /* Should never happen, mode already checked */
3923 pr_err("%s: Error: Unknown bonding mode %d\n",
3924 bond_dev->name, mode);
3925 break;
3926 }
3927}
3928
3929static int bond_ethtool_get_settings(struct net_device *bond_dev, 3869static int bond_ethtool_get_settings(struct net_device *bond_dev,
3930 struct ethtool_cmd *ecmd) 3870 struct ethtool_cmd *ecmd)
3931{ 3871{
@@ -4027,7 +3967,6 @@ static void bond_setup(struct net_device *bond_dev)
4027 ether_setup(bond_dev); 3967 ether_setup(bond_dev);
4028 bond_dev->netdev_ops = &bond_netdev_ops; 3968 bond_dev->netdev_ops = &bond_netdev_ops;
4029 bond_dev->ethtool_ops = &bond_ethtool_ops; 3969 bond_dev->ethtool_ops = &bond_ethtool_ops;
4030 bond_set_mode_ops(bond, bond->params.mode);
4031 3970
4032 bond_dev->destructor = bond_destructor; 3971 bond_dev->destructor = bond_destructor;
4033 3972
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index e06c644470b1..e9249527e7e7 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -318,7 +318,6 @@ static ssize_t bonding_store_mode(struct device *d,
318 /* don't cache arp_validate between modes */ 318 /* don't cache arp_validate between modes */
319 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; 319 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
320 bond->params.mode = new_value; 320 bond->params.mode = new_value;
321 bond_set_mode_ops(bond, bond->params.mode);
322 pr_info("%s: setting mode to %s (%d).\n", 321 pr_info("%s: setting mode to %s (%d).\n",
323 bond->dev->name, bond_mode_tbl[new_value].modename, 322 bond->dev->name, bond_mode_tbl[new_value].modename,
324 new_value); 323 new_value);
@@ -358,7 +357,6 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
358 ret = -EINVAL; 357 ret = -EINVAL;
359 } else { 358 } else {
360 bond->params.xmit_policy = new_value; 359 bond->params.xmit_policy = new_value;
361 bond_set_mode_ops(bond, bond->params.mode);
362 pr_info("%s: setting xmit hash policy to %s (%d).\n", 360 pr_info("%s: setting xmit hash policy to %s (%d).\n",
363 bond->dev->name, 361 bond->dev->name,
364 xmit_hashtype_tbl[new_value].modename, new_value); 362 xmit_hashtype_tbl[new_value].modename, new_value);
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 9a26fbd82645..0bd04fbda8e9 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -217,7 +217,6 @@ struct bonding {
217 char proc_file_name[IFNAMSIZ]; 217 char proc_file_name[IFNAMSIZ];
218#endif /* CONFIG_PROC_FS */ 218#endif /* CONFIG_PROC_FS */
219 struct list_head bond_list; 219 struct list_head bond_list;
220 int (*xmit_hash_policy)(struct sk_buff *, int);
221 u16 rr_tx_counter; 220 u16 rr_tx_counter;
222 struct ad_bond_info ad_info; 221 struct ad_bond_info ad_info;
223 struct alb_bond_info alb_info; 222 struct alb_bond_info alb_info;
@@ -409,7 +408,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
409void bond_mii_monitor(struct work_struct *); 408void bond_mii_monitor(struct work_struct *);
410void bond_loadbalance_arp_mon(struct work_struct *); 409void bond_loadbalance_arp_mon(struct work_struct *);
411void bond_activebackup_arp_mon(struct work_struct *); 410void bond_activebackup_arp_mon(struct work_struct *);
412void bond_set_mode_ops(struct bonding *bond, int mode); 411int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count);
413int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl); 412int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl);
414void bond_select_active_slave(struct bonding *bond); 413void bond_select_active_slave(struct bonding *bond);
415void bond_change_active_slave(struct bonding *bond, struct slave *new_active); 414void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
diff --git a/include/net/flow_keys.h b/include/net/flow_keys.h
index ac2439d02f54..7e64bd8bbda9 100644
--- a/include/net/flow_keys.h
+++ b/include/net/flow_keys.h
@@ -14,4 +14,5 @@ struct flow_keys {
14}; 14};
15 15
16bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow); 16bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
17__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto);
17#endif 18#endif
diff --git a/include/uapi/linux/if_bonding.h b/include/uapi/linux/if_bonding.h
index a17edda8a781..9635a62f6f89 100644
--- a/include/uapi/linux/if_bonding.h
+++ b/include/uapi/linux/if_bonding.h
@@ -91,6 +91,8 @@
91#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ 91#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
92#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ 92#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
93#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */ 93#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */
94#define BOND_XMIT_POLICY_ENCAP23 3 /* encapsulated layer 2+3 */
95#define BOND_XMIT_POLICY_ENCAP34 4 /* encapsulated layer 3+4 */
94 96
95typedef struct ifbond { 97typedef struct ifbond {
96 __s32 bond_mode; 98 __s32 bond_mode;
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 8d7d0dd72db2..f8e25ac41c6c 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -25,9 +25,35 @@ static void iph_to_flow_copy_addrs(struct flow_keys *flow, const struct iphdr *i
25 memcpy(&flow->src, &iph->saddr, sizeof(flow->src) + sizeof(flow->dst)); 25 memcpy(&flow->src, &iph->saddr, sizeof(flow->src) + sizeof(flow->dst));
26} 26}
27 27
28/**
29 * skb_flow_get_ports - extract the upper layer ports and return them
30 * @skb: buffer to extract the ports from
31 * @thoff: transport header offset
32 * @ip_proto: protocol for which to get port offset
33 *
34 * The function will try to retrieve the ports at offset thoff + poff where poff
35 * is the protocol port offset returned from proto_ports_offset
36 */
37__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto)
38{
39 int poff = proto_ports_offset(ip_proto);
40
41 if (poff >= 0) {
42 __be32 *ports, _ports;
43
44 ports = skb_header_pointer(skb, thoff + poff,
45 sizeof(_ports), &_ports);
46 if (ports)
47 return *ports;
48 }
49
50 return 0;
51}
52EXPORT_SYMBOL(skb_flow_get_ports);
53
28bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow) 54bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow)
29{ 55{
30 int poff, nhoff = skb_network_offset(skb); 56 int nhoff = skb_network_offset(skb);
31 u8 ip_proto; 57 u8 ip_proto;
32 __be16 proto = skb->protocol; 58 __be16 proto = skb->protocol;
33 59
@@ -150,16 +176,7 @@ ipv6:
150 } 176 }
151 177
152 flow->ip_proto = ip_proto; 178 flow->ip_proto = ip_proto;
153 poff = proto_ports_offset(ip_proto); 179 flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto);
154 if (poff >= 0) {
155 __be32 *ports, _ports;
156
157 ports = skb_header_pointer(skb, nhoff + poff,
158 sizeof(_ports), &_ports);
159 if (ports)
160 flow->ports = *ports;
161 }
162
163 flow->thoff = (u16) nhoff; 180 flow->thoff = (u16) nhoff;
164 181
165 return true; 182 return true;