|
@@ -1708,72 +1708,27 @@ out_kfree_skb:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static u32 simple_tx_hashrnd;
|
|
|
-static int simple_tx_hashrnd_initialized = 0;
|
|
|
+static u32 skb_tx_hashrnd;
|
|
|
+static int skb_tx_hashrnd_initialized = 0;
|
|
|
|
|
|
-static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
|
|
|
+static u16 skb_tx_hash(struct net_device *dev, struct sk_buff *skb)
|
|
|
{
|
|
|
- u32 addr1, addr2, ports;
|
|
|
- u32 hash, ihl;
|
|
|
- u8 ip_proto = 0;
|
|
|
+ u32 hash;
|
|
|
|
|
|
- if (unlikely(!simple_tx_hashrnd_initialized)) {
|
|
|
- get_random_bytes(&simple_tx_hashrnd, 4);
|
|
|
- simple_tx_hashrnd_initialized = 1;
|
|
|
+ if (unlikely(!skb_tx_hashrnd_initialized)) {
|
|
|
+ get_random_bytes(&skb_tx_hashrnd, 4);
|
|
|
+ skb_tx_hashrnd_initialized = 1;
|
|
|
}
|
|
|
|
|
|
if (skb_rx_queue_recorded(skb)) {
|
|
|
- u32 val = skb_get_rx_queue(skb);
|
|
|
-
|
|
|
- hash = jhash_1word(val, simple_tx_hashrnd);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- if (skb->sk && skb->sk->sk_hash) {
|
|
|
- u32 val = skb->sk->sk_hash;
|
|
|
-
|
|
|
- hash = jhash_1word(val, simple_tx_hashrnd);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- switch (skb->protocol) {
|
|
|
- case htons(ETH_P_IP):
|
|
|
- if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
|
|
|
- ip_proto = ip_hdr(skb)->protocol;
|
|
|
- addr1 = ip_hdr(skb)->saddr;
|
|
|
- addr2 = ip_hdr(skb)->daddr;
|
|
|
- ihl = ip_hdr(skb)->ihl;
|
|
|
- break;
|
|
|
- case htons(ETH_P_IPV6):
|
|
|
- ip_proto = ipv6_hdr(skb)->nexthdr;
|
|
|
- addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
|
|
|
- addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
|
|
|
- ihl = (40 >> 2);
|
|
|
- break;
|
|
|
- default:
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- switch (ip_proto) {
|
|
|
- case IPPROTO_TCP:
|
|
|
- case IPPROTO_UDP:
|
|
|
- case IPPROTO_DCCP:
|
|
|
- case IPPROTO_ESP:
|
|
|
- case IPPROTO_AH:
|
|
|
- case IPPROTO_SCTP:
|
|
|
- case IPPROTO_UDPLITE:
|
|
|
- ports = *((u32 *) (skb_network_header(skb) + (ihl * 4)));
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- ports = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
+ hash = skb_get_rx_queue(skb);
|
|
|
+ } else if (skb->sk && skb->sk->sk_hash) {
|
|
|
+ hash = skb->sk->sk_hash;
|
|
|
+ } else
|
|
|
+ hash = skb->protocol;
|
|
|
|
|
|
- hash = jhash_3words(addr1, addr2, ports, simple_tx_hashrnd);
|
|
|
+ hash = jhash_1word(hash, skb_tx_hashrnd);
|
|
|
|
|
|
-out:
|
|
|
return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
|
|
|
}
|
|
|
|
|
@@ -1786,7 +1741,7 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
|
|
|
if (ops->ndo_select_queue)
|
|
|
queue_index = ops->ndo_select_queue(dev, skb);
|
|
|
else if (dev->real_num_tx_queues > 1)
|
|
|
- queue_index = simple_tx_hash(dev, skb);
|
|
|
+ queue_index = skb_tx_hash(dev, skb);
|
|
|
|
|
|
skb_set_queue_mapping(skb, queue_index);
|
|
|
return netdev_get_tx_queue(dev, queue_index);
|