All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adel Abouchaev <adel.abushaev@gmail.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, corbet@lwn.net, dsahern@kernel.org,
	shuah@kernel.org, paul@paul-moore.com, jmorris@namei.org,
	serge@hallyn.com, linux-security-module@vger.kernel.org,
	netdev@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kselftest@vger.kernel.org
Subject: [net-next v4 3/6] net: Add UDP ULP operations, initialization and handling prototype functions.
Date: Thu,  8 Sep 2022 17:12:35 -0700	[thread overview]
Message-ID: <20220909001238.3965798-4-adel.abushaev@gmail.com> (raw)
In-Reply-To: <20220909001238.3965798-1-adel.abushaev@gmail.com>

Define functions to add UDP ULP handling, registration with UDP protocol
and supporting data structures. Create structure for QUIC ULP and add empty
prototype functions to support it.

Signed-off-by: Adel Abouchaev <adel.abushaev@gmail.com>

---

Removed reference to net/quic/Kconfig from this patch into the next.

Fixed formatting around brackets.
---
 include/net/inet_sock.h  |   2 +
 include/net/udp.h        |  33 +++++++
 include/uapi/linux/udp.h |   1 +
 net/Makefile             |   1 +
 net/ipv4/Makefile        |   3 +-
 net/ipv4/udp.c           |   6 ++
 net/ipv4/udp_ulp.c       | 192 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 net/ipv4/udp_ulp.c

diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index bf5654ce711e..650e332bdb50 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -249,6 +249,8 @@ struct inet_sock {
 	__be32			mc_addr;
 	struct ip_mc_socklist __rcu	*mc_list;
 	struct inet_cork_full	cork;
+	const struct udp_ulp_ops	*udp_ulp_ops;
+	void __rcu		*ulp_data;
 };
 
 #define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
diff --git a/include/net/udp.h b/include/net/udp.h
index 5ee88ddf79c3..f22ebabbb186 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -523,4 +523,37 @@ struct proto *udp_bpf_get_proto(struct sock *sk, struct sk_psock *psock);
 int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore);
 #endif
 
+/*
+ * Interface for adding Upper Level Protocols over UDP
+ */
+
+#define UDP_ULP_NAME_MAX	16
+#define UDP_ULP_MAX		128
+
+struct udp_ulp_ops {
+	struct list_head	list;
+
+	/* initialize ulp */
+	int (*init)(struct sock *sk);
+	/* cleanup ulp */
+	void (*release)(struct sock *sk);
+
+	char		name[UDP_ULP_NAME_MAX];
+	struct module	*owner;
+};
+
+int udp_register_ulp(struct udp_ulp_ops *type);
+void udp_unregister_ulp(struct udp_ulp_ops *type);
+int udp_set_ulp(struct sock *sk, const char *name);
+void udp_get_available_ulp(char *buf, size_t len);
+void udp_cleanup_ulp(struct sock *sk);
+int udp_setsockopt_ulp(struct sock *sk, sockptr_t optval,
+		       unsigned int optlen);
+int udp_getsockopt_ulp(struct sock *sk, char __user *optval,
+		       int __user *optlen);
+
+#define MODULE_ALIAS_UDP_ULP(name)\
+	__MODULE_INFO(alias, alias_userspace, name);\
+	__MODULE_INFO(alias, alias_udp_ulp, "udp-ulp-" name)
+
 #endif	/* _UDP_H */
diff --git a/include/uapi/linux/udp.h b/include/uapi/linux/udp.h
index 0ee4c598e70b..893691f0108a 100644
--- a/include/uapi/linux/udp.h
+++ b/include/uapi/linux/udp.h
@@ -34,6 +34,7 @@ struct udphdr {
 #define UDP_NO_CHECK6_RX 102	/* Disable accpeting checksum for UDP6 */
 #define UDP_SEGMENT	103	/* Set GSO segmentation size */
 #define UDP_GRO		104	/* This socket can receive UDP GRO packets */
+#define UDP_ULP		105	/* Attach ULP to a UDP socket */
 #define UDP_QUIC_ADD_TX_CONNECTION	106 /* Add QUIC Tx crypto offload */
 #define UDP_QUIC_DEL_TX_CONNECTION	107 /* Del QUIC Tx crypto offload */
 #define UDP_QUIC_ENCRYPT		108 /* QUIC encryption parameters */
diff --git a/net/Makefile b/net/Makefile
index 6a62e5b27378..021ea3698d3a 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -16,6 +16,7 @@ obj-y				+= ethernet/ 802/ sched/ netlink/ bpf/ ethtool/
 obj-$(CONFIG_NETFILTER)		+= netfilter/
 obj-$(CONFIG_INET)		+= ipv4/
 obj-$(CONFIG_TLS)		+= tls/
+obj-$(CONFIG_QUIC)		+= quic/
 obj-$(CONFIG_XFRM)		+= xfrm/
 obj-$(CONFIG_UNIX_SCM)		+= unix/
 obj-y				+= ipv6/
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index bbdd9c44f14e..88d3baf4af95 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -14,7 +14,8 @@ obj-y     := route.o inetpeer.o protocol.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 \
-	     metrics.o netlink.o nexthop.o udp_tunnel_stub.o
+	     metrics.o netlink.o nexthop.o udp_tunnel_stub.o \
+	     udp_ulp.o
 
 obj-$(CONFIG_BPFILTER) += bpfilter/
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index cd72158e953a..0f5c842dbd3f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2781,6 +2781,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 		up->pcflag |= UDPLITE_RECV_CC;
 		break;
 
+	case UDP_ULP:
+		return udp_setsockopt_ulp(sk, optval, optlen);
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -2849,6 +2852,9 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 		val = up->pcrlen;
 		break;
 
+	case UDP_ULP:
+		return udp_getsockopt_ulp(sk, optval, optlen);
+
 	default:
 		return -ENOPROTOOPT;
 	}
diff --git a/net/ipv4/udp_ulp.c b/net/ipv4/udp_ulp.c
new file mode 100644
index 000000000000..138818690151
--- /dev/null
+++ b/net/ipv4/udp_ulp.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Pluggable UDP upper layer protocol support, based on pluggable TCP upper
+ * layer protocol support.
+ *
+ * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights
+ * reserved.
+ * Copyright (c) 2021-2022, Meta Platforms, Inc. All rights reserved.
+ */
+
+#include <linux/gfp.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/skmsg.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+
+static DEFINE_SPINLOCK(udp_ulp_list_lock);
+static LIST_HEAD(udp_ulp_list);
+
+/* Simple linear search, don't expect many entries! */
+static struct udp_ulp_ops *udp_ulp_find(const char *name)
+{
+	struct udp_ulp_ops *e;
+
+	list_for_each_entry_rcu(e, &udp_ulp_list, list,
+				lockdep_is_held(&udp_ulp_list_lock)) {
+		if (strcmp(e->name, name) == 0)
+			return e;
+	}
+
+	return NULL;
+}
+
+static const struct udp_ulp_ops *__udp_ulp_find_autoload(const char *name)
+{
+	const struct udp_ulp_ops *ulp = NULL;
+
+	rcu_read_lock();
+	ulp = udp_ulp_find(name);
+
+#ifdef CONFIG_MODULES
+	if (!ulp && capable(CAP_NET_ADMIN)) {
+		rcu_read_unlock();
+		request_module("udp-ulp-%s", name);
+		rcu_read_lock();
+		ulp = udp_ulp_find(name);
+	}
+#endif
+	if (!ulp || !try_module_get(ulp->owner))
+		ulp = NULL;
+
+	rcu_read_unlock();
+	return ulp;
+}
+
+/* Attach new upper layer protocol to the list
+ * of available protocols.
+ */
+int udp_register_ulp(struct udp_ulp_ops *ulp)
+{
+	int ret = 0;
+
+	spin_lock(&udp_ulp_list_lock);
+	if (udp_ulp_find(ulp->name))
+		ret = -EEXIST;
+	else
+		list_add_tail_rcu(&ulp->list, &udp_ulp_list);
+
+	spin_unlock(&udp_ulp_list_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(udp_register_ulp);
+
+void udp_unregister_ulp(struct udp_ulp_ops *ulp)
+{
+	spin_lock(&udp_ulp_list_lock);
+	list_del_rcu(&ulp->list);
+	spin_unlock(&udp_ulp_list_lock);
+
+	synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(udp_unregister_ulp);
+
+void udp_cleanup_ulp(struct sock *sk)
+{
+	struct inet_sock *inet = inet_sk(sk);
+
+	/* No sock_owned_by_me() check here as at the time the
+	 * stack calls this function, the socket is dead and
+	 * about to be destroyed.
+	 */
+	if (!inet->udp_ulp_ops)
+		return;
+
+	if (inet->udp_ulp_ops->release)
+		inet->udp_ulp_ops->release(sk);
+	module_put(inet->udp_ulp_ops->owner);
+
+	inet->udp_ulp_ops = NULL;
+}
+
+static int __udp_set_ulp(struct sock *sk, const struct udp_ulp_ops *ulp_ops)
+{
+	struct inet_sock *inet = inet_sk(sk);
+	int err;
+
+	err = -EEXIST;
+	if (inet->udp_ulp_ops)
+		goto out_err;
+
+	err = ulp_ops->init(sk);
+	if (err)
+		goto out_err;
+
+	inet->udp_ulp_ops = ulp_ops;
+	return 0;
+
+out_err:
+	module_put(ulp_ops->owner);
+	return err;
+}
+
+int udp_set_ulp(struct sock *sk, const char *name)
+{
+	struct sk_psock *psock = sk_psock_get(sk);
+	const struct udp_ulp_ops *ulp_ops;
+
+	if (psock) {
+		sk_psock_put(sk, psock);
+		return -EINVAL;
+	}
+
+	sock_owned_by_me(sk);
+	ulp_ops = __udp_ulp_find_autoload(name);
+	if (!ulp_ops)
+		return -ENOENT;
+
+	return __udp_set_ulp(sk, ulp_ops);
+}
+
+int udp_setsockopt_ulp(struct sock *sk, sockptr_t optval, unsigned int optlen)
+{
+	char name[UDP_ULP_NAME_MAX];
+	int val, err;
+
+	if (!optlen || optlen > UDP_ULP_NAME_MAX)
+		return -EINVAL;
+
+	val = strncpy_from_sockptr(name, optval, optlen);
+	if (val < 0)
+		return -EFAULT;
+
+	if (val == UDP_ULP_NAME_MAX)
+		return -EINVAL;
+
+	name[val] = 0;
+	lock_sock(sk);
+	err = udp_set_ulp(sk, name);
+	release_sock(sk);
+	return err;
+}
+
+int udp_getsockopt_ulp(struct sock *sk, char __user *optval, int __user *optlen)
+{
+	struct inet_sock *inet = inet_sk(sk);
+	int len;
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	len = min_t(unsigned int, len, UDP_ULP_NAME_MAX);
+	if (len < 0)
+		return -EINVAL;
+
+	if (!inet->udp_ulp_ops) {
+		if (put_user(0, optlen))
+			return -EFAULT;
+		return 0;
+	}
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+	if (copy_to_user(optval, inet->udp_ulp_ops->name, len))
+		return -EFAULT;
+
+	return 0;
+}
-- 
2.30.2


  parent reply	other threads:[~2022-09-09  0:13 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Adel Abouchaev <adel.abushaev@gmail.com>
2022-08-01 19:52 ` [RFC net-next 0/6] net: support QUIC crypto Adel Abouchaev
2022-08-01 19:52   ` [RFC net-next 1/6] net: Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-08-01 19:52   ` [RFC net-next 2/6] net: Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-08-01 19:52   ` [RFC net-next 3/6] net: Add UDP ULP operations, initialization and handling prototype functions Adel Abouchaev
2022-08-01 19:52   ` [RFC net-next 4/6] net: Implement QUIC offload functions Adel Abouchaev
2022-08-01 19:52   ` [RFC net-next 5/6] net: Add flow counters and Tx processing error counter Adel Abouchaev
2022-08-01 19:52   ` [RFC net-next 6/6] net: Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev
2022-08-05  3:37   ` [RFC net-next 0/6] net: support QUIC crypto Bagas Sanjaya
2022-08-03 16:40 ` Adel Abouchaev
2022-08-03 16:40   ` [RFC net-next 1/6] net: Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-08-03 18:23     ` Andrew Lunn
2022-08-03 18:51       ` Adel Abouchaev
2022-08-04 15:29         ` Andrew Lunn
2022-08-04 16:57           ` Adel Abouchaev
2022-08-04 17:00             ` Eric Dumazet
2022-08-04 18:09               ` Jakub Kicinski
2022-08-04 18:45                 ` Eric Dumazet
2022-08-04 13:57     ` Jonathan Corbet
2022-08-03 16:40   ` [RFC net-next 2/6] net: Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-08-03 16:40   ` [RFC net-next 3/6] net: Add UDP ULP operations, initialization and handling prototype functions Adel Abouchaev
2022-08-03 16:40   ` [RFC net-next 4/6] net: Implement QUIC offload functions Adel Abouchaev
2022-08-03 16:40   ` [RFC net-next 5/6] net: Add flow counters and Tx processing error counter Adel Abouchaev
2022-08-03 16:40   ` [RFC net-next 6/6] net: Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev
2022-08-06  0:11 ` [RFC net-next v2 0/6] net: support QUIC crypto Adel Abouchaev
2022-08-06  0:11   ` [RFC net-next v2 1/6] Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-08-06  3:05     ` Bagas Sanjaya
2022-08-08 19:05       ` Adel Abouchaev
2022-08-06  0:11   ` [RFC net-next v2 2/6] Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-08-06  0:11   ` [RFC net-next v2 3/6] Add UDP ULP operations, initialization and handling prototype functions Adel Abouchaev
2022-08-06  0:11   ` [RFC net-next v2 4/6] Implement QUIC offload functions Adel Abouchaev
2022-08-06  0:11   ` [RFC net-next v2 5/6] Add flow counters and Tx processing error counter Adel Abouchaev
2022-08-06  0:11   ` [RFC net-next v2 6/6] Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev
2022-08-16 18:11 ` [net-next 0/6] net: support QUIC crypto Adel Abouchaev
2022-08-16 18:11   ` [net-next 1/6] Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-08-16 18:11   ` [net-next 2/6] Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-08-16 18:11   ` [net-next 3/6] Add UDP ULP operations, initialization and handling prototype functions Adel Abouchaev
2022-08-16 18:11   ` [net-next 4/6] Implement QUIC offload functions Adel Abouchaev
2022-08-16 18:11   ` [net-next 5/6] Add flow counters and Tx processing error counter Adel Abouchaev
2022-08-16 18:11   ` [net-next 6/6] Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev
2022-08-17  8:09   ` [net-next 0/6] net: support QUIC crypto Bagas Sanjaya
2022-08-17 18:49     ` Adel Abouchaev
2022-08-17 20:09 ` [net-next v2 " Adel Abouchaev
2022-08-17 20:09   ` [net-next v2 1/6] Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-08-18  2:53     ` Bagas Sanjaya
2022-08-17 20:09   ` [net-next v2 2/6] Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-08-17 20:09   ` [net-next v2 3/6] Add UDP ULP operations, initialization and handling prototype functions Adel Abouchaev
2022-08-17 20:09   ` [net-next v2 4/6] Implement QUIC offload functions Adel Abouchaev
2022-08-17 20:09   ` [net-next v2 5/6] Add flow counters and Tx processing error counter Adel Abouchaev
2022-08-17 20:09   ` [net-next v2 6/6] Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev
2022-08-18  2:18   ` [net-next v2 0/6] net: support QUIC crypto Bagas Sanjaya
2022-08-24 18:29   ` Xin Long
2022-08-24 19:52     ` Matt Joras
2022-08-24 23:09     ` Adel Abouchaev
2022-09-25 18:04       ` Willem de Bruijn
2022-09-27 16:44         ` Adel Abouchaev
2022-09-27 17:12           ` Willem de Bruijn
2022-09-27 17:28             ` Adel Abouchaev
2022-08-24 18:43 ` [net-next] Fix reinitialization of TEST_PROGS in net self tests Adel Abouchaev
2022-08-24 20:12   ` Shuah Khan
2022-08-25 20:30   ` patchwork-bot+netdevbpf
2022-09-07  0:49 ` [net-next v3 0/6] net: support QUIC crypto Adel Abouchaev
2022-09-07  0:49   ` [net-next v3 1/6] net: Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-09-07  3:38     ` Bagas Sanjaya
2022-09-07 17:29       ` Adel Abouchaev
2022-09-07  0:49   ` [net-next v3 2/6] net: Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-09-07  0:49   ` [net-next v3 3/6] net: Add UDP ULP operations, initialization and handling prototype functions Adel Abouchaev
2022-09-07  0:49   ` [net-next v3 4/6] net: Implement QUIC offload functions Adel Abouchaev
2022-09-07  0:49   ` [net-next v3 5/6] net: Add flow counters and Tx processing error counter Adel Abouchaev
2022-09-07  0:49   ` [net-next v3 6/6] net: Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev
2022-09-09  0:12 ` [net-next v4 0/6] net: support QUIC crypto Adel Abouchaev
2022-09-09  0:12   ` [net-next v4 1/6] net: Documentation on QUIC kernel Tx crypto Adel Abouchaev
2022-09-09  1:40     ` Bagas Sanjaya
2022-09-09  0:12   ` [net-next v4 2/6] net: Define QUIC specific constants, control and data plane structures Adel Abouchaev
2022-09-09  0:12   ` Adel Abouchaev [this message]
2022-09-09  0:12   ` [net-next v4 4/6] net: Implement QUIC offload functions Adel Abouchaev
2022-09-09  0:12   ` [net-next v4 5/6] net: Add flow counters and Tx processing error counter Adel Abouchaev
2022-09-09  0:12   ` [net-next v4 6/6] net: Add self tests for ULP operations, flow setup and crypto tests Adel Abouchaev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220909001238.3965798-4-adel.abushaev@gmail.com \
    --to=adel.abushaev@gmail.com \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=jmorris@namei.org \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=serge@hallyn.com \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.