aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/skbuff.h5
-rw-r--r--include/net/dst.h9
-rw-r--r--include/net/sock.h15
-rw-r--r--net/core/dev.c10
-rw-r--r--net/core/skbuff.c1
-rw-r--r--net/ipv4/tcp_ipv4.c6
-rw-r--r--net/ipv4/udp.c4
-rw-r--r--net/ipv6/tcp_ipv6.c6
-rw-r--r--net/ipv6/udp.c2
9 files changed, 39 insertions, 19 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7b996ed86d5b..f902c331217b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -414,6 +414,7 @@ struct sk_buff {
414 __u8 ndisc_nodetype:2; 414 __u8 ndisc_nodetype:2;
415#endif 415#endif
416 __u8 ooo_okay:1; 416 __u8 ooo_okay:1;
417 __u8 l4_rxhash:1;
417 kmemcheck_bitfield_end(flags2); 418 kmemcheck_bitfield_end(flags2);
418 419
419 /* 0/13 bit hole */ 420 /* 0/13 bit hole */
@@ -572,11 +573,11 @@ extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
572 unsigned int to, struct ts_config *config, 573 unsigned int to, struct ts_config *config,
573 struct ts_state *state); 574 struct ts_state *state);
574 575
575extern __u32 __skb_get_rxhash(struct sk_buff *skb); 576extern void __skb_get_rxhash(struct sk_buff *skb);
576static inline __u32 skb_get_rxhash(struct sk_buff *skb) 577static inline __u32 skb_get_rxhash(struct sk_buff *skb)
577{ 578{
578 if (!skb->rxhash) 579 if (!skb->rxhash)
579 skb->rxhash = __skb_get_rxhash(skb); 580 __skb_get_rxhash(skb);
580 581
581 return skb->rxhash; 582 return skb->rxhash;
582} 583}
diff --git a/include/net/dst.h b/include/net/dst.h
index 13d507d69ddb..4fb6c4381791 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -325,7 +325,14 @@ static inline void skb_dst_force(struct sk_buff *skb)
325static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) 325static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
326{ 326{
327 skb->dev = dev; 327 skb->dev = dev;
328 skb->rxhash = 0; 328
329 /*
330 * Clear rxhash so that we can recalulate the hash for the
331 * encapsulated packet, unless we have already determine the hash
332 * over the L4 4-tuple.
333 */
334 if (!skb->l4_rxhash)
335 skb->rxhash = 0;
329 skb_set_queue_mapping(skb, 0); 336 skb_set_queue_mapping(skb, 0);
330 skb_dst_drop(skb); 337 skb_dst_drop(skb);
331 nf_reset(skb); 338 nf_reset(skb);
diff --git a/include/net/sock.h b/include/net/sock.h
index 8e4062f165b8..5ac682f73d63 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -686,16 +686,25 @@ static inline void sock_rps_reset_flow(const struct sock *sk)
686#endif 686#endif
687} 687}
688 688
689static inline void sock_rps_save_rxhash(struct sock *sk, u32 rxhash) 689static inline void sock_rps_save_rxhash(struct sock *sk,
690 const struct sk_buff *skb)
690{ 691{
691#ifdef CONFIG_RPS 692#ifdef CONFIG_RPS
692 if (unlikely(sk->sk_rxhash != rxhash)) { 693 if (unlikely(sk->sk_rxhash != skb->rxhash)) {
693 sock_rps_reset_flow(sk); 694 sock_rps_reset_flow(sk);
694 sk->sk_rxhash = rxhash; 695 sk->sk_rxhash = skb->rxhash;
695 } 696 }
696#endif 697#endif
697} 698}
698 699
700static inline void sock_rps_reset_rxhash(struct sock *sk)
701{
702#ifdef CONFIG_RPS
703 sock_rps_reset_flow(sk);
704 sk->sk_rxhash = 0;
705#endif
706}
707
699#define sk_wait_event(__sk, __timeo, __condition) \ 708#define sk_wait_event(__sk, __timeo, __condition) \
700 ({ int __rc; \ 709 ({ int __rc; \
701 release_sock(__sk); \ 710 release_sock(__sk); \
diff --git a/net/core/dev.c b/net/core/dev.c
index 6578d9483043..e485cb37228f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2519,10 +2519,11 @@ static inline void ____napi_schedule(struct softnet_data *sd,
2519 2519
2520/* 2520/*
2521 * __skb_get_rxhash: calculate a flow hash based on src/dst addresses 2521 * __skb_get_rxhash: calculate a flow hash based on src/dst addresses
2522 * and src/dst port numbers. Returns a non-zero hash number on success 2522 * and src/dst port numbers. Sets rxhash in skb to non-zero hash value
2523 * and 0 on failure. 2523 * on success, zero indicates no valid hash. Also, sets l4_rxhash in skb
2524 * if hash is a canonical 4-tuple hash over transport ports.
2524 */ 2525 */
2525__u32 __skb_get_rxhash(struct sk_buff *skb) 2526void __skb_get_rxhash(struct sk_buff *skb)
2526{ 2527{
2527 int nhoff, hash = 0, poff; 2528 int nhoff, hash = 0, poff;
2528 const struct ipv6hdr *ip6; 2529 const struct ipv6hdr *ip6;
@@ -2574,6 +2575,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
2574 ports.v32 = * (__force u32 *) (skb->data + nhoff); 2575 ports.v32 = * (__force u32 *) (skb->data + nhoff);
2575 if (ports.v16[1] < ports.v16[0]) 2576 if (ports.v16[1] < ports.v16[0])
2576 swap(ports.v16[0], ports.v16[1]); 2577 swap(ports.v16[0], ports.v16[1]);
2578 skb->l4_rxhash = 1;
2577 } 2579 }
2578 } 2580 }
2579 2581
@@ -2586,7 +2588,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
2586 hash = 1; 2588 hash = 1;
2587 2589
2588done: 2590done:
2589 return hash; 2591 skb->rxhash = hash;
2590} 2592}
2591EXPORT_SYMBOL(__skb_get_rxhash); 2593EXPORT_SYMBOL(__skb_get_rxhash);
2592 2594
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 27002dffe7ed..edb66f3e24f1 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -529,6 +529,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
529 new->mac_header = old->mac_header; 529 new->mac_header = old->mac_header;
530 skb_dst_copy(new, old); 530 skb_dst_copy(new, old);
531 new->rxhash = old->rxhash; 531 new->rxhash = old->rxhash;
532 new->l4_rxhash = old->l4_rxhash;
532#ifdef CONFIG_XFRM 533#ifdef CONFIG_XFRM
533 new->sp = secpath_get(old->sp); 534 new->sp = secpath_get(old->sp);
534#endif 535#endif
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 1c12b8ec849d..b3f26114b03e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1578,7 +1578,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1578#endif 1578#endif
1579 1579
1580 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1580 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
1581 sock_rps_save_rxhash(sk, skb->rxhash); 1581 sock_rps_save_rxhash(sk, skb);
1582 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { 1582 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
1583 rsk = sk; 1583 rsk = sk;
1584 goto reset; 1584 goto reset;
@@ -1595,7 +1595,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1595 goto discard; 1595 goto discard;
1596 1596
1597 if (nsk != sk) { 1597 if (nsk != sk) {
1598 sock_rps_save_rxhash(nsk, skb->rxhash); 1598 sock_rps_save_rxhash(nsk, skb);
1599 if (tcp_child_process(sk, nsk, skb)) { 1599 if (tcp_child_process(sk, nsk, skb)) {
1600 rsk = nsk; 1600 rsk = nsk;
1601 goto reset; 1601 goto reset;
@@ -1603,7 +1603,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1603 return 0; 1603 return 0;
1604 } 1604 }
1605 } else 1605 } else
1606 sock_rps_save_rxhash(sk, skb->rxhash); 1606 sock_rps_save_rxhash(sk, skb);
1607 1607
1608 if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) { 1608 if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
1609 rsk = sk; 1609 rsk = sk;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c1d5facab7c9..ebaa96bd3464 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1267,7 +1267,7 @@ int udp_disconnect(struct sock *sk, int flags)
1267 sk->sk_state = TCP_CLOSE; 1267 sk->sk_state = TCP_CLOSE;
1268 inet->inet_daddr = 0; 1268 inet->inet_daddr = 0;
1269 inet->inet_dport = 0; 1269 inet->inet_dport = 0;
1270 sock_rps_save_rxhash(sk, 0); 1270 sock_rps_reset_rxhash(sk);
1271 sk->sk_bound_dev_if = 0; 1271 sk->sk_bound_dev_if = 0;
1272 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) 1272 if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
1273 inet_reset_saddr(sk); 1273 inet_reset_saddr(sk);
@@ -1355,7 +1355,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1355 int rc; 1355 int rc;
1356 1356
1357 if (inet_sk(sk)->inet_daddr) 1357 if (inet_sk(sk)->inet_daddr)
1358 sock_rps_save_rxhash(sk, skb->rxhash); 1358 sock_rps_save_rxhash(sk, skb);
1359 1359
1360 rc = ip_queue_rcv_skb(sk, skb); 1360 rc = ip_queue_rcv_skb(sk, skb);
1361 if (rc < 0) { 1361 if (rc < 0) {
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index d1fb63f4aeb7..44a5859535b5 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1628,7 +1628,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1628 opt_skb = skb_clone(skb, GFP_ATOMIC); 1628 opt_skb = skb_clone(skb, GFP_ATOMIC);
1629 1629
1630 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1630 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
1631 sock_rps_save_rxhash(sk, skb->rxhash); 1631 sock_rps_save_rxhash(sk, skb);
1632 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) 1632 if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
1633 goto reset; 1633 goto reset;
1634 if (opt_skb) 1634 if (opt_skb)
@@ -1650,7 +1650,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1650 * the new socket.. 1650 * the new socket..
1651 */ 1651 */
1652 if(nsk != sk) { 1652 if(nsk != sk) {
1653 sock_rps_save_rxhash(nsk, skb->rxhash); 1653 sock_rps_save_rxhash(nsk, skb);
1654 if (tcp_child_process(sk, nsk, skb)) 1654 if (tcp_child_process(sk, nsk, skb))
1655 goto reset; 1655 goto reset;
1656 if (opt_skb) 1656 if (opt_skb)
@@ -1658,7 +1658,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1658 return 0; 1658 return 0;
1659 } 1659 }
1660 } else 1660 } else
1661 sock_rps_save_rxhash(sk, skb->rxhash); 1661 sock_rps_save_rxhash(sk, skb);
1662 1662
1663 if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) 1663 if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len))
1664 goto reset; 1664 goto reset;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 97e47f06e8b7..35bbdc42241e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -509,7 +509,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
509 int is_udplite = IS_UDPLITE(sk); 509 int is_udplite = IS_UDPLITE(sk);
510 510
511 if (!ipv6_addr_any(&inet6_sk(sk)->daddr)) 511 if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
512 sock_rps_save_rxhash(sk, skb->rxhash); 512 sock_rps_save_rxhash(sk, skb);
513 513
514 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 514 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
515 goto drop; 515 goto drop;