Skip to contentSkip to conversation

Patch "udp6: set rx_dst_cookie on rx_dst updates" has been added to the 4.12-stable tree

PATCH [email protected] 1 participant 1 message Sep 15, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

udp6: set rx_dst_cookie on rx_dst updates

to the 4.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
udp6-set-rx_dst_cookie-on-rx_dst-updates.patch
and it can be found in the queue-4.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Thu Sep 14 23:20:23 PDT 2017

From: Paolo Abeni <[email protected]>
Date: Fri, 25 Aug 2017 14:31:01 +0200
Subject: udp6: set rx_dst_cookie on rx_dst updates

From: Paolo Abeni <[email protected]>

[ Upstream commit 64f0f5d18a47c703c85576375cc010e83dac6a48 ]

Currently, in the udp6 code, the dst cookie is not initialized/updated concurrently with the RX dst used by early demux.

As a result, the dst_check() in the early_demux path always fails, the rx dst cache is always invalidated, and we can't really leverage significant gain from the demux lookup.

Fix it adding udp6 specific variant of sk_rx_dst_set() and use it to set the dst cookie when the dst entry is really changed.

The issue is there since the introduction of early demux for ipv6.

Fixes 5425077d73e0 ("net: ipv6: Add early demux handler for UDP unicast")
---
 include/net/udp.h |    2 +-
 net/ipv4/udp.c    |    3 ++-
 net/ipv6/udp.c    |   11 ++++++++++-
 3 files changed, 13 insertions(+), 3 deletions(-)
include/net/udp.h +1 -1
@@ -265,7 +265,7 @@ static inline struct sk_buff *skb_recv_u
 }
 
 void udp_v4_early_demux(struct sk_buff *skb);
-void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst);
+bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst);
 int udp_get_port(struct sock *sk, unsigned short snum,
 		 int (*saddr_cmp)(const struct sock *,
 				  const struct sock *));
net/ipv4/udp.c +2 -1
@@ -1762,13 +1762,14 @@ drop:
 /* For TCP sockets, sk_rx_dst is protected by socket lock
  * For UDP, we use xchg() to guard against concurrent changes.
  */
-void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
+bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
 {
 	struct dst_entry *old;
 
 	dst_hold(dst);
 	old = xchg(&sk->sk_rx_dst, dst);
 	dst_release(old);
+	return old != dst;
 }
 
 /*
net/ipv6/udp.c +10 -1
@@ -752,6 +752,15 @@ start_lookup:
 	return 0;
 }
 
+static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
+{
+	if (udp_sk_rx_dst_set(sk, dst)) {
+		const struct rt6_info *rt = (const struct rt6_info *)dst;
+
+		inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
+	}
+}
+
 int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		   int proto)
 {
@@ -801,7 +810,7 @@ int __udp6_lib_rcv(struct sk_buff *skb,
 		int ret;
 
 		if (unlikely(sk->sk_rx_dst != dst))
-			udp_sk_rx_dst_set(sk, dst);
+			udp6_sk_rx_dst_set(sk, dst);
 
 		ret = udpv6_queue_rcv_skb(sk, skb);
 		sock_put(sk);

Patches currently in stable-queue which might be from [email protected] are

queue-4.12/ipv6-do-not-set-sk_destruct-in-ipv6_addrform-sockopt.patch queue-4.12/udp6-set-rx_dst_cookie-on-rx_dst-updates.patch queue-4.12/udp-on-peeking-bad-csum-drop-packets-even-if-not-at-head.patch