From: Yuya Kusakabe <yuya.kusakabe@gmail.com>
To: Andrea Mayer <andrea.mayer@uniroma2.it>,
Andrea Mayer <andrea@common-net.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
David Ahern <dsahern@kernel.org>,
Ido Schimmel <idosch@nvidia.com>, Shuah Khan <shuah@kernel.org>
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-kselftest@vger.kernel.org,
Yuya Kusakabe <yuya.kusakabe@gmail.com>
Subject: [PATCH RFC net-next 2/2] selftests: seg6: add selftest for End.MAP behavior
Date: Fri, 10 Jul 2026 17:58:17 +0900 [thread overview]
Message-ID: <20260710-seg6-mobile-end-map-v1-2-99be02d68143@gmail.com> (raw)
In-Reply-To: <20260710-seg6-mobile-end-map-v1-0-99be02d68143@gmail.com>
Add tools/testing/selftests/net/srv6_end_map_test.sh covering the
End.MAP behavior over a three-node topology (the script header
documents the address plan). Five cases are exercised: SRH-absent,
SRH-present (H.Encaps) and SRH-inline (H.Insert) forwarding verified
by ICMPv6 echo with Icmp6InCsumErrors asserted to stay zero, a
malformed routing header verified to be dropped via the route's own
errors counter, and a Hop Limit expiring at the End.MAP node answered
with an ICMPv6 Time Exceeded. The original and replacement addresses
are chosen with different 16-bit word sums so a transport-checksum
regression cannot cancel out. The malformed packet is crafted by a
small C helper (srv6_mobile_send) added to TEST_GEN_FILES; the test
SKIPs when iproute2 lacks the seg6mobile keyword.
Signed-off-by: Yuya Kusakabe <yuya.kusakabe@gmail.com>
---
tools/testing/selftests/net/Makefile | 2 +
tools/testing/selftests/net/srv6_end_map_test.sh | 360 +++++++++++++++++++++++
tools/testing/selftests/net/srv6_mobile_send.c | 139 +++++++++
3 files changed, 501 insertions(+)
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 708d960ae07d..9acdd4187762 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -91,6 +91,7 @@ TEST_PROGS := \
srv6_end_dx4_netfilter_test.sh \
srv6_end_dx6_netfilter_test.sh \
srv6_end_flavors_test.sh \
+ srv6_end_map_test.sh \
srv6_end_next_csid_l3vpn_test.sh \
srv6_end_x_next_csid_l3vpn_test.sh \
srv6_hencap_red_l3vpn_test.sh \
@@ -161,6 +162,7 @@ TEST_GEN_FILES := \
so_netns_cookie \
so_rcv_listener \
socket \
+ srv6_mobile_send \
stress_reuseport_listen \
tcp_fastopen_backup_key \
tcp_inq \
diff --git a/tools/testing/selftests/net/srv6_end_map_test.sh b/tools/testing/selftests/net/srv6_end_map_test.sh
new file mode 100755
index 000000000000..2a45997b6728
--- /dev/null
+++ b/tools/testing/selftests/net/srv6_end_map_test.sh
@@ -0,0 +1,360 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Selftest for the SRv6 End.MAP behavior (RFC 9433).
+#
+# +------+ 2001:db8:1::/64 +------+ 2001:db8:2::/64 +------+
+# | rt-1 | --------------------- | rt-2 | --------------------- | rt-3 |
+# +------+ veth1 +------+ veth2 +------+
+# (End.MAP)
+#
+# rt-2 holds the End.MAP route for 2001:db8:f::/64 that replaces the
+# IPv6 destination with 2001:db8:3::3 (an address on rt-3's loopback,
+# also used as the final SRv6 segment in the SRH-present scenarios).
+#
+# The original destination 2001:db8:f::1 and the replacement
+# 2001:db8:3::3 have different 16-bit word sums, so any regression in
+# the transport-checksum diff update would corrupt the ICMPv6
+# checksum and bump Icmp6InCsumErrors -- this test asserts that the
+# counter stays at zero across the run.
+#
+# Five cases are exercised:
+#
+# 1. SRH absent -- plain ICMPv6 echo to the End.MAP SID.
+# 2. SRH present -- the destination is reached through an
+# H.Encaps wrapper that carries an SRH with
+# two segments; End.MAP must leave the SRH
+# structurally intact.
+# 3. SRH inline -- the destination is reached through an
+# H.Insert wrapper that inserts an SRH whose
+# first hop is the End.MAP SID; End.MAP must
+# NOT patch the L4 checksum, because the
+# receiver's SRv6 processing restores the
+# destination from segments[0] before the
+# ICMPv6 handler verifies it.
+# 4. SRH malformed -- a C helper sends a packet whose Routing
+# Header type is not 4; End.MAP must drop it.
+# The behavior's own errors counter binds the
+# assertion to the drop.
+# 5. Hop Limit -- an echo whose Hop Limit is 1 on arrival at
+# the End.MAP node must yield an ICMPv6 Time
+# Exceeded from that node, confirming Hop Limit
+# handling is delegated to the ip6_forward path.
+
+source lib.sh
+
+readonly PING_TIMEOUT_SEC=4
+readonly END_MAP_PREFIX="2001:db8:f::/64"
+readonly END_MAP_SID="2001:db8:f::1"
+readonly RT3_SID="2001:db8:3::3"
+HELPER_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
+readonly HELPER_DIR
+readonly HELPER="${HELPER_DIR}/srv6_mobile_send"
+
+ret=0
+nsuccess=0
+nfail=0
+
+PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
+
+log_test()
+{
+ local rc=$1
+ local expected=$2
+ local msg="$3"
+
+ if [ "${rc}" -eq "${expected}" ]; then
+ nsuccess=$((nsuccess + 1))
+ printf "\n TEST: %-60s [ OK ]\n" "${msg}"
+ else
+ ret=1
+ nfail=$((nfail + 1))
+ printf "\n TEST: %-60s [FAIL]\n" "${msg}"
+ if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
+ echo
+ echo "hit enter to continue, 'q' to quit"
+ read -r a
+ [ "$a" = "q" ] && exit 1
+ fi
+ fi
+}
+
+print_log_test_results()
+{
+ printf "\nTests passed: %3d\n" "${nsuccess}"
+ printf "Tests failed: %3d\n" "${nfail}"
+}
+
+cleanup()
+{
+ cleanup_all_ns
+}
+
+trap cleanup EXIT
+
+check_dependencies()
+{
+ if [ "$(id -u)" -ne 0 ]; then
+ echo "SKIP: need root privileges"
+ exit "${ksft_skip}"
+ fi
+
+ for cmd in ip ping; do
+ if ! command -v "$cmd" >/dev/null; then
+ echo "SKIP: ${cmd} is required"
+ exit "${ksft_skip}"
+ fi
+ done
+
+ if [ ! -x "${HELPER}" ]; then
+ echo "SKIP: ${HELPER} not built"
+ exit "${ksft_skip}"
+ fi
+
+ if ! ip route help 2>&1 | grep -qF "seg6mobile"; then
+ echo "SKIP: iproute2 lacks seg6mobile support"
+ exit "${ksft_skip}"
+ fi
+
+ if ! ip route help 2>&1 | grep -qF "End.MAP"; then
+ echo "SKIP: iproute2 lacks End.MAP action"
+ exit "${ksft_skip}"
+ fi
+}
+
+setup()
+{
+ setup_ns rt1 rt2 rt3
+
+ ip -n "$rt1" link set lo up
+ ip -n "$rt2" link set lo up
+ ip -n "$rt3" link set lo up
+
+ ip link add veth1 netns "$rt1" \
+ type veth peer name veth1-rt2 netns "$rt2"
+ ip link add veth2 netns "$rt2" \
+ type veth peer name veth2-rt3 netns "$rt3"
+
+ ip -n "$rt1" addr add 2001:db8:1::1/64 dev veth1 nodad
+ ip -n "$rt2" addr add 2001:db8:1::2/64 dev veth1-rt2 nodad
+ ip -n "$rt2" addr add 2001:db8:2::1/64 dev veth2 nodad
+ ip -n "$rt3" addr add 2001:db8:2::2/64 dev veth2-rt3 nodad
+ # rt-3 also owns the End.MAP replacement SID / SRH endpoint.
+ ip -n "$rt3" addr add "$RT3_SID/128" dev lo nodad
+
+ ip -n "$rt1" link set veth1 up
+ ip -n "$rt2" link set veth1-rt2 up
+ ip -n "$rt2" link set veth2 up
+ ip -n "$rt3" link set veth2-rt3 up
+
+ ip netns exec "$rt2" sysctl -wq net.ipv6.conf.all.forwarding=1
+
+ # rt-3 must accept SRv6 packets so ipv6_srh_rcv lets the
+ # extension header chain through to local delivery.
+ ip netns exec "$rt3" sysctl -wq net.ipv6.conf.all.seg6_enabled=1
+ ip netns exec "$rt3" \
+ sysctl -wq net.ipv6.conf.veth2-rt3.seg6_enabled=1
+ ip netns exec "$rt3" sysctl -wq net.ipv6.conf.lo.seg6_enabled=1
+
+ # Disable HW checksum offload so the kernel software checksum
+ # path runs unconditionally and any csum bug surfaces.
+ ip netns exec "$rt1" ethtool -K veth1 tx off rx off 2>/dev/null
+ ip netns exec "$rt2" ethtool -K veth1-rt2 tx off rx off \
+ 2>/dev/null
+ ip netns exec "$rt2" ethtool -K veth2 tx off rx off 2>/dev/null
+ ip netns exec "$rt3" ethtool -K veth2-rt3 tx off rx off \
+ 2>/dev/null
+
+ # rt-1: route the End.MAP locator into rt-2.
+ ip -n "$rt1" -6 route add "$END_MAP_PREFIX" via 2001:db8:1::2
+
+ # rt-1: a separate H.Encaps route for the SRH-present scenario,
+ # wrapping the inner ICMPv6 echo in an outer IPv6+SRH carrying
+ # [End.MAP_SID, RT3_SID].
+ ip -n "$rt1" -6 route add "$RT3_SID/128" via 2001:db8:1::2 \
+ encap seg6 mode encap \
+ segs "$END_MAP_SID","$RT3_SID" \
+ dev veth1
+
+ # rt-2: End.MAP -- swap DA from the End.MAP SID to RT3_SID
+ # (an address on rt-3) and forward via the IPv6 FIB. "count"
+ # enables the per-behavior counters the malformed-SRH test reads.
+ ip -n "$rt2" -6 route add "$END_MAP_PREFIX" \
+ encap seg6mobile action End.MAP nh6 "$RT3_SID" count \
+ dev veth2
+
+ # rt-2: reach RT3_SID (on rt-3's loopback) through the
+ # directly connected neighbour 2001:db8:2::2.
+ ip -n "$rt2" -6 route add "$RT3_SID/128" via 2001:db8:2::2
+
+ # rt-3: return route for the ICMPv6 echo reply.
+ ip -n "$rt3" -6 route add 2001:db8:1::/64 via 2001:db8:2::1
+}
+
+read_nstat_counter()
+{
+ local ns=$1
+ local name=$2
+
+ # nstat -az reports a counter that has never incremented as 0,
+ # which is what we rely on for a clean before/after delta.
+ ip netns exec "$ns" nstat -az "$name" \
+ | awk -v n="$name" '$1 == n {print $2}'
+}
+
+read_route_errors()
+{
+ # The End.MAP route carries "count", so its errors counter
+ # increments once for every packet the behavior drops. Reading it
+ # binds the negative test to the drop itself rather than to any
+ # unrelated loss on the path to rt-3.
+ ip -n "$rt2" -j -s -6 route show "$END_MAP_PREFIX" \
+ | grep -oE '"errors":[0-9]+' | grep -oE '[0-9]+'
+}
+
+# Test 1: SRH absent.
+test_srh_absent()
+{
+ local before after rc=0
+
+ before=$(read_nstat_counter "$rt3" Icmp6InCsumErrors)
+
+ if ! ip netns exec "$rt1" \
+ ping -6 -c 1 -W "$PING_TIMEOUT_SEC" "$END_MAP_SID" \
+ >/dev/null 2>&1; then
+ rc=1
+ fi
+
+ if [ "$rc" -eq 0 ]; then
+ after=$(read_nstat_counter "$rt3" Icmp6InCsumErrors)
+ [ "$before" != "$after" ] && rc=1
+ fi
+
+ log_test "$rc" 0 "End.MAP forwards an ICMPv6 echo without an SRH"
+}
+
+# Test 2: SRH present (H.Encaps from rt-1).
+#
+# The packet rt-1 emits carries an SRH whose only intermediate
+# segment is the End.MAP SID; the final segment is RT3_SID. End.MAP
+# rewrites the outer destination from END_MAP_SID to RT3_SID
+# without touching the SRH, so on rt-3 the SRH processing advances
+# to segments[0] = RT3_SID (local) and the encapsulated inner
+# packet is decapsulated and replied to. A regression that mangles
+# the SRH (e.g. flipping bits in segments_left) would break the chain
+# and the ping would not return.
+test_srh_present()
+{
+ local before after rc=0
+
+ before=$(read_nstat_counter "$rt3" Icmp6InCsumErrors)
+
+ if ! ip netns exec "$rt1" \
+ ping -6 -c 1 -W "$PING_TIMEOUT_SEC" "$RT3_SID" \
+ >/dev/null 2>&1; then
+ rc=1
+ fi
+
+ if [ "$rc" -eq 0 ]; then
+ after=$(read_nstat_counter "$rt3" Icmp6InCsumErrors)
+ [ "$before" != "$after" ] && rc=1
+ fi
+
+ log_test "$rc" 0 "End.MAP preserves an SRH carried by H.Encaps"
+}
+
+# Test 3: SRH inserted in-place by H.Insert (mode inline).
+#
+# rt-1 inserts an SRH between the IPv6 header and the L4 payload;
+# segments[0] is the original DA (2001:db8:2::2), segments[1] is the
+# End.MAP SID. End.MAP rewrites the outer DA to RT3_SID but must
+# NOT patch the L4 checksum, because the kernel's standard SRv6
+# processing on rt-3 will decrement Segments Left to 0 and restore
+# the destination to segments[0] before the ICMPv6 handler verifies
+# the checksum against the original pseudo-header. Over-patching the
+# checksum would corrupt it and bump Icmp6InCsumErrors.
+test_srh_inline()
+{
+ local before after rc=0
+
+ ip -n "$rt1" -6 route add 2001:db8:2::2/128 via 2001:db8:1::2 \
+ encap seg6 mode inline segs "$END_MAP_SID" \
+ dev veth1
+
+ before=$(read_nstat_counter "$rt3" Icmp6InCsumErrors)
+
+ if ! ip netns exec "$rt1" \
+ ping -6 -c 1 -W "$PING_TIMEOUT_SEC" 2001:db8:2::2 \
+ >/dev/null 2>&1; then
+ rc=1
+ fi
+
+ if [ "$rc" -eq 0 ]; then
+ after=$(read_nstat_counter "$rt3" Icmp6InCsumErrors)
+ [ "$before" != "$after" ] && rc=1
+ fi
+
+ log_test "$rc" 0 "End.MAP preserves L4 csum across mode inline SRH"
+}
+
+# Test 4: SRH malformed (negative test).
+#
+# A C helper crafts an IPv6 packet whose Routing Header type is 0
+# rather than 4 (SRH), then sends it from rt-1 toward the End.MAP
+# SID. End.MAP's seg6_mobile_get_and_validate_srh() must return
+# MALFORMED and the handler must drop the packet. The assertion reads
+# the behavior's own errors counter, so it is satisfied only by the
+# End.MAP drop and not by any unrelated loss.
+test_srh_malformed()
+{
+ local before after rc=0
+
+ before=$(read_route_errors)
+
+ ip netns exec "$rt1" "$HELPER" 2001:db8:1::1 "$END_MAP_SID" \
+ >/dev/null 2>&1
+
+ after=$(read_route_errors)
+ [ "$((after - before))" -eq 1 ] || rc=1
+
+ log_test "$rc" 0 "End.MAP drops a packet carrying a malformed SRH"
+}
+
+# Test 5: Hop Limit expiry.
+#
+# End.MAP delegates the Hop Limit check and decrement to the ip6_forward
+# path. An echo whose Hop Limit is 1 when it reaches rt-2 must elicit
+# an ICMPv6 Time Exceeded from rt-2 instead of being forwarded, so
+# rt-2's Icmp6OutTimeExcds increments by exactly one.
+test_hoplimit_expiry()
+{
+ local before after rc=0
+
+ before=$(read_nstat_counter "$rt2" Icmp6OutTimeExcds)
+
+ ip netns exec "$rt1" \
+ ping -6 -c 1 -t 1 -W "$PING_TIMEOUT_SEC" "$END_MAP_SID" \
+ >/dev/null 2>&1
+
+ after=$(read_nstat_counter "$rt2" Icmp6OutTimeExcds)
+ [ "$((after - before))" -eq 1 ] || rc=1
+
+ log_test "$rc" 0 "End.MAP delegates Hop Limit expiry to ip6_forward"
+}
+
+main()
+{
+ check_dependencies
+ setup
+
+ test_srh_absent
+ test_srh_present
+ test_srh_inline
+ test_srh_malformed
+ test_hoplimit_expiry
+
+ print_log_test_results
+ exit "${ret}"
+}
+
+main "$@"
diff --git a/tools/testing/selftests/net/srv6_mobile_send.c b/tools/testing/selftests/net/srv6_mobile_send.c
new file mode 100644
index 000000000000..37d75df3704b
--- /dev/null
+++ b/tools/testing/selftests/net/srv6_mobile_send.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helper for SRv6 Mobile (RFC 9433) selftests.
+ *
+ * Usage: srv6_mobile_send <src-addr> <dst-addr>
+ */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* RFC 8200 Routing header common fields are 4 bytes; an additional
+ * 4 bytes of type-specific data follow (the Reserved field for the
+ * deprecated type 0, or first_segment/flags/tag for SRH type 4). The
+ * segment list then runs in 16-byte units, giving a total of 24 bytes
+ * for one segment -- which is what ip6r_len = 2 advertises.
+ */
+struct srh {
+ struct ip6_rthdr rthdr;
+ uint32_t type_data;
+ struct in6_addr segments[];
+};
+
+#define SRH_ONE_SEG_LEN (sizeof(struct srh) + sizeof(struct in6_addr))
+
+static uint16_t csum_fold(uint32_t sum)
+{
+ while (sum >> 16)
+ sum = (sum & 0xffff) + (sum >> 16);
+ return ~sum;
+}
+
+static uint32_t csum_partial(const void *buf, size_t len, uint32_t sum)
+{
+ const uint16_t *p = buf;
+
+ while (len > 1) {
+ sum += *p++;
+ len -= 2;
+ }
+ if (len)
+ sum += *(const uint8_t *)p;
+ return sum;
+}
+
+static uint16_t icmpv6_checksum(const struct in6_addr *src,
+ const struct in6_addr *dst,
+ const void *payload, size_t len)
+{
+ uint32_t nexthdr = htonl(IPPROTO_ICMPV6);
+ uint32_t plen = htonl(len);
+ uint32_t sum;
+
+ sum = csum_partial(src, sizeof(*src), 0);
+ sum = csum_partial(dst, sizeof(*dst), sum);
+ sum = csum_partial(&plen, sizeof(plen), sum);
+ sum = csum_partial(&nexthdr, sizeof(nexthdr), sum);
+ sum = csum_partial(payload, len, sum);
+ return csum_fold(sum);
+}
+
+int main(int argc, char **argv)
+{
+ uint8_t frame[sizeof(struct ip6_hdr) + SRH_ONE_SEG_LEN +
+ sizeof(struct icmp6_hdr)];
+ struct sockaddr_in6 dst_addr = {};
+ struct icmp6_hdr *icmp6;
+ struct ip6_hdr *ip6;
+ struct srh *srh;
+ ssize_t res;
+ int fd;
+
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s <src-addr> <dst-addr>\n", argv[0]);
+ return 1;
+ }
+
+ memset(frame, 0, sizeof(frame));
+ ip6 = (struct ip6_hdr *)frame;
+ srh = (struct srh *)(frame + sizeof(*ip6));
+ icmp6 = (struct icmp6_hdr *)(frame + sizeof(*ip6) + SRH_ONE_SEG_LEN);
+
+ ip6->ip6_flow = htonl(6u << 28);
+ ip6->ip6_plen = htons(SRH_ONE_SEG_LEN + sizeof(*icmp6));
+ ip6->ip6_nxt = IPPROTO_ROUTING;
+ ip6->ip6_hops = 64;
+ if (inet_pton(AF_INET6, argv[1], &ip6->ip6_src) != 1) {
+ fprintf(stderr, "invalid src %s\n", argv[1]);
+ return 1;
+ }
+ if (inet_pton(AF_INET6, argv[2], &ip6->ip6_dst) != 1) {
+ fprintf(stderr, "invalid dst %s\n", argv[2]);
+ return 1;
+ }
+
+ srh->rthdr.ip6r_nxt = IPPROTO_ICMPV6;
+ srh->rthdr.ip6r_len = 2; /* (1 + ip6r_len) * 8 = 24 */
+ srh->rthdr.ip6r_type = 0; /* RFC 8754: SRH is type 4 */
+ srh->rthdr.ip6r_segleft = 0;
+ srh->segments[0] = ip6->ip6_dst;
+
+ icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
+ icmp6->icmp6_code = 0;
+ icmp6->icmp6_cksum = 0;
+ icmp6->icmp6_dataun.icmp6_un_data16[0] = htons(0x1234);
+ icmp6->icmp6_dataun.icmp6_un_data16[1] = htons(1);
+ icmp6->icmp6_cksum =
+ icmpv6_checksum(&ip6->ip6_src, &ip6->ip6_dst,
+ icmp6, sizeof(*icmp6));
+
+ fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
+ if (fd < 0) {
+ perror("socket");
+ return 1;
+ }
+
+ dst_addr.sin6_family = AF_INET6;
+ dst_addr.sin6_addr = ip6->ip6_dst;
+
+ res = sendto(fd, frame, sizeof(frame), 0,
+ (struct sockaddr *)&dst_addr, sizeof(dst_addr));
+ if (res != (ssize_t)sizeof(frame)) {
+ perror("sendto");
+ close(fd);
+ return 1;
+ }
+
+ close(fd);
+ return 0;
+}
--
2.50.1
next prev parent reply other threads:[~2026-07-10 8:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 8:58 [PATCH RFC net-next 0/2] seg6: add support for the SRv6 End.MAP behavior Yuya Kusakabe
2026-07-10 8:58 ` [PATCH RFC net-next 1/2] " Yuya Kusakabe
2026-07-10 8:58 ` Yuya Kusakabe [this message]
2026-07-10 11:24 ` [PATCH RFC net-next 0/2] " Yuya Kusakabe
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=20260710-seg6-mobile-end-map-v1-2-99be02d68143@gmail.com \
--to=yuya.kusakabe@gmail.com \
--cc=andrea.mayer@uniroma2.it \
--cc=andrea@common-net.org \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox