aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/dev.c73
1 files changed, 14 insertions, 59 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index cb8caa93caca..e61b95c11fc0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1708,72 +1708,27 @@ out_kfree_skb:
1708 return 0; 1708 return 0;
1709} 1709}
1710 1710
1711static u32 simple_tx_hashrnd; 1711static u32 skb_tx_hashrnd;
1712static int simple_tx_hashrnd_initialized = 0; 1712static int skb_tx_hashrnd_initialized = 0;
1713 1713
1714static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) 1714static u16 skb_tx_hash(struct net_device *dev, struct sk_buff *skb)
1715{ 1715{
1716 u32 addr1, addr2, ports; 1716 u32 hash;
1717 u32 hash, ihl;
1718 u8 ip_proto = 0;
1719 1717
1720 if (unlikely(!simple_tx_hashrnd_initialized)) { 1718 if (unlikely(!skb_tx_hashrnd_initialized)) {
1721 get_random_bytes(&simple_tx_hashrnd, 4); 1719 get_random_bytes(&skb_tx_hashrnd, 4);
1722 simple_tx_hashrnd_initialized = 1; 1720 skb_tx_hashrnd_initialized = 1;
1723 } 1721 }
1724 1722
1725 if (skb_rx_queue_recorded(skb)) { 1723 if (skb_rx_queue_recorded(skb)) {
1726 u32 val = skb_get_rx_queue(skb); 1724 hash = skb_get_rx_queue(skb);
1727 1725 } else if (skb->sk && skb->sk->sk_hash) {
1728 hash = jhash_1word(val, simple_tx_hashrnd); 1726 hash = skb->sk->sk_hash;
1729 goto out; 1727 } else
1730 } 1728 hash = skb->protocol;
1731
1732 if (skb->sk && skb->sk->sk_hash) {
1733 u32 val = skb->sk->sk_hash;
1734
1735 hash = jhash_1word(val, simple_tx_hashrnd);
1736 goto out;
1737 }
1738
1739 switch (skb->protocol) {
1740 case htons(ETH_P_IP):
1741 if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
1742 ip_proto = ip_hdr(skb)->protocol;
1743 addr1 = ip_hdr(skb)->saddr;
1744 addr2 = ip_hdr(skb)->daddr;
1745 ihl = ip_hdr(skb)->ihl;
1746 break;
1747 case htons(ETH_P_IPV6):
1748 ip_proto = ipv6_hdr(skb)->nexthdr;
1749 addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
1750 addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
1751 ihl = (40 >> 2);
1752 break;
1753 default:
1754 return 0;
1755 }
1756
1757
1758 switch (ip_proto) {
1759 case IPPROTO_TCP:
1760 case IPPROTO_UDP:
1761 case IPPROTO_DCCP:
1762 case IPPROTO_ESP:
1763 case IPPROTO_AH:
1764 case IPPROTO_SCTP:
1765 case IPPROTO_UDPLITE:
1766 ports = *((u32 *) (skb_network_header(skb) + (ihl * 4)));
1767 break;
1768
1769 default:
1770 ports = 0;
1771 break;
1772 }
1773 1729
1774 hash = jhash_3words(addr1, addr2, ports, simple_tx_hashrnd); 1730 hash = jhash_1word(hash, skb_tx_hashrnd);
1775 1731
1776out:
1777 return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32); 1732 return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
1778} 1733}
1779 1734
@@ -1786,7 +1741,7 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
1786 if (ops->ndo_select_queue) 1741 if (ops->ndo_select_queue)
1787 queue_index = ops->ndo_select_queue(dev, skb); 1742 queue_index = ops->ndo_select_queue(dev, skb);
1788 else if (dev->real_num_tx_queues > 1) 1743 else if (dev->real_num_tx_queues > 1)
1789 queue_index = simple_tx_hash(dev, skb); 1744 queue_index = skb_tx_hash(dev, skb);
1790 1745
1791 skb_set_queue_mapping(skb, queue_index); 1746 skb_set_queue_mapping(skb, queue_index);
1792 return netdev_get_tx_queue(dev, queue_index); 1747 return netdev_get_tx_queue(dev, queue_index);