udp6: add missing rehash callback to udplite [Linux 5.0]

This Linux kernel change "udp6: add missing rehash callback to udplite" is included in the Linux 5.0 release. This change is authored by Alexey Kodanev <alexey.kodanev [at] oracle.com> on Wed Jan 16 19:17:45 2019 +0300. The commit for this change in Linux stable tree is f7c4615 (patch).

udp6: add missing rehash callback to udplite

After commit 23b0269e58ae ("net: udp6: prefer listeners bound to an
address"), UDP-Lite only works when specifying a local address for
the sockets.

This is related to the problem addressed in the commit 719f835853a9
("udp: add rehash on connect()"). Moreover, __udp6_lib_lookup() now
looks for a socket immediately in the secondary hash table.

And this issue was found with LTP/network tests as well.

Fixes: 23b0269e58ae ("net: udp6: prefer listeners bound to an address")
Signed-off-by: Alexey Kodanev <[email protected]>
Reviewed-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>

There are 4 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/ipv6/udp.c      | 2 +-
 net/ipv6/udp_impl.h | 1 +
 net/ipv6/udplite.c  | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e1f2b96..2596ffd 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -102,7 +102,7 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)
    return udp_lib_get_port(sk, snum, hash2_nulladdr);
 }

-static void udp_v6_rehash(struct sock *sk)
+void udp_v6_rehash(struct sock *sk)
 {
    u16 new_hash = ipv6_portaddr_hash(sock_net(sk),
                      &sk->sk_v6_rcv_saddr,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 5730e65..20e324b 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -13,6 +13,7 @@ int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
           __be32, struct udp_table *);

 int udp_v6_get_port(struct sock *sk, unsigned short snum);
+void udp_v6_rehash(struct sock *sk);

 int udpv6_getsockopt(struct sock *sk, int level, int optname,
             char __user *optval, int __user *optlen);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index a125aeb..f359078 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -49,6 +49,7 @@ struct proto udplitev6_prot = {
    .recvmsg       = udpv6_recvmsg,
    .hash          = udp_lib_hash,
    .unhash        = udp_lib_unhash,
+   .rehash        = udp_v6_rehash,
    .get_port      = udp_v6_get_port,
    .memory_allocated  = &udp_memory_allocated,
    .sysctl_mem    = sysctl_udp_mem,

Leave a Reply

Your email address will not be published. Required fields are marked *