All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
@ 2023-05-30  1:03 Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 01/14] udp: Random clenaup Kuniyuki Iwashima
                   ` (14 more replies)
  0 siblings, 15 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

Recently syzkaller reported a 7-year-old null-ptr-deref [0] that occurs
when a UDP-Lite socket tries to allocate a buffer under memory pressure.

Someone should have stumbled on the bug much earlier if UDP-Lite had been
used in a real app.  Additionally, we do not always need a large UDP-Lite
workload to hit the bug since UDP and UDP-Lite share the same memory
accounting limit.

Given no one uses UDP-Lite, we can drop it and simplify UDP code by
removing a bunch of conditionals.

This series removes UDP-Lite support from the core networking stack first
and incrementally removes the dead code.

[0]: https://lore.kernel.org/netdev/20230523163305.66466-1-kuniyu@amazon.com/


Kuniyuki Iwashima (14):
  udp: Random clenaup.
  udplite: Retire UDP-Lite for IPv6.
  ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE.
  udplite: Retire UDP-Lite for IPv4.
  udp: Remove UDP-Lite SNMP stats.
  udp: Remove UDPLITE_SEND_CSCOV and UDPLITE_RECV_CSCOV.
  udp: Remove pcslen, pcrlen, and pcflag in struct udp_sock.
  udp: Remove csum branch for UDP-Lite.
  udp: Don't pass proto to udp[46]_csum_init().
  udp: Don't pass proto to __udp[46]_lib_rcv().
  udp: Optimise ulen tests in __udp[46]_lib_rcv().
  udp: Remove udp_table in struct proto.
  udp: Remove udp_table in struct udp_seq_afinfo.
  udp: Don't pass udp_table to __udp[46]_lib_lookup().

 include/linux/udp.h        |  14 +-
 include/net/ip6_checksum.h |   1 -
 include/net/ipv6.h         |   2 -
 include/net/ipv6_stubs.h   |   3 +-
 include/net/netns/mib.h    |   5 -
 include/net/sock.h         |   5 +-
 include/net/transp_v6.h    |   3 -
 include/net/udp.h          |  71 +++----
 include/net/udplite.h      |  86 --------
 net/core/filter.c          |   5 +-
 net/ipv4/Makefile          |   2 +-
 net/ipv4/af_inet.c         |  10 -
 net/ipv4/proc.c            |  15 --
 net/ipv4/udp.c             | 421 ++++++++++++-------------------------
 net/ipv4/udp_bpf.c         |   2 -
 net/ipv4/udp_diag.c        |  84 ++------
 net/ipv4/udp_impl.h        |  29 ---
 net/ipv4/udp_offload.c     |   5 +-
 net/ipv4/udplite.c         | 136 ------------
 net/ipv6/Makefile          |   2 +-
 net/ipv6/af_inet6.c        |  25 +--
 net/ipv6/ip6_checksum.c    |  49 +----
 net/ipv6/ipv6_sockglue.c   |  17 +-
 net/ipv6/proc.c            |  16 --
 net/ipv6/udp.c             | 294 ++++++++++++--------------
 net/ipv6/udp_impl.h        |  31 ---
 net/ipv6/udp_offload.c     |   5 +-
 net/ipv6/udplite.c         | 136 ------------
 28 files changed, 330 insertions(+), 1144 deletions(-)
 delete mode 100644 include/net/udplite.h
 delete mode 100644 net/ipv4/udp_impl.h
 delete mode 100644 net/ipv4/udplite.c
 delete mode 100644 net/ipv6/udp_impl.h
 delete mode 100644 net/ipv6/udplite.c

-- 
2.30.2


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 01/14] udp: Random clenaup.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30 12:56   ` Simon Horman
  2023-05-30  1:03 ` [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6 Kuniyuki Iwashima
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

This is preparation patch to make the following diff smaller.

No functional changes are intended:

  - Keep Reverse Xmas Tree Order
  - Define struct net instead of using sock_net() repeatedly

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/udp.c | 68 +++++++++++++++++++++++++++-----------------------
 net/ipv6/udp.c | 58 +++++++++++++++++++++++-------------------
 2 files changed, 69 insertions(+), 57 deletions(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index fd3dae081f3a..7a874c497cbd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -901,16 +901,17 @@ EXPORT_SYMBOL(udp_set_csum);
 static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
 			struct inet_cork *cork)
 {
+	int err, len, datalen, is_udplite;
 	struct sock *sk = skb->sk;
-	struct inet_sock *inet = inet_sk(sk);
+	struct inet_sock *inet;
 	struct udphdr *uh;
-	int err;
-	int is_udplite = IS_UDPLITE(sk);
-	int offset = skb_transport_offset(skb);
-	int len = skb->len - offset;
-	int datalen = len - sizeof(*uh);
 	__wsum csum = 0;
 
+	inet = inet_sk(sk);
+	is_udplite = IS_UDPLITE(sk);
+	len = skb->len - skb_transport_offset(skb);
+	datalen = len - sizeof(*uh);
+
 	/*
 	 * Create a UDP header
 	 */
@@ -1051,24 +1052,25 @@ EXPORT_SYMBOL_GPL(udp_cmsg_send);
 
 int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
+	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
+	DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
 	struct inet_sock *inet = inet_sk(sk);
 	struct udp_sock *up = udp_sk(sk);
-	DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
+	struct ip_options_data opt_copy;
+	int is_udplite = IS_UDPLITE(sk);
+	__be32 daddr, faddr, saddr;
+	struct rtable *rt = NULL;
 	struct flowi4 fl4_stack;
-	struct flowi4 *fl4;
-	int ulen = len;
 	struct ipcm_cookie ipc;
-	struct rtable *rt = NULL;
-	int free = 0;
+	struct sk_buff *skb;
+	struct flowi4 *fl4;
 	int connected = 0;
-	__be32 daddr, faddr, saddr;
+	int ulen = len;
 	u8 tos, scope;
 	__be16 dport;
-	int err, is_udplite = IS_UDPLITE(sk);
-	int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE;
-	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
-	struct sk_buff *skb;
-	struct ip_options_data opt_copy;
+	int free = 0;
+	int corkreq;
+	int err;
 
 	if (len > 0xFFFF)
 		return -EMSGSIZE;
@@ -1080,6 +1082,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
 		return -EOPNOTSUPP;
 
+	corkreq = READ_ONCE(up->corkflag) || msg->msg_flags & MSG_MORE;
 	getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
 
 	fl4 = &inet->cork.fl.u.ip4;
@@ -1805,13 +1808,13 @@ EXPORT_SYMBOL(udp_read_skb);
 int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 		int *addr_len)
 {
-	struct inet_sock *inet = inet_sk(sk);
 	DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
-	struct sk_buff *skb;
-	unsigned int ulen, copied;
 	int off, err, peeking = flags & MSG_PEEK;
+	struct inet_sock *inet = inet_sk(sk);
 	int is_udplite = IS_UDPLITE(sk);
 	bool checksum_valid = false;
+	unsigned int ulen, copied;
+	struct sk_buff *skb;
 
 	if (flags & MSG_ERRQUEUE)
 		return ip_recv_error(sk, msg, len, addr_len);
@@ -1965,9 +1968,9 @@ void udp_lib_unhash(struct sock *sk)
 	if (sk_hashed(sk)) {
 		struct udp_table *udptable = udp_get_table_prot(sk);
 		struct udp_hslot *hslot, *hslot2;
+		struct net *net = sock_net(sk);
 
-		hslot  = udp_hashslot(udptable, sock_net(sk),
-				      udp_sk(sk)->udp_port_hash);
+		hslot  = udp_hashslot(udptable, net, udp_sk(sk)->udp_port_hash);
 		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
 
 		spin_lock_bh(&hslot->lock);
@@ -1976,7 +1979,7 @@ void udp_lib_unhash(struct sock *sk)
 		if (sk_del_node_init_rcu(sk)) {
 			hslot->count--;
 			inet_sk(sk)->inet_num = 0;
-			sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+			sock_prot_inuse_add(net, sk->sk_prot, -1);
 
 			spin_lock(&hslot2->lock);
 			hlist_del_init_rcu(&udp_sk(sk)->udp_portaddr_node);
@@ -1996,6 +1999,7 @@ void udp_lib_rehash(struct sock *sk, u16 newhash)
 	if (sk_hashed(sk)) {
 		struct udp_table *udptable = udp_get_table_prot(sk);
 		struct udp_hslot *hslot, *hslot2, *nhslot2;
+		struct net *net = sock_net(sk);
 
 		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
 		nhslot2 = udp_hashslot2(udptable, newhash);
@@ -2003,8 +2007,7 @@ void udp_lib_rehash(struct sock *sk, u16 newhash)
 
 		if (hslot2 != nhslot2 ||
 		    rcu_access_pointer(sk->sk_reuseport_cb)) {
-			hslot = udp_hashslot(udptable, sock_net(sk),
-					     udp_sk(sk)->udp_port_hash);
+			hslot = udp_hashslot(udptable, net, udp_sk(sk)->udp_port_hash);
 			/* we must lock primary chain too */
 			spin_lock_bh(&hslot->lock);
 			if (rcu_access_pointer(sk->sk_reuseport_cb))
@@ -2239,15 +2242,18 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 				    struct udp_table *udptable,
 				    int proto)
 {
-	struct sock *sk, *first = NULL;
+	int dif = skb->dev->ifindex, sdif = inet_sdif(skb);
+	unsigned int offset, hash2 = 0, hash2_any = 0;
 	unsigned short hnum = ntohs(uh->dest);
-	struct udp_hslot *hslot = udp_hashslot(udptable, net, hnum);
-	unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
-	unsigned int offset = offsetof(typeof(*sk), sk_node);
-	int dif = skb->dev->ifindex;
-	int sdif = inet_sdif(skb);
+	struct sock *sk, *first = NULL;
 	struct hlist_node *node;
+	struct udp_hslot *hslot;
 	struct sk_buff *nskb;
+	bool use_hash2;
+
+	hslot = udp_hashslot(udptable, net, hnum);
+	offset = offsetof(typeof(*sk), sk_node);
+	use_hash2 = hslot->count > 10;
 
 	if (use_hash2) {
 		hash2_any = ipv4_portaddr_hash(net, htonl(INADDR_ANY), hnum) &
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e5a337e6b970..2ec611c2f964 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -340,14 +340,14 @@ static int udp6_skb_len(struct sk_buff *skb)
 int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		  int flags, int *addr_len)
 {
+	int off, err, peeking = flags & MSG_PEEK;
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
-	struct sk_buff *skb;
-	unsigned int ulen, copied;
-	int off, err, peeking = flags & MSG_PEEK;
 	int is_udplite = IS_UDPLITE(sk);
 	struct udp_mib __percpu *mib;
 	bool checksum_valid = false;
+	unsigned int ulen, copied;
+	struct sk_buff *skb;
 	int is_udp4;
 
 	if (flags & MSG_ERRQUEUE)
@@ -848,16 +848,19 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 		const struct in6_addr *saddr, const struct in6_addr *daddr,
 		struct udp_table *udptable, int proto)
 {
-	struct sock *sk, *first = NULL;
+	int dif = inet6_iif(skb), sdif = inet6_sdif(skb);
+	unsigned int offset, hash2 = 0, hash2_any = 0;
 	const struct udphdr *uh = udp_hdr(skb);
 	unsigned short hnum = ntohs(uh->dest);
-	struct udp_hslot *hslot = udp_hashslot(udptable, net, hnum);
-	unsigned int offset = offsetof(typeof(*sk), sk_node);
-	unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
-	int dif = inet6_iif(skb);
-	int sdif = inet6_sdif(skb);
+	struct sock *sk, *first = NULL;
 	struct hlist_node *node;
+	struct udp_hslot *hslot;
 	struct sk_buff *nskb;
+	bool use_hash2;
+
+	hslot = udp_hashslot(udptable, net, hnum);
+	offset = offsetof(typeof(*sk), sk_node);
+	use_hash2 = hslot->count > 10;
 
 	if (use_hash2) {
 		hash2_any = ipv6_portaddr_hash(net, &in6addr_any, hnum) &
@@ -1225,14 +1228,14 @@ static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
 static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 			   struct inet_cork *cork)
 {
+	int err, len, datalen, is_udplite;
 	struct sock *sk = skb->sk;
 	struct udphdr *uh;
-	int err = 0;
-	int is_udplite = IS_UDPLITE(sk);
 	__wsum csum = 0;
-	int offset = skb_transport_offset(skb);
-	int len = skb->len - offset;
-	int datalen = len - sizeof(*uh);
+
+	is_udplite = IS_UDPLITE(sk);
+	len = skb->len - skb_transport_offset(skb);
+	datalen = len - sizeof(*uh);
 
 	/*
 	 * Create a UDP header
@@ -1330,26 +1333,26 @@ static int udp_v6_push_pending_frames(struct sock *sk)
 
 int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
-	struct ipv6_txoptions opt_space;
-	struct udp_sock *up = udp_sk(sk);
-	struct inet_sock *inet = inet_sk(sk);
-	struct ipv6_pinfo *np = inet6_sk(sk);
+	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 	DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
-	struct in6_addr *daddr, *final_p, final;
-	struct ipv6_txoptions *opt = NULL;
 	struct ipv6_txoptions *opt_to_free = NULL;
+	struct in6_addr *daddr, *final_p, final;
 	struct ip6_flowlabel *flowlabel = NULL;
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct ipv6_txoptions *opt = NULL;
+	struct udp_sock *up = udp_sk(sk);
+	struct ipv6_txoptions opt_space;
+	int addr_len = msg->msg_namelen;
+	int is_udplite = IS_UDPLITE(sk);
 	struct inet_cork_full cork;
-	struct flowi6 *fl6 = &cork.fl.u.ip6;
-	struct dst_entry *dst;
 	struct ipcm6_cookie ipc6;
-	int addr_len = msg->msg_namelen;
 	bool connected = false;
+	struct dst_entry *dst;
+	struct flowi6 *fl6;
 	int ulen = len;
-	int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE;
+	int corkreq;
 	int err;
-	int is_udplite = IS_UDPLITE(sk);
-	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 
 	ipcm6_init(&ipc6);
 	ipc6.gso_size = READ_ONCE(up->gso_size);
@@ -1411,6 +1414,9 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (len > INT_MAX - sizeof(struct udphdr))
 		return -EMSGSIZE;
 
+	corkreq = READ_ONCE(up->corkflag) || msg->msg_flags & MSG_MORE;
+	fl6 = &cork.fl.u.ip6;
+
 	getfrag  =  is_udplite ?  udplite_getfrag : ip_generic_getfrag;
 	if (up->pending) {
 		if (up->pending == AF_INET)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 01/14] udp: Random clenaup Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30 13:01   ` Simon Horman
  2023-05-30  1:03 ` [PATCH v1 net-next 03/14] ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE Kuniyuki Iwashima
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We no longer support IPPROTO_UDPLITE for AF_INET6.

This commit removes udplite.c and udp_impl.h under net/ipv6 and makes
some functions static that UDP shared.

Note that udplite.h is included in udp.c temporarily not to introduce
breakage, but we will remove it later with dead code.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/ipv6.h      |   2 -
 include/net/transp_v6.h |   3 -
 net/ipv6/Makefile       |   2 +-
 net/ipv6/af_inet6.c     |  19 +-----
 net/ipv6/proc.c         |   2 -
 net/ipv6/udp.c          |  31 ++++-----
 net/ipv6/udp_impl.h     |  31 ---------
 net/ipv6/udplite.c      | 136 ----------------------------------------
 8 files changed, 18 insertions(+), 208 deletions(-)
 delete mode 100644 net/ipv6/udp_impl.h
 delete mode 100644 net/ipv6/udplite.c

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 7332296eca44..c180c03e4e69 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -1258,8 +1258,6 @@ int tcp6_proc_init(struct net *net);
 void tcp6_proc_exit(struct net *net);
 int udp6_proc_init(struct net *net);
 void udp6_proc_exit(struct net *net);
-int udplite6_proc_init(void);
-void udplite6_proc_exit(void);
 int ipv6_misc_proc_init(void);
 void ipv6_misc_proc_exit(void);
 int snmp6_register_dev(struct inet6_dev *idev);
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index d27b1caf3753..76211668055b 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -8,7 +8,6 @@
 /* IPv6 transport protocols */
 extern struct proto rawv6_prot;
 extern struct proto udpv6_prot;
-extern struct proto udplitev6_prot;
 extern struct proto tcpv6_prot;
 extern struct proto pingv6_prot;
 
@@ -28,8 +27,6 @@ int rawv6_init(void);
 void rawv6_exit(void);
 int udpv6_init(void);
 void udpv6_exit(void);
-int udplitev6_init(void);
-void udplitev6_exit(void);
 int tcpv6_init(void);
 void tcpv6_exit(void);
 
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 3036a45e8a1e..63b7830d8146 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_IPV6) += ipv6.o
 
 ipv6-y :=	af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
 		addrlabel.o \
-		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
+		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o \
 		raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
 		exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o \
 		udp_offload.o seg6.o fib6_notifier.o rpl.o ioam6.o
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2bbf13216a3d..ca360680fae0 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -43,7 +43,6 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <net/tcp.h>
 #include <net/ping.h>
 #include <net/protocol.h>
@@ -1086,13 +1085,9 @@ static int __init inet6_init(void)
 	if (err)
 		goto out_unregister_tcp_proto;
 
-	err = proto_register(&udplitev6_prot, 1);
-	if (err)
-		goto out_unregister_udp_proto;
-
 	err = proto_register(&rawv6_prot, 1);
 	if (err)
-		goto out_unregister_udplite_proto;
+		goto out_unregister_udp_proto;
 
 	err = proto_register(&pingv6_prot, 1);
 	if (err)
@@ -1143,8 +1138,6 @@ static int __init inet6_init(void)
 	err = -ENOMEM;
 	if (raw6_proc_init())
 		goto proc_raw6_fail;
-	if (udplite6_proc_init())
-		goto proc_udplite6_fail;
 	if (ipv6_misc_proc_init())
 		goto proc_misc6_fail;
 	if (if6_proc_init())
@@ -1180,10 +1173,6 @@ static int __init inet6_init(void)
 	if (err)
 		goto udpv6_fail;
 
-	err = udplitev6_init();
-	if (err)
-		goto udplitev6_fail;
-
 	err = udpv6_offload_init();
 	if (err)
 		goto udpv6_offload_fail;
@@ -1254,8 +1243,6 @@ static int __init inet6_init(void)
 tcpv6_fail:
 	udpv6_offload_exit();
 udpv6_offload_fail:
-	udplitev6_exit();
-udplitev6_fail:
 	udpv6_exit();
 udpv6_fail:
 	ipv6_frag_exit();
@@ -1277,8 +1264,6 @@ static int __init inet6_init(void)
 proc_if6_fail:
 	ipv6_misc_proc_exit();
 proc_misc6_fail:
-	udplite6_proc_exit();
-proc_udplite6_fail:
 	raw6_proc_exit();
 proc_raw6_fail:
 #endif
@@ -1302,8 +1287,6 @@ static int __init inet6_init(void)
 	proto_unregister(&pingv6_prot);
 out_unregister_raw_proto:
 	proto_unregister(&rawv6_prot);
-out_unregister_udplite_proto:
-	proto_unregister(&udplitev6_prot);
 out_unregister_udp_proto:
 	proto_unregister(&udpv6_prot);
 out_unregister_tcp_proto:
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index e20b3705c2d2..91bcd4525494 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -39,8 +39,6 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
 		       sock_prot_inuse_get(net, &tcpv6_prot));
 	seq_printf(seq, "UDP6: inuse %d\n",
 		       sock_prot_inuse_get(net, &udpv6_prot));
-	seq_printf(seq, "UDPLITE6: inuse %d\n",
-			sock_prot_inuse_get(net, &udplitev6_prot));
 	seq_printf(seq, "RAW6: inuse %d\n",
 		       sock_prot_inuse_get(net, &rawv6_prot));
 	seq_printf(seq, "FRAG6: inuse %u memory %lu\n",
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 2ec611c2f964..bc3f7ac8c28a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -50,11 +50,12 @@
 #include <net/inet6_hashtables.h>
 #include <net/busy_poll.h>
 #include <net/sock_reuseport.h>
+#include <net/udp.h>
+#include <net/udplite.h>
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <trace/events/skb.h>
-#include "udp_impl.h"
 
 static void udpv6_destruct_sock(struct sock *sk)
 {
@@ -62,7 +63,7 @@ static void udpv6_destruct_sock(struct sock *sk)
 	inet6_sock_destruct(sk);
 }
 
-int udpv6_init_sock(struct sock *sk)
+static int udpv6_init_sock(struct sock *sk)
 {
 	udp_lib_init_sock(sk);
 	sk->sk_destruct = udpv6_destruct_sock;
@@ -93,7 +94,7 @@ static u32 udp6_ehashfn(const struct net *net,
 			       udp_ipv6_hash_secret + net_hash_mix(net));
 }
 
-int udp_v6_get_port(struct sock *sk, unsigned short snum)
+static int udp_v6_get_port(struct sock *sk, unsigned short snum)
 {
 	unsigned int hash2_nulladdr =
 		ipv6_portaddr_hash(sock_net(sk), &in6addr_any, snum);
@@ -105,7 +106,7 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)
 	return udp_lib_get_port(sk, snum, hash2_nulladdr);
 }
 
-void udp_v6_rehash(struct sock *sk)
+static void udp_v6_rehash(struct sock *sk)
 {
 	u16 new_hash = ipv6_portaddr_hash(sock_net(sk),
 					  &sk->sk_v6_rcv_saddr,
@@ -572,9 +573,9 @@ static struct sock *__udp6_lib_err_encap(struct net *net,
 	return sk;
 }
 
-int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-		   u8 type, u8 code, int offset, __be32 info,
-		   struct udp_table *udptable)
+static int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			  u8 type, u8 code, int offset, __be32 info,
+			  struct udp_table *udptable)
 {
 	struct ipv6_pinfo *np;
 	const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
@@ -944,8 +945,8 @@ static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
 	return 0;
 }
 
-int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
-		   int proto)
+static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+			  int proto)
 {
 	enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	const struct in6_addr *saddr, *daddr;
@@ -1659,7 +1660,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 }
 EXPORT_SYMBOL(udpv6_sendmsg);
 
-void udpv6_destroy_sock(struct sock *sk)
+static void udpv6_destroy_sock(struct sock *sk)
 {
 	struct udp_sock *up = udp_sk(sk);
 	lock_sock(sk);
@@ -1686,8 +1687,8 @@ void udpv6_destroy_sock(struct sock *sk)
 /*
  *	Socket option code for UDP
  */
-int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
-		     unsigned int optlen)
+static int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
+			    unsigned int optlen)
 {
 	if (level == SOL_UDP  ||  level == SOL_UDPLITE || level == SOL_SOCKET)
 		return udp_lib_setsockopt(sk, level, optname,
@@ -1696,8 +1697,8 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
 	return ipv6_setsockopt(sk, level, optname, optval, optlen);
 }
 
-int udpv6_getsockopt(struct sock *sk, int level, int optname,
-		     char __user *optval, int __user *optlen)
+static int udpv6_getsockopt(struct sock *sk, int level, int optname,
+			    char __user *optval, int __user *optlen)
 {
 	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
 		return udp_lib_getsockopt(sk, level, optname, optval, optlen);
@@ -1712,7 +1713,7 @@ static const struct inet6_protocol udpv6_protocol = {
 
 /* ------------------------------------------------------------------------ */
 #ifdef CONFIG_PROC_FS
-int udp6_seq_show(struct seq_file *seq, void *v)
+static int udp6_seq_show(struct seq_file *seq, void *v)
 {
 	if (v == SEQ_START_TOKEN) {
 		seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
deleted file mode 100644
index 0590f566379d..000000000000
--- a/net/ipv6/udp_impl.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _UDP6_IMPL_H
-#define _UDP6_IMPL_H
-#include <net/udp.h>
-#include <net/udplite.h>
-#include <net/protocol.h>
-#include <net/addrconf.h>
-#include <net/inet_common.h>
-#include <net/transp_v6.h>
-
-int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int);
-int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
-		   __be32, struct udp_table *);
-
-int udpv6_init_sock(struct sock *sk);
-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);
-int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
-		     unsigned int optlen);
-int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
-int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
-		  int *addr_len);
-void udpv6_destroy_sock(struct sock *sk);
-
-#ifdef CONFIG_PROC_FS
-int udp6_seq_show(struct seq_file *seq, void *v);
-#endif
-#endif	/* _UDP6_IMPL_H */
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
deleted file mode 100644
index 3bab0cc13697..000000000000
--- a/net/ipv6/udplite.c
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *  UDPLITEv6   An implementation of the UDP-Lite protocol over IPv6.
- *              See also net/ipv4/udplite.c
- *
- *  Authors:    Gerrit Renker       <gerrit@erg.abdn.ac.uk>
- *
- *  Changes:
- *  Fixes:
- */
-#include <linux/export.h>
-#include <linux/proc_fs.h>
-#include "udp_impl.h"
-
-static int udplitev6_sk_init(struct sock *sk)
-{
-	udpv6_init_sock(sk);
-	udp_sk(sk)->pcflag = UDPLITE_BIT;
-	return 0;
-}
-
-static int udplitev6_rcv(struct sk_buff *skb)
-{
-	return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
-}
-
-static int udplitev6_err(struct sk_buff *skb,
-			  struct inet6_skb_parm *opt,
-			  u8 type, u8 code, int offset, __be32 info)
-{
-	return __udp6_lib_err(skb, opt, type, code, offset, info,
-			      &udplite_table);
-}
-
-static const struct inet6_protocol udplitev6_protocol = {
-	.handler	=	udplitev6_rcv,
-	.err_handler	=	udplitev6_err,
-	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
-};
-
-struct proto udplitev6_prot = {
-	.name		   = "UDPLITEv6",
-	.owner		   = THIS_MODULE,
-	.close		   = udp_lib_close,
-	.connect	   = ip6_datagram_connect,
-	.disconnect	   = udp_disconnect,
-	.ioctl		   = udp_ioctl,
-	.init		   = udplitev6_sk_init,
-	.destroy	   = udpv6_destroy_sock,
-	.setsockopt	   = udpv6_setsockopt,
-	.getsockopt	   = udpv6_getsockopt,
-	.sendmsg	   = udpv6_sendmsg,
-	.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,
-	.per_cpu_fw_alloc  = &udp_memory_per_cpu_fw_alloc,
-
-	.sysctl_mem	   = sysctl_udp_mem,
-	.sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
-	.sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
-	.obj_size	   = sizeof(struct udp6_sock),
-	.h.udp_table	   = &udplite_table,
-};
-
-static struct inet_protosw udplite6_protosw = {
-	.type		= SOCK_DGRAM,
-	.protocol	= IPPROTO_UDPLITE,
-	.prot		= &udplitev6_prot,
-	.ops		= &inet6_dgram_ops,
-	.flags		= INET_PROTOSW_PERMANENT,
-};
-
-int __init udplitev6_init(void)
-{
-	int ret;
-
-	ret = inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
-	if (ret)
-		goto out;
-
-	ret = inet6_register_protosw(&udplite6_protosw);
-	if (ret)
-		goto out_udplitev6_protocol;
-out:
-	return ret;
-
-out_udplitev6_protocol:
-	inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
-	goto out;
-}
-
-void udplitev6_exit(void)
-{
-	inet6_unregister_protosw(&udplite6_protosw);
-	inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
-}
-
-#ifdef CONFIG_PROC_FS
-static struct udp_seq_afinfo udplite6_seq_afinfo = {
-	.family		= AF_INET6,
-	.udp_table	= &udplite_table,
-};
-
-static int __net_init udplite6_proc_init_net(struct net *net)
-{
-	if (!proc_create_net_data("udplite6", 0444, net->proc_net,
-			&udp6_seq_ops, sizeof(struct udp_iter_state),
-			&udplite6_seq_afinfo))
-		return -ENOMEM;
-	return 0;
-}
-
-static void __net_exit udplite6_proc_exit_net(struct net *net)
-{
-	remove_proc_entry("udplite6", net->proc_net);
-}
-
-static struct pernet_operations udplite6_net_ops = {
-	.init = udplite6_proc_init_net,
-	.exit = udplite6_proc_exit_net,
-};
-
-int __init udplite6_proc_init(void)
-{
-	return register_pernet_subsys(&udplite6_net_ops);
-}
-
-void udplite6_proc_exit(void)
-{
-	unregister_pernet_subsys(&udplite6_net_ops);
-}
-#endif
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 03/14] ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 01/14] udp: Random clenaup Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6 Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30 14:22   ` Simon Horman
  2023-05-30  1:03 ` [PATCH v1 net-next 04/14] udplite: Retire UDP-Lite for IPv4 Kuniyuki Iwashima
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

The previous commit removes UDP-Lite v6 support, so conversion
from UDP-Lite v6 to v4 never occurs.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv6/ipv6_sockglue.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ae818ff46224..150cd6620315 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -45,7 +45,6 @@
 #include <net/inet_common.h>
 #include <net/tcp.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <net/xfrm.h>
 #include <net/compat.h>
 #include <net/seg6.h>
@@ -434,10 +433,8 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 			if (sk->sk_type == SOCK_RAW)
 				break;
 
-			if (sk->sk_protocol == IPPROTO_UDP ||
-			    sk->sk_protocol == IPPROTO_UDPLITE) {
-				struct udp_sock *up = udp_sk(sk);
-				if (up->pending == AF_INET6) {
+			if (sk->sk_protocol == IPPROTO_UDP) {
+				if (udp_sk(sk)->pending == AF_INET6) {
 					retv = -EBUSY;
 					break;
 				}
@@ -478,16 +475,11 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 				sk->sk_family = PF_INET;
 				tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 			} else {
-				struct proto *prot = &udp_prot;
-
-				if (sk->sk_protocol == IPPROTO_UDPLITE)
-					prot = &udplite_prot;
-
 				sock_prot_inuse_add(net, sk->sk_prot, -1);
-				sock_prot_inuse_add(net, prot, 1);
+				sock_prot_inuse_add(net, &udp_prot, 1);
 
 				/* Paired with READ_ONCE(sk->sk_prot) in inet6_dgram_ops */
-				WRITE_ONCE(sk->sk_prot, prot);
+				WRITE_ONCE(sk->sk_prot, &udp_prot);
 				sk->sk_socket->ops = &inet_dgram_ops;
 				sk->sk_family = PF_INET;
 			}
@@ -1137,7 +1129,6 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 	switch (optname) {
 	case IPV6_ADDRFORM:
 		if (sk->sk_protocol != IPPROTO_UDP &&
-		    sk->sk_protocol != IPPROTO_UDPLITE &&
 		    sk->sk_protocol != IPPROTO_TCP)
 			return -ENOPROTOOPT;
 		if (sk->sk_state != TCP_ESTABLISHED)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 04/14] udplite: Retire UDP-Lite for IPv4.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (2 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 03/14] ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 05/14] udp: Remove UDP-Lite SNMP stats Kuniyuki Iwashima
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We no longer support IPPROTO_UDPLITE for AF_INET.

This commit removes udplite.c and udp_impl.h under net/ipv4 and makes
some functions static that UDP shared.

Also, we remove the SOCK_DIAG code for UDP-Lite.

Note that udplite.h is included in udp.c temporarily not to introduce
breakage, but we will remove it later with dead code.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/sock.h    |   4 +-
 include/net/udp.h     |   5 +-
 include/net/udplite.h |   6 --
 net/ipv4/Makefile     |   2 +-
 net/ipv4/af_inet.c    |   4 --
 net/ipv4/proc.c       |   2 -
 net/ipv4/udp.c        |  36 +++++------
 net/ipv4/udp_bpf.c    |   2 -
 net/ipv4/udp_diag.c   |  46 +-------------
 net/ipv4/udp_impl.h   |  29 ---------
 net/ipv4/udplite.c    | 136 ------------------------------------------
 11 files changed, 25 insertions(+), 247 deletions(-)
 delete mode 100644 net/ipv4/udp_impl.h
 delete mode 100644 net/ipv4/udplite.c

diff --git a/include/net/sock.h b/include/net/sock.h
index 656ea89f60ff..0b6c74bdd688 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -133,14 +133,14 @@ typedef __u64 __bitwise __addrpair;
  *	@skc_net_refcnt: socket is using net ref counting
  *	@skc_bound_dev_if: bound device index if != 0
  *	@skc_bind_node: bind hash linkage for various protocol lookup tables
- *	@skc_portaddr_node: second hash linkage for UDP/UDP-Lite protocol
+ *	@skc_portaddr_node: second hash linkage for UDP protocol
  *	@skc_prot: protocol handlers inside a network family
  *	@skc_net: reference to the network namespace of this socket
  *	@skc_v6_daddr: IPV6 destination address
  *	@skc_v6_rcv_saddr: IPV6 source address
  *	@skc_cookie: socket's cookie value
  *	@skc_node: main hash linkage for various protocol lookup tables
- *	@skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol
+ *	@skc_nulls_node: main hash linkage for TCP protocol
  *	@skc_tx_queue_mapping: tx queue number for this connection
  *	@skc_rx_queue_mapping: rx queue number for this connection
  *	@skc_flags: place holder for sk_flags
diff --git a/include/net/udp.h b/include/net/udp.h
index 5cad44318d71..bfe62e73552a 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -76,7 +76,7 @@ struct udp_table {
 	unsigned int		log;
 };
 extern struct udp_table udp_table;
-void udp_table_init(struct udp_table *, const char *);
+
 static inline struct udp_hslot *udp_hashslot(struct udp_table *table,
 					     struct net *net, unsigned int num)
 {
@@ -183,7 +183,7 @@ static inline void udp_lib_init_sock(struct sock *sk)
 	set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags);
 }
 
-/* hash routines shared between UDPv4/6 and UDP-Litev4/6 */
+/* hash routines shared between UDPv4/6 */
 static inline int udp_lib_hash(struct sock *sk)
 {
 	BUG();
@@ -284,7 +284,6 @@ int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size);
 void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst);
 int udp_rcv(struct sk_buff *skb);
 int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-int udp_init_sock(struct sock *sk);
 int udp_pre_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
 int __udp_disconnect(struct sock *sk, int flags);
 int udp_disconnect(struct sock *sk, int flags);
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 299c14ce2bb9..e436917f9b14 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -12,9 +12,6 @@
 #define UDPLITE_SEND_CSCOV   10 /* sender partial coverage (as sent)      */
 #define UDPLITE_RECV_CSCOV   11 /* receiver partial coverage (threshold ) */
 
-extern struct proto 		udplite_prot;
-extern struct udp_table		udplite_table;
-
 /*
  *	Checksum computation is all in software, hence simpler getfrag.
  */
@@ -80,7 +77,4 @@ static inline __wsum udplite_csum(struct sk_buff *skb)
 	return skb_checksum(skb, off, len, 0);
 }
 
-void udplite4_register(void);
-int udplite_get_port(struct sock *sk, unsigned short snum,
-		     int (*scmp)(const struct sock *, const struct sock *));
 #endif	/* _UDPLITE_H */
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index b18ba8ef93ad..a49e09f3f32a 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -10,7 +10,7 @@ obj-y     := route.o inetpeer.o protocol.o \
 	     tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
 	     tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \
 	     tcp_rate.o tcp_recovery.o tcp_ulp.o \
-	     tcp_offload.o tcp_plb.o datagram.o raw.o udp.o udplite.o \
+	     tcp_offload.o tcp_plb.o datagram.o raw.o udp.o \
 	     udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
 	     fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
 	     inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o \
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 946650036c7f..bf9fdce5bd05 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -102,7 +102,6 @@
 #include <net/gro.h>
 #include <net/tcp.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <net/ping.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
@@ -2009,9 +2008,6 @@ static int __init inet_init(void)
 	/* Setup UDP memory threshold */
 	udp_init();
 
-	/* Add UDP-Lite (RFC 3828) */
-	udplite4_register();
-
 	raw_init();
 
 	ping_init();
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index eaf1d3113b62..7cf33b1763ed 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -64,8 +64,6 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "UDP: inuse %d mem %ld\n",
 		   sock_prot_inuse_get(net, &udp_prot),
 		   proto_memory_allocated(&udp_prot));
-	seq_printf(seq, "UDPLITE: inuse %d\n",
-		   sock_prot_inuse_get(net, &udplite_prot));
 	seq_printf(seq, "RAW: inuse %d\n",
 		   sock_prot_inuse_get(net, &raw_prot));
 	seq_printf(seq,  "FRAG: inuse %u memory %lu\n",
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 7a874c497cbd..2e966ce4a41b 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -99,6 +99,7 @@
 #include <linux/seq_file.h>
 #include <net/net_namespace.h>
 #include <net/icmp.h>
+#include <net/inet_common.h>
 #include <net/inet_hashtables.h>
 #include <net/ip_tunnels.h>
 #include <net/route.h>
@@ -109,9 +110,10 @@
 #include <linux/btf_ids.h>
 #include <trace/events/skb.h>
 #include <net/busy_poll.h>
-#include "udp_impl.h"
 #include <net/sock_reuseport.h>
 #include <net/addrconf.h>
+#include <net/udp.h>
+#include <net/udplite.h>
 #include <net/udp_tunnel.h>
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6_stubs.h>
@@ -227,7 +229,7 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
 }
 
 /**
- *  udp_lib_get_port  -  UDP/-Lite port lookup for IPv4 and IPv6
+ *  udp_lib_get_port  -  UDP port lookup for IPv4 and IPv6
  *
  *  @sk:          socket struct in question
  *  @snum:        port number to look up
@@ -349,7 +351,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
 }
 EXPORT_SYMBOL(udp_lib_get_port);
 
-int udp_v4_get_port(struct sock *sk, unsigned short snum)
+static int udp_v4_get_port(struct sock *sk, unsigned short snum)
 {
 	unsigned int hash2_nulladdr =
 		ipv4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum);
@@ -712,7 +714,7 @@ static struct sock *__udp4_lib_err_encap(struct net *net,
  * to find the appropriate port.
  */
 
-int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
+static int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
 {
 	struct inet_sock *inet;
 	const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -1327,8 +1329,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 }
 EXPORT_SYMBOL(udp_sendmsg);
 
-int udp_sendpage(struct sock *sk, struct page *page, int offset,
-		 size_t size, int flags)
+static int udp_sendpage(struct sock *sk, struct page *page, int offset,
+			size_t size, int flags)
 {
 	struct bio_vec bvec;
 	struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES };
@@ -1591,7 +1593,7 @@ static void udp_destruct_sock(struct sock *sk)
 	inet_sock_destruct(sk);
 }
 
-int udp_init_sock(struct sock *sk)
+static int udp_init_sock(struct sock *sk)
 {
 	udp_lib_init_sock(sk);
 	sk->sk_destruct = udp_destruct_sock;
@@ -2032,7 +2034,7 @@ void udp_lib_rehash(struct sock *sk, u16 newhash)
 }
 EXPORT_SYMBOL(udp_lib_rehash);
 
-void udp_v4_rehash(struct sock *sk)
+static void udp_v4_rehash(struct sock *sk)
 {
 	u16 new_hash = ipv4_portaddr_hash(sock_net(sk),
 					  inet_sk(sk)->inet_rcv_saddr,
@@ -2376,8 +2378,8 @@ static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
  *	All we need to do is get the socket, and then do a checksum.
  */
 
-int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
-		   int proto)
+static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+			  int proto)
 {
 	struct sock *sk;
 	struct udphdr *uh;
@@ -2619,7 +2621,7 @@ int udp_rcv(struct sk_buff *skb)
 	return __udp4_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table, IPPROTO_UDP);
 }
 
-void udp_destroy_sock(struct sock *sk)
+static void udp_destroy_sock(struct sock *sk)
 {
 	struct udp_sock *up = udp_sk(sk);
 	bool slow = lock_sock_fast(sk);
@@ -2774,8 +2776,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 }
 EXPORT_SYMBOL(udp_lib_setsockopt);
 
-int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
-		   unsigned int optlen)
+static int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
+			  unsigned int optlen)
 {
 	if (level == SOL_UDP  ||  level == SOL_UDPLITE || level == SOL_SOCKET)
 		return udp_lib_setsockopt(sk, level, optname,
@@ -2845,8 +2847,8 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 }
 EXPORT_SYMBOL(udp_lib_getsockopt);
 
-int udp_getsockopt(struct sock *sk, int level, int optname,
-		   char __user *optval, int __user *optlen)
+static int udp_getsockopt(struct sock *sk, int level, int optname,
+			  char __user *optval, int __user *optlen)
 {
 	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
 		return udp_lib_getsockopt(sk, level, optname, optval, optlen);
@@ -3092,7 +3094,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
 		atomic_read(&sp->sk_drops));
 }
 
-int udp4_seq_show(struct seq_file *seq, void *v)
+static int udp4_seq_show(struct seq_file *seq, void *v)
 {
 	seq_setwidth(seq, 127);
 	if (v == SEQ_START_TOKEN)
@@ -3403,7 +3405,7 @@ static int __init set_uhash_entries(char *str)
 }
 __setup("uhash_entries=", set_uhash_entries);
 
-void __init udp_table_init(struct udp_table *table, const char *name)
+static void __init udp_table_init(struct udp_table *table, const char *name)
 {
 	unsigned int i;
 
diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c
index 0735d820e413..90336d215f79 100644
--- a/net/ipv4/udp_bpf.c
+++ b/net/ipv4/udp_bpf.c
@@ -6,8 +6,6 @@
 #include <net/udp.h>
 #include <net/inet_common.h>
 
-#include "udp_impl.h"
-
 static struct proto *udpv6_prot_saved __read_mostly;
 
 static int sk_udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index de3f2d31f510..b8de2babfb0c 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -10,7 +10,6 @@
 #include <linux/inet_diag.h>
 #include <linux/udp.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <linux/sock_diag.h>
 
 static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
@@ -228,12 +227,6 @@ static int udp_diag_destroy(struct sk_buff *in_skb,
 	return __udp_diag_destroy(in_skb, req, sock_net(in_skb->sk)->ipv4.udp_table);
 }
 
-static int udplite_diag_destroy(struct sk_buff *in_skb,
-				const struct inet_diag_req_v2 *req)
-{
-	return __udp_diag_destroy(in_skb, req, &udplite_table);
-}
-
 #endif
 
 static const struct inet_diag_handler udp_diag_handler = {
@@ -247,49 +240,13 @@ static const struct inet_diag_handler udp_diag_handler = {
 #endif
 };
 
-static void udplite_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
-			      const struct inet_diag_req_v2 *r)
-{
-	udp_dump(&udplite_table, skb, cb, r);
-}
-
-static int udplite_diag_dump_one(struct netlink_callback *cb,
-				 const struct inet_diag_req_v2 *req)
-{
-	return udp_dump_one(&udplite_table, cb, req);
-}
-
-static const struct inet_diag_handler udplite_diag_handler = {
-	.dump		 = udplite_diag_dump,
-	.dump_one	 = udplite_diag_dump_one,
-	.idiag_get_info  = udp_diag_get_info,
-	.idiag_type	 = IPPROTO_UDPLITE,
-	.idiag_info_size = 0,
-#ifdef CONFIG_INET_DIAG_DESTROY
-	.destroy	 = udplite_diag_destroy,
-#endif
-};
-
 static int __init udp_diag_init(void)
 {
-	int err;
-
-	err = inet_diag_register(&udp_diag_handler);
-	if (err)
-		goto out;
-	err = inet_diag_register(&udplite_diag_handler);
-	if (err)
-		goto out_lite;
-out:
-	return err;
-out_lite:
-	inet_diag_unregister(&udp_diag_handler);
-	goto out;
+	return inet_diag_register(&udp_diag_handler);
 }
 
 static void __exit udp_diag_exit(void)
 {
-	inet_diag_unregister(&udplite_diag_handler);
 	inet_diag_unregister(&udp_diag_handler);
 }
 
@@ -297,4 +254,3 @@ module_init(udp_diag_init);
 module_exit(udp_diag_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2-17 /* AF_INET - IPPROTO_UDP */);
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2-136 /* AF_INET - IPPROTO_UDPLITE */);
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
deleted file mode 100644
index 4ba7a88a1b1d..000000000000
--- a/net/ipv4/udp_impl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _UDP4_IMPL_H
-#define _UDP4_IMPL_H
-#include <net/udp.h>
-#include <net/udplite.h>
-#include <net/protocol.h>
-#include <net/inet_common.h>
-
-int __udp4_lib_rcv(struct sk_buff *, struct udp_table *, int);
-int __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
-
-int udp_v4_get_port(struct sock *sk, unsigned short snum);
-void udp_v4_rehash(struct sock *sk);
-
-int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
-		   unsigned int optlen);
-int udp_getsockopt(struct sock *sk, int level, int optname,
-		   char __user *optval, int __user *optlen);
-
-int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
-		int *addr_len);
-int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size,
-		 int flags);
-void udp_destroy_sock(struct sock *sk);
-
-#ifdef CONFIG_PROC_FS
-int udp4_seq_show(struct seq_file *seq, void *v);
-#endif
-#endif	/* _UDP4_IMPL_H */
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
deleted file mode 100644
index 56d94d23b9e0..000000000000
--- a/net/ipv4/udplite.c
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *  UDPLITE     An implementation of the UDP-Lite protocol (RFC 3828).
- *
- *  Authors:    Gerrit Renker       <gerrit@erg.abdn.ac.uk>
- *
- *  Changes:
- *  Fixes:
- */
-
-#define pr_fmt(fmt) "UDPLite: " fmt
-
-#include <linux/export.h>
-#include <linux/proc_fs.h>
-#include "udp_impl.h"
-
-struct udp_table 	udplite_table __read_mostly;
-EXPORT_SYMBOL(udplite_table);
-
-/* Designate sk as UDP-Lite socket */
-static int udplite_sk_init(struct sock *sk)
-{
-	udp_init_sock(sk);
-	udp_sk(sk)->pcflag = UDPLITE_BIT;
-	return 0;
-}
-
-static int udplite_rcv(struct sk_buff *skb)
-{
-	return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
-}
-
-static int udplite_err(struct sk_buff *skb, u32 info)
-{
-	return __udp4_lib_err(skb, info, &udplite_table);
-}
-
-static const struct net_protocol udplite_protocol = {
-	.handler	= udplite_rcv,
-	.err_handler	= udplite_err,
-	.no_policy	= 1,
-};
-
-struct proto 	udplite_prot = {
-	.name		   = "UDP-Lite",
-	.owner		   = THIS_MODULE,
-	.close		   = udp_lib_close,
-	.connect	   = ip4_datagram_connect,
-	.disconnect	   = udp_disconnect,
-	.ioctl		   = udp_ioctl,
-	.init		   = udplite_sk_init,
-	.destroy	   = udp_destroy_sock,
-	.setsockopt	   = udp_setsockopt,
-	.getsockopt	   = udp_getsockopt,
-	.sendmsg	   = udp_sendmsg,
-	.recvmsg	   = udp_recvmsg,
-	.sendpage	   = udp_sendpage,
-	.hash		   = udp_lib_hash,
-	.unhash		   = udp_lib_unhash,
-	.rehash		   = udp_v4_rehash,
-	.get_port	   = udp_v4_get_port,
-
-	.memory_allocated  = &udp_memory_allocated,
-	.per_cpu_fw_alloc  = &udp_memory_per_cpu_fw_alloc,
-
-	.sysctl_mem	   = sysctl_udp_mem,
-	.sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
-	.sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
-	.obj_size	   = sizeof(struct udp_sock),
-	.h.udp_table	   = &udplite_table,
-};
-EXPORT_SYMBOL(udplite_prot);
-
-static struct inet_protosw udplite4_protosw = {
-	.type		=  SOCK_DGRAM,
-	.protocol	=  IPPROTO_UDPLITE,
-	.prot		=  &udplite_prot,
-	.ops		=  &inet_dgram_ops,
-	.flags		=  INET_PROTOSW_PERMANENT,
-};
-
-#ifdef CONFIG_PROC_FS
-static struct udp_seq_afinfo udplite4_seq_afinfo = {
-	.family		= AF_INET,
-	.udp_table 	= &udplite_table,
-};
-
-static int __net_init udplite4_proc_init_net(struct net *net)
-{
-	if (!proc_create_net_data("udplite", 0444, net->proc_net, &udp_seq_ops,
-			sizeof(struct udp_iter_state), &udplite4_seq_afinfo))
-		return -ENOMEM;
-	return 0;
-}
-
-static void __net_exit udplite4_proc_exit_net(struct net *net)
-{
-	remove_proc_entry("udplite", net->proc_net);
-}
-
-static struct pernet_operations udplite4_net_ops = {
-	.init = udplite4_proc_init_net,
-	.exit = udplite4_proc_exit_net,
-};
-
-static __init int udplite4_proc_init(void)
-{
-	return register_pernet_subsys(&udplite4_net_ops);
-}
-#else
-static inline int udplite4_proc_init(void)
-{
-	return 0;
-}
-#endif
-
-void __init udplite4_register(void)
-{
-	udp_table_init(&udplite_table, "UDP-Lite");
-	if (proto_register(&udplite_prot, 1))
-		goto out_register_err;
-
-	if (inet_add_protocol(&udplite_protocol, IPPROTO_UDPLITE) < 0)
-		goto out_unregister_proto;
-
-	inet_register_protosw(&udplite4_protosw);
-
-	if (udplite4_proc_init())
-		pr_err("%s: Cannot register /proc!\n", __func__);
-	return;
-
-out_unregister_proto:
-	proto_unregister(&udplite_prot);
-out_register_err:
-	pr_crit("%s: Cannot add UDP-Lite protocol\n", __func__);
-}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 05/14] udp: Remove UDP-Lite SNMP stats.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (3 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 04/14] udplite: Retire UDP-Lite for IPv4 Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30 14:24   ` Simon Horman
  2023-05-30  1:03 ` [PATCH v1 net-next 06/14] udp: Remove UDPLITE_SEND_CSCOV and UDPLITE_RECV_CSCOV Kuniyuki Iwashima
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We stored UDP-Lite stats in udplite_statistics and udplite_stats_in6
of struct netns_mib.

Since UDP and UDP-Lite share code, UDP_INC_STATS() always has to
check if the socket is UDP-Lite.  However, we no longer increment
UDP-Lite stats.

Let's remove the stats and save one protocol test.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/netns/mib.h |  5 ---
 include/net/udp.h       | 43 +++++++++--------------
 net/ipv4/af_inet.c      |  6 ----
 net/ipv4/proc.c         | 13 -------
 net/ipv4/udp.c          | 76 ++++++++++++++++++-----------------------
 net/ipv6/af_inet6.c     |  6 ----
 net/ipv6/proc.c         | 14 --------
 net/ipv6/udp.c          | 48 +++++++++++---------------
 8 files changed, 69 insertions(+), 142 deletions(-)

diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
index 7e373664b1e7..dce05f8e6a33 100644
--- a/include/net/netns/mib.h
+++ b/include/net/netns/mib.h
@@ -28,11 +28,6 @@ struct netns_mib {
 	DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics);
 #endif
 
-	DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics);
-#if IS_ENABLED(CONFIG_IPV6)
-	DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
-#endif
-
 	DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics);
 	DEFINE_SNMP_STAT_ATOMIC(struct icmpmsg_mib, icmpmsg_statistics);
 #if IS_ENABLED(CONFIG_IPV6)
diff --git a/include/net/udp.h b/include/net/udp.h
index bfe62e73552a..d00509873f6f 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -390,37 +390,28 @@ static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
 }
 
 /*
- * 	SNMP statistics for UDP and UDP-Lite
+ * 	SNMP statistics for UDP
  */
-#define UDP_INC_STATS(net, field, is_udplite)		      do { \
-	if (is_udplite) SNMP_INC_STATS((net)->mib.udplite_statistics, field);       \
-	else		SNMP_INC_STATS((net)->mib.udp_statistics, field);  }  while(0)
-#define __UDP_INC_STATS(net, field, is_udplite) 	      do { \
-	if (is_udplite) __SNMP_INC_STATS((net)->mib.udplite_statistics, field);         \
-	else		__SNMP_INC_STATS((net)->mib.udp_statistics, field);    }  while(0)
-
-#define __UDP6_INC_STATS(net, field, is_udplite)	    do { \
-	if (is_udplite) __SNMP_INC_STATS((net)->mib.udplite_stats_in6, field);\
-	else		__SNMP_INC_STATS((net)->mib.udp_stats_in6, field);  \
-} while(0)
-#define UDP6_INC_STATS(net, field, __lite)		    do { \
-	if (__lite) SNMP_INC_STATS((net)->mib.udplite_stats_in6, field);  \
-	else	    SNMP_INC_STATS((net)->mib.udp_stats_in6, field);      \
-} while(0)
+#define __UDP_INC_STATS(net, field)				\
+	__SNMP_INC_STATS((net)->mib.udp_statistics, field)
+#define UDP_INC_STATS(net, field)				\
+	SNMP_INC_STATS((net)->mib.udp_statistics, field)
+
+#define __UDP6_INC_STATS(net, field)				\
+	__SNMP_INC_STATS((net)->mib.udp_stats_in6, field)
+#define UDP6_INC_STATS(net, field)				\
+	SNMP_INC_STATS((net)->mib.udp_stats_in6, field)
 
 #if IS_ENABLED(CONFIG_IPV6)
-#define __UDPX_MIB(sk, ipv4)						\
-({									\
-	ipv4 ? (IS_UDPLITE(sk) ? sock_net(sk)->mib.udplite_statistics :	\
-				 sock_net(sk)->mib.udp_statistics) :	\
-		(IS_UDPLITE(sk) ? sock_net(sk)->mib.udplite_stats_in6 :	\
-				 sock_net(sk)->mib.udp_stats_in6);	\
+#define __UDPX_MIB(sk, ipv4)				\
+({							\
+	ipv4 ? sock_net(sk)->mib.udp_statistics :	\
+		sock_net(sk)->mib.udp_stats_in6;	\
 })
 #else
-#define __UDPX_MIB(sk, ipv4)						\
-({									\
-	IS_UDPLITE(sk) ? sock_net(sk)->mib.udplite_statistics :		\
-			 sock_net(sk)->mib.udp_statistics;		\
+#define __UDPX_MIB(sk, ipv4)				\
+({							\
+	sock_net(sk)->mib.udp_statistics;		\
 })
 #endif
 
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index bf9fdce5bd05..332a01ffd550 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1769,9 +1769,6 @@ static __net_init int ipv4_mib_init_net(struct net *net)
 	net->mib.udp_statistics = alloc_percpu(struct udp_mib);
 	if (!net->mib.udp_statistics)
 		goto err_udp_mib;
-	net->mib.udplite_statistics = alloc_percpu(struct udp_mib);
-	if (!net->mib.udplite_statistics)
-		goto err_udplite_mib;
 	net->mib.icmp_statistics = alloc_percpu(struct icmp_mib);
 	if (!net->mib.icmp_statistics)
 		goto err_icmp_mib;
@@ -1786,8 +1783,6 @@ static __net_init int ipv4_mib_init_net(struct net *net)
 err_icmpmsg_mib:
 	free_percpu(net->mib.icmp_statistics);
 err_icmp_mib:
-	free_percpu(net->mib.udplite_statistics);
-err_udplite_mib:
 	free_percpu(net->mib.udp_statistics);
 err_udp_mib:
 	free_percpu(net->mib.net_statistics);
@@ -1803,7 +1798,6 @@ static __net_exit void ipv4_mib_exit_net(struct net *net)
 {
 	kfree(net->mib.icmpmsg_statistics);
 	free_percpu(net->mib.icmp_statistics);
-	free_percpu(net->mib.udplite_statistics);
 	free_percpu(net->mib.udp_statistics);
 	free_percpu(net->mib.net_statistics);
 	free_percpu(net->mib.ip_statistics);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 7cf33b1763ed..d27e92fc45c1 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -34,7 +34,6 @@
 #include <net/tcp.h>
 #include <net/mptcp.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <linux/bottom_half.h>
 #include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
@@ -434,18 +433,6 @@ static int snmp_seq_show_tcp_udp(struct seq_file *seq, void *v)
 	for (i = 0; snmp4_udp_list[i].name; i++)
 		seq_printf(seq, " %lu", buff[i]);
 
-	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
-
-	/* the UDP and UDP-Lite MIBs are the same */
-	seq_puts(seq, "\nUdpLite:");
-	snmp_get_cpu_field_batch(buff, snmp4_udp_list,
-				 net->mib.udplite_statistics);
-	for (i = 0; snmp4_udp_list[i].name; i++)
-		seq_printf(seq, " %s", snmp4_udp_list[i].name);
-	seq_puts(seq, "\nUdpLite:");
-	for (i = 0; snmp4_udp_list[i].name; i++)
-		seq_printf(seq, " %lu", buff[i]);
-
 	seq_putc(seq, '\n');
 	return 0;
 }
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2e966ce4a41b..9d836604562a 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -981,13 +981,13 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
 	err = ip_send_skb(sock_net(sk), skb);
 	if (err) {
 		if (err == -ENOBUFS && !inet->recverr) {
-			UDP_INC_STATS(sock_net(sk),
-				      UDP_MIB_SNDBUFERRORS, is_udplite);
+			UDP_INC_STATS(sock_net(sk), UDP_MIB_SNDBUFERRORS);
 			err = 0;
 		}
-	} else
-		UDP_INC_STATS(sock_net(sk),
-			      UDP_MIB_OUTDATAGRAMS, is_udplite);
+	} else {
+		UDP_INC_STATS(sock_net(sk), UDP_MIB_OUTDATAGRAMS);
+	}
+
 	return err;
 }
 
@@ -1313,10 +1313,9 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	 * things).  We could add another new stat but at least for now that
 	 * seems like overkill.
 	 */
-	if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
-		UDP_INC_STATS(sock_net(sk),
-			      UDP_MIB_SNDBUFERRORS, is_udplite);
-	}
+	if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+		UDP_INC_STATS(sock_net(sk), UDP_MIB_SNDBUFERRORS);
+
 	return err;
 
 do_confirm:
@@ -1630,10 +1629,10 @@ static struct sk_buff *__first_packet_length(struct sock *sk,
 
 	while ((skb = skb_peek(rcvq)) != NULL) {
 		if (udp_lib_checksum_complete(skb)) {
-			__UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS,
-					IS_UDPLITE(sk));
-			__UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS,
-					IS_UDPLITE(sk));
+			struct net *net = sock_net(sk);
+
+			__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS);
+			__UDP_INC_STATS(net, UDP_MIB_INERRORS);
 			atomic_inc(&sk->sk_drops);
 			__skb_unlink(skb, rcvq);
 			*total += skb->truesize;
@@ -1787,11 +1786,10 @@ int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
 		return err;
 
 	if (udp_lib_checksum_complete(skb)) {
-		int is_udplite = IS_UDPLITE(sk);
 		struct net *net = sock_net(sk);
 
-		__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS, is_udplite);
-		__UDP_INC_STATS(net, UDP_MIB_INERRORS, is_udplite);
+		__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS);
+		__UDP_INC_STATS(net, UDP_MIB_INERRORS);
 		atomic_inc(&sk->sk_drops);
 		kfree_skb(skb);
 		goto try_again;
@@ -1814,6 +1812,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 	int off, err, peeking = flags & MSG_PEEK;
 	struct inet_sock *inet = inet_sk(sk);
 	int is_udplite = IS_UDPLITE(sk);
+	struct net *net = sock_net(sk);
 	bool checksum_valid = false;
 	unsigned int ulen, copied;
 	struct sk_buff *skb;
@@ -1863,16 +1862,14 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 	if (unlikely(err)) {
 		if (!peeking) {
 			atomic_inc(&sk->sk_drops);
-			UDP_INC_STATS(sock_net(sk),
-				      UDP_MIB_INERRORS, is_udplite);
+			UDP_INC_STATS(net, UDP_MIB_INERRORS);
 		}
 		kfree_skb(skb);
 		return err;
 	}
 
 	if (!peeking)
-		UDP_INC_STATS(sock_net(sk),
-			      UDP_MIB_INDATAGRAMS, is_udplite);
+		UDP_INC_STATS(net, UDP_MIB_INDATAGRAMS);
 
 	sock_recv_cmsgs(msg, sk, skb);
 
@@ -1904,8 +1901,8 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 csum_copy_err:
 	if (!__sk_queue_drop_skb(sk, &udp_sk(sk)->reader_queue, skb, flags,
 				 udp_skb_destructor)) {
-		UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
-		UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+		UDP_INC_STATS(net, UDP_MIB_CSUMERRORS);
+		UDP_INC_STATS(net, UDP_MIB_INERRORS);
 	}
 	kfree_skb(skb);
 
@@ -2056,20 +2053,18 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 	rc = __udp_enqueue_schedule_skb(sk, skb);
 	if (rc < 0) {
-		int is_udplite = IS_UDPLITE(sk);
+		struct net *net = sock_net(sk);
 		int drop_reason;
 
 		/* Note that an ENOMEM error is charged twice */
 		if (rc == -ENOMEM) {
-			UDP_INC_STATS(sock_net(sk), UDP_MIB_RCVBUFERRORS,
-					is_udplite);
+			UDP_INC_STATS(net, UDP_MIB_RCVBUFERRORS);
 			drop_reason = SKB_DROP_REASON_SOCKET_RCVBUFF;
 		} else {
-			UDP_INC_STATS(sock_net(sk), UDP_MIB_MEMERRORS,
-				      is_udplite);
+			UDP_INC_STATS(net, UDP_MIB_MEMERRORS);
 			drop_reason = SKB_DROP_REASON_PROTO_MEM;
 		}
-		UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+		UDP_INC_STATS(net, UDP_MIB_INERRORS);
 		kfree_skb_reason(skb, drop_reason);
 		trace_udp_fail_queue_rcv_skb(rc, sk);
 		return -1;
@@ -2090,7 +2085,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 {
 	int drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	struct udp_sock *up = udp_sk(sk);
-	int is_udplite = IS_UDPLITE(sk);
+	struct net *net = sock_net(sk);
 
 	/*
 	 *	Charge it to the socket, dropping if the queue is full.
@@ -2126,9 +2121,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 
 			ret = encap_rcv(sk, skb);
 			if (ret <= 0) {
-				__UDP_INC_STATS(sock_net(sk),
-						UDP_MIB_INDATAGRAMS,
-						is_udplite);
+				__UDP_INC_STATS(net, UDP_MIB_INDATAGRAMS);
 				return -ret;
 			}
 		}
@@ -2187,9 +2180,9 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 
 csum_error:
 	drop_reason = SKB_DROP_REASON_UDP_CSUM;
-	__UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
+	__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS);
 drop:
-	__UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+	__UDP_INC_STATS(net, UDP_MIB_INERRORS);
 	atomic_inc(&sk->sk_drops);
 	kfree_skb_reason(skb, drop_reason);
 	return -1;
@@ -2279,10 +2272,8 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 
 		if (unlikely(!nskb)) {
 			atomic_inc(&sk->sk_drops);
-			__UDP_INC_STATS(net, UDP_MIB_RCVBUFERRORS,
-					IS_UDPLITE(sk));
-			__UDP_INC_STATS(net, UDP_MIB_INERRORS,
-					IS_UDPLITE(sk));
+			__UDP_INC_STATS(net, UDP_MIB_RCVBUFERRORS);
+			__UDP_INC_STATS(net, UDP_MIB_INERRORS);
 			continue;
 		}
 		if (udp_queue_rcv_skb(sk, nskb) > 0)
@@ -2300,8 +2291,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 			consume_skb(skb);
 	} else {
 		kfree_skb(skb);
-		__UDP_INC_STATS(net, UDP_MIB_IGNOREDMULTI,
-				proto == IPPROTO_UDPLITE);
+		__UDP_INC_STATS(net, UDP_MIB_IGNOREDMULTI);
 	}
 	return 0;
 }
@@ -2447,7 +2437,7 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	drop_reason = SKB_DROP_REASON_NO_SOCKET;
-	__UDP_INC_STATS(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
+	__UDP_INC_STATS(net, UDP_MIB_NOPORTS);
 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
 
 	/*
@@ -2476,9 +2466,9 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 			    proto == IPPROTO_UDPLITE ? "Lite" : "",
 			    &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest),
 			    ulen);
-	__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
+	__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS);
 drop:
-	__UDP_INC_STATS(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
+	__UDP_INC_STATS(net, UDP_MIB_INERRORS);
 	kfree_skb_reason(skb, drop_reason);
 	return 0;
 }
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index ca360680fae0..16df217be69d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -899,9 +899,6 @@ static int __net_init ipv6_init_mibs(struct net *net)
 	net->mib.udp_stats_in6 = alloc_percpu(struct udp_mib);
 	if (!net->mib.udp_stats_in6)
 		return -ENOMEM;
-	net->mib.udplite_stats_in6 = alloc_percpu(struct udp_mib);
-	if (!net->mib.udplite_stats_in6)
-		goto err_udplite_mib;
 	net->mib.ipv6_statistics = alloc_percpu(struct ipstats_mib);
 	if (!net->mib.ipv6_statistics)
 		goto err_ip_mib;
@@ -927,8 +924,6 @@ static int __net_init ipv6_init_mibs(struct net *net)
 err_icmp_mib:
 	free_percpu(net->mib.ipv6_statistics);
 err_ip_mib:
-	free_percpu(net->mib.udplite_stats_in6);
-err_udplite_mib:
 	free_percpu(net->mib.udp_stats_in6);
 	return -ENOMEM;
 }
@@ -936,7 +931,6 @@ static int __net_init ipv6_init_mibs(struct net *net)
 static void ipv6_cleanup_mibs(struct net *net)
 {
 	free_percpu(net->mib.udp_stats_in6);
-	free_percpu(net->mib.udplite_stats_in6);
 	free_percpu(net->mib.ipv6_statistics);
 	free_percpu(net->mib.icmpv6_statistics);
 	kfree(net->mib.icmpv6msg_statistics);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 91bcd4525494..5b431057969c 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -129,18 +129,6 @@ static const struct snmp_mib snmp6_udp6_list[] = {
 	SNMP_MIB_SENTINEL
 };
 
-static const struct snmp_mib snmp6_udplite6_list[] = {
-	SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
-	SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
-	SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
-	SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
-	SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
-	SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS),
-	SNMP_MIB_ITEM("UdpLite6InCsumErrors", UDP_MIB_CSUMERRORS),
-	SNMP_MIB_ITEM("UdpLite6MemErrors", UDP_MIB_MEMERRORS),
-	SNMP_MIB_SENTINEL
-};
-
 static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, atomic_long_t *smib)
 {
 	char name[32];
@@ -222,8 +210,6 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
 	snmp6_seq_show_icmpv6msg(seq, net->mib.icmpv6msg_statistics->mibs);
 	snmp6_seq_show_item(seq, net->mib.udp_stats_in6,
 			    NULL, snmp6_udp6_list);
-	snmp6_seq_show_item(seq, net->mib.udplite_stats_in6,
-			    NULL, snmp6_udplite6_list);
 	return 0;
 }
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index bc3f7ac8c28a..161686aa0dbe 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -666,20 +666,18 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 	rc = __udp_enqueue_schedule_skb(sk, skb);
 	if (rc < 0) {
-		int is_udplite = IS_UDPLITE(sk);
 		enum skb_drop_reason drop_reason;
+		struct net *net = sock_net(sk);
 
 		/* Note that an ENOMEM error is charged twice */
 		if (rc == -ENOMEM) {
-			UDP6_INC_STATS(sock_net(sk),
-					 UDP_MIB_RCVBUFERRORS, is_udplite);
+			UDP6_INC_STATS(net, UDP_MIB_RCVBUFERRORS);
 			drop_reason = SKB_DROP_REASON_SOCKET_RCVBUFF;
 		} else {
-			UDP6_INC_STATS(sock_net(sk),
-				       UDP_MIB_MEMERRORS, is_udplite);
+			UDP6_INC_STATS(net, UDP_MIB_MEMERRORS);
 			drop_reason = SKB_DROP_REASON_PROTO_MEM;
 		}
-		UDP6_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+		UDP6_INC_STATS(net, UDP_MIB_INERRORS);
 		kfree_skb_reason(skb, drop_reason);
 		return -1;
 	}
@@ -699,7 +697,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 {
 	enum skb_drop_reason drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	struct udp_sock *up = udp_sk(sk);
-	int is_udplite = IS_UDPLITE(sk);
+	struct net *net = sock_net(sk);
 
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) {
 		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
@@ -732,9 +730,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 
 			ret = encap_rcv(sk, skb);
 			if (ret <= 0) {
-				__UDP6_INC_STATS(sock_net(sk),
-						 UDP_MIB_INDATAGRAMS,
-						 is_udplite);
+				__UDP6_INC_STATS(net, UDP_MIB_INDATAGRAMS);
 				return -ret;
 			}
 		}
@@ -777,9 +773,9 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 
 csum_error:
 	drop_reason = SKB_DROP_REASON_UDP_CSUM;
-	__UDP6_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
+	__UDP6_INC_STATS(net, UDP_MIB_CSUMERRORS);
 drop:
-	__UDP6_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+	__UDP6_INC_STATS(net, UDP_MIB_INERRORS);
 	atomic_inc(&sk->sk_drops);
 	kfree_skb_reason(skb, drop_reason);
 	return -1;
@@ -889,10 +885,8 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 		nskb = skb_clone(skb, GFP_ATOMIC);
 		if (unlikely(!nskb)) {
 			atomic_inc(&sk->sk_drops);
-			__UDP6_INC_STATS(net, UDP_MIB_RCVBUFERRORS,
-					 IS_UDPLITE(sk));
-			__UDP6_INC_STATS(net, UDP_MIB_INERRORS,
-					 IS_UDPLITE(sk));
+			__UDP6_INC_STATS(net, UDP_MIB_RCVBUFERRORS);
+			__UDP6_INC_STATS(net, UDP_MIB_INERRORS);
 			continue;
 		}
 
@@ -911,8 +905,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 			consume_skb(skb);
 	} else {
 		kfree_skb(skb);
-		__UDP6_INC_STATS(net, UDP_MIB_IGNOREDMULTI,
-				 proto == IPPROTO_UDPLITE);
+		__UDP6_INC_STATS(net, UDP_MIB_IGNOREDMULTI);
 	}
 	return 0;
 }
@@ -1037,7 +1030,7 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (udp_lib_checksum_complete(skb))
 		goto csum_error;
 
-	__UDP6_INC_STATS(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
+	__UDP6_INC_STATS(net, UDP_MIB_NOPORTS);
 	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
 
 	kfree_skb_reason(skb, reason);
@@ -1058,9 +1051,9 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 csum_error:
 	if (reason == SKB_DROP_REASON_NOT_SPECIFIED)
 		reason = SKB_DROP_REASON_UDP_CSUM;
-	__UDP6_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
+	__UDP6_INC_STATS(net, UDP_MIB_CSUMERRORS);
 discard:
-	__UDP6_INC_STATS(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
+	__UDP6_INC_STATS(net, UDP_MIB_INERRORS);
 	kfree_skb_reason(skb, reason);
 	return 0;
 }
@@ -1300,13 +1293,11 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 	err = ip6_send_skb(skb);
 	if (err) {
 		if (err == -ENOBUFS && !inet6_sk(sk)->recverr) {
-			UDP6_INC_STATS(sock_net(sk),
-				       UDP_MIB_SNDBUFERRORS, is_udplite);
+			UDP6_INC_STATS(sock_net(sk), UDP_MIB_SNDBUFERRORS);
 			err = 0;
 		}
 	} else {
-		UDP6_INC_STATS(sock_net(sk),
-			       UDP_MIB_OUTDATAGRAMS, is_udplite);
+		UDP6_INC_STATS(sock_net(sk), UDP_MIB_OUTDATAGRAMS);
 	}
 	return err;
 }
@@ -1644,10 +1635,9 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	 * things).  We could add another new stat but at least for now that
 	 * seems like overkill.
 	 */
-	if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
-		UDP6_INC_STATS(sock_net(sk),
-			       UDP_MIB_SNDBUFERRORS, is_udplite);
-	}
+	if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+		UDP6_INC_STATS(sock_net(sk), UDP_MIB_SNDBUFERRORS);
+
 	return err;
 
 do_confirm:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 06/14] udp: Remove UDPLITE_SEND_CSCOV and UDPLITE_RECV_CSCOV.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (4 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 05/14] udp: Remove UDP-Lite SNMP stats Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 07/14] udp: Remove pcslen, pcrlen, and pcflag in struct udp_sock Kuniyuki Iwashima
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We could set partial checksum coverage for UDP-Lite via setsockopt,
but it's no longer supported.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/udplite.h |  4 ----
 net/ipv4/udp.c        | 45 ++-----------------------------------------
 net/ipv6/udp.c        |  4 ++--
 3 files changed, 4 insertions(+), 49 deletions(-)

diff --git a/include/net/udplite.h b/include/net/udplite.h
index e436917f9b14..f4c513cff753 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -8,10 +8,6 @@
 #include <net/ip6_checksum.h>
 #include <net/udp.h>
 
-/* UDP-Lite socket options */
-#define UDPLITE_SEND_CSCOV   10 /* sender partial coverage (as sent)      */
-#define UDPLITE_RECV_CSCOV   11 /* receiver partial coverage (threshold ) */
-
 /*
  *	Checksum computation is all in software, hence simpler getfrag.
  */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9d836604562a..dc416db001c8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2642,7 +2642,6 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 	struct udp_sock *up = udp_sk(sk);
 	int val, valbool;
 	int err = 0;
-	int is_udplite = IS_UDPLITE(sk);
 
 	if (level == SOL_SOCKET) {
 		err = sk_setsockopt(sk, level, optname, optval, optlen);
@@ -2727,36 +2726,6 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		release_sock(sk);
 		break;
 
-	/*
-	 * 	UDP-Lite's partial checksum coverage (RFC 3828).
-	 */
-	/* The sender sets actual checksum coverage length via this option.
-	 * The case coverage > packet length is handled by send module. */
-	case UDPLITE_SEND_CSCOV:
-		if (!is_udplite)         /* Disable the option on UDP sockets */
-			return -ENOPROTOOPT;
-		if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
-			val = 8;
-		else if (val > USHRT_MAX)
-			val = USHRT_MAX;
-		up->pcslen = val;
-		up->pcflag |= UDPLITE_SEND_CC;
-		break;
-
-	/* The receiver specifies a minimum checksum coverage value. To make
-	 * sense, this should be set to at least 8 (as done below). If zero is
-	 * used, this again means full checksum coverage.                     */
-	case UDPLITE_RECV_CSCOV:
-		if (!is_udplite)         /* Disable the option on UDP sockets */
-			return -ENOPROTOOPT;
-		if (val != 0 && val < 8) /* Avoid silly minimal values.       */
-			val = 8;
-		else if (val > USHRT_MAX)
-			val = USHRT_MAX;
-		up->pcrlen = val;
-		up->pcflag |= UDPLITE_RECV_CC;
-		break;
-
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -2769,7 +2738,7 @@ EXPORT_SYMBOL(udp_lib_setsockopt);
 static int udp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
 			  unsigned int optlen)
 {
-	if (level == SOL_UDP  ||  level == SOL_UDPLITE || level == SOL_SOCKET)
+	if (level == SOL_UDP || level == SOL_SOCKET)
 		return udp_lib_setsockopt(sk, level, optname,
 					  optval, optlen,
 					  udp_push_pending_frames);
@@ -2815,16 +2784,6 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		val = up->gro_enabled;
 		break;
 
-	/* The following two cannot be changed on UDP sockets, the return is
-	 * always 0 (which corresponds to the full checksum coverage of UDP). */
-	case UDPLITE_SEND_CSCOV:
-		val = up->pcslen;
-		break;
-
-	case UDPLITE_RECV_CSCOV:
-		val = up->pcrlen;
-		break;
-
 	default:
 		return -ENOPROTOOPT;
 	}
@@ -2840,7 +2799,7 @@ EXPORT_SYMBOL(udp_lib_getsockopt);
 static int udp_getsockopt(struct sock *sk, int level, int optname,
 			  char __user *optval, int __user *optlen)
 {
-	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
+	if (level == SOL_UDP)
 		return udp_lib_getsockopt(sk, level, optname, optval, optlen);
 	return ip_getsockopt(sk, level, optname, optval, optlen);
 }
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 161686aa0dbe..ecd304bbecb4 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1680,7 +1680,7 @@ static void udpv6_destroy_sock(struct sock *sk)
 static int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
 			    unsigned int optlen)
 {
-	if (level == SOL_UDP  ||  level == SOL_UDPLITE || level == SOL_SOCKET)
+	if (level == SOL_UDP || level == SOL_SOCKET)
 		return udp_lib_setsockopt(sk, level, optname,
 					  optval, optlen,
 					  udp_v6_push_pending_frames);
@@ -1690,7 +1690,7 @@ static int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t o
 static int udpv6_getsockopt(struct sock *sk, int level, int optname,
 			    char __user *optval, int __user *optlen)
 {
-	if (level == SOL_UDP  ||  level == SOL_UDPLITE)
+	if (level == SOL_UDP)
 		return udp_lib_getsockopt(sk, level, optname, optval, optlen);
 	return ipv6_getsockopt(sk, level, optname, optval, optlen);
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 07/14] udp: Remove pcslen, pcrlen, and pcflag in struct udp_sock.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (5 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 06/14] udp: Remove UDPLITE_SEND_CSCOV and UDPLITE_RECV_CSCOV Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 08/14] udp: Remove csum branch for UDP-Lite Kuniyuki Iwashima
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We removed partial checksum coverage support in the previous commit;
thus, udp_sk(sk)->{pcslen,pcrlen,pcflag} are always zero.  We can safely
remove the related code guarded by pcflag.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
After removing these members, the layout of udp_sock changes as follows.
We may want to move encap/gro functions on the last cache line to save
one cache line ?

Before:

struct udp_sock {
        struct inet_sock           inet __attribute__((__aligned__(8))); /*     0   976 */

        /* XXX last struct has 4 bytes of padding */

        /* --- cacheline 15 boundary (960 bytes) was 16 bytes ago --- */
...
        unsigned char              accept_udp_fraglist:1; /*   985: 5  1 */

        /* XXX 2 bits hole, try to pack */

        __u16                      len;                  /*   986     2 */
        __u16                      gso_size;             /*   988     2 */
        __u16                      pcslen;               /*   990     2 */
        __u16                      pcrlen;               /*   992     2 */
        __u8                       pcflag;               /*   994     1 */
        __u8                       unused[3];            /*   995     3 */

        /* XXX 2 bytes hole, try to pack */

        int                        (*encap_rcv)(struct sock *, struct sk_buff *); /*  1000     8 */
        void                       (*encap_err_rcv)(struct sock *, struct sk_buff *, int, __be16, u32, u8 *); /*  1008     8 */
        int                        (*encap_err_lookup)(struct sock *, struct sk_buff *); /*  1016     8 */
        /* --- cacheline 16 boundary (1024 bytes) --- */
        void                       (*encap_destroy)(struct sock *); /*  1024     8 */
        struct sk_buff *           (*gro_receive)(struct sock *, struct list_head *, struct sk_buff *); /*  1032     8 */
        int                        (*gro_complete)(struct sock *, struct sk_buff *, int); /*  1040     8 */

        /* XXX 40 bytes hole, try to pack */

        /* --- cacheline 17 boundary (1088 bytes) --- */
        struct sk_buff_head        reader_queue __attribute__((__aligned__(64))); /*  1088    24 */
        int                        forward_deficit;      /*  1112     4 */
        int                        forward_threshold;    /*  1116     4 */

        /* size: 1152, cachelines: 18, members: 25 */
        /* sum members: 1077, holes: 2, sum holes: 42 */
        /* sum bitfield members: 6 bits, bit holes: 1, sum bit holes: 2 bits */
        /* padding: 32 */
        /* paddings: 1, sum paddings: 4 */
        /* forced alignments: 2, forced holes: 1, sum forced holes: 40 */
} __attribute__((__aligned__(64)));

After:

struct udp_sock {
        struct inet_sock           inet __attribute__((__aligned__(8))); /*     0   976 */

        /* XXX last struct has 4 bytes of padding */

        /* --- cacheline 15 boundary (960 bytes) was 16 bytes ago --- */
...
        unsigned char              accept_udp_fraglist:1; /*   985: 5  1 */

        /* XXX 2 bits hole, try to pack */

        __u16                      len;                  /*   986     2 */
        __u16                      gso_size;             /*   988     2 */

        /* XXX 2 bytes hole, try to pack */

        int                        (*encap_rcv)(struct sock *, struct sk_buff *); /*   992     8 */
        void                       (*encap_err_rcv)(struct sock *, struct sk_buff *, int, __be16, u32, u8 *); /*  1000     8 */
        int                        (*encap_err_lookup)(struct sock *, struct sk_buff *); /*  1008     8 */
        void                       (*encap_destroy)(struct sock *); /*  1016     8 */
        /* --- cacheline 16 boundary (1024 bytes) --- */
        struct sk_buff *           (*gro_receive)(struct sock *, struct list_head *, struct sk_buff *); /*  1024     8 */
        int                        (*gro_complete)(struct sock *, struct sk_buff *, int); /*  1032     8 */

        /* XXX 48 bytes hole, try to pack */

        /* --- cacheline 17 boundary (1088 bytes) --- */
        struct sk_buff_head        reader_queue __attribute__((__aligned__(64))); /*  1088    24 */
        int                        forward_deficit;      /*  1112     4 */
        int                        forward_threshold;    /*  1116     4 */

        /* size: 1152, cachelines: 18, members: 21 */
        /* sum members: 1069, holes: 2, sum holes: 50 */
        /* sum bitfield members: 6 bits, bit holes: 1, sum bit holes: 2 bits */
        /* padding: 32 */
        /* paddings: 1, sum paddings: 4 */
        /* forced alignments: 2, forced holes: 1, sum forced holes: 48 */
} __attribute__((__aligned__(64)));
---
 include/linux/udp.h   | 12 +-----------
 include/net/udplite.h |  6 ------
 net/ipv4/udp.c        | 34 ----------------------------------
 net/ipv6/udp.c        | 17 -----------------
 4 files changed, 1 insertion(+), 68 deletions(-)

diff --git a/include/linux/udp.h b/include/linux/udp.h
index 43c1fb2d2c21..f2f44ad62ea0 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -57,17 +57,7 @@ struct udp_sock {
 	 */
 	__u16		 len;		/* total length of pending frames */
 	__u16		 gso_size;
-	/*
-	 * Fields specific to UDP-Lite.
-	 */
-	__u16		 pcslen;
-	__u16		 pcrlen;
-/* indicator bits used by pcflag: */
-#define UDPLITE_BIT      0x1  		/* set by udplite proto init function */
-#define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
-#define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
-	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
-	__u8		 unused[3];
+
 	/*
 	 * For encapsulation sockets.
 	 */
diff --git a/include/net/udplite.h b/include/net/udplite.h
index f4c513cff753..1bc9393f2890 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -59,15 +59,9 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
 /* Fast-path computation of checksum. Socket may not be locked. */
 static inline __wsum udplite_csum(struct sk_buff *skb)
 {
-	const struct udp_sock *up = udp_sk(skb->sk);
 	const int off = skb_transport_offset(skb);
 	int len = skb->len - off;
 
-	if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) {
-		if (0 < up->pcslen)
-			len = up->pcslen;
-		udp_hdr(skb)->len = htons(up->pcslen);
-	}
 	skb->ip_summed = CHECKSUM_NONE;     /* no HW support for checksumming */
 
 	return skb_checksum(skb, off, len, 0);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index dc416db001c8..345a6364a969 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2129,40 +2129,6 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 		/* FALLTHROUGH -- it's a UDP Packet */
 	}
 
-	/*
-	 * 	UDP-Lite specific tests, ignored on UDP sockets
-	 */
-	if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
-
-		/*
-		 * MIB statistics other than incrementing the error count are
-		 * disabled for the following two types of errors: these depend
-		 * on the application settings, not on the functioning of the
-		 * protocol stack as such.
-		 *
-		 * RFC 3828 here recommends (sec 3.3): "There should also be a
-		 * way ... to ... at least let the receiving application block
-		 * delivery of packets with coverage values less than a value
-		 * provided by the application."
-		 */
-		if (up->pcrlen == 0) {          /* full coverage was set  */
-			net_dbg_ratelimited("UDPLite: partial coverage %d while full coverage %d requested\n",
-					    UDP_SKB_CB(skb)->cscov, skb->len);
-			goto drop;
-		}
-		/* The next case involves violating the min. coverage requested
-		 * by the receiver. This is subtle: if receiver wants x and x is
-		 * greater than the buffersize/MTU then receiver will complain
-		 * that it wants x while sender emits packets of smaller size y.
-		 * Therefore the above ...()->partial_cov statement is essential.
-		 */
-		if (UDP_SKB_CB(skb)->cscov  <  up->pcrlen) {
-			net_dbg_ratelimited("UDPLite: coverage %d too small, need min %d\n",
-					    UDP_SKB_CB(skb)->cscov, up->pcrlen);
-			goto drop;
-		}
-	}
-
 	prefetch(&sk->sk_rmem_alloc);
 	if (rcu_access_pointer(sk->sk_filter) &&
 	    udp_lib_checksum_complete(skb))
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index ecd304bbecb4..5c4b0e662ff5 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -738,23 +738,6 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 		/* FALLTHROUGH -- it's a UDP Packet */
 	}
 
-	/*
-	 * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
-	 */
-	if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
-
-		if (up->pcrlen == 0) {          /* full coverage was set  */
-			net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n",
-					    UDP_SKB_CB(skb)->cscov, skb->len);
-			goto drop;
-		}
-		if (UDP_SKB_CB(skb)->cscov  <  up->pcrlen) {
-			net_dbg_ratelimited("UDPLITE6: coverage %d too small, need min %d\n",
-					    UDP_SKB_CB(skb)->cscov, up->pcrlen);
-			goto drop;
-		}
-	}
-
 	prefetch(&sk->sk_rmem_alloc);
 	if (rcu_access_pointer(sk->sk_filter) &&
 	    udp_lib_checksum_complete(skb))
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 08/14] udp: Remove csum branch for UDP-Lite.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (6 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 07/14] udp: Remove pcslen, pcrlen, and pcflag in struct udp_sock Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 09/14] udp: Don't pass proto to udp[46]_csum_init() Kuniyuki Iwashima
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

Some functions still have conditional branches for UDP-Lite's
checksum that we can altogether remove now.

We can remove udp_skb_cb and partial_cov in struct udp_skb_cb
and finally remove udplite.h.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/linux/udp.h     |  2 --
 include/net/udp.h       | 17 ++--------
 include/net/udplite.h   | 70 -----------------------------------------
 net/ipv4/udp.c          | 58 +++++++---------------------------
 net/ipv6/ip6_checksum.c | 16 +---------
 net/ipv6/udp.c          | 37 +++++++---------------
 6 files changed, 27 insertions(+), 173 deletions(-)
 delete mode 100644 include/net/udplite.h

diff --git a/include/linux/udp.h b/include/linux/udp.h
index f2f44ad62ea0..ed6cad269fd1 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -146,6 +146,4 @@ static inline void udp_allow_gso(struct sock *sk)
 #define udp_portaddr_for_each_entry_rcu(__sk, list) \
 	hlist_for_each_entry_rcu(__sk, list, __sk_common.skc_portaddr_node)
 
-#define IS_UDPLITE(__sk) (__sk->sk_protocol == IPPROTO_UDPLITE)
-
 #endif	/* _LINUX_UDP_H */
diff --git a/include/net/udp.h b/include/net/udp.h
index d00509873f6f..902ee75bd25e 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -30,11 +30,9 @@
 #include <linux/indirect_call_wrapper.h>
 
 /**
- *	struct udp_skb_cb  -  UDP(-Lite) private variables
+ *	struct udp_skb_cb  -  UDP private variables
  *
  *	@header:      private variables used by IPv4/IPv6
- *	@cscov:       checksum coverage length (UDP-Lite only)
- *	@partial_cov: if set indicates partial csum coverage
  */
 struct udp_skb_cb {
 	union {
@@ -43,8 +41,6 @@ struct udp_skb_cb {
 		struct inet6_skb_parm	h6;
 #endif
 	} header;
-	__u16		cscov;
-	__u8		partial_cov;
 };
 #define UDP_SKB_CB(__skb)	((struct udp_skb_cb *)((__skb)->cb))
 
@@ -105,13 +101,11 @@ extern int sysctl_udp_wmem_min;
 struct sk_buff;
 
 /*
- *	Generic checksumming routines for UDP(-Lite) v4 and v6
+ *	Generic checksumming routines for UDP v4 and v6
  */
 static inline __sum16 __udp_lib_checksum_complete(struct sk_buff *skb)
 {
-	return (UDP_SKB_CB(skb)->cscov == skb->len ?
-		__skb_checksum_complete(skb) :
-		__skb_checksum_complete_head(skb, UDP_SKB_CB(skb)->cscov));
+	return __skb_checksum_complete(skb);
 }
 
 static inline int udp_lib_checksum_complete(struct sk_buff *skb)
@@ -162,7 +156,6 @@ static inline void udp_csum_pull_header(struct sk_buff *skb)
 		skb->csum = csum_partial(skb->data, sizeof(struct udphdr),
 					 skb->csum);
 	skb_pull_rcsum(skb, sizeof(struct udphdr));
-	UDP_SKB_CB(skb)->cscov -= sizeof(struct udphdr);
 }
 
 typedef struct sock *(*udp_lookup_t)(const struct sk_buff *skb, __be16 sport,
@@ -494,9 +487,6 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk,
 
 static inline void udp_post_segment_fix_csum(struct sk_buff *skb)
 {
-	/* UDP-lite can't land here - no GRO */
-	WARN_ON_ONCE(UDP_SKB_CB(skb)->partial_cov);
-
 	/* UDP packets generated with UDP_SEGMENT and traversing:
 	 *
 	 * UDP tunnel(xmit) -> veth (segmentation) -> veth (gro) -> UDP tunnel (rx)
@@ -510,7 +500,6 @@ static inline void udp_post_segment_fix_csum(struct sk_buff *skb)
 	 * a valid csum after the segmentation.
 	 * Additionally fixup the UDP CB.
 	 */
-	UDP_SKB_CB(skb)->cscov = skb->len;
 	if (skb->ip_summed == CHECKSUM_NONE && !skb->csum_valid)
 		skb->csum_valid = 1;
 }
diff --git a/include/net/udplite.h b/include/net/udplite.h
deleted file mode 100644
index 1bc9393f2890..000000000000
--- a/include/net/udplite.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *	Definitions for the UDP-Lite (RFC 3828) code.
- */
-#ifndef _UDPLITE_H
-#define _UDPLITE_H
-
-#include <net/ip6_checksum.h>
-#include <net/udp.h>
-
-/*
- *	Checksum computation is all in software, hence simpler getfrag.
- */
-static __inline__ int udplite_getfrag(void *from, char *to, int  offset,
-				      int len, int odd, struct sk_buff *skb)
-{
-	struct msghdr *msg = from;
-	return copy_from_iter_full(to, len, &msg->msg_iter) ? 0 : -EFAULT;
-}
-
-/*
- * 	Checksumming routines
- */
-static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
-{
-	u16 cscov;
-
-        /* In UDPv4 a zero checksum means that the transmitter generated no
-         * checksum. UDP-Lite (like IPv6) mandates checksums, hence packets
-         * with a zero checksum field are illegal.                            */
-	if (uh->check == 0) {
-		net_dbg_ratelimited("UDPLite: zeroed checksum field\n");
-		return 1;
-	}
-
-	cscov = ntohs(uh->len);
-
-	if (cscov == 0)		 /* Indicates that full coverage is required. */
-		;
-	else if (cscov < 8  || cscov > skb->len) {
-		/*
-		 * Coverage length violates RFC 3828: log and discard silently.
-		 */
-		net_dbg_ratelimited("UDPLite: bad csum coverage %d/%d\n",
-				    cscov, skb->len);
-		return 1;
-
-	} else if (cscov < skb->len) {
-        	UDP_SKB_CB(skb)->partial_cov = 1;
-		UDP_SKB_CB(skb)->cscov = cscov;
-		if (skb->ip_summed == CHECKSUM_COMPLETE)
-			skb->ip_summed = CHECKSUM_NONE;
-		skb->csum_valid = 0;
-        }
-
-	return 0;
-}
-
-/* Fast-path computation of checksum. Socket may not be locked. */
-static inline __wsum udplite_csum(struct sk_buff *skb)
-{
-	const int off = skb_transport_offset(skb);
-	int len = skb->len - off;
-
-	skb->ip_summed = CHECKSUM_NONE;     /* no HW support for checksumming */
-
-	return skb_checksum(skb, off, len, 0);
-}
-
-#endif	/* _UDPLITE_H */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 345a6364a969..aee075fb5f4f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -113,7 +113,6 @@
 #include <net/sock_reuseport.h>
 #include <net/addrconf.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <net/udp_tunnel.h>
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6_stubs.h>
@@ -903,14 +902,12 @@ EXPORT_SYMBOL(udp_set_csum);
 static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
 			struct inet_cork *cork)
 {
-	int err, len, datalen, is_udplite;
 	struct sock *sk = skb->sk;
 	struct inet_sock *inet;
+	int err, len, datalen;
 	struct udphdr *uh;
-	__wsum csum = 0;
 
 	inet = inet_sk(sk);
-	is_udplite = IS_UDPLITE(sk);
 	len = skb->len - skb_transport_offset(skb);
 	datalen = len - sizeof(*uh);
 
@@ -939,8 +936,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
 			kfree_skb(skb);
 			return -EINVAL;
 		}
-		if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
-		    dst_xfrm(skb_dst(skb))) {
+		if (skb->ip_summed != CHECKSUM_PARTIAL || dst_xfrm(skb_dst(skb))) {
 			kfree_skb(skb);
 			return -EIO;
 		}
@@ -954,26 +950,18 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
 		goto csum_partial;
 	}
 
-	if (is_udplite)  				 /*     UDP-Lite      */
-		csum = udplite_csum(skb);
-
-	else if (sk->sk_no_check_tx) {			 /* UDP csum off */
-
+	if (sk->sk_no_check_tx) {			 /* UDP csum off */
 		skb->ip_summed = CHECKSUM_NONE;
 		goto send;
-
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
 csum_partial:
-
 		udp4_hwcsum(skb, fl4->saddr, fl4->daddr);
 		goto send;
-
-	} else
-		csum = udp_csum(skb);
+	}
 
 	/* add protocol-dependent pseudo-header */
 	uh->check = csum_tcpudp_magic(fl4->saddr, fl4->daddr, len,
-				      sk->sk_protocol, csum);
+				      sk->sk_protocol, udp_csum(skb));
 	if (uh->check == 0)
 		uh->check = CSUM_MANGLED_0;
 
@@ -1054,12 +1042,10 @@ EXPORT_SYMBOL_GPL(udp_cmsg_send);
 
 int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
-	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 	DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
 	struct inet_sock *inet = inet_sk(sk);
 	struct udp_sock *up = udp_sk(sk);
 	struct ip_options_data opt_copy;
-	int is_udplite = IS_UDPLITE(sk);
 	__be32 daddr, faddr, saddr;
 	struct rtable *rt = NULL;
 	struct flowi4 fl4_stack;
@@ -1085,9 +1071,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		return -EOPNOTSUPP;
 
 	corkreq = READ_ONCE(up->corkflag) || msg->msg_flags & MSG_MORE;
-	getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
-
 	fl4 = &inet->cork.fl.u.ip4;
+
 	if (up->pending) {
 		/*
 		 * There are pending frames.
@@ -1257,7 +1242,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (!corkreq) {
 		struct inet_cork cork;
 
-		skb = ip_make_skb(sk, fl4, getfrag, msg, ulen,
+		skb = ip_make_skb(sk, fl4, ip_generic_getfrag, msg, ulen,
 				  sizeof(struct udphdr), &ipc, &rt,
 				  &cork, msg->msg_flags);
 		err = PTR_ERR(skb);
@@ -1288,7 +1273,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
 do_append_data:
 	up->len += ulen;
-	err = ip_append_data(sk, fl4, getfrag, msg, ulen,
+	err = ip_append_data(sk, fl4, ip_generic_getfrag, msg, ulen,
 			     sizeof(struct udphdr), &ipc, &rt,
 			     corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
 	if (err)
@@ -1811,7 +1796,6 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 	DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
 	int off, err, peeking = flags & MSG_PEEK;
 	struct inet_sock *inet = inet_sk(sk);
-	int is_udplite = IS_UDPLITE(sk);
 	struct net *net = sock_net(sk);
 	bool checksum_valid = false;
 	unsigned int ulen, copied;
@@ -1833,14 +1817,10 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 	else if (copied < ulen)
 		msg->msg_flags |= MSG_TRUNC;
 
-	/*
-	 * If checksum is needed at all, try to do it while copying the
-	 * data.  If the data is truncated, or if we only want a partial
-	 * coverage checksum (UDP-Lite), do it before the copy.
+	/* If checksum is needed at all, try to do it while copying the
+	 * data.  If the data is truncated, do it before the copy.
 	 */
-
-	if (copied < ulen || peeking ||
-	    (is_udplite && UDP_SKB_CB(skb)->partial_cov)) {
+	if (copied < ulen || peeking) {
 		checksum_valid = udp_skb_csum_unnecessary(skb) ||
 				!__udp_lib_checksum_complete(skb);
 		if (!checksum_valid)
@@ -2272,20 +2252,6 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
 {
 	int err;
 
-	UDP_SKB_CB(skb)->partial_cov = 0;
-	UDP_SKB_CB(skb)->cscov = skb->len;
-
-	if (proto == IPPROTO_UDPLITE) {
-		err = udplite_checksum_init(skb, uh);
-		if (err)
-			return err;
-
-		if (UDP_SKB_CB(skb)->partial_cov) {
-			skb->csum = inet_compute_pseudo(skb, proto);
-			return 0;
-		}
-	}
-
 	/* Note, we are only interested in != 0 or == 0, thus the
 	 * force to int.
 	 */
@@ -2317,7 +2283,7 @@ static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
 {
 	int ret;
 
-	if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
+	if (inet_get_convert_csum(sk) && uh->check)
 		skb_checksum_try_convert(skb, IPPROTO_UDP, inet_compute_pseudo);
 
 	ret = udp_queue_rcv_skb(sk, skb);
diff --git a/net/ipv6/ip6_checksum.c b/net/ipv6/ip6_checksum.c
index 377717045f8f..1362db7a3660 100644
--- a/net/ipv6/ip6_checksum.c
+++ b/net/ipv6/ip6_checksum.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <net/ip.h>
+#include <net/ip6_checksum.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 #include <asm/checksum.h>
 
 #ifndef _HAVE_ARCH_IPV6_CSUM
@@ -66,20 +66,6 @@ int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto)
 {
 	int err;
 
-	UDP_SKB_CB(skb)->partial_cov = 0;
-	UDP_SKB_CB(skb)->cscov = skb->len;
-
-	if (proto == IPPROTO_UDPLITE) {
-		err = udplite_checksum_init(skb, uh);
-		if (err)
-			return err;
-
-		if (UDP_SKB_CB(skb)->partial_cov) {
-			skb->csum = ip6_compute_pseudo(skb, proto);
-			return 0;
-		}
-	}
-
 	/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)
 	 * we accept a checksum of zero here. When we find the socket
 	 * for the UDP packet we'll check if that socket allows zero checksum
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5c4b0e662ff5..21d48f8803d0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -51,7 +51,6 @@
 #include <net/busy_poll.h>
 #include <net/sock_reuseport.h>
 #include <net/udp.h>
-#include <net/udplite.h>
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -344,7 +343,6 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	int off, err, peeking = flags & MSG_PEEK;
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
-	int is_udplite = IS_UDPLITE(sk);
 	struct udp_mib __percpu *mib;
 	bool checksum_valid = false;
 	unsigned int ulen, copied;
@@ -373,14 +371,10 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	is_udp4 = (skb->protocol == htons(ETH_P_IP));
 	mib = __UDPX_MIB(sk, is_udp4);
 
-	/*
-	 * If checksum is needed at all, try to do it while copying the
-	 * data.  If the data is truncated, or if we only want a partial
-	 * coverage checksum (UDP-Lite), do it before the copy.
+	/* If checksum is needed at all, try to do it while copying the
+	 * data.  If the data is truncated, do it before the copy.
 	 */
-
-	if (copied < ulen || peeking ||
-	    (is_udplite && UDP_SKB_CB(skb)->partial_cov)) {
+	if (copied < ulen || peeking) {
 		checksum_valid = udp_skb_csum_unnecessary(skb) ||
 				!__udp_lib_checksum_complete(skb);
 		if (!checksum_valid)
@@ -910,7 +904,7 @@ static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
 {
 	int ret;
 
-	if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
+	if (inet_get_convert_csum(sk) && uh->check)
 		skb_checksum_try_convert(skb, IPPROTO_UDP, ip6_compute_pseudo);
 
 	ret = udpv6_queue_rcv_skb(sk, skb);
@@ -1205,12 +1199,10 @@ static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
 static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 			   struct inet_cork *cork)
 {
-	int err, len, datalen, is_udplite;
 	struct sock *sk = skb->sk;
+	int err, len, datalen;
 	struct udphdr *uh;
-	__wsum csum = 0;
 
-	is_udplite = IS_UDPLITE(sk);
 	len = skb->len - skb_transport_offset(skb);
 	datalen = len - sizeof(*uh);
 
@@ -1239,8 +1231,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 			kfree_skb(skb);
 			return -EINVAL;
 		}
-		if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
-		    dst_xfrm(skb_dst(skb))) {
+		if (skb->ip_summed != CHECKSUM_PARTIAL || dst_xfrm(skb_dst(skb))) {
 			kfree_skb(skb);
 			return -EIO;
 		}
@@ -1254,21 +1245,18 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
 		goto csum_partial;
 	}
 
-	if (is_udplite)
-		csum = udplite_csum(skb);
-	else if (udp_sk(sk)->no_check6_tx) {   /* UDP csum disabled */
+	if (udp_sk(sk)->no_check6_tx) {   /* UDP csum disabled */
 		skb->ip_summed = CHECKSUM_NONE;
 		goto send;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
 csum_partial:
 		udp6_hwcsum_outgoing(sk, skb, &fl6->saddr, &fl6->daddr, len);
 		goto send;
-	} else
-		csum = udp_csum(skb);
+	}
 
 	/* add protocol-dependent pseudo-header */
 	uh->check = csum_ipv6_magic(&fl6->saddr, &fl6->daddr,
-				    len, fl6->flowi6_proto, csum);
+				    len, fl6->flowi6_proto, udp_csum(skb));
 	if (uh->check == 0)
 		uh->check = CSUM_MANGLED_0;
 
@@ -1308,7 +1296,6 @@ static int udp_v6_push_pending_frames(struct sock *sk)
 
 int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
-	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 	DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
 	struct ipv6_txoptions *opt_to_free = NULL;
 	struct in6_addr *daddr, *final_p, final;
@@ -1319,7 +1306,6 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	struct udp_sock *up = udp_sk(sk);
 	struct ipv6_txoptions opt_space;
 	int addr_len = msg->msg_namelen;
-	int is_udplite = IS_UDPLITE(sk);
 	struct inet_cork_full cork;
 	struct ipcm6_cookie ipc6;
 	bool connected = false;
@@ -1392,7 +1378,6 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	corkreq = READ_ONCE(up->corkflag) || msg->msg_flags & MSG_MORE;
 	fl6 = &cork.fl.u.ip6;
 
-	getfrag  =  is_udplite ?  udplite_getfrag : ip_generic_getfrag;
 	if (up->pending) {
 		if (up->pending == AF_INET)
 			return udp_sendmsg(sk, msg, len);
@@ -1562,7 +1547,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (!corkreq) {
 		struct sk_buff *skb;
 
-		skb = ip6_make_skb(sk, getfrag, msg, ulen,
+		skb = ip6_make_skb(sk, ip_generic_getfrag, msg, ulen,
 				   sizeof(struct udphdr), &ipc6,
 				   (struct rt6_info *)dst,
 				   msg->msg_flags, &cork);
@@ -1590,7 +1575,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (ipc6.dontfrag < 0)
 		ipc6.dontfrag = np->dontfrag;
 	up->len += ulen;
-	err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr),
+	err = ip6_append_data(sk, ip_generic_getfrag, msg, ulen, sizeof(struct udphdr),
 			      &ipc6, fl6, (struct rt6_info *)dst,
 			      corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
 	if (err)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 09/14] udp: Don't pass proto to udp[46]_csum_init().
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (7 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 08/14] udp: Remove csum branch for UDP-Lite Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 10/14] udp: Don't pass proto to __udp[46]_lib_rcv() Kuniyuki Iwashima
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We passed IPPROTO_UDPLITE as proto to __udp[46]_lib_rcv(), which passes
it to udp[46]_csum_init().

However, we no longer call __udp[46]_lib_rcv() with IPPROTO_UDPLITE, so
proto is always IPPROTO_UDP in udp[46]_csum_init(), and we can hard-code
it.

Also, udp6_csum_init() is not called from other functions, so we move it
to net/ipv6/udp.c as a static function.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/ip6_checksum.h |  1 -
 net/ipv4/udp.c             |  7 +++----
 net/ipv6/ip6_checksum.c    | 33 ---------------------------------
 net/ipv6/udp.c             | 34 +++++++++++++++++++++++++++++++++-
 4 files changed, 36 insertions(+), 39 deletions(-)

diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h
index c8a96b888277..f9e03cc7a19c 100644
--- a/include/net/ip6_checksum.h
+++ b/include/net/ip6_checksum.h
@@ -83,5 +83,4 @@ void udp6_set_csum(bool nocheck, struct sk_buff *skb,
 		   const struct in6_addr *saddr,
 		   const struct in6_addr *daddr, int len);
 
-int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto);
 #endif
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index aee075fb5f4f..f8a545c6e3e7 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2247,15 +2247,14 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
  * Otherwise, csum completion requires checksumming packet body,
  * including udp header and folding it to skb->csum.
  */
-static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
-				 int proto)
+static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh)
 {
 	int err;
 
 	/* Note, we are only interested in != 0 or == 0, thus the
 	 * force to int.
 	 */
-	err = (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
+	err = (__force int)skb_checksum_init_zero_check(skb, IPPROTO_UDP, uh->check,
 							inet_compute_pseudo);
 	if (err)
 		return err;
@@ -2335,7 +2334,7 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		uh = udp_hdr(skb);
 	}
 
-	if (udp4_csum_init(skb, uh, proto))
+	if (udp4_csum_init(skb, uh))
 		goto csum_error;
 
 	sk = skb_steal_sock(skb, &refcounted);
diff --git a/net/ipv6/ip6_checksum.c b/net/ipv6/ip6_checksum.c
index 1362db7a3660..e1a594873675 100644
--- a/net/ipv6/ip6_checksum.c
+++ b/net/ipv6/ip6_checksum.c
@@ -62,39 +62,6 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
 EXPORT_SYMBOL(csum_ipv6_magic);
 #endif
 
-int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto)
-{
-	int err;
-
-	/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)
-	 * we accept a checksum of zero here. When we find the socket
-	 * for the UDP packet we'll check if that socket allows zero checksum
-	 * for IPv6 (set by socket option).
-	 *
-	 * Note, we are only interested in != 0 or == 0, thus the
-	 * force to int.
-	 */
-	err = (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
-							ip6_compute_pseudo);
-	if (err)
-		return err;
-
-	if (skb->ip_summed == CHECKSUM_COMPLETE && !skb->csum_valid) {
-		/* If SW calculated the value, we know it's bad */
-		if (skb->csum_complete_sw)
-			return 1;
-
-		/* HW says the value is bad. Let's validate that.
-		 * skb->csum is no longer the full packet checksum,
-		 * so don't treat is as such.
-		 */
-		skb_checksum_complete_unset(skb);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(udp6_csum_init);
-
 /* Function to set UDP checksum for an IPv6 UDP packet. This is intended
  * for the simple case like when setting the checksum for a UDP tunnel.
  */
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 21d48f8803d0..170bbaa4a9d4 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -896,6 +896,38 @@ static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
 	}
 }
 
+static int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh)
+{
+	int err;
+
+	/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)
+	 * we accept a checksum of zero here. When we find the socket
+	 * for the UDP packet we'll check if that socket allows zero checksum
+	 * for IPv6 (set by socket option).
+	 *
+	 * Note, we are only interested in != 0 or == 0, thus the
+	 * force to int.
+	 */
+	err = (__force int)skb_checksum_init_zero_check(skb, IPPROTO_UDP, uh->check,
+							ip6_compute_pseudo);
+	if (err)
+		return err;
+
+	if (skb->ip_summed == CHECKSUM_COMPLETE && !skb->csum_valid) {
+		/* If SW calculated the value, we know it's bad */
+		if (skb->csum_complete_sw)
+			return 1;
+
+		/* HW says the value is bad. Let's validate that.
+		 * skb->csum is no longer the full packet checksum,
+		 * so don't treat is as such.
+		 */
+		skb_checksum_complete_unset(skb);
+	}
+
+	return 0;
+}
+
 /* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
  * return code conversion for ip layer consumption
  */
@@ -956,7 +988,7 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		}
 	}
 
-	if (udp6_csum_init(skb, uh, proto))
+	if (udp6_csum_init(skb, uh))
 		goto csum_error;
 
 	/* Check if the socket is already available, e.g. due to early demux */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 10/14] udp: Don't pass proto to __udp[46]_lib_rcv().
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (8 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 09/14] udp: Don't pass proto to udp[46]_csum_init() Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 11/14] udp: Optimise ulen tests in __udp[46]_lib_rcv() Kuniyuki Iwashima
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We passed IPPROTO_UDPLITE as proto to __udp[46]_lib_rcv() to share the
code with UDP-Lite, which we no longer support.

We need not check proto in __udp[46]_lib_rcv().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/udp.c | 26 ++++++++++----------------
 net/ipv6/udp.c | 38 +++++++++++++++++---------------------
 2 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f8a545c6e3e7..23ebea2b84e4 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2180,8 +2180,7 @@ EXPORT_SYMBOL(udp_sk_rx_dst_set);
 static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 				    struct udphdr  *uh,
 				    __be32 saddr, __be32 daddr,
-				    struct udp_table *udptable,
-				    int proto)
+				    struct udp_table *udptable)
 {
 	int dif = skb->dev->ifindex, sdif = inet_sdif(skb);
 	unsigned int offset, hash2 = 0, hash2_any = 0;
@@ -2299,8 +2298,7 @@ static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
  *	All we need to do is get the socket, and then do a checksum.
  */
 
-static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
-			  int proto)
+static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
 {
 	struct sock *sk;
 	struct udphdr *uh;
@@ -2327,12 +2325,10 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (ulen > skb->len)
 		goto short_packet;
 
-	if (proto == IPPROTO_UDP) {
-		/* UDP validates ulen. */
-		if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
-			goto short_packet;
-		uh = udp_hdr(skb);
-	}
+	if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
+		goto short_packet;
+
+	uh = udp_hdr(skb);
 
 	if (udp4_csum_init(skb, uh))
 		goto csum_error;
@@ -2353,7 +2349,7 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
 	if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
 		return __udp4_lib_mcast_deliver(net, skb, uh,
-						saddr, daddr, udptable, proto);
+						saddr, daddr, udptable);
 
 	sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
 	if (sk)
@@ -2380,8 +2376,7 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
 short_packet:
 	drop_reason = SKB_DROP_REASON_PKT_TOO_SMALL;
-	net_dbg_ratelimited("UDP%s: short packet: From %pI4:%u %d/%d to %pI4:%u\n",
-			    proto == IPPROTO_UDPLITE ? "Lite" : "",
+	net_dbg_ratelimited("UDP: short packet: From %pI4:%u %d/%d to %pI4:%u\n",
 			    &saddr, ntohs(uh->source),
 			    ulen, skb->len,
 			    &daddr, ntohs(uh->dest));
@@ -2393,8 +2388,7 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	 * the network is concerned, anyway) as per 4.1.3.4 (MUST).
 	 */
 	drop_reason = SKB_DROP_REASON_UDP_CSUM;
-	net_dbg_ratelimited("UDP%s: bad checksum. From %pI4:%u to %pI4:%u ulen %d\n",
-			    proto == IPPROTO_UDPLITE ? "Lite" : "",
+	net_dbg_ratelimited("UDP: bad checksum. From %pI4:%u to %pI4:%u ulen %d\n",
 			    &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest),
 			    ulen);
 	__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS);
@@ -2539,7 +2533,7 @@ int udp_v4_early_demux(struct sk_buff *skb)
 
 int udp_rcv(struct sk_buff *skb)
 {
-	return __udp4_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table, IPPROTO_UDP);
+	return __udp4_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table);
 }
 
 static void udp_destroy_sock(struct sock *sk)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 170bbaa4a9d4..ee859679427a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -819,8 +819,9 @@ static void udp6_csum_zero_error(struct sk_buff *skb)
  * so we don't need to lock the hashes.
  */
 static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
-		const struct in6_addr *saddr, const struct in6_addr *daddr,
-		struct udp_table *udptable, int proto)
+				    const struct in6_addr *saddr,
+				    const struct in6_addr *daddr,
+				    struct udp_table *udptable)
 {
 	int dif = inet6_iif(skb), sdif = inet6_sdif(skb);
 	unsigned int offset, hash2 = 0, hash2_any = 0;
@@ -947,8 +948,7 @@ static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
 	return 0;
 }
 
-static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
-			  int proto)
+static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
 {
 	enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	const struct in6_addr *saddr, *daddr;
@@ -969,23 +969,20 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (ulen > skb->len)
 		goto short_packet;
 
-	if (proto == IPPROTO_UDP) {
-		/* UDP validates ulen. */
+	/* Check for jumbo payload */
+	if (ulen == 0)
+		ulen = skb->len;
 
-		/* Check for jumbo payload */
-		if (ulen == 0)
-			ulen = skb->len;
+	if (ulen < sizeof(*uh))
+		goto short_packet;
 
-		if (ulen < sizeof(*uh))
+	if (ulen < skb->len) {
+		if (pskb_trim_rcsum(skb, ulen))
 			goto short_packet;
 
-		if (ulen < skb->len) {
-			if (pskb_trim_rcsum(skb, ulen))
-				goto short_packet;
-			saddr = &ipv6_hdr(skb)->saddr;
-			daddr = &ipv6_hdr(skb)->daddr;
-			uh = udp_hdr(skb);
-		}
+		saddr = &ipv6_hdr(skb)->saddr;
+		daddr = &ipv6_hdr(skb)->daddr;
+		uh = udp_hdr(skb);
 	}
 
 	if (udp6_csum_init(skb, uh))
@@ -1017,7 +1014,7 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	 */
 	if (ipv6_addr_is_multicast(daddr))
 		return __udp6_lib_mcast_deliver(net, skb,
-				saddr, daddr, udptable, proto);
+						saddr, daddr, udptable);
 
 	/* Unicast */
 	sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
@@ -1048,8 +1045,7 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 short_packet:
 	if (reason == SKB_DROP_REASON_NOT_SPECIFIED)
 		reason = SKB_DROP_REASON_PKT_TOO_SMALL;
-	net_dbg_ratelimited("UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n",
-			    proto == IPPROTO_UDPLITE ? "-Lite" : "",
+	net_dbg_ratelimited("UDPv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n",
 			    saddr, ntohs(uh->source),
 			    ulen, skb->len,
 			    daddr, ntohs(uh->dest));
@@ -1138,7 +1134,7 @@ void udp_v6_early_demux(struct sk_buff *skb)
 
 INDIRECT_CALLABLE_SCOPE int udpv6_rcv(struct sk_buff *skb)
 {
-	return __udp6_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table, IPPROTO_UDP);
+	return __udp6_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table);
 }
 
 /*
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 11/14] udp: Optimise ulen tests in __udp[46]_lib_rcv().
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (9 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 10/14] udp: Don't pass proto to __udp[46]_lib_rcv() Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 12/14] udp: Remove udp_table in struct proto Kuniyuki Iwashima
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

In __udp4_lib_rcv(), we need not call udp_hdr() unless we call
pskb_trim_rcsum().

In __udp6_lib_rcv(), we can save two unneeded conditions for every
jumbo payload that never be true.

	if (ulen > skb->len)
		goto short_packet;
	if (ulen == 0)
		ulen = skb->len;
	if (ulen < skb->len)

Note the number of tests for non-jumbo IPv6 payload is not changed.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/udp.c |  8 +++++---
 net/ipv6/udp.c | 30 +++++++++++++++++-------------
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 23ebea2b84e4..eb968d20d5a8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2325,10 +2325,12 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
 	if (ulen > skb->len)
 		goto short_packet;
 
-	if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
-		goto short_packet;
+	if (ulen < sizeof(*uh)) {
+		if (pskb_trim_rcsum(skb, ulen))
+			goto short_packet;
 
-	uh = udp_hdr(skb);
+		uh = udp_hdr(skb);
+	}
 
 	if (udp4_csum_init(skb, uh))
 		goto csum_error;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index ee859679427a..6f5c29af4157 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -966,23 +966,27 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
 	uh = udp_hdr(skb);
 
 	ulen = ntohs(uh->len);
-	if (ulen > skb->len)
-		goto short_packet;
+	if (ulen) {
+		if (ulen > skb->len)
+			goto short_packet;
 
-	/* Check for jumbo payload */
-	if (ulen == 0)
-		ulen = skb->len;
+		if (ulen < sizeof(*uh))
+			goto short_packet;
 
-	if (ulen < sizeof(*uh))
-		goto short_packet;
+		if (ulen < skb->len) {
+			if (pskb_trim_rcsum(skb, ulen))
+				goto short_packet;
 
-	if (ulen < skb->len) {
-		if (pskb_trim_rcsum(skb, ulen))
-			goto short_packet;
+			saddr = &ipv6_hdr(skb)->saddr;
+			daddr = &ipv6_hdr(skb)->daddr;
+			uh = udp_hdr(skb);
+		}
+	} else {
+		/* jumbo payload */
+		ulen = skb->len;
 
-		saddr = &ipv6_hdr(skb)->saddr;
-		daddr = &ipv6_hdr(skb)->daddr;
-		uh = udp_hdr(skb);
+		if (ulen < sizeof(*uh))
+			goto short_packet;
 	}
 
 	if (udp6_csum_init(skb, uh))
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 12/14] udp: Remove udp_table in struct proto.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (10 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 11/14] udp: Optimise ulen tests in __udp[46]_lib_rcv() Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 13/14] udp: Remove udp_table in struct udp_seq_afinfo Kuniyuki Iwashima
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We managed UDP-Lite sockets in a global hash table (udplite_table) that
we can get from the global per-protocol variable, sk_prot->h.udp_table.

OTOH, we use per-netns hash tables for UDP, so we set NULL to
sk_prot->h.udp_table.

When we got a hash table, we needed to check if sk_prot->h.udp_table was
NULL to get a proper one.

However, we no longer support UDP-Lite and always use the per-netns hash
table without the test.  Also, we can remove h.udp_table in struct proto.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/sock.h |  1 -
 net/ipv4/udp.c     | 16 +++++++---------
 net/ipv6/udp.c     |  1 -
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 0b6c74bdd688..52f56a01b590 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1339,7 +1339,6 @@ struct proto {
 
 	union {
 		struct inet_hashinfo	*hashinfo;
-		struct udp_table	*udp_table;
 		struct raw_hashinfo	*raw_hash;
 		struct smc_hashinfo	*smc_hash;
 	} h;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index eb968d20d5a8..8b460e0e73bc 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -132,11 +132,6 @@ EXPORT_PER_CPU_SYMBOL_GPL(udp_memory_per_cpu_fw_alloc);
 #define MAX_UDP_PORTS 65536
 #define PORTS_PER_CHAIN (MAX_UDP_PORTS / UDP_HTABLE_SIZE_MIN_PERNET)
 
-static struct udp_table *udp_get_table_prot(struct sock *sk)
-{
-	return sk->sk_prot->h.udp_table ? : sock_net(sk)->ipv4.udp_table;
-}
-
 static int udp_lib_lport_inuse(struct net *net, __u16 num,
 			       const struct udp_hslot *hslot,
 			       unsigned long *bitmap,
@@ -238,11 +233,13 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
 int udp_lib_get_port(struct sock *sk, unsigned short snum,
 		     unsigned int hash2_nulladdr)
 {
-	struct udp_table *udptable = udp_get_table_prot(sk);
 	struct udp_hslot *hslot, *hslot2;
 	struct net *net = sock_net(sk);
+	struct udp_table *udptable;
 	int error = -EADDRINUSE;
 
+	udptable = net->ipv4.udp_table;
+
 	if (!snum) {
 		DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
 		unsigned short first, last;
@@ -1945,10 +1942,11 @@ EXPORT_SYMBOL(udp_disconnect);
 void udp_lib_unhash(struct sock *sk)
 {
 	if (sk_hashed(sk)) {
-		struct udp_table *udptable = udp_get_table_prot(sk);
 		struct udp_hslot *hslot, *hslot2;
 		struct net *net = sock_net(sk);
+		struct udp_table *udptable;
 
+		udptable = net->ipv4.udp_table;
 		hslot  = udp_hashslot(udptable, net, udp_sk(sk)->udp_port_hash);
 		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
 
@@ -1976,10 +1974,11 @@ EXPORT_SYMBOL(udp_lib_unhash);
 void udp_lib_rehash(struct sock *sk, u16 newhash)
 {
 	if (sk_hashed(sk)) {
-		struct udp_table *udptable = udp_get_table_prot(sk);
 		struct udp_hslot *hslot, *hslot2, *nhslot2;
 		struct net *net = sock_net(sk);
+		struct udp_table *udptable;
 
+		udptable = net->ipv4.udp_table;
 		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
 		nhslot2 = udp_hashslot2(udptable, newhash);
 		udp_sk(sk)->udp_portaddr_hash = newhash;
@@ -2819,7 +2818,6 @@ struct proto udp_prot = {
 	.sysctl_wmem_offset	= offsetof(struct net, ipv4.sysctl_udp_wmem_min),
 	.sysctl_rmem_offset	= offsetof(struct net, ipv4.sysctl_udp_rmem_min),
 	.obj_size		= sizeof(struct udp_sock),
-	.h.udp_table		= NULL,
 	.diag_destroy		= udp_abort,
 };
 EXPORT_SYMBOL(udp_prot);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 6f5c29af4157..23480b84ba08 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1778,7 +1778,6 @@ struct proto udpv6_prot = {
 	.sysctl_wmem_offset     = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
 	.sysctl_rmem_offset     = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
 	.obj_size		= sizeof(struct udp6_sock),
-	.h.udp_table		= NULL,
 	.diag_destroy		= udp_abort,
 };
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 13/14] udp: Remove udp_table in struct udp_seq_afinfo.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (11 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 12/14] udp: Remove udp_table in struct proto Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  1:03 ` [PATCH v1 net-next 14/14] udp: Don't pass udp_table to __udp[46]_lib_lookup() Kuniyuki Iwashima
  2023-05-30  2:15 ` [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Willem de Bruijn
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We managed UDP-Lite sockets in a global hash table (udplite_table) that
we can get from a per-protocol variable, udp_seq_afinfo.udp_table.

OTOH, we use per-netns hash tables for UDP, so we set NULL to
udp_seq_afinfo.udp_table.

When we got a hash table, we needed to check if udp_seq_afinfo.udp_table
was NULL to get a proper one.

However, we no longer support UDP-Lite and always use the per-netns
hash table without the test.  Also, we can remove udp_table in struct
udp_seq_afinfo.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/udp.h |  1 -
 net/ipv4/udp.c    | 22 ++++------------------
 net/ipv6/udp.c    |  1 -
 3 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/include/net/udp.h b/include/net/udp.h
index 902ee75bd25e..ea2308989dc7 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -414,7 +414,6 @@ static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
 #ifdef CONFIG_PROC_FS
 struct udp_seq_afinfo {
 	sa_family_t			family;
-	struct udp_table		*udp_table;
 };
 
 struct udp_iter_state {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8b460e0e73bc..7eddf88dfce6 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2837,21 +2837,8 @@ static bool seq_sk_match(struct seq_file *seq, const struct sock *sk)
 
 #ifdef CONFIG_BPF_SYSCALL
 static const struct seq_operations bpf_iter_udp_seq_ops;
-#endif
-static struct udp_table *udp_get_table_seq(struct seq_file *seq,
-					   struct net *net)
-{
-	const struct udp_seq_afinfo *afinfo;
-
-#ifdef CONFIG_BPF_SYSCALL
-	if (seq->op == &bpf_iter_udp_seq_ops)
-		return net->ipv4.udp_table;
 #endif
 
-	afinfo = pde_data(file_inode(seq->file));
-	return afinfo->udp_table ? : net->ipv4.udp_table;
-}
-
 static struct sock *udp_get_first(struct seq_file *seq, int start)
 {
 	struct udp_iter_state *state = seq->private;
@@ -2859,7 +2846,7 @@ static struct sock *udp_get_first(struct seq_file *seq, int start)
 	struct udp_table *udptable;
 	struct sock *sk;
 
-	udptable = udp_get_table_seq(seq, net);
+	udptable = net->ipv4.udp_table;
 
 	for (state->bucket = start; state->bucket <= udptable->mask;
 	     ++state->bucket) {
@@ -2891,7 +2878,7 @@ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
 	} while (sk && !seq_sk_match(seq, sk));
 
 	if (!sk) {
-		udptable = udp_get_table_seq(seq, net);
+		udptable = net->ipv4.udp_table;
 
 		if (state->bucket <= udptable->mask)
 			spin_unlock_bh(&udptable->hash[state->bucket].lock);
@@ -2939,7 +2926,7 @@ void udp_seq_stop(struct seq_file *seq, void *v)
 	struct udp_iter_state *state = seq->private;
 	struct udp_table *udptable;
 
-	udptable = udp_get_table_seq(seq, seq_file_net(seq));
+	udptable = seq_file_net(seq)->ipv4.udp_table;
 
 	if (state->bucket <= udptable->mask)
 		spin_unlock_bh(&udptable->hash[state->bucket].lock);
@@ -3020,7 +3007,7 @@ static struct sock *bpf_iter_udp_batch(struct seq_file *seq)
 		iter->offset = 0;
 	}
 
-	udptable = udp_get_table_seq(seq, net);
+	udptable = net->ipv4.udp_table;
 
 again:
 	/* New batch for the next bucket.
@@ -3229,7 +3216,6 @@ EXPORT_SYMBOL(udp_seq_ops);
 
 static struct udp_seq_afinfo udp4_seq_afinfo = {
 	.family		= AF_INET,
-	.udp_table	= NULL,
 };
 
 static int __net_init udp4_proc_init_net(struct net *net)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 23480b84ba08..066e9b9ae5f0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1728,7 +1728,6 @@ EXPORT_SYMBOL(udp6_seq_ops);
 
 static struct udp_seq_afinfo udp6_seq_afinfo = {
 	.family		= AF_INET6,
-	.udp_table	= NULL,
 };
 
 int __net_init udp6_proc_init(struct net *net)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v1 net-next 14/14] udp: Don't pass udp_table to __udp[46]_lib_lookup().
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (12 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 13/14] udp: Remove udp_table in struct udp_seq_afinfo Kuniyuki Iwashima
@ 2023-05-30  1:03 ` Kuniyuki Iwashima
  2023-05-30  2:15 ` [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Willem de Bruijn
  14 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30  1:03 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn
  Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We use the same socket lookup function for UDP and UDP-Lite.

However, we managed UDP-Lite sockets in a global hash table and
UDP sockets in per-netns hash tables.

To use a proper table in __udp6_lib_lookup(), we needed to add an
argument for udp_table in many functions.

However, we no longer support UDP-Lite and need not pass udp_table
again and again.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/ipv6_stubs.h |  3 +-
 include/net/udp.h        |  5 ++--
 net/core/filter.c        |  5 ++--
 net/ipv4/udp.c           | 61 +++++++++++++---------------------------
 net/ipv4/udp_diag.c      | 38 ++++++++++++-------------
 net/ipv4/udp_offload.c   |  5 ++--
 net/ipv6/udp.c           | 55 +++++++++++-------------------------
 net/ipv6/udp_offload.c   |  5 ++--
 8 files changed, 65 insertions(+), 112 deletions(-)

diff --git a/include/net/ipv6_stubs.h b/include/net/ipv6_stubs.h
index c48186bf4737..ff6ac49b02f5 100644
--- a/include/net/ipv6_stubs.h
+++ b/include/net/ipv6_stubs.h
@@ -79,8 +79,7 @@ struct ipv6_bpf_stub {
 	struct sock *(*udp6_lib_lookup)(struct net *net,
 				     const struct in6_addr *saddr, __be16 sport,
 				     const struct in6_addr *daddr, __be16 dport,
-				     int dif, int sdif, struct udp_table *tbl,
-				     struct sk_buff *skb);
+				     int dif, int sdif, struct sk_buff *skb);
 	int (*ipv6_setsockopt)(struct sock *sk, int level, int optname,
 			       sockptr_t optval, unsigned int optlen);
 	int (*ipv6_getsockopt)(struct sock *sk, int level, int optname,
diff --git a/include/net/udp.h b/include/net/udp.h
index ea2308989dc7..31bcf12c8b20 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -293,7 +293,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 			     __be32 daddr, __be16 dport, int dif);
 struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 			       __be32 daddr, __be16 dport, int dif, int sdif,
-			       struct udp_table *tbl, struct sk_buff *skb);
+			       struct sk_buff *skb);
 struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb,
 				 __be16 sport, __be16 dport);
 struct sock *udp6_lib_lookup(struct net *net,
@@ -303,8 +303,7 @@ struct sock *udp6_lib_lookup(struct net *net,
 struct sock *__udp6_lib_lookup(struct net *net,
 			       const struct in6_addr *saddr, __be16 sport,
 			       const struct in6_addr *daddr, __be16 dport,
-			       int dif, int sdif, struct udp_table *tbl,
-			       struct sk_buff *skb);
+			       int dif, int sdif, struct sk_buff *skb);
 struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
 				 __be16 sport, __be16 dport);
 int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
diff --git a/net/core/filter.c b/net/core/filter.c
index 968139f4a1ac..32e3a0677f99 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -6522,7 +6522,7 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
 		else
 			sk = __udp4_lib_lookup(net, src4, tuple->ipv4.sport,
 					       dst4, tuple->ipv4.dport,
-					       dif, sdif, net->ipv4.udp_table, NULL);
+					       dif, sdif, NULL);
 #if IS_ENABLED(CONFIG_IPV6)
 	} else {
 		struct in6_addr *src6 = (struct in6_addr *)&tuple->ipv6.saddr;
@@ -6537,8 +6537,7 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
 			sk = ipv6_bpf_stub->udp6_lib_lookup(net,
 							    src6, tuple->ipv6.sport,
 							    dst6, tuple->ipv6.dport,
-							    dif, sdif,
-							    net->ipv4.udp_table, NULL);
+							    dif, sdif, NULL);
 #endif
 	}
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 7eddf88dfce6..e6d7b830929d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -462,7 +462,6 @@ static struct sock *udp4_lib_lookup2(struct net *net,
 }
 
 static struct sock *udp4_lookup_run_bpf(struct net *net,
-					struct udp_table *udptable,
 					struct sk_buff *skb,
 					__be32 saddr, __be16 sport,
 					__be32 daddr, u16 hnum, const int dif)
@@ -470,9 +469,6 @@ static struct sock *udp4_lookup_run_bpf(struct net *net,
 	struct sock *sk, *reuse_sk;
 	bool no_reuseport;
 
-	if (udptable != net->ipv4.udp_table)
-		return NULL; /* only UDP is supported */
-
 	no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP, saddr, sport,
 					    daddr, hnum, dif, &sk);
 	if (no_reuseport || IS_ERR_OR_NULL(sk))
@@ -487,10 +483,11 @@ static struct sock *udp4_lookup_run_bpf(struct net *net,
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
-struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
-		__be16 sport, __be32 daddr, __be16 dport, int dif,
-		int sdif, struct udp_table *udptable, struct sk_buff *skb)
+struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
+			       __be32 daddr, __be16 dport, int dif, int sdif,
+			       struct sk_buff *skb)
 {
+	struct udp_table *udptable = net->ipv4.udp_table;
 	unsigned short hnum = ntohs(dport);
 	unsigned int hash2, slot2;
 	struct udp_hslot *hslot2;
@@ -509,8 +506,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
 
 	/* Lookup redirect from BPF */
 	if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
-		sk = udp4_lookup_run_bpf(net, udptable, skb,
-					 saddr, sport, daddr, hnum, dif);
+		sk = udp4_lookup_run_bpf(net, skb, saddr, sport, daddr, hnum, dif);
 		if (sk) {
 			result = sk;
 			goto done;
@@ -537,25 +533,23 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
 EXPORT_SYMBOL_GPL(__udp4_lib_lookup);
 
 static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
-						 __be16 sport, __be16 dport,
-						 struct udp_table *udptable)
+						 __be16 sport, __be16 dport)
 {
 	const struct iphdr *iph = ip_hdr(skb);
 
 	return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport,
 				 iph->daddr, dport, inet_iif(skb),
-				 inet_sdif(skb), udptable, skb);
+				 inet_sdif(skb), skb);
 }
 
 struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb,
 				 __be16 sport, __be16 dport)
 {
 	const struct iphdr *iph = ip_hdr(skb);
-	struct net *net = dev_net(skb->dev);
 
-	return __udp4_lib_lookup(net, iph->saddr, sport,
+	return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport,
 				 iph->daddr, dport, inet_iif(skb),
-				 inet_sdif(skb), net->ipv4.udp_table, NULL);
+				 inet_sdif(skb), NULL);
 }
 
 /* Must be called under rcu_read_lock().
@@ -567,8 +561,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 {
 	struct sock *sk;
 
-	sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport,
-			       dif, 0, net->ipv4.udp_table, NULL);
+	sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, 0, NULL);
 	if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
 		sk = NULL;
 	return sk;
@@ -651,7 +644,6 @@ static int __udp4_lib_err_encap_no_sk(struct sk_buff *skb, u32 info)
 static struct sock *__udp4_lib_err_encap(struct net *net,
 					 const struct iphdr *iph,
 					 struct udphdr *uh,
-					 struct udp_table *udptable,
 					 struct sock *sk,
 					 struct sk_buff *skb, u32 info)
 {
@@ -678,9 +670,8 @@ static struct sock *__udp4_lib_err_encap(struct net *net,
 		goto out;
 	}
 
-	sk = __udp4_lib_lookup(net, iph->daddr, uh->source,
-			       iph->saddr, uh->dest, skb->dev->ifindex, 0,
-			       udptable, NULL);
+	sk = __udp4_lib_lookup(net, iph->daddr, uh->source, iph->saddr, uh->dest,
+			       skb->dev->ifindex, 0, NULL);
 	if (sk) {
 		up = udp_sk(sk);
 
@@ -710,7 +701,7 @@ static struct sock *__udp4_lib_err_encap(struct net *net,
  * to find the appropriate port.
  */
 
-static int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
+int udp_err(struct sk_buff *skb, u32 info)
 {
 	struct inet_sock *inet;
 	const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -725,13 +716,12 @@ static int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udpta
 
 	sk = __udp4_lib_lookup(net, iph->daddr, uh->dest,
 			       iph->saddr, uh->source, skb->dev->ifindex,
-			       inet_sdif(skb), udptable, NULL);
+			       inet_sdif(skb), NULL);
 
 	if (!sk || udp_sk(sk)->encap_type) {
 		/* No socket for error: try tunnels before discarding */
 		if (static_branch_unlikely(&udp_encap_needed_key)) {
-			sk = __udp4_lib_err_encap(net, iph, uh, udptable, sk, skb,
-						  info);
+			sk = __udp4_lib_err_encap(net, iph, uh, sk, skb, info);
 			if (!sk)
 				return 0;
 		} else
@@ -804,11 +794,6 @@ static int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udpta
 	return 0;
 }
 
-int udp_err(struct sk_buff *skb, u32 info)
-{
-	return __udp4_lib_err(skb, info, dev_net(skb->dev)->ipv4.udp_table);
-}
-
 /*
  * Throw away all pending data and cancel the corking. Socket is locked.
  */
@@ -2178,10 +2163,10 @@ EXPORT_SYMBOL(udp_sk_rx_dst_set);
  */
 static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 				    struct udphdr  *uh,
-				    __be32 saddr, __be32 daddr,
-				    struct udp_table *udptable)
+				    __be32 saddr, __be32 daddr)
 {
 	int dif = skb->dev->ifindex, sdif = inet_sdif(skb);
+	struct udp_table *udptable = net->ipv4.udp_table;
 	unsigned int offset, hash2 = 0, hash2_any = 0;
 	unsigned short hnum = ntohs(uh->dest);
 	struct sock *sk, *first = NULL;
@@ -2297,7 +2282,7 @@ static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
  *	All we need to do is get the socket, and then do a checksum.
  */
 
-static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
+int udp_rcv(struct sk_buff *skb)
 {
 	struct sock *sk;
 	struct udphdr *uh;
@@ -2349,10 +2334,9 @@ static int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
 	}
 
 	if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
-		return __udp4_lib_mcast_deliver(net, skb, uh,
-						saddr, daddr, udptable);
+		return __udp4_lib_mcast_deliver(net, skb, uh, saddr, daddr);
 
-	sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
+	sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest);
 	if (sk)
 		return udp_unicast_rcv_skb(sk, skb, uh);
 
@@ -2532,11 +2516,6 @@ int udp_v4_early_demux(struct sk_buff *skb)
 	return 0;
 }
 
-int udp_rcv(struct sk_buff *skb)
-{
-	return __udp4_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table);
-}
-
 static void udp_destroy_sock(struct sock *sk)
 {
 	struct udp_sock *up = udp_sk(sk);
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index b8de2babfb0c..0f4ffd516efb 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -38,17 +38,17 @@ static int udp_dump_one(struct udp_table *tbl,
 	if (req->sdiag_family == AF_INET)
 		/* src and dst are swapped for historical reasons */
 		sk = __udp4_lib_lookup(net,
-				req->id.idiag_src[0], req->id.idiag_sport,
-				req->id.idiag_dst[0], req->id.idiag_dport,
-				req->id.idiag_if, 0, tbl, NULL);
+				       req->id.idiag_src[0], req->id.idiag_sport,
+				       req->id.idiag_dst[0], req->id.idiag_dport,
+				       req->id.idiag_if, 0, NULL);
 #if IS_ENABLED(CONFIG_IPV6)
 	else if (req->sdiag_family == AF_INET6)
 		sk = __udp6_lib_lookup(net,
-				(struct in6_addr *)req->id.idiag_src,
-				req->id.idiag_sport,
-				(struct in6_addr *)req->id.idiag_dst,
-				req->id.idiag_dport,
-				req->id.idiag_if, 0, tbl, NULL);
+				       (struct in6_addr *)req->id.idiag_src,
+				       req->id.idiag_sport,
+				       (struct in6_addr *)req->id.idiag_dst,
+				       req->id.idiag_dport,
+				       req->id.idiag_if, 0, NULL);
 #endif
 	if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
 		sk = NULL;
@@ -175,25 +175,25 @@ static int __udp_diag_destroy(struct sk_buff *in_skb,
 
 	if (req->sdiag_family == AF_INET)
 		sk = __udp4_lib_lookup(net,
-				req->id.idiag_dst[0], req->id.idiag_dport,
-				req->id.idiag_src[0], req->id.idiag_sport,
-				req->id.idiag_if, 0, tbl, NULL);
+				       req->id.idiag_dst[0], req->id.idiag_dport,
+				       req->id.idiag_src[0], req->id.idiag_sport,
+				       req->id.idiag_if, 0, NULL);
 #if IS_ENABLED(CONFIG_IPV6)
 	else if (req->sdiag_family == AF_INET6) {
 		if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) &&
 		    ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_src))
 			sk = __udp4_lib_lookup(net,
-					req->id.idiag_dst[3], req->id.idiag_dport,
-					req->id.idiag_src[3], req->id.idiag_sport,
-					req->id.idiag_if, 0, tbl, NULL);
+					       req->id.idiag_dst[3], req->id.idiag_dport,
+					       req->id.idiag_src[3], req->id.idiag_sport,
+					       req->id.idiag_if, 0, NULL);
 
 		else
 			sk = __udp6_lib_lookup(net,
-					(struct in6_addr *)req->id.idiag_dst,
-					req->id.idiag_dport,
-					(struct in6_addr *)req->id.idiag_src,
-					req->id.idiag_sport,
-					req->id.idiag_if, 0, tbl, NULL);
+					       (struct in6_addr *)req->id.idiag_dst,
+					       req->id.idiag_dport,
+					       (struct in6_addr *)req->id.idiag_src,
+					       req->id.idiag_sport,
+					       req->id.idiag_if, 0, NULL);
 	}
 #endif
 	else {
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 1f01e15ca24f..fd1a002b99d3 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -601,11 +601,10 @@ static struct sock *udp4_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
 					__be16 dport)
 {
 	const struct iphdr *iph = skb_gro_network_header(skb);
-	struct net *net = dev_net(skb->dev);
 
-	return __udp4_lib_lookup(net, iph->saddr, sport,
+	return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport,
 				 iph->daddr, dport, inet_iif(skb),
-				 inet_sdif(skb), net->ipv4.udp_table, NULL);
+				 inet_sdif(skb), NULL);
 }
 
 INDIRECT_CALLABLE_SCOPE
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 066e9b9ae5f0..f04bf69d13ea 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -207,7 +207,6 @@ static struct sock *udp6_lib_lookup2(struct net *net,
 }
 
 static inline struct sock *udp6_lookup_run_bpf(struct net *net,
-					       struct udp_table *udptable,
 					       struct sk_buff *skb,
 					       const struct in6_addr *saddr,
 					       __be16 sport,
@@ -217,9 +216,6 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net,
 	struct sock *sk, *reuse_sk;
 	bool no_reuseport;
 
-	if (udptable != net->ipv4.udp_table)
-		return NULL; /* only UDP is supported */
-
 	no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_UDP, saddr, sport,
 					    daddr, hnum, dif, &sk);
 	if (no_reuseport || IS_ERR_OR_NULL(sk))
@@ -235,9 +231,9 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net,
 struct sock *__udp6_lib_lookup(struct net *net,
 			       const struct in6_addr *saddr, __be16 sport,
 			       const struct in6_addr *daddr, __be16 dport,
-			       int dif, int sdif, struct udp_table *udptable,
-			       struct sk_buff *skb)
+			       int dif, int sdif, struct sk_buff *skb)
 {
+	struct udp_table *udptable = net->ipv4.udp_table;
 	unsigned short hnum = ntohs(dport);
 	unsigned int hash2, slot2;
 	struct udp_hslot *hslot2;
@@ -256,8 +252,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
 
 	/* Lookup redirect from BPF */
 	if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
-		sk = udp6_lookup_run_bpf(net, udptable, skb,
-					 saddr, sport, daddr, hnum, dif);
+		sk = udp6_lookup_run_bpf(net, skb, saddr, sport, daddr, hnum, dif);
 		if (sk) {
 			result = sk;
 			goto done;
@@ -284,25 +279,23 @@ struct sock *__udp6_lib_lookup(struct net *net,
 EXPORT_SYMBOL_GPL(__udp6_lib_lookup);
 
 static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
-					  __be16 sport, __be16 dport,
-					  struct udp_table *udptable)
+					  __be16 sport, __be16 dport)
 {
 	const struct ipv6hdr *iph = ipv6_hdr(skb);
 
 	return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport,
 				 &iph->daddr, dport, inet6_iif(skb),
-				 inet6_sdif(skb), udptable, skb);
+				 inet6_sdif(skb), skb);
 }
 
 struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
 				 __be16 sport, __be16 dport)
 {
 	const struct ipv6hdr *iph = ipv6_hdr(skb);
-	struct net *net = dev_net(skb->dev);
 
-	return __udp6_lib_lookup(net, &iph->saddr, sport,
+	return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport,
 				 &iph->daddr, dport, inet6_iif(skb),
-				 inet6_sdif(skb), net->ipv4.udp_table, NULL);
+				 inet6_sdif(skb), NULL);
 }
 
 /* Must be called under rcu_read_lock().
@@ -314,8 +307,7 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be
 {
 	struct sock *sk;
 
-	sk =  __udp6_lib_lookup(net, saddr, sport, daddr, dport,
-				dif, 0, net->ipv4.udp_table, NULL);
+	sk =  __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, 0, NULL);
 	if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
 		sk = NULL;
 	return sk;
@@ -515,7 +507,6 @@ static int __udp6_lib_err_encap_no_sk(struct sk_buff *skb,
 static struct sock *__udp6_lib_err_encap(struct net *net,
 					 const struct ipv6hdr *hdr, int offset,
 					 struct udphdr *uh,
-					 struct udp_table *udptable,
 					 struct sock *sk,
 					 struct sk_buff *skb,
 					 struct inet6_skb_parm *opt,
@@ -545,8 +536,7 @@ static struct sock *__udp6_lib_err_encap(struct net *net,
 	}
 
 	sk = __udp6_lib_lookup(net, &hdr->daddr, uh->source,
-			       &hdr->saddr, uh->dest,
-			       inet6_iif(skb), 0, udptable, skb);
+			       &hdr->saddr, uh->dest, inet6_iif(skb), 0, skb);
 	if (sk) {
 		up = udp_sk(sk);
 
@@ -567,9 +557,8 @@ static struct sock *__udp6_lib_err_encap(struct net *net,
 	return sk;
 }
 
-static int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-			  u8 type, u8 code, int offset, __be32 info,
-			  struct udp_table *udptable)
+static int udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+		     u8 type, u8 code, int offset, __be32 info)
 {
 	struct ipv6_pinfo *np;
 	const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
@@ -583,14 +572,13 @@ static int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	struct net *net = dev_net(skb->dev);
 
 	sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source,
-			       inet6_iif(skb), inet6_sdif(skb), udptable, NULL);
+			       inet6_iif(skb), inet6_sdif(skb), NULL);
 
 	if (!sk || udp_sk(sk)->encap_type) {
 		/* No socket for error: try tunnels before discarding */
 		if (static_branch_unlikely(&udpv6_encap_needed_key)) {
 			sk = __udp6_lib_err_encap(net, hdr, offset, uh,
-						  udptable, sk, skb,
-						  opt, type, code, info);
+						  sk, skb, opt, type, code, info);
 			if (!sk)
 				return 0;
 		} else
@@ -679,14 +667,6 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	return 0;
 }
 
-static __inline__ int udpv6_err(struct sk_buff *skb,
-				struct inet6_skb_parm *opt, u8 type,
-				u8 code, int offset, __be32 info)
-{
-	return __udp6_lib_err(skb, opt, type, code, offset, info,
-			      dev_net(skb->dev)->ipv4.udp_table);
-}
-
 static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
 {
 	enum skb_drop_reason drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
@@ -820,9 +800,9 @@ static void udp6_csum_zero_error(struct sk_buff *skb)
  */
 static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 				    const struct in6_addr *saddr,
-				    const struct in6_addr *daddr,
-				    struct udp_table *udptable)
+				    const struct in6_addr *daddr)
 {
+	struct udp_table *udptable = net->ipv4.udp_table;
 	int dif = inet6_iif(skb), sdif = inet6_sdif(skb);
 	unsigned int offset, hash2 = 0, hash2_any = 0;
 	const struct udphdr *uh = udp_hdr(skb);
@@ -1017,11 +997,10 @@ static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable)
 	 *	Multicast receive code
 	 */
 	if (ipv6_addr_is_multicast(daddr))
-		return __udp6_lib_mcast_deliver(net, skb,
-						saddr, daddr, udptable);
+		return __udp6_lib_mcast_deliver(net, skb, saddr, daddr);
 
 	/* Unicast */
-	sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
+	sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest);
 	if (sk) {
 		if (!uh->check && !udp_sk(sk)->no_check6_rx)
 			goto report_csum_error;
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index c39c1e32f980..2195ac83f077 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -117,11 +117,10 @@ static struct sock *udp6_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
 					__be16 dport)
 {
 	const struct ipv6hdr *iph = skb_gro_network_header(skb);
-	struct net *net = dev_net(skb->dev);
 
-	return __udp6_lib_lookup(net, &iph->saddr, sport,
+	return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport,
 				 &iph->daddr, dport, inet6_iif(skb),
-				 inet6_sdif(skb), net->ipv4.udp_table, NULL);
+				 inet6_sdif(skb), NULL);
 }
 
 INDIRECT_CALLABLE_SCOPE
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
                   ` (13 preceding siblings ...)
  2023-05-30  1:03 ` [PATCH v1 net-next 14/14] udp: Don't pass udp_table to __udp[46]_lib_lookup() Kuniyuki Iwashima
@ 2023-05-30  2:15 ` Willem de Bruijn
  2023-05-30 17:34   ` Kuniyuki Iwashima
  14 siblings, 1 reply; 29+ messages in thread
From: Willem de Bruijn @ 2023-05-30  2:15 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Kuniyuki Iwashima, netdev

On Mon, May 29, 2023 at 9:04 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> Recently syzkaller reported a 7-year-old null-ptr-deref [0] that occurs
> when a UDP-Lite socket tries to allocate a buffer under memory pressure.
>
> Someone should have stumbled on the bug much earlier if UDP-Lite had been
> used in a real app.  Additionally, we do not always need a large UDP-Lite
> workload to hit the bug since UDP and UDP-Lite share the same memory
> accounting limit.
>
> Given no one uses UDP-Lite, we can drop it and simplify UDP code by
> removing a bunch of conditionals.
>
> This series removes UDP-Lite support from the core networking stack first
> and incrementally removes the dead code.
>
> [0]: https://lore.kernel.org/netdev/20230523163305.66466-1-kuniyu@amazon.com/

Even if there is high confidence that this protocol is unused, for
which I'm not sure the above is sufficient proof, it should be
disabled first and left in place, and removed only when there is no
chance that it has to be re-enabled.

We already have code churn here from the split between UDP and
UDPLite, which was reverted in commit db8dac20d519 ("[UDP]: Revert
udplite and code split."). This series would be an enormous change to
revert. And if sufficient time passes in between, there might be ample
patch conflicts, the fixups of which are sources for subtle bugs.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 01/14] udp: Random clenaup.
  2023-05-30  1:03 ` [PATCH v1 net-next 01/14] udp: Random clenaup Kuniyuki Iwashima
@ 2023-05-30 12:56   ` Simon Horman
  0 siblings, 0 replies; 29+ messages in thread
From: Simon Horman @ 2023-05-30 12:56 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn, Kuniyuki Iwashima, netdev

On Mon, May 29, 2023 at 06:03:35PM -0700, Kuniyuki Iwashima wrote:
> This is preparation patch to make the following diff smaller.
> 
> No functional changes are intended:
> 
>   - Keep Reverse Xmas Tree Order
>   - Define struct net instead of using sock_net() repeatedly
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>

Reviewed-by: Simon Horman <simon.horman@corigine.com>


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6.
  2023-05-30  1:03 ` [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6 Kuniyuki Iwashima
@ 2023-05-30 13:01   ` Simon Horman
  2023-05-30 17:49     ` Kuniyuki Iwashima
  0 siblings, 1 reply; 29+ messages in thread
From: Simon Horman @ 2023-05-30 13:01 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn, Kuniyuki Iwashima, netdev

On Mon, May 29, 2023 at 06:03:36PM -0700, Kuniyuki Iwashima wrote:
> We no longer support IPPROTO_UDPLITE for AF_INET6.
> 
> This commit removes udplite.c and udp_impl.h under net/ipv6 and makes
> some functions static that UDP shared.
> 
> Note that udplite.h is included in udp.c temporarily not to introduce
> breakage, but we will remove it later with dead code.
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>

...

> diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
> deleted file mode 100644
> index 0590f566379d..000000000000
> --- a/net/ipv6/udp_impl.h
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _UDP6_IMPL_H
> -#define _UDP6_IMPL_H
> -#include <net/udp.h>
> -#include <net/udplite.h>
> -#include <net/protocol.h>
> -#include <net/addrconf.h>
> -#include <net/inet_common.h>
> -#include <net/transp_v6.h>
> -
> -int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int);
> -int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
> -		   __be32, struct udp_table *);
> -
> -int udpv6_init_sock(struct sock *sk);
> -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);
> -int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
> -		     unsigned int optlen);
> -int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
> -int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
> -		  int *addr_len);

clang-16 with W=1 complains that:

 +net/ipv6/udp.c:341:5: warning: no previous prototype for 'udpv6_recvmsg' [-Wmissing-prototypes]
 +  341 | int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 +      |     ^~~~~~~~~~~~~
 +net/ipv6/udp.c:1335:5: warning: no previous prototype for 'udpv6_sendmsg' [-Wmissing-prototypes]
 + 1335 | int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 +      |     ^~~~~~~~~~~~~

Likewise it has similar complains about ipv4 in a subsequent patch.

> -void udpv6_destroy_sock(struct sock *sk);
> -
> -#ifdef CONFIG_PROC_FS
> -int udp6_seq_show(struct seq_file *seq, void *v);
> -#endif
> -#endif	/* _UDP6_IMPL_H */

...

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 03/14] ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE.
  2023-05-30  1:03 ` [PATCH v1 net-next 03/14] ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE Kuniyuki Iwashima
@ 2023-05-30 14:22   ` Simon Horman
  0 siblings, 0 replies; 29+ messages in thread
From: Simon Horman @ 2023-05-30 14:22 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn, Kuniyuki Iwashima, netdev

On Mon, May 29, 2023 at 06:03:37PM -0700, Kuniyuki Iwashima wrote:
> The previous commit removes UDP-Lite v6 support, so conversion
> from UDP-Lite v6 to v4 never occurs.
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>

Reviewed-by: Simon Horman <simon.horman@corigine.com>


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 05/14] udp: Remove UDP-Lite SNMP stats.
  2023-05-30  1:03 ` [PATCH v1 net-next 05/14] udp: Remove UDP-Lite SNMP stats Kuniyuki Iwashima
@ 2023-05-30 14:24   ` Simon Horman
  0 siblings, 0 replies; 29+ messages in thread
From: Simon Horman @ 2023-05-30 14:24 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Willem de Bruijn, Kuniyuki Iwashima, netdev

On Mon, May 29, 2023 at 06:03:39PM -0700, Kuniyuki Iwashima wrote:
> We stored UDP-Lite stats in udplite_statistics and udplite_stats_in6
> of struct netns_mib.
> 
> Since UDP and UDP-Lite share code, UDP_INC_STATS() always has to
> check if the socket is UDP-Lite.  However, we no longer increment
> UDP-Lite stats.
> 
> Let's remove the stats and save one protocol test.
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>

...

> diff --git a/include/net/udp.h b/include/net/udp.h
> index bfe62e73552a..d00509873f6f 100644
> --- a/include/net/udp.h
> +++ b/include/net/udp.h
> @@ -390,37 +390,28 @@ static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
>  }
>  
>  /*
> - * 	SNMP statistics for UDP and UDP-Lite
> + * 	SNMP statistics for UDP

nit: While we are here perhaps the space before the tab can be removed.

Otherwise, LGTM.

Reviewed-by: Simon Horman <simon.horman@corigine.com>


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-30  2:15 ` [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Willem de Bruijn
@ 2023-05-30 17:34   ` Kuniyuki Iwashima
  2023-05-30 20:16     ` Willem de Bruijn
  0 siblings, 1 reply; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30 17:34 UTC (permalink / raw)
  To: willemdebruijn.kernel
  Cc: davem, dsahern, edumazet, kuba, kuni1840, kuniyu, netdev, pabeni

From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Mon, 29 May 2023 22:15:06 -0400
> On Mon, May 29, 2023 at 9:04 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
> >
> > Recently syzkaller reported a 7-year-old null-ptr-deref [0] that occurs
> > when a UDP-Lite socket tries to allocate a buffer under memory pressure.
> >
> > Someone should have stumbled on the bug much earlier if UDP-Lite had been
> > used in a real app.  Additionally, we do not always need a large UDP-Lite
> > workload to hit the bug since UDP and UDP-Lite share the same memory
> > accounting limit.
> >
> > Given no one uses UDP-Lite, we can drop it and simplify UDP code by
> > removing a bunch of conditionals.
> >
> > This series removes UDP-Lite support from the core networking stack first
> > and incrementally removes the dead code.
> >
> > [0]: https://lore.kernel.org/netdev/20230523163305.66466-1-kuniyu@amazon.com/
> 
> Even if there is high confidence that this protocol is unused, for
> which I'm not sure the above is sufficient proof, it should be
> disabled first and left in place, and removed only when there is no
> chance that it has to be re-enabled.
> 
> We already have code churn here from the split between UDP and
> UDPLite, which was reverted in commit db8dac20d519 ("[UDP]: Revert
> udplite and code split."). This series would be an enormous change to
> revert. And if sufficient time passes in between, there might be ample
> patch conflicts, the fixups of which are sources for subtle bugs.

Thanks Willem, I didn't know someone attempted to disable UDP-Lite.

You may prefer this way.
https://lore.kernel.org/netdev/20230525151011.84390-1-kuniyu@amazon.com/

I'm fine whichever, but the next question will be like how long should we
wait ?  We happen to know that we have already waited for 7 years.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6.
  2023-05-30 13:01   ` Simon Horman
@ 2023-05-30 17:49     ` Kuniyuki Iwashima
  0 siblings, 0 replies; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-30 17:49 UTC (permalink / raw)
  To: simon.horman
  Cc: davem, dsahern, edumazet, kuba, kuni1840, kuniyu, netdev, pabeni,
	willemdebruijn.kernel

From: Simon Horman <simon.horman@corigine.com>
Date: Tue, 30 May 2023 15:01:11 +0200
> On Mon, May 29, 2023 at 06:03:36PM -0700, Kuniyuki Iwashima wrote:
> > We no longer support IPPROTO_UDPLITE for AF_INET6.
> > 
> > This commit removes udplite.c and udp_impl.h under net/ipv6 and makes
> > some functions static that UDP shared.
> > 
> > Note that udplite.h is included in udp.c temporarily not to introduce
> > breakage, but we will remove it later with dead code.
> > 
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> 
> ...
> 
> > diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
> > deleted file mode 100644
> > index 0590f566379d..000000000000
> > --- a/net/ipv6/udp_impl.h
> > +++ /dev/null
> > @@ -1,31 +0,0 @@
> > -/* SPDX-License-Identifier: GPL-2.0 */
> > -#ifndef _UDP6_IMPL_H
> > -#define _UDP6_IMPL_H
> > -#include <net/udp.h>
> > -#include <net/udplite.h>
> > -#include <net/protocol.h>
> > -#include <net/addrconf.h>
> > -#include <net/inet_common.h>
> > -#include <net/transp_v6.h>
> > -
> > -int __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int);
> > -int __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, u8, u8, int,
> > -		   __be32, struct udp_table *);
> > -
> > -int udpv6_init_sock(struct sock *sk);
> > -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);
> > -int udpv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
> > -		     unsigned int optlen);
> > -int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
> > -int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
> > -		  int *addr_len);
> 
> clang-16 with W=1 complains that:
> 
>  +net/ipv6/udp.c:341:5: warning: no previous prototype for 'udpv6_recvmsg' [-Wmissing-prototypes]
>  +  341 | int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  +      |     ^~~~~~~~~~~~~
>  +net/ipv6/udp.c:1335:5: warning: no previous prototype for 'udpv6_sendmsg' [-Wmissing-prototypes]
>  + 1335 | int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
>  +      |     ^~~~~~~~~~~~~
> 
> Likewise it has similar complains about ipv4 in a subsequent patch.

Good catch!

This series survived allmodconfig and allyesconfig with gcc, but I
didn't add W=1.

Will fix it, thanks!


> 
> > -void udpv6_destroy_sock(struct sock *sk);
> > -
> > -#ifdef CONFIG_PROC_FS
> > -int udp6_seq_show(struct seq_file *seq, void *v);
> > -#endif
> > -#endif	/* _UDP6_IMPL_H */

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-30 17:34   ` Kuniyuki Iwashima
@ 2023-05-30 20:16     ` Willem de Bruijn
  2023-05-30 22:14       ` Jakub Kicinski
  0 siblings, 1 reply; 29+ messages in thread
From: Willem de Bruijn @ 2023-05-30 20:16 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: davem, dsahern, edumazet, kuba, kuni1840, netdev, pabeni

On Tue, May 30, 2023 at 1:34 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
> Date: Mon, 29 May 2023 22:15:06 -0400
> > On Mon, May 29, 2023 at 9:04 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
> > >
> > > Recently syzkaller reported a 7-year-old null-ptr-deref [0] that occurs
> > > when a UDP-Lite socket tries to allocate a buffer under memory pressure.
> > >
> > > Someone should have stumbled on the bug much earlier if UDP-Lite had been
> > > used in a real app.  Additionally, we do not always need a large UDP-Lite
> > > workload to hit the bug since UDP and UDP-Lite share the same memory
> > > accounting limit.
> > >
> > > Given no one uses UDP-Lite, we can drop it and simplify UDP code by
> > > removing a bunch of conditionals.
> > >
> > > This series removes UDP-Lite support from the core networking stack first
> > > and incrementally removes the dead code.
> > >
> > > [0]: https://lore.kernel.org/netdev/20230523163305.66466-1-kuniyu@amazon.com/
> >
> > Even if there is high confidence that this protocol is unused, for
> > which I'm not sure the above is sufficient proof, it should be
> > disabled first and left in place, and removed only when there is no
> > chance that it has to be re-enabled.
> >
> > We already have code churn here from the split between UDP and
> > UDPLite, which was reverted in commit db8dac20d519 ("[UDP]: Revert
> > udplite and code split."). This series would be an enormous change to
> > revert. And if sufficient time passes in between, there might be ample
> > patch conflicts, the fixups of which are sources for subtle bugs.
>
> Thanks Willem, I didn't know someone attempted to disable UDP-Lite.
>
> You may prefer this way.
> https://lore.kernel.org/netdev/20230525151011.84390-1-kuniyu@amazon.com/
>
> I'm fine whichever, but the next question will be like how long should we
> wait ?  We happen to know that we have already waited for 7 years.

Is it a significant burden to keep the protocol, in case anyone is
willing to maintain it?

If consensus is that it is time to remove, a warning may not be
sufficient for people to notice.

Perhaps break it, but in a way that can be undone trivially,
preferably even without recompiling the kernel. Say, returning
EOPNOTSUPP on socket creation, unless a sysctl has some magic
non-deprecated value. But maybe I'm overthinking it. There must be
prior art for this?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-30 20:16     ` Willem de Bruijn
@ 2023-05-30 22:14       ` Jakub Kicinski
  2023-05-31  1:01         ` Kuniyuki Iwashima
  0 siblings, 1 reply; 29+ messages in thread
From: Jakub Kicinski @ 2023-05-30 22:14 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: Kuniyuki Iwashima, davem, dsahern, edumazet, kuni1840, netdev, pabeni

On Tue, 30 May 2023 16:16:20 -0400 Willem de Bruijn wrote:
> Is it a significant burden to keep the protocol, in case anyone is
> willing to maintain it?
> 
> If consensus is that it is time to remove, a warning may not be
> sufficient for people to notice.
> 
> Perhaps break it, but in a way that can be undone trivially,
> preferably even without recompiling the kernel. Say, returning
> EOPNOTSUPP on socket creation, unless a sysctl has some magic
> non-deprecated value. But maybe I'm overthinking it. There must be
> prior art for this?

It may be the most intertwined feature we attempted to remove.
UFO was smaller, right?

Did deprecation warnings ever work? 

How about we try to push a WARN_ONCE() on socket creation to net and
stable? With a message along the lines of "UDP lite is assumed to have
no users, and is been deleted, please contact netdev@.."

Then delete the whole thing in net-next? Hopefully pushing to stable
would expedite user reports? We'll find out if Greg throws rotten fruit
at us or not..

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-30 22:14       ` Jakub Kicinski
@ 2023-05-31  1:01         ` Kuniyuki Iwashima
  2023-05-31  4:25           ` Eric Dumazet
  0 siblings, 1 reply; 29+ messages in thread
From: Kuniyuki Iwashima @ 2023-05-31  1:01 UTC (permalink / raw)
  To: kuba
  Cc: davem, dsahern, edumazet, kuni1840, kuniyu, netdev, pabeni,
	willemdebruijn.kernel

From: Jakub Kicinski <kuba@kernel.org>
Date: Tue, 30 May 2023 15:14:01 -0700
> On Tue, 30 May 2023 16:16:20 -0400 Willem de Bruijn wrote:
> > Is it a significant burden to keep the protocol, in case anyone is
> > willing to maintain it?
> > 
> > If consensus is that it is time to remove, a warning may not be
> > sufficient for people to notice.
> > 
> > Perhaps break it, but in a way that can be undone trivially,
> > preferably even without recompiling the kernel. Say, returning
> > EOPNOTSUPP on socket creation, unless a sysctl has some magic
> > non-deprecated value. But maybe I'm overthinking it. There must be
> > prior art for this?
> 
> It may be the most intertwined feature we attempted to remove.
> UFO was smaller, right?
> 
> Did deprecation warnings ever work? 
> 
> How about we try to push a WARN_ONCE() on socket creation to net and
> stable? With a message along the lines of "UDP lite is assumed to have
> no users, and is been deleted, please contact netdev@.."
> 
> Then delete the whole thing in net-next? Hopefully pushing to stable
> would expedite user reports? We'll find out if Greg throws rotten fruit
> at us or not..

Yes, if it's ok, it would be better to add a WARN_ONCE() to stable.

If we added it only in net-next, no one might notice it and we could
remove UDP-Lite before the warning is available in the next LTS stable
tree.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-31  1:01         ` Kuniyuki Iwashima
@ 2023-05-31  4:25           ` Eric Dumazet
  2023-05-31  5:10             ` Jakub Kicinski
  0 siblings, 1 reply; 29+ messages in thread
From: Eric Dumazet @ 2023-05-31  4:25 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: kuba, davem, dsahern, kuni1840, netdev, pabeni, willemdebruijn.kernel

On Wed, May 31, 2023 at 3:01 AM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> From: Jakub Kicinski <kuba@kernel.org>
> Date: Tue, 30 May 2023 15:14:01 -0700
> > On Tue, 30 May 2023 16:16:20 -0400 Willem de Bruijn wrote:
> > > Is it a significant burden to keep the protocol, in case anyone is
> > > willing to maintain it?
> > >
> > > If consensus is that it is time to remove, a warning may not be
> > > sufficient for people to notice.
> > >
> > > Perhaps break it, but in a way that can be undone trivially,
> > > preferably even without recompiling the kernel. Say, returning
> > > EOPNOTSUPP on socket creation, unless a sysctl has some magic
> > > non-deprecated value. But maybe I'm overthinking it. There must be
> > > prior art for this?
> >
> > It may be the most intertwined feature we attempted to remove.
> > UFO was smaller, right?
> >
> > Did deprecation warnings ever work?
> >
> > How about we try to push a WARN_ONCE() on socket creation to net and
> > stable? With a message along the lines of "UDP lite is assumed to have
> > no users, and is been deleted, please contact netdev@.."
> >
> > Then delete the whole thing in net-next? Hopefully pushing to stable
> > would expedite user reports? We'll find out if Greg throws rotten fruit
> > at us or not..
>
> Yes, if it's ok, it would be better to add a WARN_ONCE() to stable.
>
> If we added it only in net-next, no one might notice it and we could
> remove UDP-Lite before the warning is available in the next LTS stable
> tree.

WARN_ONCE() will fire a syzbot report.

Honestly I do not  think UDP-Lite is a significant burden.

What about instead adding a CONFIG_UDPLITE and default it to
"CONFIG_UDPLITE is not set" ?

And add a static key, with /proc/sys/net/core/udplite_enable to
eventually save some cycles in various fast paths
and let the user opt-in, in case it is using a distro kernel. with
CONFIG_UDPLITE=y

DCCP is more interesting because removing it would allow for a better
organisation of tcp fields to reduce
number of cache lines hit in the fast path.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-31  4:25           ` Eric Dumazet
@ 2023-05-31  5:10             ` Jakub Kicinski
  2023-05-31  6:24               ` Paolo Abeni
  0 siblings, 1 reply; 29+ messages in thread
From: Jakub Kicinski @ 2023-05-31  5:10 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Kuniyuki Iwashima, davem, dsahern, kuni1840, netdev, pabeni,
	willemdebruijn.kernel

On Wed, 31 May 2023 06:25:33 +0200 Eric Dumazet wrote:
> > Yes, if it's ok, it would be better to add a WARN_ONCE() to stable.
> >
> > If we added it only in net-next, no one might notice it and we could
> > remove UDP-Lite before the warning is available in the next LTS stable
> > tree.  
> 
> WARN_ONCE() will fire a syzbot report.
> 
> Honestly I do not  think UDP-Lite is a significant burden.
> 
> What about instead adding a CONFIG_UDPLITE and default it to
> "CONFIG_UDPLITE is not set" ?
> 
> And add a static key, with /proc/sys/net/core/udplite_enable to
> eventually save some cycles in various fast paths
> and let the user opt-in, in case it is using a distro kernel. with
> CONFIG_UDPLITE=y

oohm, fair point user-reachable WARN() is a liability.
CONFIG_UDPLITE sounds like the best available option :(
With an appropriately discouraging config text.
That way syzbot can prevent bitrot but distros will hopefully drop it.

> DCCP is more interesting because removing it would allow for a better
> organisation of tcp fields to reduce
> number of cache lines hit in the fast path.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-31  5:10             ` Jakub Kicinski
@ 2023-05-31  6:24               ` Paolo Abeni
  2023-05-31  6:44                 ` Jakub Kicinski
  0 siblings, 1 reply; 29+ messages in thread
From: Paolo Abeni @ 2023-05-31  6:24 UTC (permalink / raw)
  To: Jakub Kicinski, Eric Dumazet
  Cc: Kuniyuki Iwashima, davem, dsahern, kuni1840, netdev,
	willemdebruijn.kernel

On Tue, 2023-05-30 at 22:10 -0700, Jakub Kicinski wrote:
> On Wed, 31 May 2023 06:25:33 +0200 Eric Dumazet wrote:
> > > Yes, if it's ok, it would be better to add a WARN_ONCE() to stable.
> > > 
> > > If we added it only in net-next, no one might notice it and we could
> > > remove UDP-Lite before the warning is available in the next LTS stable
> > > tree.  
> > 
> > WARN_ONCE() will fire a syzbot report.
> > 
> > Honestly I do not  think UDP-Lite is a significant burden.
> > 
> > What about instead adding a CONFIG_UDPLITE and default it to
> > "CONFIG_UDPLITE is not set" ?
> > 
> > And add a static key, with /proc/sys/net/core/udplite_enable to
> > eventually save some cycles in various fast paths
> > and let the user opt-in, in case it is using a distro kernel. with
> > CONFIG_UDPLITE=y
> 
> oohm, fair point user-reachable WARN() is a liability.

What about a plain pr_warn_once() banner, verbose enough to be
noticeable? Alike:

https://lwn.net/ml/linux-fsdevel/20220225125445.29942-1-jack@suse.cz/


Cheers,

Paolo


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite.
  2023-05-31  6:24               ` Paolo Abeni
@ 2023-05-31  6:44                 ` Jakub Kicinski
  0 siblings, 0 replies; 29+ messages in thread
From: Jakub Kicinski @ 2023-05-31  6:44 UTC (permalink / raw)
  To: Paolo Abeni
  Cc: Eric Dumazet, Kuniyuki Iwashima, davem, dsahern, kuni1840,
	netdev, willemdebruijn.kernel

On Wed, 31 May 2023 08:24:02 +0200 Paolo Abeni wrote:
> > oohm, fair point user-reachable WARN() is a liability.  
> 
> What about a plain pr_warn_once() banner, verbose enough to be
> noticeable? Alike:
> 
> https://lwn.net/ml/linux-fsdevel/20220225125445.29942-1-jack@suse.cz/

SGTM, I think the config option will do the heavy lifting, but doesn't
hurt to throw in a print as well.

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2023-05-31  6:44 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-30  1:03 [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 01/14] udp: Random clenaup Kuniyuki Iwashima
2023-05-30 12:56   ` Simon Horman
2023-05-30  1:03 ` [PATCH v1 net-next 02/14] udplite: Retire UDP-Lite for IPv6 Kuniyuki Iwashima
2023-05-30 13:01   ` Simon Horman
2023-05-30 17:49     ` Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 03/14] ipv6: Remove IPV6_ADDRFORM support for IPPROTO_UDPLITE Kuniyuki Iwashima
2023-05-30 14:22   ` Simon Horman
2023-05-30  1:03 ` [PATCH v1 net-next 04/14] udplite: Retire UDP-Lite for IPv4 Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 05/14] udp: Remove UDP-Lite SNMP stats Kuniyuki Iwashima
2023-05-30 14:24   ` Simon Horman
2023-05-30  1:03 ` [PATCH v1 net-next 06/14] udp: Remove UDPLITE_SEND_CSCOV and UDPLITE_RECV_CSCOV Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 07/14] udp: Remove pcslen, pcrlen, and pcflag in struct udp_sock Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 08/14] udp: Remove csum branch for UDP-Lite Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 09/14] udp: Don't pass proto to udp[46]_csum_init() Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 10/14] udp: Don't pass proto to __udp[46]_lib_rcv() Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 11/14] udp: Optimise ulen tests in __udp[46]_lib_rcv() Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 12/14] udp: Remove udp_table in struct proto Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 13/14] udp: Remove udp_table in struct udp_seq_afinfo Kuniyuki Iwashima
2023-05-30  1:03 ` [PATCH v1 net-next 14/14] udp: Don't pass udp_table to __udp[46]_lib_lookup() Kuniyuki Iwashima
2023-05-30  2:15 ` [PATCH v1 net-next 00/14] udp: Farewell to UDP-Lite Willem de Bruijn
2023-05-30 17:34   ` Kuniyuki Iwashima
2023-05-30 20:16     ` Willem de Bruijn
2023-05-30 22:14       ` Jakub Kicinski
2023-05-31  1:01         ` Kuniyuki Iwashima
2023-05-31  4:25           ` Eric Dumazet
2023-05-31  5:10             ` Jakub Kicinski
2023-05-31  6:24               ` Paolo Abeni
2023-05-31  6:44                 ` Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.