From: Fernando Fernandez Mancera <fmancera@suse.de>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, dsahern@kernel.org, horms@kernel.org,
idosch@nvidia.com, Fernando Fernandez Mancera <fmancera@suse.de>,
Eric Biggers <ebiggers@kernel.org>,
Kuniyuki Iwashima <kuniyu@google.com>,
Ard Biesheuvel <ardb@kernel.org>, Julian Anastasov <ja@ssi.bg>,
Florian Westphal <fw@strlen.de>,
Yue Haibing <yuehaibing@huawei.com>,
"yuan.gao" <yuan.gao@ucloud.cn>, Jeff Layton <jlayton@kernel.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Kees Cook <kees@kernel.org>,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org
Subject: [PATCH 08/13 RFC net-next] net: ping: split IPv4 specific logic into ping_ipv4.c
Date: Sun, 12 Jul 2026 03:39:06 +0200 [thread overview]
Message-ID: <20260712013941.4570-9-fmancera@suse.de> (raw)
In-Reply-To: <20260712013941.4570-1-fmancera@suse.de>
To enable compiling INET subsystem withot IPv4, ping socket IPv4
specific functions must be isolated from the generic ping
infrastructure.
This patch creates ping_ipv4.c and move all the functions for packet
transmission, error handling and the AF_INET ping_prot definition from
ping.c to the new file. The Makefile is updated to compile ping_ipv4.c
only when CONFIG_IPV4 is enabled.
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
net/ipv4/Makefile | 2 +-
net/ipv4/ping.c | 215 +++--------------------------------------
net/ipv4/ping_ipv4.c | 225 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 238 insertions(+), 204 deletions(-)
create mode 100644 net/ipv4/ping_ipv4.c
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 651835073a29..83c25f52eb58 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -14,7 +14,7 @@ obj-y := inetpeer.o protocol.o inet_hashtables.o inet_timewait_sock.o \
obj-$(CONFIG_IPV4) += route.o ip_input.o ip_fragment.o ip_forward.o ip_options.o \
ip_sockglue.o tcp_ipv4.o datagram.o arp.o devinet.o igmp.o \
fib_notifier.o ip_output.o fib_frontend.o fib_semantics.o \
- fib_trie.o raw_ipv4.o udp_ipv4.o icmp_ipv4.o
+ fib_trie.o raw_ipv4.o udp_ipv4.o icmp_ipv4.o ping_ipv4.o
obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index d36f1e273fde..31ee56eeac81 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -285,25 +285,13 @@ void ping_close(struct sock *sk, long timeout)
sk_common_release(sk);
}
-static int ping_pre_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
- int addr_len)
-{
- /* This check is replicated from __ip4_datagram_connect() and
- * intended to prevent BPF program called below from accessing bytes
- * that are out of the bound specified by user in addr_len.
- */
- if (addr_len < sizeof(struct sockaddr_in))
- return -EINVAL;
-
- return BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr, &addr_len);
-}
-
/* Checks the bind address and possibly modifies sk->sk_bound_dev_if. */
static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
struct sockaddr_unsized *uaddr, int addr_len)
{
struct net *net = sock_net(sk);
if (sk->sk_family == AF_INET) {
+#if IS_ENABLED(CONFIG_IPV4)
struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
u32 tb_id = RT_TABLE_LOCAL;
int chk_addr_ret;
@@ -331,6 +319,9 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
!inet_can_nonlocal_bind(net, isk)))
return -EADDRNOTAVAIL;
+#else
+ return -EAFNOSUPPORT;
+#endif
#if IS_ENABLED(CONFIG_IPV6)
} else if (sk->sk_family == AF_INET6) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
@@ -528,6 +519,7 @@ void ping_err(struct sk_buff *skb, int offset, u32 info)
inet_sock = inet_sk(sk);
if (skb->protocol == htons(ETH_P_IP)) {
+#if IS_ENABLED(CONFIG_IPV4)
switch (type) {
default:
case ICMP_TIME_EXCEEDED:
@@ -565,6 +557,7 @@ void ping_err(struct sk_buff *skb, int offset, u32 info)
err = EREMOTEIO;
break;
}
+#endif
#if IS_ENABLED(CONFIG_IPV6)
} else if (skb->protocol == htons(ETH_P_IPV6)) {
harderr = pingv6_ops.icmpv6_err_convert(type, code, &err);
@@ -581,8 +574,10 @@ void ping_err(struct sk_buff *skb, int offset, u32 info)
goto out;
} else {
if (family == AF_INET) {
+#if IS_ENABLED(CONFIG_IPV4)
ip_icmp_error(sk, skb, err, 0 /* no remote port */,
info, (u8 *)icmph);
+#endif
#if IS_ENABLED(CONFIG_IPV6)
} else if (family == AF_INET6) {
pingv6_ops.ipv6_icmp_error(sk, skb, err, 0,
@@ -625,21 +620,6 @@ int ping_getfrag(void *from, char *to,
return 0;
}
-static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
- struct flowi4 *fl4)
-{
- struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
-
- if (!skb)
- return 0;
- pfh->wcheck = csum_partial((char *)&pfh->icmph,
- sizeof(struct icmphdr), pfh->wcheck);
- pfh->icmph.checksum = csum_fold(pfh->wcheck);
- memcpy(icmp_hdr(skb), &pfh->icmph, sizeof(struct icmphdr));
- skb->ip_summed = CHECKSUM_NONE;
- return ip_push_pending_frames(sk, fl4);
-}
-
int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
void *user_icmph, size_t icmph_len)
{
@@ -685,160 +665,6 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
return 0;
}
-static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
-{
- DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data,
- IP_OPTIONS_DATA_FIXED_SIZE);
- struct net *net = sock_net(sk);
- struct flowi4 fl4;
- struct inet_sock *inet = inet_sk(sk);
- struct ipcm_cookie ipc;
- struct icmphdr user_icmph;
- struct pingfakehdr pfh;
- struct rtable *rt = NULL;
- int free = 0;
- __be32 saddr, daddr, faddr;
- u8 scope;
- int err;
-
- pr_debug("ping_v4_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
-
- err = ping_common_sendmsg(AF_INET, msg, len, &user_icmph,
- sizeof(user_icmph));
- if (err)
- return err;
-
- /*
- * Get and verify the address.
- */
-
- if (msg->msg_name) {
- DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
- if (msg->msg_namelen < sizeof(*usin))
- return -EINVAL;
- if (usin->sin_family != AF_INET)
- return -EAFNOSUPPORT;
- daddr = usin->sin_addr.s_addr;
- /* no remote port */
- } else {
- if (sk->sk_state != TCP_ESTABLISHED)
- return -EDESTADDRREQ;
- daddr = inet->inet_daddr;
- /* no remote port */
- }
-
- ipcm_init_sk(&ipc, inet);
-
- if (msg->msg_controllen) {
- err = ip_cmsg_send(sk, msg, &ipc, false);
- if (unlikely(err)) {
- kfree(ipc.opt);
- return err;
- }
- if (ipc.opt)
- free = 1;
- }
- if (!ipc.opt) {
- struct ip_options_rcu *inet_opt;
-
- rcu_read_lock();
- inet_opt = rcu_dereference(inet->inet_opt);
- if (inet_opt) {
- memcpy(opt_copy, inet_opt,
- sizeof(*inet_opt) + inet_opt->opt.optlen);
- ipc.opt = opt_copy;
- }
- rcu_read_unlock();
- }
-
- saddr = ipc.addr;
- ipc.addr = faddr = daddr;
-
- if (ipc.opt && ipc.opt->opt.srr) {
- if (!daddr) {
- err = -EINVAL;
- goto out_free;
- }
- faddr = ipc.opt->opt.faddr;
- }
- scope = ip_sendmsg_scope(inet, &ipc, msg);
-
- if (ipv4_is_multicast(daddr)) {
- if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
- ipc.oif = READ_ONCE(inet->mc_index);
- if (!saddr)
- saddr = READ_ONCE(inet->mc_addr);
- } else if (!ipc.oif)
- ipc.oif = READ_ONCE(inet->uc_index);
-
- flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark,
- ipc.tos & INET_DSCP_MASK, scope,
- sk->sk_protocol, inet_sk_flowi_flags(sk), faddr,
- saddr, 0, 0, sk_uid(sk));
-
- fl4.fl4_icmp_type = user_icmph.type;
- fl4.fl4_icmp_code = user_icmph.code;
-
- security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
- rt = ip_route_output_flow(net, &fl4, sk);
- if (IS_ERR(rt)) {
- err = PTR_ERR(rt);
- rt = NULL;
- if (err == -ENETUNREACH)
- IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
- goto out;
- }
-
- err = -EACCES;
- if ((rt->rt_flags & RTCF_BROADCAST) &&
- !sock_flag(sk, SOCK_BROADCAST))
- goto out;
-
- if (msg->msg_flags & MSG_CONFIRM)
- goto do_confirm;
-back_from_confirm:
-
- if (!ipc.addr)
- ipc.addr = fl4.daddr;
-
- lock_sock(sk);
-
- pfh.icmph.type = user_icmph.type; /* already checked */
- pfh.icmph.code = user_icmph.code; /* ditto */
- pfh.icmph.checksum = 0;
- pfh.icmph.un.echo.id = inet->inet_sport;
- pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
- pfh.msg = msg;
- pfh.wcheck = 0;
- pfh.family = AF_INET;
-
- err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
- sizeof(struct icmphdr), &ipc, &rt,
- msg->msg_flags);
- if (err)
- ip_flush_pending_frames(sk);
- else
- err = ping_v4_push_pending_frames(sk, &pfh, &fl4);
- release_sock(sk);
-
-out:
- ip_rt_put(rt);
-out_free:
- if (free)
- kfree(ipc.opt);
- if (!err)
- return len;
- return err;
-
-do_confirm:
- if (msg->msg_flags & MSG_PROBE)
- dst_confirm_neigh(&rt->dst, &fl4.daddr);
- if (!(msg->msg_flags & MSG_PROBE) || len)
- goto back_from_confirm;
- err = 0;
- goto out;
-}
-
int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags)
{
struct inet_sock *isk = inet_sk(sk);
@@ -875,6 +701,7 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags)
/* Copy the address and add cmsg data. */
if (family == AF_INET) {
+#if IS_ENABLED(CONFIG_IPV4)
DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
if (sin) {
@@ -888,6 +715,7 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags)
if (inet_cmsg_flags(isk))
ip_cmsg_recv(msg, skb);
+#endif
#if IS_ENABLED(CONFIG_IPV6)
} else if (family == AF_INET6) {
struct ipv6hdr *ip6 = ipv6_hdr(skb);
@@ -911,9 +739,11 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags)
if (skb->protocol == htons(ETH_P_IPV6) &&
inet6_sk(sk)->rxopt.all)
pingv6_ops.ip6_datagram_recv_specific_ctl(sk, msg, skb);
+#if IS_ENABLED(CONFIG_IPV4)
else if (skb->protocol == htons(ETH_P_IP) &&
inet_cmsg_flags(isk))
ip_cmsg_recv(msg, skb);
+#endif
#endif
} else {
BUG();
@@ -976,27 +806,6 @@ enum skb_drop_reason ping_rcv(struct sk_buff *skb)
return SKB_DROP_REASON_NO_SOCKET;
}
-struct proto ping_prot = {
- .name = "PING",
- .owner = THIS_MODULE,
- .init = ping_init_sock,
- .close = ping_close,
- .pre_connect = ping_pre_connect,
- .connect = ip4_datagram_connect,
- .disconnect = __udp_disconnect,
- .setsockopt = ip_setsockopt,
- .getsockopt = ip_getsockopt,
- .sendmsg = ping_v4_sendmsg,
- .recvmsg = ping_recvmsg,
- .bind = ping_bind,
- .backlog_rcv = ping_queue_rcv_skb,
- .release_cb = ip4_datagram_release_cb,
- .unhash = ping_unhash,
- .get_port = ping_get_port,
- .put_port = ping_unhash,
- .obj_size = sizeof(struct inet_sock),
-};
-
#ifdef CONFIG_PROC_FS
static struct sock *ping_get_first(struct seq_file *seq, int start)
diff --git a/net/ipv4/ping_ipv4.c b/net/ipv4/ping_ipv4.c
new file mode 100644
index 000000000000..09fc1d85846d
--- /dev/null
+++ b/net/ipv4/ping_ipv4.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * "Ping" sockets
+ *
+ * IPv4 specific functions
+ *
+ * code split from:
+ * net/ipv4/ping.c
+ *
+ * See ping.c for author information
+ */
+
+#include <linux/bpf-cgroup.h>
+#include <linux/in.h>
+#include <linux/socket.h>
+#include <linux/types.h>
+#include <net/ping.h>
+#include <net/udp.h>
+
+static int ping_pre_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
+ int addr_len)
+{
+ /* This check is replicated from __ip4_datagram_connect() and
+ * intended to prevent BPF program called below from accessing bytes
+ * that are out of the bound specified by user in addr_len.
+ */
+ if (addr_len < sizeof(struct sockaddr_in))
+ return -EINVAL;
+
+ return BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr, &addr_len);
+}
+
+static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
+ struct flowi4 *fl4)
+{
+ struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
+
+ if (!skb)
+ return 0;
+ pfh->wcheck = csum_partial((char *)&pfh->icmph,
+ sizeof(struct icmphdr), pfh->wcheck);
+ pfh->icmph.checksum = csum_fold(pfh->wcheck);
+ memcpy(icmp_hdr(skb), &pfh->icmph, sizeof(struct icmphdr));
+ skb->ip_summed = CHECKSUM_NONE;
+ return ip_push_pending_frames(sk, fl4);
+}
+
+static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+{
+ DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data,
+ IP_OPTIONS_DATA_FIXED_SIZE);
+ struct net *net = sock_net(sk);
+ struct flowi4 fl4;
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipcm_cookie ipc;
+ struct icmphdr user_icmph;
+ struct pingfakehdr pfh;
+ struct rtable *rt = NULL;
+ int free = 0;
+ __be32 saddr, daddr, faddr;
+ u8 scope;
+ int err;
+
+ pr_debug("ping_v4_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
+
+ err = ping_common_sendmsg(AF_INET, msg, len, &user_icmph,
+ sizeof(user_icmph));
+ if (err)
+ return err;
+
+ /*
+ * Get and verify the address.
+ */
+
+ if (msg->msg_name) {
+ DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
+ if (msg->msg_namelen < sizeof(*usin))
+ return -EINVAL;
+ if (usin->sin_family != AF_INET)
+ return -EAFNOSUPPORT;
+ daddr = usin->sin_addr.s_addr;
+ /* no remote port */
+ } else {
+ if (sk->sk_state != TCP_ESTABLISHED)
+ return -EDESTADDRREQ;
+ daddr = inet->inet_daddr;
+ /* no remote port */
+ }
+
+ ipcm_init_sk(&ipc, inet);
+
+ if (msg->msg_controllen) {
+ err = ip_cmsg_send(sk, msg, &ipc, false);
+ if (unlikely(err)) {
+ kfree(ipc.opt);
+ return err;
+ }
+ if (ipc.opt)
+ free = 1;
+ }
+ if (!ipc.opt) {
+ struct ip_options_rcu *inet_opt;
+
+ rcu_read_lock();
+ inet_opt = rcu_dereference(inet->inet_opt);
+ if (inet_opt) {
+ memcpy(opt_copy, inet_opt,
+ sizeof(*inet_opt) + inet_opt->opt.optlen);
+ ipc.opt = opt_copy;
+ }
+ rcu_read_unlock();
+ }
+
+ saddr = ipc.addr;
+ ipc.addr = faddr = daddr;
+
+ if (ipc.opt && ipc.opt->opt.srr) {
+ if (!daddr) {
+ err = -EINVAL;
+ goto out_free;
+ }
+ faddr = ipc.opt->opt.faddr;
+ }
+ scope = ip_sendmsg_scope(inet, &ipc, msg);
+
+ if (ipv4_is_multicast(daddr)) {
+ if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
+ ipc.oif = READ_ONCE(inet->mc_index);
+ if (!saddr)
+ saddr = READ_ONCE(inet->mc_addr);
+ } else if (!ipc.oif)
+ ipc.oif = READ_ONCE(inet->uc_index);
+
+ flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark,
+ ipc.tos & INET_DSCP_MASK, scope,
+ sk->sk_protocol, inet_sk_flowi_flags(sk), faddr,
+ saddr, 0, 0, sk_uid(sk));
+
+ fl4.fl4_icmp_type = user_icmph.type;
+ fl4.fl4_icmp_code = user_icmph.code;
+
+ security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
+ rt = ip_route_output_flow(net, &fl4, sk);
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ rt = NULL;
+ if (err == -ENETUNREACH)
+ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
+ goto out;
+ }
+
+ err = -EACCES;
+ if ((rt->rt_flags & RTCF_BROADCAST) &&
+ !sock_flag(sk, SOCK_BROADCAST))
+ goto out;
+
+ if (msg->msg_flags & MSG_CONFIRM)
+ goto do_confirm;
+back_from_confirm:
+
+ if (!ipc.addr)
+ ipc.addr = fl4.daddr;
+
+ lock_sock(sk);
+
+ pfh.icmph.type = user_icmph.type; /* already checked */
+ pfh.icmph.code = user_icmph.code; /* ditto */
+ pfh.icmph.checksum = 0;
+ pfh.icmph.un.echo.id = inet->inet_sport;
+ pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
+ pfh.msg = msg;
+ pfh.wcheck = 0;
+ pfh.family = AF_INET;
+
+ err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
+ sizeof(struct icmphdr), &ipc, &rt,
+ msg->msg_flags);
+ if (err)
+ ip_flush_pending_frames(sk);
+ else
+ err = ping_v4_push_pending_frames(sk, &pfh, &fl4);
+ release_sock(sk);
+
+out:
+ ip_rt_put(rt);
+out_free:
+ if (free)
+ kfree(ipc.opt);
+ if (!err)
+ return len;
+ return err;
+
+do_confirm:
+ if (msg->msg_flags & MSG_PROBE)
+ dst_confirm_neigh(&rt->dst, &fl4.daddr);
+ if (!(msg->msg_flags & MSG_PROBE) || len)
+ goto back_from_confirm;
+ err = 0;
+ goto out;
+}
+
+struct proto ping_prot = {
+ .name = "PING",
+ .owner = THIS_MODULE,
+ .init = ping_init_sock,
+ .close = ping_close,
+ .pre_connect = ping_pre_connect,
+ .connect = ip4_datagram_connect,
+ .disconnect = __udp_disconnect,
+ .setsockopt = ip_setsockopt,
+ .getsockopt = ip_getsockopt,
+ .sendmsg = ping_v4_sendmsg,
+ .recvmsg = ping_recvmsg,
+ .bind = ping_bind,
+ .backlog_rcv = ping_queue_rcv_skb,
+ .release_cb = ip4_datagram_release_cb,
+ .unhash = ping_unhash,
+ .get_port = ping_get_port,
+ .put_port = ping_unhash,
+ .obj_size = sizeof(struct inet_sock),
+};
--
2.54.0
next prev parent reply other threads:[~2026-07-12 1:41 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260712013941.4570-1-fmancera@suse.de>
2026-07-12 1:39 ` [PATCH 02/13 RFC net-next] net: core: add IPv4 fallback stubs and guards for CONFIG_IPV4=n Fernando Fernandez Mancera
2026-07-12 1:39 ` [PATCH 04/13 RFC net-next] net: tcp: move protocol agnostic TCP functions out of tcp_ipv4.c Fernando Fernandez Mancera
2026-07-12 1:39 ` [PATCH 06/13 RFC net-next] net: udp: split IPv4 specific logic into udp_ipv4.c Fernando Fernandez Mancera
2026-07-12 1:39 ` Fernando Fernandez Mancera [this message]
2026-07-12 1:39 ` [PATCH 09/13 RFC net-next] net: fib: split common nexthop logic to fib_core.c Fernando Fernandez Mancera
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=20260712013941.4570-9-fmancera@suse.de \
--to=fmancera@suse.de \
--cc=ardb@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=ebiggers@kernel.org \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=gustavoars@kernel.org \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=ja@ssi.bg \
--cc=jlayton@kernel.org \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=yuan.gao@ucloud.cn \
--cc=yuehaibing@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox