diff options
| -rw-r--r-- | net/core/dev.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 7f5755b0a57c..0d78e0454a6d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1974,7 +1974,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) | |||
| 1974 | if (skb->sk && skb->sk->sk_hash) | 1974 | if (skb->sk && skb->sk->sk_hash) |
| 1975 | hash = skb->sk->sk_hash; | 1975 | hash = skb->sk->sk_hash; |
| 1976 | else | 1976 | else |
| 1977 | hash = skb->protocol; | 1977 | hash = (__force u16) skb->protocol; |
| 1978 | 1978 | ||
| 1979 | hash = jhash_1word(hash, hashrnd); | 1979 | hash = jhash_1word(hash, hashrnd); |
| 1980 | 1980 | ||
| @@ -2253,8 +2253,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
| 2253 | 2253 | ||
| 2254 | ip = (struct iphdr *) skb->data; | 2254 | ip = (struct iphdr *) skb->data; |
| 2255 | ip_proto = ip->protocol; | 2255 | ip_proto = ip->protocol; |
| 2256 | addr1 = ip->saddr; | 2256 | addr1 = (__force u32) ip->saddr; |
| 2257 | addr2 = ip->daddr; | 2257 | addr2 = (__force u32) ip->daddr; |
| 2258 | ihl = ip->ihl; | 2258 | ihl = ip->ihl; |
| 2259 | break; | 2259 | break; |
| 2260 | case __constant_htons(ETH_P_IPV6): | 2260 | case __constant_htons(ETH_P_IPV6): |
| @@ -2263,8 +2263,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
| 2263 | 2263 | ||
| 2264 | ip6 = (struct ipv6hdr *) skb->data; | 2264 | ip6 = (struct ipv6hdr *) skb->data; |
| 2265 | ip_proto = ip6->nexthdr; | 2265 | ip_proto = ip6->nexthdr; |
| 2266 | addr1 = ip6->saddr.s6_addr32[3]; | 2266 | addr1 = (__force u32) ip6->saddr.s6_addr32[3]; |
| 2267 | addr2 = ip6->daddr.s6_addr32[3]; | 2267 | addr2 = (__force u32) ip6->daddr.s6_addr32[3]; |
| 2268 | ihl = (40 >> 2); | 2268 | ihl = (40 >> 2); |
| 2269 | break; | 2269 | break; |
| 2270 | default: | 2270 | default: |
| @@ -2279,14 +2279,25 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
| 2279 | case IPPROTO_AH: | 2279 | case IPPROTO_AH: |
| 2280 | case IPPROTO_SCTP: | 2280 | case IPPROTO_SCTP: |
| 2281 | case IPPROTO_UDPLITE: | 2281 | case IPPROTO_UDPLITE: |
| 2282 | if (pskb_may_pull(skb, (ihl * 4) + 4)) | 2282 | if (pskb_may_pull(skb, (ihl * 4) + 4)) { |
| 2283 | ports = *((u32 *) (skb->data + (ihl * 4))); | 2283 | __be16 *hports = (__be16 *) (skb->data + (ihl * 4)); |
| 2284 | u32 sport, dport; | ||
| 2285 | |||
| 2286 | sport = (__force u16) hports[0]; | ||
| 2287 | dport = (__force u16) hports[1]; | ||
| 2288 | if (dport < sport) | ||
| 2289 | swap(sport, dport); | ||
| 2290 | ports = (sport << 16) + dport; | ||
| 2291 | } | ||
| 2284 | break; | 2292 | break; |
| 2285 | 2293 | ||
| 2286 | default: | 2294 | default: |
| 2287 | break; | 2295 | break; |
| 2288 | } | 2296 | } |
| 2289 | 2297 | ||
| 2298 | /* get a consistent hash (same value on both flow directions) */ | ||
| 2299 | if (addr2 < addr1) | ||
| 2300 | swap(addr1, addr2); | ||
| 2290 | skb->rxhash = jhash_3words(addr1, addr2, ports, hashrnd); | 2301 | skb->rxhash = jhash_3words(addr1, addr2, ports, hashrnd); |
| 2291 | if (!skb->rxhash) | 2302 | if (!skb->rxhash) |
| 2292 | skb->rxhash = 1; | 2303 | skb->rxhash = 1; |
