* [PATCH] net: add sock_open() for unified socket creation @ 2026-06-18 13:06 Alex Goltsev 2026-06-18 21:12 ` Al Viro 2026-06-21 11:05 ` [PATCH v2] net: add sock_open() with flags for " Alex Goltsev 0 siblings, 2 replies; 8+ messages in thread From: Alex Goltsev @ 2026-06-18 13:06 UTC (permalink / raw) To: davem; +Cc: netdev, linux-kernel From c3d9f58bd314011fdbf18bfb9ea2e410898a9770 Mon Sep 17 00:00:00 2001 From: 0-x-0-0 <sasha.goltsev777@gmail.com> Date: Thu, 18 Jun 2026 15:21:32 +0300 Subject: [PATCH] net: add sock_open() for unified socket creation Signed-off-by: 0-x-0-0 <sasha.goltsev777@gmail.com> --- include/linux/net.h | 14 ++++++++++++++ net/socket.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/linux/net.h b/include/linux/net.h index f268f395c..18883ea74 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -116,6 +116,18 @@ enum sock_shutdown_cmd { SHUT_RDWR, }; +/** + * enum sock_create_type_t - Socket create types + * @SOCK_USER: creates a userspace socket + * @SOCK_KERN: creates a kernel socket + * @SOCK_LITE: creates a lightweight uninitialized socket + */ +enum sock_create_type_t { + SOCK_USER, + SOCK_KERN, + SOCK_LITE, +}; + struct socket_wq { /* Note: wait MUST be first field of socket_wq */ wait_queue_head_t wait; @@ -273,6 +285,8 @@ int sock_wake_async(struct socket_wq *sk_wq, int how, int band); int sock_register(const struct net_proto_family *fam); void sock_unregister(int family); bool sock_is_registered(int family); +int sock_open(int family, int type, int protocol, struct socket **res, + enum sock_create_type_t sock_type); int __sock_create(struct net *net, int family, int type, int proto, struct socket **res, int kern); int sock_create(int family, int type, int proto, struct socket **res); diff --git a/net/socket.c b/net/socket.c index 63c69a0fa..2c79c022a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1562,6 +1562,37 @@ int sock_wake_async(struct socket_wq *wq, int how, int band) } EXPORT_SYMBOL(sock_wake_async); +/** + * sock_open - creates a socket (unified interface) + * @family: protocol family (AF_INET, ...) + * @type: communication type (SOCK_STREAM, ...) + * @protocol: protocol (0, ...) + * @res: new socket + * @sock_type: one of SOCK_USER, SOCK_KERN, or SOCK_LITE + * + * Unified entry point for all socket creation variants. + * SOCK_USER creates a userspace socket (via sock_create). + * SOCK_KERN creates a kernel socket (via sock_create_kern). + * SOCK_LITE creates a lightweight uninitialized socket (via sock_create_lite). + * + * Return: 0 on success, negative errno on failure. On failure @res is NULL. + */ + +int sock_open(int family, int type, int protocol, struct socket **res, enum sock_create_type_t sock_type) +{ + switch (sock_type) { + case SOCK_USER: + return sock_create(family, type, protocol, res); + case SOCK_KERN: + return sock_create_kern(current->nsproxy->net_ns, family, type, protocol, res); + case SOCK_LITE: + return sock_create_lite(family, type, protocol, res); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL(sock_open); + /** * __sock_create - creates a socket * @net: net namespace -- 2.47.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] net: add sock_open() for unified socket creation 2026-06-18 13:06 [PATCH] net: add sock_open() for unified socket creation Alex Goltsev @ 2026-06-18 21:12 ` Al Viro 2026-06-19 10:35 ` Alex Goltsev 2026-06-21 11:05 ` [PATCH v2] net: add sock_open() with flags for " Alex Goltsev 1 sibling, 1 reply; 8+ messages in thread From: Al Viro @ 2026-06-18 21:12 UTC (permalink / raw) To: Alex Goltsev; +Cc: davem, netdev, linux-kernel On Thu, Jun 18, 2026 at 04:06:31PM +0300, Alex Goltsev wrote: > +/** > + * sock_open - creates a socket (unified interface) > + * @family: protocol family (AF_INET, ...) > + * @type: communication type (SOCK_STREAM, ...) > + * @protocol: protocol (0, ...) > + * @res: new socket > + * @sock_type: one of SOCK_USER, SOCK_KERN, or SOCK_LITE > + * > + * Unified entry point for all socket creation variants. > + * SOCK_USER creates a userspace socket (via sock_create). > + * SOCK_KERN creates a kernel socket (via sock_create_kern). > + * SOCK_LITE creates a lightweight uninitialized socket (via sock_create_lite). > + * > + * Return: 0 on success, negative errno on failure. On failure @res is NULL. > + */ What's the point (and why not make it inline, while we are at it)? Are there really callers that would pass a non-constant value as the last argument, and if so, what are they doing next? ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] net: add sock_open() for unified socket creation 2026-06-18 21:12 ` Al Viro @ 2026-06-19 10:35 ` Alex Goltsev 2026-06-19 16:34 ` Al Viro 0 siblings, 1 reply; 8+ messages in thread From: Alex Goltsev @ 2026-06-19 10:35 UTC (permalink / raw) To: Al Viro; +Cc: davem, netdev, linux-kernel > What's the point (and why not make it inline, while we are at it)? > Are there really callers that would pass a non-constant value as the last argument, > and if so, what are they doing next? As for `inline`: in this case, it would have no practical significance. The compiler already treats a simple inline function as a regular symbol within the `EXPORT_SYMBOL` context, whereas a static inline function (the standard kernel template for helper functions) would completely break the export to the LKM. This function solves the problem of actual API fragmentation: currently, there are three nearly identical functions (sock_create, sock_create_kern, sock_create_lite) with slightly different signatures. If new variants are added in the future, this will turn into a “zoo,” similar to what happened with `kmalloc` before it was unified. I propose unifying this now, while maintaining backward compatibility (all three existing functions will remain unchanged). As for the last argument, yes, today it is usually a constant, but that’s not the point. The purpose of the enumeration is to provide a unified, explicit control interface. It’s important that if, in the future, someone adds a new type of socket creation, existing calling programs won’t panic or throw a compilation error, but will smoothly fall back to the default case and return -EINVAL, which is a safe failure mode. I’m also aware that in `sock_open`, the first argument passed to the `sock_create_kern` branch is not safe; I’ve placed it there as a placeholder and am considering how to elegantly pass the `struct net` to the `sock_create_kern` branch. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] net: add sock_open() for unified socket creation 2026-06-19 10:35 ` Alex Goltsev @ 2026-06-19 16:34 ` Al Viro 2026-06-19 17:54 ` Alex Goltsev 0 siblings, 1 reply; 8+ messages in thread From: Al Viro @ 2026-06-19 16:34 UTC (permalink / raw) To: Alex Goltsev; +Cc: davem, netdev, linux-kernel On Fri, Jun 19, 2026 at 01:35:56PM +0300, Alex Goltsev wrote: > > What's the point (and why not make it inline, while we are at it)? > > > Are there really callers that would pass a non-constant value as the last argument, > > and if so, what are they doing next? > > > As for `inline`: in this case, it would have no practical significance. > > The compiler already treats a simple inline function as a regular > > symbol within the `EXPORT_SYMBOL` context, whereas a static inline > function (the standard > > kernel template for helper functions) would completely break the > export to the LKM. How so? All three underlying primitives are exported, so static inline in whatever include/*/*.h you put it in would work just fine. > As for the last argument, yes, today it is usually a constant, > > but that’s not the point. The purpose of the enumeration is to provide > > a unified, explicit control interface. It’s important that if, in the future, > > someone adds a new type of socket creation, existing calling programs won’t > > panic or throw a compilation error, but will smoothly fall back to > > the default case and return -EINVAL, which is a safe failure mode. Collapsing several functions together is worthless unless the combination can be _used_ other than a (questionable) syntax sugar. kmalloc() can; something that would only result in trading multiple identifiers for functions for multiple identifiers for "which function to call" is not an improvement. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] net: add sock_open() for unified socket creation 2026-06-19 16:34 ` Al Viro @ 2026-06-19 17:54 ` Alex Goltsev 0 siblings, 0 replies; 8+ messages in thread From: Alex Goltsev @ 2026-06-19 17:54 UTC (permalink / raw) To: Al Viro; +Cc: davem, netdev, linux-kernel On Fri, 19 Jun 2026 at 19:34, Al Viro <viro@zeniv.linux.org.uk> wrote: > > On Fri, Jun 19, 2026 at 01:35:56PM +0300, Alex Goltsev wrote: > > > What's the point (and why not make it inline, while we are at it)? > > > > > Are there really callers that would pass a non-constant value as the last argument, > > > and if so, what are they doing next? > > > > > > As for `inline`: in this case, it would have no practical significance. > > > > The compiler already treats a simple inline function as a regular > > > > symbol within the `EXPORT_SYMBOL` context, whereas a static inline > > function (the standard > > > > kernel template for helper functions) would completely break the > > export to the LKM. > > How so? All three underlying primitives are exported, so static inline > in whatever include/*/*.h you put it in would work just fine. > > > As for the last argument, yes, today it is usually a constant, > > > > but that’s not the point. The purpose of the enumeration is to provide > > > > a unified, explicit control interface. It’s important that if, in the future, > > > > someone adds a new type of socket creation, existing calling programs won’t > > > > panic or throw a compilation error, but will smoothly fall back to > > > > the default case and return -EINVAL, which is a safe failure mode. > > Collapsing several functions together is worthless unless the combination > can be _used_ other than a (questionable) syntax sugar. kmalloc() can; > something that would only result in trading multiple identifiers for > functions for multiple identifiers for "which function to call" is not > an improvement. Thank you for the detailed overview. I understand your point of view, standardization without adding new features isn’t an improvement. I’ll consider a v2 version in which flags can be combined to produce unique behavior, so that the API offers more than just syntactic sugar. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] net: add sock_open() with flags for socket creation 2026-06-18 13:06 [PATCH] net: add sock_open() for unified socket creation Alex Goltsev 2026-06-18 21:12 ` Al Viro @ 2026-06-21 11:05 ` Alex Goltsev 2026-06-21 12:57 ` David Laight 1 sibling, 1 reply; 8+ messages in thread From: Alex Goltsev @ 2026-06-21 11:05 UTC (permalink / raw) To: davem, netdev; +Cc: linux-kernel, Al Viro From a9316957e594708dfb4258ad968fe88666c9b736 Mon Sep 17 00:00:00 2001 From: 0-x-0-0 <sasha.goltsev777@gmail.com> Date: Sun, 21 Jun 2026 13:24:29 +0300 Subject: [PATCH v2] net: add sock_open() with flags for socket creation --- Changes in V2: - Replaced the use of plain integer constants for flags with proper enums to improve readability and type safety. - `sock_open` is intentionally left as a regular exported symbol rather than being moved to a header as `static inline`. This is because it dereferences `current->nsproxy->net_ns`, which would require pulling in heavy headers like <linux/sched.h> and <linux/nsproxy.h> into the already widely-used <linux/net.h>, causing unnecessary header bloat and potential circular dependencies. - Introduced two new creation flags for specialized use cases within kernel modules: * SOCK_CREATE_NOLSM: This flag allows a kernel module to bypass LSM hooks during socket creation. This enables a micro-optimization for kernel-internal sockets where the security check is known *a priori* to be a no-op (e.g., for specific configurations or high-performance paths). This is safe because the API is restricted to in-kernel (LKM) contexts only, and does not weaken the security boundary for user-triggered socket creation. * SOCK_CREATE_NOWARN: This flag suppresses the standard warning messages on creation failure. This is useful for callers in the kernel that probe for protocol support and handle the error gracefully, without wanting to pollute the kernel log with misleading warnings. Signed-off-by: Alexander Goltsev <sasha.goltsev777@gmail.com> --- include/linux/net.h | 22 ++++++++ net/socket.c | 133 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 134 insertions(+), 21 deletions(-) diff --git a/include/linux/net.h b/include/linux/net.h index f268f395c..6367c00db 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -116,6 +116,22 @@ enum sock_shutdown_cmd { SHUT_RDWR, }; +/** + * enum sock_create_flags - socket creation flags + * @SOCK_CREATE_KERN: creates a kernel socket + * @SOCK_CREATE_USER: creates a regular socket + * @SOCK_CREATE_LITE: creates a lite socket + * @SOCK_CREATE_NOLSM: disables LSM + * @SOCK_CREATE_NOWARN: disables warning + */ +enum sock_create_flags { + SOCK_CREATE_KERN = BIT(0), + SOCK_CREATE_USER = BIT(1), + SOCK_CREATE_LITE = BIT(2), + SOCK_CREATE_NOLSM = BIT(3), + SOCK_CREATE_NOWARN = BIT(4), +}; + struct socket_wq { /* Note: wait MUST be first field of socket_wq */ wait_queue_head_t wait; @@ -275,6 +291,12 @@ void sock_unregister(int family); bool sock_is_registered(int family); int __sock_create(struct net *net, int family, int type, int proto, struct socket **res, int kern); +int __sock_create_flags(struct net *net, int family, int type, int protocol, + struct socket **res, int kern, int flags); +int __sock_create_lite_flags(int family, int type, int protocol, + struct socket **res, int flags); +int sock_open(struct net *net, int family, + int type, int protocol, struct socket **res, int flags); int sock_create(int family, int type, int proto, struct socket **res); int sock_create_kern(struct net *net, int family, int type, int proto, struct socket **res); int sock_create_lite(int family, int type, int proto, struct socket **res); diff --git a/net/socket.c b/net/socket.c index 63c69a0fa..2359fd5bf 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1425,26 +1425,28 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) } /** - * sock_create_lite - creates a socket + * __sock_create_lite_flags - creates a socket (with flags) * @family: protocol family (AF_INET, ...) * @type: communication type (SOCK_STREAM, ...) * @protocol: protocol (0, ...) * @res: new socket + * @flags: defines socket creation flags * * Creates a new socket and assigns it to @res, passing through LSM. * The new socket initialization is not complete, see kernel_accept(). * Returns 0 or an error. On failure @res is set to %NULL. * This function internally uses GFP_KERNEL. */ - -int sock_create_lite(int family, int type, int protocol, struct socket **res) +int __sock_create_lite_flags(int family, int type, int protocol, struct socket **res, int flags) { int err; struct socket *sock = NULL; - err = security_socket_create(family, type, protocol, 1); - if (err) - goto out; + if (!(flags & SOCK_CREATE_NOLSM)) { + err = security_socket_create(family, type, protocol, 1); + if (err) + goto out; + } sock = sock_alloc(); if (!sock) { @@ -1453,9 +1455,11 @@ int sock_create_lite(int family, int type, int protocol, struct socket **res) } sock->type = type; - err = security_socket_post_create(sock, family, type, protocol, 1); - if (err) - goto out_release; + if (!(flags & SOCK_CREATE_NOLSM)) { + err = security_socket_post_create(sock, family, type, protocol, 1); + if (err) + goto out_release; + } out: *res = sock; @@ -1465,6 +1469,25 @@ int sock_create_lite(int family, int type, int protocol, struct socket **res) sock = NULL; goto out; } +EXPORT_SYMBOL(__sock_create_lite_flags); + +/** + * sock_create_lite - creates a socket + * @family: protocol family (AF_INET, ...) + * @type: communication type (SOCK_STREAM, ...) + * @protocol: protocol (0, ...) + * @res: new socket + * + * Creates a new socket and assigns it to @res, passing through LSM. + * The new socket initialization is not complete, see kernel_accept(). + * Returns 0 or an error. On failure @res is set to %NULL. + * This function internally uses GFP_KERNEL. + */ + +int sock_create_lite(int family, int type, int protocol, struct socket **res) +{ + return __sock_create_lite_flags(family, type, protocol, res, 0); +} EXPORT_SYMBOL(sock_create_lite); /* No kernel lock held - perfect */ @@ -1563,22 +1586,23 @@ int sock_wake_async(struct socket_wq *wq, int how, int band) EXPORT_SYMBOL(sock_wake_async); /** - * __sock_create - creates a socket + * __sock_create_flags - creates a socket (with flags) * @net: net namespace * @family: protocol family (AF_INET, ...) * @type: communication type (SOCK_STREAM, ...) * @protocol: protocol (0, ...) * @res: new socket * @kern: boolean for kernel space sockets + * @flags: defines socket creation flags * * Creates a new socket and assigns it to @res, passing through LSM. * Returns 0 or an error. On failure @res is set to %NULL. @kern must * be set to true if the socket resides in kernel space. * This function internally uses GFP_KERNEL. */ - -int __sock_create(struct net *net, int family, int type, int protocol, - struct socket **res, int kern) +int __sock_create_flags(struct net *net, int family, + int type, int protocol, struct socket **res, + int kern, int flags) { int err; struct socket *sock; @@ -1598,14 +1622,18 @@ int __sock_create(struct net *net, int family, int type, int protocol, deadlock in module load. */ if (family == PF_INET && type == SOCK_PACKET) { - pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n", + if (!(flags & SOCK_CREATE_NOWARN)) { + pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n", current->comm); + } family = PF_PACKET; } - err = security_socket_create(family, type, protocol, kern); - if (err) - return err; + if (!(flags & SOCK_CREATE_NOLSM)) { + err = security_socket_create(family, type, protocol, kern); + if (err) + return err; + } /* * Allocate the socket and allow the family to set things up. if @@ -1614,7 +1642,8 @@ int __sock_create(struct net *net, int family, int type, int protocol, */ sock = sock_alloc(); if (!sock) { - net_warn_ratelimited("socket: no more sockets\n"); + if (!(flags & SOCK_CREATE_NOWARN)) + net_warn_ratelimited("socket: no more sockets\n"); return -ENFILE; /* Not exactly a match, but its the closest posix thing */ } @@ -1671,9 +1700,12 @@ int __sock_create(struct net *net, int family, int type, int protocol, * module can have its refcnt decremented */ module_put(pf->owner); - err = security_socket_post_create(sock, family, type, protocol, kern); - if (err) - goto out_sock_release; + + if (!(flags & SOCK_CREATE_NOLSM)) { + err = security_socket_post_create(sock, family, type, protocol, kern); + if (err) + goto out_sock_release; + } *res = sock; return 0; @@ -1691,6 +1723,28 @@ int __sock_create(struct net *net, int family, int type, int protocol, rcu_read_unlock(); goto out_sock_release; } +EXPORT_SYMBOL(__sock_create_flags); + +/** + * __sock_create - creates a socket + * @net: net namespace + * @family: protocol family (AF_INET, ...) + * @type: communication type (SOCK_STREAM, ...) + * @protocol: protocol (0, ...) + * @res: new socket + * @kern: boolean for kernel space sockets + * + * Creates a new socket and assigns it to @res, passing through LSM. + * Returns 0 or an error. On failure @res is set to %NULL. @kern must + * be set to true if the socket resides in kernel space. + * This function internally uses GFP_KERNEL. + */ + +int __sock_create(struct net *net, int family, int type, int protocol, + struct socket **res, int kern) +{ + return __sock_create_flags(net, family, type, protocol, res, kern, 0); +} EXPORT_SYMBOL(__sock_create); /** @@ -1710,6 +1764,43 @@ int sock_create(int family, int type, int protocol, struct socket **res) } EXPORT_SYMBOL(sock_create); +/** + * sock_open - creates a socket (with flags) + * @net: net namespace (may be NULL in non-SOCK_CREATE_KERN modes) + * @family: protocol family (AF_INET, ...) + * @type: communication type (SOCK_STREAM, ...) + * @protocol: protocol (0, ...) + * @res: new socket + * @flags: socket creation flags + * + * Unified entry point for socket creation with flags. + * Returns 0 or an error. This function internally uses GFP_KERNEL. + */ +int sock_open(struct net *net, int family, + int type, int protocol, struct socket **res, + int flags) +{ + int type_bits = flags & (SOCK_CREATE_KERN | SOCK_CREATE_USER | SOCK_CREATE_LITE); + int optional_flags = flags & ~(SOCK_CREATE_KERN | SOCK_CREATE_USER | SOCK_CREATE_LITE); + + if (type_bits == 0 || (type_bits & (type_bits - 1)) != 0) + return -EINVAL; + + if (optional_flags & ~(SOCK_CREATE_NOLSM | SOCK_CREATE_NOWARN)) + return -EINVAL; + + switch (type_bits) { + case SOCK_CREATE_KERN: return __sock_create_flags(net, family, type, protocol, + res, 1, optional_flags); + case SOCK_CREATE_USER: return __sock_create_flags(current->nsproxy->net_ns, + family, type, protocol, res, 0, optional_flags); + case SOCK_CREATE_LITE: return __sock_create_lite_flags(family, + type, protocol, res, optional_flags); + default: return -EINVAL; + } +} +EXPORT_SYMBOL(sock_open); + /** * sock_create_kern - creates a socket (kernel space) * @net: net namespace -- 2.47.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] net: add sock_open() with flags for socket creation 2026-06-21 11:05 ` [PATCH v2] net: add sock_open() with flags for " Alex Goltsev @ 2026-06-21 12:57 ` David Laight 2026-06-21 13:59 ` Andrew Lunn 0 siblings, 1 reply; 8+ messages in thread From: David Laight @ 2026-06-21 12:57 UTC (permalink / raw) To: Alex Goltsev; +Cc: davem, netdev, linux-kernel, Al Viro On Sun, 21 Jun 2026 14:05:40 +0300 Alex Goltsev <sasha.goltsev777@gmail.com> wrote: > From a9316957e594708dfb4258ad968fe88666c9b736 Mon Sep 17 00:00:00 2001 > From: 0-x-0-0 <sasha.goltsev777@gmail.com> > Date: Sun, 21 Jun 2026 13:24:29 +0300 > Subject: [PATCH v2] net: add sock_open() with flags for socket creation A) There is no info here. B) You've not said why this is of any use. C) It isn't a bug fix so would go into net-next D) net-next is closed. David > > --- > Changes in V2: > - Replaced the use of plain integer constants for flags with proper > enums to improve readability and type safety. > - `sock_open` is intentionally left as a regular exported symbol rather > than being moved to a header as `static inline`. This is because it > dereferences `current->nsproxy->net_ns`, which would require pulling > in heavy headers like <linux/sched.h> and <linux/nsproxy.h> into the > already widely-used <linux/net.h>, causing unnecessary header bloat > and potential circular dependencies. > - Introduced two new creation flags for specialized use cases within > kernel modules: > > * SOCK_CREATE_NOLSM: This flag allows a kernel module to bypass > LSM hooks during socket creation. This > enables a micro-optimization for kernel-internal sockets where > the security check is known *a priori* to be a no-op (e.g., for > specific configurations or high-performance paths). > This is safe because the API is restricted to in-kernel (LKM) > contexts only, and does not weaken the security boundary for > user-triggered socket creation. > > * SOCK_CREATE_NOWARN: This flag suppresses the standard warning > messages on creation failure. This is useful for callers in the > kernel that probe for protocol support and handle the error > gracefully, without wanting to pollute the kernel log with > misleading warnings. > > Signed-off-by: Alexander Goltsev <sasha.goltsev777@gmail.com> > --- > include/linux/net.h | 22 ++++++++ > net/socket.c | 133 +++++++++++++++++++++++++++++++++++++------- > 2 files changed, 134 insertions(+), 21 deletions(-) > > diff --git a/include/linux/net.h b/include/linux/net.h > index f268f395c..6367c00db 100644 > --- a/include/linux/net.h > +++ b/include/linux/net.h > @@ -116,6 +116,22 @@ enum sock_shutdown_cmd { > SHUT_RDWR, > }; > +/** > + * enum sock_create_flags - socket creation flags > + * @SOCK_CREATE_KERN: creates a kernel socket > + * @SOCK_CREATE_USER: creates a regular socket > + * @SOCK_CREATE_LITE: creates a lite socket > + * @SOCK_CREATE_NOLSM: disables LSM > + * @SOCK_CREATE_NOWARN: disables warning > + */ > +enum sock_create_flags { > + SOCK_CREATE_KERN = BIT(0), > + SOCK_CREATE_USER = BIT(1), > + SOCK_CREATE_LITE = BIT(2), > + SOCK_CREATE_NOLSM = BIT(3), > + SOCK_CREATE_NOWARN = BIT(4), > +}; > + > struct socket_wq { > /* Note: wait MUST be first field of socket_wq */ > wait_queue_head_t wait; > @@ -275,6 +291,12 @@ void sock_unregister(int family); > bool sock_is_registered(int family); > int __sock_create(struct net *net, int family, int type, int proto, > struct socket **res, int kern); > +int __sock_create_flags(struct net *net, int family, int type, int protocol, > + struct socket **res, int kern, int flags); > +int __sock_create_lite_flags(int family, int type, int protocol, > + struct socket **res, int flags); > +int sock_open(struct net *net, int family, > + int type, int protocol, struct socket **res, int flags); > int sock_create(int family, int type, int proto, struct socket **res); > int sock_create_kern(struct net *net, int family, int type, int proto, > struct socket **res); > int sock_create_lite(int family, int type, int proto, struct socket **res); > diff --git a/net/socket.c b/net/socket.c > index 63c69a0fa..2359fd5bf 100644 > --- a/net/socket.c > +++ b/net/socket.c > @@ -1425,26 +1425,28 @@ static long sock_ioctl(struct file *file, > unsigned cmd, unsigned long arg) > } > /** > - * sock_create_lite - creates a socket > + * __sock_create_lite_flags - creates a socket (with flags) > * @family: protocol family (AF_INET, ...) > * @type: communication type (SOCK_STREAM, ...) > * @protocol: protocol (0, ...) > * @res: new socket > + * @flags: defines socket creation flags > * > * Creates a new socket and assigns it to @res, passing through LSM. > * The new socket initialization is not complete, see kernel_accept(). > * Returns 0 or an error. On failure @res is set to %NULL. > * This function internally uses GFP_KERNEL. > */ > - > -int sock_create_lite(int family, int type, int protocol, struct socket **res) > +int __sock_create_lite_flags(int family, int type, int protocol, > struct socket **res, int flags) > { > int err; > struct socket *sock = NULL; > - err = security_socket_create(family, type, protocol, 1); > - if (err) > - goto out; > + if (!(flags & SOCK_CREATE_NOLSM)) { > + err = security_socket_create(family, type, protocol, 1); > + if (err) > + goto out; > + } > sock = sock_alloc(); > if (!sock) { > @@ -1453,9 +1455,11 @@ int sock_create_lite(int family, int type, int > protocol, struct socket **res) > } > sock->type = type; > - err = security_socket_post_create(sock, family, type, protocol, 1); > - if (err) > - goto out_release; > + if (!(flags & SOCK_CREATE_NOLSM)) { > + err = security_socket_post_create(sock, family, type, protocol, 1); > + if (err) > + goto out_release; > + } > out: > *res = sock; > @@ -1465,6 +1469,25 @@ int sock_create_lite(int family, int type, int > protocol, struct socket **res) > sock = NULL; > goto out; > } > +EXPORT_SYMBOL(__sock_create_lite_flags); > + > +/** > + * sock_create_lite - creates a socket > + * @family: protocol family (AF_INET, ...) > + * @type: communication type (SOCK_STREAM, ...) > + * @protocol: protocol (0, ...) > + * @res: new socket > + * > + * Creates a new socket and assigns it to @res, passing through LSM. > + * The new socket initialization is not complete, see kernel_accept(). > + * Returns 0 or an error. On failure @res is set to %NULL. > + * This function internally uses GFP_KERNEL. > + */ > + > +int sock_create_lite(int family, int type, int protocol, struct socket **res) > +{ > + return __sock_create_lite_flags(family, type, protocol, res, 0); > +} > EXPORT_SYMBOL(sock_create_lite); > /* No kernel lock held - perfect */ > @@ -1563,22 +1586,23 @@ int sock_wake_async(struct socket_wq *wq, int > how, int band) > EXPORT_SYMBOL(sock_wake_async); > /** > - * __sock_create - creates a socket > + * __sock_create_flags - creates a socket (with flags) > * @net: net namespace > * @family: protocol family (AF_INET, ...) > * @type: communication type (SOCK_STREAM, ...) > * @protocol: protocol (0, ...) > * @res: new socket > * @kern: boolean for kernel space sockets > + * @flags: defines socket creation flags > * > * Creates a new socket and assigns it to @res, passing through LSM. > * Returns 0 or an error. On failure @res is set to %NULL. @kern must > * be set to true if the socket resides in kernel space. > * This function internally uses GFP_KERNEL. > */ > - > -int __sock_create(struct net *net, int family, int type, int protocol, > - struct socket **res, int kern) > +int __sock_create_flags(struct net *net, int family, > + int type, int protocol, struct socket **res, > + int kern, int flags) > { > int err; > struct socket *sock; > @@ -1598,14 +1622,18 @@ int __sock_create(struct net *net, int family, > int type, int protocol, > deadlock in module load. > */ > if (family == PF_INET && type == SOCK_PACKET) { > - pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n", > + if (!(flags & SOCK_CREATE_NOWARN)) { > + pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n", > current->comm); > + } > family = PF_PACKET; > } > - err = security_socket_create(family, type, protocol, kern); > - if (err) > - return err; > + if (!(flags & SOCK_CREATE_NOLSM)) { > + err = security_socket_create(family, type, protocol, kern); > + if (err) > + return err; > + } > /* > * Allocate the socket and allow the family to set things up. if > @@ -1614,7 +1642,8 @@ int __sock_create(struct net *net, int family, > int type, int protocol, > */ > sock = sock_alloc(); > if (!sock) { > - net_warn_ratelimited("socket: no more sockets\n"); > + if (!(flags & SOCK_CREATE_NOWARN)) > + net_warn_ratelimited("socket: no more sockets\n"); > return -ENFILE; /* Not exactly a match, but its the > closest posix thing */ > } > @@ -1671,9 +1700,12 @@ int __sock_create(struct net *net, int family, > int type, int protocol, > * module can have its refcnt decremented > */ > module_put(pf->owner); > - err = security_socket_post_create(sock, family, type, protocol, kern); > - if (err) > - goto out_sock_release; > + > + if (!(flags & SOCK_CREATE_NOLSM)) { > + err = security_socket_post_create(sock, family, type, protocol, kern); > + if (err) > + goto out_sock_release; > + } > *res = sock; > return 0; > @@ -1691,6 +1723,28 @@ int __sock_create(struct net *net, int family, > int type, int protocol, > rcu_read_unlock(); > goto out_sock_release; > } > +EXPORT_SYMBOL(__sock_create_flags); > + > +/** > + * __sock_create - creates a socket > + * @net: net namespace > + * @family: protocol family (AF_INET, ...) > + * @type: communication type (SOCK_STREAM, ...) > + * @protocol: protocol (0, ...) > + * @res: new socket > + * @kern: boolean for kernel space sockets > + * > + * Creates a new socket and assigns it to @res, passing through LSM. > + * Returns 0 or an error. On failure @res is set to %NULL. @kern must > + * be set to true if the socket resides in kernel space. > + * This function internally uses GFP_KERNEL. > + */ > + > +int __sock_create(struct net *net, int family, int type, int protocol, > + struct socket **res, int kern) > +{ > + return __sock_create_flags(net, family, type, protocol, res, kern, 0); > +} > EXPORT_SYMBOL(__sock_create); > /** > @@ -1710,6 +1764,43 @@ int sock_create(int family, int type, int > protocol, struct socket **res) > } > EXPORT_SYMBOL(sock_create); > +/** > + * sock_open - creates a socket (with flags) > + * @net: net namespace (may be NULL in non-SOCK_CREATE_KERN modes) > + * @family: protocol family (AF_INET, ...) > + * @type: communication type (SOCK_STREAM, ...) > + * @protocol: protocol (0, ...) > + * @res: new socket > + * @flags: socket creation flags > + * > + * Unified entry point for socket creation with flags. > + * Returns 0 or an error. This function internally uses GFP_KERNEL. > + */ > +int sock_open(struct net *net, int family, > + int type, int protocol, struct socket **res, > + int flags) > +{ > + int type_bits = flags & (SOCK_CREATE_KERN | SOCK_CREATE_USER | > SOCK_CREATE_LITE); > + int optional_flags = flags & ~(SOCK_CREATE_KERN | SOCK_CREATE_USER | > SOCK_CREATE_LITE); > + > + if (type_bits == 0 || (type_bits & (type_bits - 1)) != 0) > + return -EINVAL; > + > + if (optional_flags & ~(SOCK_CREATE_NOLSM | SOCK_CREATE_NOWARN)) > + return -EINVAL; > + > + switch (type_bits) { > + case SOCK_CREATE_KERN: return __sock_create_flags(net, family, type, protocol, > + res, 1, optional_flags); > + case SOCK_CREATE_USER: return __sock_create_flags(current->nsproxy->net_ns, > + family, type, protocol, res, 0, optional_flags); > + case SOCK_CREATE_LITE: return __sock_create_lite_flags(family, > + type, protocol, res, optional_flags); > + default: return -EINVAL; > + } > +} > +EXPORT_SYMBOL(sock_open); > + > /** > * sock_create_kern - creates a socket (kernel space) > * @net: net namespace ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] net: add sock_open() with flags for socket creation 2026-06-21 12:57 ` David Laight @ 2026-06-21 13:59 ` Andrew Lunn 0 siblings, 0 replies; 8+ messages in thread From: Andrew Lunn @ 2026-06-21 13:59 UTC (permalink / raw) To: David Laight; +Cc: Alex Goltsev, davem, netdev, linux-kernel, Al Viro On Sun, Jun 21, 2026 at 01:57:46PM +0100, David Laight wrote: > On Sun, 21 Jun 2026 14:05:40 +0300 > Alex Goltsev <sasha.goltsev777@gmail.com> wrote: > > > From a9316957e594708dfb4258ad968fe88666c9b736 Mon Sep 17 00:00:00 2001 > > From: 0-x-0-0 <sasha.goltsev777@gmail.com> > > Date: Sun, 21 Jun 2026 13:24:29 +0300 > > Subject: [PATCH v2] net: add sock_open() with flags for socket creation > > A) There is no info here. > B) You've not said why this is of any use. > C) It isn't a bug fix so would go into net-next > D) net-next is closed. E) The patch has had all its whitespace corrupted. Please "submit" the patch to yourself and ensure you can cleanly apply it. Andrew ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-21 13:59 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-18 13:06 [PATCH] net: add sock_open() for unified socket creation Alex Goltsev 2026-06-18 21:12 ` Al Viro 2026-06-19 10:35 ` Alex Goltsev 2026-06-19 16:34 ` Al Viro 2026-06-19 17:54 ` Alex Goltsev 2026-06-21 11:05 ` [PATCH v2] net: add sock_open() with flags for " Alex Goltsev 2026-06-21 12:57 ` David Laight 2026-06-21 13:59 ` Andrew Lunn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox