diff options
-rw-r--r-- | net/core/dev.c | 73 |
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 | ||
1711 | static u32 simple_tx_hashrnd; | 1711 | static u32 skb_tx_hashrnd; |
1712 | static int simple_tx_hashrnd_initialized = 0; | 1712 | static int skb_tx_hashrnd_initialized = 0; |
1713 | 1713 | ||
1714 | static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) | 1714 | static 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 | ||
1776 | out: | ||
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); |