Re: [PATCH v2 5/7] seg6: add End.M.GTP6.D.Di behavior
From: Andrea Mayer <hidden>
Date: 2026-06-07 14:01:22
Also in:
linux-doc, linux-kselftest, lkml
On Tue, 05 May 2026 01:30:15 +0900 Yuya Kusakabe [off-list ref] wrote: Hi Yuya, I do not repeat below the points from the cover letter thread and patch 1-4 replies (drop reasons, OIF/VRF removal, C helper, coding style, etc.). The patch 4 review applies here, except for the parts where Section 6.4 is implemented instead of Section 6.3 (which is incorrectly implemented in patch 4).
quoted hunk ↗ jump to hunk
Add the End.M.GTP6.D.Di drop-in mode variant of End.M.GTP6.D (RFC 9433 Section 6.4). Unlike End.M.GTP6.D, the drop-in variant does NOT fold the GTP-U identifiers into Args.Mob.Session: the original outer IPv6 destination is preserved at SRH[0] of the new SRH, so the destination side can keep the original address untouched while still benefiting from SR Policy steering. The augmented SRH builder/destroyer is shared with End.M.GTP6.D. The TEID and QFI parsed out of the inbound GTP-U header are intentionally discarded for this variant (matching RFC 9433 Section 6.4). When net.netfilter.nf_hooks_lwtunnel=1, the inner T-PDU traverses NF_INET_PRE_ROUTING between the GTP-U strip and the SRv6 push, mirroring End.DX4 / End.DX6. Non-T-PDU GTP-U messages are forwarded the same way as in End.M.GTP6.D: passed through via the lwtunnel's saved orig_input to a downstream peer that owns the GTP-U control plane. Configuration: ip -6 route add 2001:db8:f::/64 \ encap seg6local action End.M.GTP6.D.Di \ srh segs 2001:db8:2::e,2001:db8:3::e \ src 2001:db8:2::1 \ dev <dev> Link: https://www.rfc-editor.org/rfc/rfc9433.html#section-6.4 Signed-off-by: Yuya Kusakabe <redacted> --- include/uapi/linux/seg6_local.h | 2 + net/ipv6/seg6_local.c | 222 +++++++++++ tools/testing/selftests/net/Makefile | 1 + .../selftests/net/srv6_end_m_gtp6_d_di_test.sh | 427 +++++++++++++++++++++ 4 files changed, 652 insertions(+)diff --git a/include/uapi/linux/seg6_local.h b/include/uapi/linux/seg6_local.h index 7d3d3d245b47..326da65ad5aa 100644 --- a/include/uapi/linux/seg6_local.h +++ b/include/uapi/linux/seg6_local.h@@ -80,6 +80,8 @@ enum { SEG6_LOCAL_ACTION_END_M_GTP6_E = 19, /* IPv6/GTP-U decap into SRv6 (RFC 9433 Section 6.3) */ SEG6_LOCAL_ACTION_END_M_GTP6_D = 20, + /* IPv6/GTP-U decap into SRv6, drop-in mode (RFC 9433 Section 6.4) */ + SEG6_LOCAL_ACTION_END_M_GTP6_D_DI = 21, __SEG6_LOCAL_ACTION_MAX, };diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index 09e912e17df8..a6cd57ebcbde 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c
+ [snip]
input_action_end_m_gtp6_d_di() and its finish callback are largely identical to the patch 4 functions (input_action_end_m_gtp6_d() and its finish): the SRH check, GTP-U dispatch, outer strip, inner protocol detection, and NF_HOOK invocation are identical. The duplication should be reduced via shared helpers.
+static int input_action_end_m_gtp6_d_di(struct sk_buff *skb,
+ struct seg6_local_lwt *slwt)
+{+ [snip]
+ gtp_hdrlen = seg6_mobile_parse_gtpu(skb,
+ upper_off + sizeof(*uh),
+ &teid, &qfi);
+ if (gtp_hdrlen == -EOPNOTSUPP)
+ return seg6_mobile_passthrough_non_tpdu(skb);
+ if (gtp_hdrlen < 0) {
+ reason = SKB_DROP_REASON_SEG6_MOBILE_BAD_GTPU;
+ goto drop;
+ }
+ (void)teid;
+ (void)qfi;D.Di does not use teid or qfi, so these variables and the (void) casts are dead code and should be avoided. For example, seg6_mobile_parse_gtpu() could accept NULL for teid and qfi so callers that do not need them can pass NULL directly. Thanks, Ciao, Andrea P.S. I am temporarily writing from another address due to a mail delivery issue at my @uniroma2.it address. Please always Cc my default andrea.mayer@uniroma2.it address on replies.