Thread (5 messages) 5 messages, 2 authors, 5d ago
COOLING5d

[PATCH iproute2-next 1/2] seg6: add support for lookup attribute in SRv6 encap routes

From: Andrea Mayer <andrea.mayer@uniroma2.it>
Date: 2026-07-12 02:13:42
Subsystem: the rest · Maintainer: Linus Torvalds

Add support for the new optional "lookup" attribute for seg6 encap
routes. It selects the FIB table for the post-encap SID route lookup
and accepts a table number or a table name.

Examples:

  # SID route installed in the underlay table 500
  ip -6 route add fc00::100/128 via fd00::1 dev veth0 table 500

  # encap route in vrf-100; the first SID is looked up in table 500
  ip -6 route add cafe::1/128 vrf vrf-100 \
      encap seg6 mode encap segs fc00::100 lookup 500 dev veth0

  # or if the SID is already handled by the main table
  ip -6 route add cafe::1/128 vrf vrf-100 \
      encap seg6 mode encap segs fc00::100 lookup main dev veth0

When the attribute is omitted, the post-encap SID route lookup behaves
as before, using the current routing context (e.g. the tables selected
according to the routing policy database).

Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
---
 ip/iproute.c          |  1 +
 ip/iproute_lwtunnel.c | 22 +++++++++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index 5b9e7ac1..1ce71f78 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -101,6 +101,7 @@ static void usage(void)
 		"ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl | ioam6 | xfrm ]\n"
 		"ENCAPHDR := [ MPLSLABEL | SEG6HDR | SEG6LOCAL | IOAM6HDR | XFRMINFO ]\n"
 		"SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]\n"
+		"           [ lookup TABLEID ]\n"
 		"SEGMODE := [ encap | encap.red | inline | l2encap | l2encap.red ]\n"
 		"SEG6LOCAL := action ACTION [ OPTIONS ] [ count ]\n"
 		"ACTION := { End | End.X | End.T | End.DX2 | End.DX6 | End.DX4 |\n"
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 00b4f756..9a1e747c 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -256,6 +256,7 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
 {
 	struct rtattr *tb[SEG6_IPTUNNEL_MAX+1];
 	struct seg6_iptunnel_encap *tuninfo;
+	SPRINT_BUF(b1);
 
 	parse_rtattr_nested(tb, SEG6_IPTUNNEL_MAX, encap);
 
@@ -274,6 +275,12 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
 	}
 
 	print_srh(fp, tuninfo->srh);
+
+	if (tb[SEG6_IPTUNNEL_TABLE]) {
+		print_string(PRINT_ANY, "lookup", "lookup %s ",
+			     rtnl_rttable_n2a(rta_getattr_u32(tb[SEG6_IPTUNNEL_TABLE]),
+					      b1, sizeof(b1)));
+	}
 }
 
 static void print_rpl_srh(FILE *fp, struct ipv6_rpl_sr_hdr *srh)
@@ -955,7 +962,7 @@ static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
 static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
 			    char ***argvp)
 {
-	int mode_ok = 0, segs_ok = 0, hmac_ok = 0;
+	int mode_ok = 0, segs_ok = 0, hmac_ok = 0, lookup_ok = 0;
 	struct seg6_iptunnel_encap *tuninfo = NULL;
 	struct ipv6_sr_hdr *srh;
 	char **argv = *argvp;
@@ -963,6 +970,7 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
 	bool tunsrc = false;
 	inet_prefix saddr;
 	int argc = *argcp;
+	__u32 lookup = 0;
 	int encap = -1;
 	__u32 hmac = 0;
 	int ret = -1;
@@ -1006,6 +1014,13 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
 			if (hmac_ok++)
 				duparg2("hmac", *argv);
 			get_u32(&hmac, *argv, 0);
+		} else if (strcmp(*argv, "lookup") == 0) {
+			NEXT_ARG();
+			if (lookup_ok++)
+				duparg2("lookup", *argv);
+			/* note that table 0 is considered an invalid value */
+			if (rtnl_rttable_a2n(&lookup, *argv) || !lookup)
+				invarg("\"lookup\" value is invalid\n", *argv);
 		} else {
 			break;
 		}
@@ -1036,6 +1051,11 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
 			goto out;
 	}
 
+	if (lookup) {
+		if (rta_addattr32(rta, len, SEG6_IPTUNNEL_TABLE, lookup))
+			goto out;
+	}
+
 	*argcp = argc + 1;
 	*argvp = argv - 1;
 	ret = 0;
-- 
2.20.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help