Add support for the End.M.GTP6.D.Di drop-in interconnect behavior, which translates IPv6/GTP-U traffic into an SRv6 SR Policy while preserving the original outer IPv6 destination as the final SRH segment. Unlike End.M.GTP6.D, this behavior does not take sr_prefix_len. Example: ip -6 r a 2001:db8:f::/64 encap seg6local action End.M.GTP6.D.Di \ srh segs 2001:db8:2::1,2001:db8:3::e \ src 2001:db8::1 dev sr0 Link: https://datatracker.ietf.org/doc/html/rfc9433 Signed-off-by: Yuya Kusakabe --- include/uapi/linux/seg6_local.h | 2 ++ ip/iproute.c | 2 +- ip/iproute_lwtunnel.c | 2 ++ man/man8/ip-route.8.in | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/seg6_local.h b/include/uapi/linux/seg6_local.h index ed44fb858600..0ca8405df2f2 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/ip/iproute.c b/ip/iproute.c index 6cd19c2c2b00..40494ccf8eaa 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -107,7 +107,7 @@ static void usage(void) " End.DT6 | End.DT4 | End.DT46 | End.B6 | End.B6.Encaps |\n" " End.BM | End.S | End.AS | End.AM | End.BPF |\n" " End.MAP | End.M.GTP4.E | End.M.GTP6.E |\n" - " End.M.GTP6.D }\n" + " End.M.GTP6.D | End.M.GTP6.D.Di }\n" "OPTIONS := OPTION [ OPTIONS ]\n" "OPTION := { flavors FLAVORS | srh SEG6HDR | nh4 ADDR | nh6 ADDR | iif DEV | oif DEV |\n" " table TABLEID | vrftable TABLEID | endpoint PROGNAME | MOBILE_OPTION }\n" diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c index a63dfe379a89..570d95780ae4 100644 --- a/ip/iproute_lwtunnel.c +++ b/ip/iproute_lwtunnel.c @@ -409,6 +409,7 @@ static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = { [SEG6_LOCAL_ACTION_END_M_GTP4_E] = "End.M.GTP4.E", [SEG6_LOCAL_ACTION_END_M_GTP6_E] = "End.M.GTP6.E", [SEG6_LOCAL_ACTION_END_M_GTP6_D] = "End.M.GTP6.D", + [SEG6_LOCAL_ACTION_END_M_GTP6_D_DI] = "End.M.GTP6.D.Di", }; static const char *format_action_type(int action) @@ -632,6 +633,7 @@ static bool seg6local_action_excludes_final_seg(int action) switch (action) { case SEG6_LOCAL_ACTION_END_B6_ENCAP: case SEG6_LOCAL_ACTION_END_M_GTP6_D: + case SEG6_LOCAL_ACTION_END_M_GTP6_D_DI: return true; default: return false; diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in index 35e6e2080a1f..0487338707c6 100644 --- a/man/man8/ip-route.8.in +++ b/man/man8/ip-route.8.in @@ -1117,6 +1117,22 @@ The action requires either no SRH or an SRH with equal to zero on the inbound packet; other matching packets are dropped. +.B End.M.GTP6.D.Di srh segs +.IR SEGMENTS +.B src +.IR ADDRESS +- SRv6 Mobile User Plane End.M.GTP6.D.Di drop-in interconnect behavior +(RFC 9433 Section 6.4). Identical to +.B End.M.GTP6.D +except that the original outer IPv6 destination address of the +incoming GTP-U packet is preserved as the final segment of the new +SRH, allowing existing SRv6 networks to be inserted into a legacy +mobile path without changing the destination semantics. +.B sr_prefix_len +is rejected for this action: the original outer destination is +preserved verbatim instead of being repacked with an Args.Mob.Session +field, so no locator length needs to be carried. + .B Flavors parameters The flavors represent additional operations that can modify or extend a -- 2.50.1