linux-sctp.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/3] add sock_kmemdup helper
@ 2025-02-28 10:01 Geliang Tang
  2025-02-28 10:01 ` [PATCH net-next v2 1/3] sock: " Geliang Tang
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Geliang Tang @ 2025-02-28 10:01 UTC (permalink / raw)
  To: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Neal Cardwell,
	David Ahern, Matthieu Baerts, Mat Martineau,
	Marcelo Ricardo Leitner, Xin Long
  Cc: Geliang Tang, netdev, mptcp, linux-sctp

From: Geliang Tang <tanggeliang@kylinos.cn>

v2:
 - add "EXPORT_SYMBOL(sock_kmemdup)" as Matthieu suggested.
 - drop the patch "use sock_kmemdup for tcp_ao_key".

While developing MPTCP BPF path manager [1], I found it's useful to
add a new sock_kmemdup() helper.

My use case is this:

In mptcp_userspace_pm_append_new_local_addr() function (see patch 3
in this patchset), it uses sock_kmalloc() to allocate an address
entry "e", then immediately duplicate the input "entry" to it:

'''
	e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
	if (!e) {
		ret = -ENOMEM;
		goto append_err;
	}

	*e = *entry;
'''

When I implemented MPTCP BPF path manager, I needed to implement a
code similar to this in BPF.

The kfunc sock_kmalloc() can be easily invoked in BPF to allocate
an entry "e", but the code "*e = *entry;" that assigns "entry" to
"e" is not easy to implemented. 

I had to implement such a "copy entry" helper in BPF:

'''
static void mptcp_pm_copy_addr(struct mptcp_addr_info *dst,
                               struct mptcp_addr_info *src)
{
       dst->id = src->id;
       dst->family = src->family;
       dst->port = src->port;

       if (src->family == AF_INET) {
               dst->addr.s_addr = src->addr.s_addr;
       } else if (src->family == AF_INET6) {
               dst->addr6.s6_addr32[0] = src->addr6.s6_addr32[0];
               dst->addr6.s6_addr32[1] = src->addr6.s6_addr32[1];
               dst->addr6.s6_addr32[2] = src->addr6.s6_addr32[2];
               dst->addr6.s6_addr32[3] = src->addr6.s6_addr32[3];
       }
}

static void mptcp_pm_copy_entry(struct mptcp_pm_addr_entry *dst,
                                struct mptcp_pm_addr_entry *src)
{
       mptcp_pm_copy_addr(&dst->addr, &src->addr);

       dst->flags = src->flags;
       dst->ifindex = src->ifindex;
}
'''

And add "write permission" for BPF to each field of mptcp_pm_addr_entry:

'''
@@ static int bpf_mptcp_pm_btf_struct_access(struct bpf_verifier_log *log,
  case offsetof(struct mptcp_pm_addr_entry, addr.port):
    end = offsetofend(struct mptcp_pm_addr_entry, addr.port);
    break;
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
  case offsetof(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[0]):
    end = offsetofend(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[0]);
    break;
  case offsetof(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[1]):
    end = offsetofend(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[1]);
    break;
  case offsetof(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[2]):
    end = offsetofend(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[2]);
    break;
  case offsetof(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[3]):
    end = offsetofend(struct mptcp_pm_addr_entry, addr.addr6.s6_addr32[3]);
    break;
 #else
  case offsetof(struct mptcp_pm_addr_entry, addr.addr.s_addr):
    end = offsetofend(struct mptcp_pm_addr_entry, addr.addr.s_addr);
    break;
 #endif
'''

But if there's a sock_kmemdup() helper, it will become much simpler,
only need to call kfunc sock_kmemdup() instead in BPF.

So this patchset adds this new helper and uses it in several places.

[1]
https://lore.kernel.org/mptcp/cover.1738924875.git.tanggeliang@kylinos.cn/

Geliang Tang (3):
  sock: add sock_kmemdup helper
  net: use sock_kmemdup for ip_options
  mptcp: use sock_kmemdup for address entry

 include/net/sock.h       |  2 ++
 net/core/sock.c          | 16 ++++++++++++++++
 net/ipv6/exthdrs.c       |  3 +--
 net/mptcp/pm_userspace.c |  3 +--
 net/mptcp/protocol.c     |  7 ++-----
 net/sctp/protocol.c      |  7 ++-----
 6 files changed, 24 insertions(+), 14 deletions(-)

-- 
2.43.0


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

* [PATCH net-next v2 1/3] sock: add sock_kmemdup helper
  2025-02-28 10:01 [PATCH net-next v2 0/3] add sock_kmemdup helper Geliang Tang
@ 2025-02-28 10:01 ` Geliang Tang
  2025-03-03 23:16   ` Kuniyuki Iwashima
  2025-02-28 10:01 ` [PATCH net-next v2 2/3] net: use sock_kmemdup for ip_options Geliang Tang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Geliang Tang @ 2025-02-28 10:01 UTC (permalink / raw)
  To: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Neal Cardwell,
	David Ahern, Matthieu Baerts, Mat Martineau,
	Marcelo Ricardo Leitner, Xin Long
  Cc: Geliang Tang, netdev, mptcp, linux-sctp

From: Geliang Tang <tanggeliang@kylinos.cn>

This patch adds the sock version of kmemdup() helper, named sock_kmemdup(),
to duplicate the input "src" memory block using the socket's option memory
buffer.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 include/net/sock.h |  2 ++
 net/core/sock.c    | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/net/sock.h b/include/net/sock.h
index e771d99f81b0..8daf1b3b12c6 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1797,6 +1797,8 @@ static inline struct sk_buff *sock_alloc_send_skb(struct sock *sk,
 }
 
 void *sock_kmalloc(struct sock *sk, int size, gfp_t priority);
+void *sock_kmemdup(struct sock *sk, const void *src,
+		   int size, gfp_t priority);
 void sock_kfree_s(struct sock *sk, void *mem, int size);
 void sock_kzfree_s(struct sock *sk, void *mem, int size);
 void sk_send_sigurg(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index 23bce41f7f1f..a0598518ce89 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2836,6 +2836,22 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
 }
 EXPORT_SYMBOL(sock_kmalloc);
 
+/*
+ * Duplicate the input "src" memory block using the socket's
+ * option memory buffer.
+ */
+void *sock_kmemdup(struct sock *sk, const void *src,
+		   int size, gfp_t priority)
+{
+	void *mem;
+
+	mem = sock_kmalloc(sk, size, priority);
+	if (mem)
+		memcpy(mem, src, size);
+	return mem;
+}
+EXPORT_SYMBOL(sock_kmemdup);
+
 /* Free an option memory block. Note, we actually want the inline
  * here as this allows gcc to detect the nullify and fold away the
  * condition entirely.
-- 
2.43.0


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

* [PATCH net-next v2 2/3] net: use sock_kmemdup for ip_options
  2025-02-28 10:01 [PATCH net-next v2 0/3] add sock_kmemdup helper Geliang Tang
  2025-02-28 10:01 ` [PATCH net-next v2 1/3] sock: " Geliang Tang
@ 2025-02-28 10:01 ` Geliang Tang
  2025-03-03 23:18   ` Kuniyuki Iwashima
  2025-02-28 10:01 ` [PATCH net-next v2 3/3] mptcp: use sock_kmemdup for address entry Geliang Tang
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Geliang Tang @ 2025-02-28 10:01 UTC (permalink / raw)
  To: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Neal Cardwell,
	David Ahern, Matthieu Baerts, Mat Martineau,
	Marcelo Ricardo Leitner, Xin Long
  Cc: Geliang Tang, netdev, mptcp, linux-sctp

From: Geliang Tang <tanggeliang@kylinos.cn>

Instead of using sock_kmalloc() to allocate an ip_options and then
immediately duplicate another ip_options to the newly allocated one in
ipv6_dup_options(), mptcp_copy_ip_options() and sctp_v4_copy_ip_options(),
the newly added sock_kmemdup() helper can be used to simplify the code.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/ipv6/exthdrs.c   | 3 +--
 net/mptcp/protocol.c | 7 ++-----
 net/sctp/protocol.c  | 7 ++-----
 3 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 6789623b2b0d..457de0745a33 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -1204,10 +1204,9 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
 {
 	struct ipv6_txoptions *opt2;
 
-	opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
+	opt2 = sock_kmemdup(sk, opt, opt->tot_len, GFP_ATOMIC);
 	if (opt2) {
 		long dif = (char *)opt2 - (char *)opt;
-		memcpy(opt2, opt, opt->tot_len);
 		if (opt2->hopopt)
 			*((char **)&opt2->hopopt) += dif;
 		if (opt2->dst0opt)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 6b61b7dee33b..ec23e65ef0f1 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3178,12 +3178,9 @@ static void mptcp_copy_ip_options(struct sock *newsk, const struct sock *sk)
 	rcu_read_lock();
 	inet_opt = rcu_dereference(inet->inet_opt);
 	if (inet_opt) {
-		newopt = sock_kmalloc(newsk, sizeof(*inet_opt) +
+		newopt = sock_kmemdup(newsk, inet_opt, sizeof(*inet_opt) +
 				      inet_opt->opt.optlen, GFP_ATOMIC);
-		if (newopt)
-			memcpy(newopt, inet_opt, sizeof(*inet_opt) +
-			       inet_opt->opt.optlen);
-		else
+		if (!newopt)
 			net_warn_ratelimited("%s: Failed to copy ip options\n", __func__);
 	}
 	RCU_INIT_POINTER(newinet->inet_opt, newopt);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 29727ed1008e..5407a3922101 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -185,12 +185,9 @@ static void sctp_v4_copy_ip_options(struct sock *sk, struct sock *newsk)
 	rcu_read_lock();
 	inet_opt = rcu_dereference(inet->inet_opt);
 	if (inet_opt) {
-		newopt = sock_kmalloc(newsk, sizeof(*inet_opt) +
+		newopt = sock_kmemdup(newsk, inet_opt, sizeof(*inet_opt) +
 				      inet_opt->opt.optlen, GFP_ATOMIC);
-		if (newopt)
-			memcpy(newopt, inet_opt, sizeof(*inet_opt) +
-			       inet_opt->opt.optlen);
-		else
+		if (!newopt)
 			pr_err("%s: Failed to copy ip options\n", __func__);
 	}
 	RCU_INIT_POINTER(newinet->inet_opt, newopt);
-- 
2.43.0


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

* [PATCH net-next v2 3/3] mptcp: use sock_kmemdup for address entry
  2025-02-28 10:01 [PATCH net-next v2 0/3] add sock_kmemdup helper Geliang Tang
  2025-02-28 10:01 ` [PATCH net-next v2 1/3] sock: " Geliang Tang
  2025-02-28 10:01 ` [PATCH net-next v2 2/3] net: use sock_kmemdup for ip_options Geliang Tang
@ 2025-02-28 10:01 ` Geliang Tang
  2025-02-28 12:06 ` [PATCH net-next v2 0/3] add sock_kmemdup helper Matthieu Baerts
  2025-03-04  2:10 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 8+ messages in thread
From: Geliang Tang @ 2025-02-28 10:01 UTC (permalink / raw)
  To: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Neal Cardwell,
	David Ahern, Matthieu Baerts, Mat Martineau,
	Marcelo Ricardo Leitner, Xin Long
  Cc: Geliang Tang, netdev, mptcp, linux-sctp

From: Geliang Tang <tanggeliang@kylinos.cn>

Instead of using sock_kmalloc() to allocate an address
entry "e" and then immediately duplicate the input "entry"
to it, the newly added sock_kmemdup() helper can be used in
mptcp_userspace_pm_append_new_local_addr() to simplify the code.

More importantly, the code "*e = *entry;" that assigns "entry"
to "e" is not easy to implemented in BPF if we use the same code
to implement an append_new_local_addr() helper of a BFP path
manager. This patch avoids this type of memory assignment
operation.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 6bf6a20ef7f3..7e7d01bef5d4 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -71,13 +71,12 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 		/* Memory for the entry is allocated from the
 		 * sock option buffer.
 		 */
-		e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
+		e = sock_kmemdup(sk, entry, sizeof(*entry), GFP_ATOMIC);
 		if (!e) {
 			ret = -ENOMEM;
 			goto append_err;
 		}
 
-		*e = *entry;
 		if (!e->addr.id && needs_id)
 			e->addr.id = find_next_zero_bit(id_bitmap,
 							MPTCP_PM_MAX_ADDR_ID + 1,
-- 
2.43.0


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

* Re: [PATCH net-next v2 0/3] add sock_kmemdup helper
  2025-02-28 10:01 [PATCH net-next v2 0/3] add sock_kmemdup helper Geliang Tang
                   ` (2 preceding siblings ...)
  2025-02-28 10:01 ` [PATCH net-next v2 3/3] mptcp: use sock_kmemdup for address entry Geliang Tang
@ 2025-02-28 12:06 ` Matthieu Baerts
  2025-03-04  2:10 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 8+ messages in thread
From: Matthieu Baerts @ 2025-02-28 12:06 UTC (permalink / raw)
  To: Geliang Tang, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni,
	Willem de Bruijn, David S. Miller, Jakub Kicinski, Simon Horman,
	Neal Cardwell, David Ahern, Mat Martineau,
	Marcelo Ricardo Leitner, Xin Long
  Cc: Geliang Tang, netdev, mptcp, linux-sctp

Hi Geliang,

On 28/02/2025 11:01, Geliang Tang wrote:
> v2:
>  - add "EXPORT_SYMBOL(sock_kmemdup)" as Matthieu suggested.
>  - drop the patch "use sock_kmemdup for tcp_ao_key".


Thank you for the v2!

For the modifications in MPTCP code, this looks OK to me:

Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


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

* Re: [PATCH net-next v2 1/3] sock: add sock_kmemdup helper
  2025-02-28 10:01 ` [PATCH net-next v2 1/3] sock: " Geliang Tang
@ 2025-03-03 23:16   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 8+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-03 23:16 UTC (permalink / raw)
  To: geliang
  Cc: davem, dsahern, edumazet, horms, kuba, kuniyu, linux-sctp,
	lucien.xin, marcelo.leitner, martineau, matttbe, mptcp, ncardwell,
	netdev, pabeni, tanggeliang, willemb

From: Geliang Tang <geliang@kernel.org>
Date: Fri, 28 Feb 2025 18:01:31 +0800
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> This patch adds the sock version of kmemdup() helper, named sock_kmemdup(),
> to duplicate the input "src" memory block using the socket's option memory
> buffer.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>

Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>

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

* Re: [PATCH net-next v2 2/3] net: use sock_kmemdup for ip_options
  2025-02-28 10:01 ` [PATCH net-next v2 2/3] net: use sock_kmemdup for ip_options Geliang Tang
@ 2025-03-03 23:18   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 8+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-03 23:18 UTC (permalink / raw)
  To: geliang
  Cc: davem, dsahern, edumazet, horms, kuba, kuniyu, linux-sctp,
	lucien.xin, marcelo.leitner, martineau, matttbe, mptcp, ncardwell,
	netdev, pabeni, tanggeliang, willemb

From: Geliang Tang <geliang@kernel.org>
Date: Fri, 28 Feb 2025 18:01:32 +0800
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Instead of using sock_kmalloc() to allocate an ip_options and then
> immediately duplicate another ip_options to the newly allocated one in
> ipv6_dup_options(), mptcp_copy_ip_options() and sctp_v4_copy_ip_options(),
> the newly added sock_kmemdup() helper can be used to simplify the code.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>

Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>

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

* Re: [PATCH net-next v2 0/3] add sock_kmemdup helper
  2025-02-28 10:01 [PATCH net-next v2 0/3] add sock_kmemdup helper Geliang Tang
                   ` (3 preceding siblings ...)
  2025-02-28 12:06 ` [PATCH net-next v2 0/3] add sock_kmemdup helper Matthieu Baerts
@ 2025-03-04  2:10 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-03-04  2:10 UTC (permalink / raw)
  To: Geliang Tang
  Cc: edumazet, kuniyu, pabeni, willemb, davem, kuba, horms, ncardwell,
	dsahern, matttbe, martineau, marcelo.leitner, lucien.xin,
	tanggeliang, netdev, mptcp, linux-sctp

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 28 Feb 2025 18:01:30 +0800 you wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> v2:
>  - add "EXPORT_SYMBOL(sock_kmemdup)" as Matthieu suggested.
>  - drop the patch "use sock_kmemdup for tcp_ao_key".
> 
> While developing MPTCP BPF path manager [1], I found it's useful to
> add a new sock_kmemdup() helper.
> 
> [...]

Here is the summary with links:
  - [net-next,v2,1/3] sock: add sock_kmemdup helper
    https://git.kernel.org/netdev/net-next/c/456cc675b6d4
  - [net-next,v2,2/3] net: use sock_kmemdup for ip_options
    https://git.kernel.org/netdev/net-next/c/483cec55c1cc
  - [net-next,v2,3/3] mptcp: use sock_kmemdup for address entry
    https://git.kernel.org/netdev/net-next/c/52f83c0b5f85

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2025-03-04  2:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-28 10:01 [PATCH net-next v2 0/3] add sock_kmemdup helper Geliang Tang
2025-02-28 10:01 ` [PATCH net-next v2 1/3] sock: " Geliang Tang
2025-03-03 23:16   ` Kuniyuki Iwashima
2025-02-28 10:01 ` [PATCH net-next v2 2/3] net: use sock_kmemdup for ip_options Geliang Tang
2025-03-03 23:18   ` Kuniyuki Iwashima
2025-02-28 10:01 ` [PATCH net-next v2 3/3] mptcp: use sock_kmemdup for address entry Geliang Tang
2025-02-28 12:06 ` [PATCH net-next v2 0/3] add sock_kmemdup helper Matthieu Baerts
2025-03-04  2:10 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).