From nobody Thu Nov 5 05:41:49 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=160.80.4.35 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793844002; b=PCF688leVl9uBJbuUdPOOd+ZlYyRkhhN1uGsOckkHJKGY5b8DGQO1QTAKLbAamrC7i1l k8Ten+Jp+977MH8wcaCu/Awuk0p8qeriA3Xi3Zo3PZmHLGXC6iBhWVXuAHZ0P17i0bNJL o10OdTda4b1eJvaygYnc41aDNIrxYEYYhSTtn2R6Me/BQOhgk02cB5sVpxmUxY01DQCYA VvzqH2wLYzu5be87JtdIwXN/x64QvH60l0Hk2OaotowedpauMHPYOCnkZ136YUUrKPFgz r26M9zzv8nNHJeTorUwAvLj0J9uOBx8vbrmqWoAB9hZLL4IdlszQ6edAq5CjKxkKm/w== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793844002; h=DMARC-Filter:Received:Received:DKIM-Signature:DKIM-Signature:From:To: Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:X-Virus-Scanned: X-Virus-Status; bh=ImAMCNfgrZHhGnvZrY4VhJufPGL6dv60m/vPtmdLXwM=; b=kG6csf0nFrSN4Vb5YdfWWrCRQ51A2O0xbH2iXX3lzYLCgnE65vXx6/3uAq9okRdy4m+i U4gTsKFRdgfCXV/yn1OOHE4P1Baj4GVNcHlx6xFilIpbkRw6uvjIpgresBkgpAIX+N6B1 a4nBWAjPxkQ8r4b2Ud6onLr/l48QbV1jE5ZzCvr4oqBCPZOxBG1B/iZLrN0o7xV2rHYD6 hJ+oI2/mA8XIgmFu/v8lKm4IGL8dwf71LBsloO+YI1NhplDFuGTUuKldec+sYSH3k50WA Cq6D4X6H/9jCW9a3oaLAphLlbHnIEHo5e3/FSX2Zl562hjsDG2KwnSn/QOrRUp6QTww== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=uniroma2.it; spf=pass smtp.mailfrom=uniroma2.it; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=tds4UUfj; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=a+awCnuz; arc=none smtp.remote-ip=160.80.4.35 Received: from smtp.uniroma2.it (smtp.uniroma2.it [160.80.4.35]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 29B88606D824; Thu, 5 Nov 2026 02:00:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 29B88606D824 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=tds4UUfj; dkim=pass (2048-bit key, unprotected) header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=a+awCnuz Received: from smtpauth-2019-1.uniroma2.it (smtpauth.uniroma2.it [160.80.5.46]) by smtp-2015.uniroma2.it (8.14.4/8.14.4/Debian-8) with ESMTP id 6A51xCAn001496; Thu, 5 Nov 2026 02:59:17 +0100 Received: from localhost.localdomain (unknown [160.80.105.87]) by smtpauth-2019-1.uniroma2.it (Postfix) with ESMTPSA id C94871228D3; Thu, 5 Nov 2026 02:59:07 +0100 (CET) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=uniroma2.it; s=ed201904; t=1793843947; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ImAMCNfgrZHhGnvZrY4VhJufPGL6dv60m/vPtmdLXwM=; b=tds4UUfj+wxvXhVWr+LUfKaO73mhLdIYrvbq50crqojK0ILr35sOKfUMwuoE1D93OFf2x5 Ppvh9wK8A+tzGZBw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uniroma2.it; s=rsa201904; t=1793843947; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ImAMCNfgrZHhGnvZrY4VhJufPGL6dv60m/vPtmdLXwM=; b=a+awCnuzUg5m36Ynwcn1qef6suk/Jd/6XWVnqJn4DS65/YiSM6e3/NDpXnTsAuIB9iWd5O QrDo7Zc1nZlLRKykBdYfsipTcRhjTTwWlHDrnajjSyhl6969sSZXhi/Opy+6SVkoTIooun OEsP+tLezGN6W2LC6Sok+yXJydLeo6qXNAi1KCRn5oIFo+7uAvJ85Yc2tBieGfNr98HgnK 7iowRBVWKCD1FkaPTeMN2JBTwogxT9r7FMQDeCfzkIYVXyB3fq6KrW50X6uyizJm4XuhES 2lyg0p1qUxcEUaShL1Cc3U9uTjAHeFo6QNtdlie4ItnCpiIFLU4zQLyo9tnfGQ== From: Andrea Mayer To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Shuah Khan , Hangbin Liu , Justin Iurman , Nicolas Dichtel , Ahmed Abdelsalam , Stefano Salsano , Andrea Mayer , andrea@common-net.org, Hangbin Liu Subject: [PATCH net-next v2 1/5] seg6: handle a Fragment or AH header before the SRH consistently in PSP Date: Thu, 5 Nov 2026 02:57:11 +0100 Message-Id: <20261105015715.57-2-andrea.mayer@uniroma2.it> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261105015715.57-1-andrea.mayer@uniroma2.it> References: <20261105015715.57-1-andrea.mayer@uniroma2.it> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: clamav-milter 0.100.0 at smtp-2015 X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" seg6_pop_srh() already fails when a Fragment or AH header comes before the SRH with other headers in between, and the packet is dropped ("we expect SRH before FRAG and AUTH" in the code). But when the SRH directly follows the Fragment or AH header, it is removed: (a) IPv6 | FRAG/AH | DOPT | SRH | ... the packet is dropped (b) IPv6 | FRAG/AH | SRH | ... the SRH is removed In both packets the Fragment or AH header comes before the SRH. Align the two cases: check first whether a header is a Fragment or AH header, and only then look at its Next Header field. In this way, the packet is dropped also when the Fragment or AH header comes directly before the SRH. A Fragment or AH header before the SRH, with or without other headers in between, does not follow RFC 8200 and RFC 4302: a Fragment header must not come before the Routing header, as the Per-Fragment headers must include the Routing header [1], and AH should not come before the routing and fragmentation headers [2]. At the penultimate segment, End with the PSP flavor alone today drops (a) and forwards (b) with the SRH removed. Packets with the Fragment or AH header after the SRH are not affected: seg6_pop_srh() does not look at the headers after the SRH. Found by manual code inspection and reproduced in a VM without kernel changes or error injection, by sending to End with PSP the packets shown in the diagram, both with a Fragment header and with AH. With this change, the packets are dropped in both cases, all tests in srv6_end_flavors_test.sh pass, and KASAN reports no error. With the whole series, all the srv6_*.sh selftests pass. [1] - https://datatracker.ietf.org/doc/html/rfc8200#section-4.5 [2] - https://datatracker.ietf.org/doc/html/rfc4302#section-3.1.1 Fixes: bdf3c0b9c10b ("seg6: add PSP flavor support for SRv6 End behavior") Reviewed-by: Hangbin Liu Signed-off-by: Andrea Mayer --- net/ipv6/seg6_local.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index 0c3d1be7f129..da8225591fe3 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -796,11 +796,6 @@ static bool seg6_pop_srh(struct sk_buff *skb, int srho= ff) if (unlikely(!hp)) return false; =20 - if (hp->nexthdr =3D=3D NEXTHDR_ROUTING) { - hp->nexthdr =3D srh_nexthdr; - break; - } - switch (nexthdr) { case NEXTHDR_FRAGMENT: fallthrough; @@ -812,6 +807,11 @@ static bool seg6_pop_srh(struct sk_buff *skb, int srho= ff) break; } =20 + if (hp->nexthdr =3D=3D NEXTHDR_ROUTING) { + hp->nexthdr =3D srh_nexthdr; + break; + } + nexthdr =3D hp->nexthdr; } } --=20 2.43.0 From nobody Thu Nov 5 05:41:49 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=160.80.4.35 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793844003; b=vPWF9ljLxZH1v+56w/4BNec6h6aPSW+Y9raVXQjr2akMLa9fVtxVWyvLxqGCvWbIDsZt FqAB0REbgz6JGqjVVTJws8WvTUo9OQOyzbe3vHrtUOEdzbumblo9BLzFIG0XeHX3KGlkS fo3tn3Su7TVj+DcZIxJcA4X/X1ovtCrfNtHk3STw08PmVvceV6eq/DA15txgkh1N/nImk eGXeimGQ0qrmx9QBHC+Q+7Rt2xA2z+Hbkp2dmZIG8kCORmALIe5rTjYhRP6auKb51NVTl CTezbVuJBPr+gHIdznL1KKlHAhEVn4PL9gWKlsAzT24VT06P41br9J98XrqXiyoQDxw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793844003; h=DMARC-Filter:Received:Received:DKIM-Signature:DKIM-Signature:From:To: Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:X-Virus-Scanned: X-Virus-Status; bh=DmQXE3CaAVl0Zz6o4LK0xCYillIz77fI97ndvt560Sg=; b=brnlEg9apV4SC8qlkbSKBPzqyV2AwiwV31hYeR/iFoHw3c/BJp5PKFru/hypZaFRa6Zs 2bxAw5qOnl5PW7yKmaq+GQdKYLa7qOqBH+Al9HMVTYYjKyYvyAT5FubVKV0xouC8z9JWb HxapnRfLrV3SNMcv+MI9uGbVCUi0is0gHJ9K8yethTlUK9GDnZ1UH1b9x5+Zq+k9hUWqd b9lZWM5Q1NjPerviwcxSzaEh4LtGx167LKBeg63SgsMnTBCUcpALR/jWxyTkD+bfziHg1 xPwwDbzElBKZI5kjudoJnt0mqKdQK6DUiXQyVdtJPPLv2biViH+kDt2SSHID4YJi+/A== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=uniroma2.it; spf=pass smtp.mailfrom=uniroma2.it; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=voiLsuYs; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=IB+17Crj; arc=none smtp.remote-ip=160.80.4.35 Received: from smtp.uniroma2.it (smtp.uniroma2.it [160.80.4.35]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7EFDC606D82B; Thu, 5 Nov 2026 02:00:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 7EFDC606D82B Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=voiLsuYs; dkim=pass (2048-bit key, unprotected) header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=IB+17Crj Received: from smtpauth-2019-1.uniroma2.it (smtpauth-2019-1.uniroma2.it [160.80.5.46]) by smtp-2015.uniroma2.it (8.14.4/8.14.4/Debian-8) with ESMTP id 6A51xCDK001497; Thu, 5 Nov 2026 02:59:17 +0100 Received: from localhost.localdomain (unknown [160.80.105.87]) by smtpauth-2019-1.uniroma2.it (Postfix) with ESMTPSA id DE621122926; Thu, 5 Nov 2026 02:59:07 +0100 (CET) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=uniroma2.it; s=ed201904; t=1793843947; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DmQXE3CaAVl0Zz6o4LK0xCYillIz77fI97ndvt560Sg=; b=voiLsuYshGeijyireJryolwAubAGQ10sSwmMGmU7dB79SnlN0eB5GqR+tal9pYEU/YNQMR zj58J3hI3z4/r4CQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uniroma2.it; s=rsa201904; t=1793843947; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DmQXE3CaAVl0Zz6o4LK0xCYillIz77fI97ndvt560Sg=; b=IB+17Crjh5ZQc3meNHUcXGnQAZsuIMWdhhMFL+DwjMCHa6JuTLdP2DOPHpzAKmVZ4/OTrl UuNwUqXPeasCcQfdgQ0kEHu0l043j47+X27vv1yLBF7mhonsbBRQjQEf3C7F6i6VBXTPh5 v3oScZm+h7MEaPKZjNHA9OEa6tvlXml9jFXMn72RbCcnFGyfAdsFZW8TMVaLaZgRAiPdXO 3dCLHwzuikwIRwlSgbUKF+9z6kdx4RnCTSjuvn6zcBfLie6TvEI7MEsJgCl2Ilz3hoQstA DqoRkI8wMKBOfHz8uckF+bm1SzlNDcLJG6smJtxORIfTs34C0kCGkqTvKwb0+A== From: Andrea Mayer To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Shuah Khan , Hangbin Liu , Justin Iurman , Nicolas Dichtel , Ahmed Abdelsalam , Stefano Salsano , Andrea Mayer , andrea@common-net.org, Hangbin Liu Subject: [PATCH net-next v2 2/5] seg6: handle a consumed SRH in SRv6 End with the PSP flavor Date: Thu, 5 Nov 2026 02:57:12 +0100 Message-Id: <20261105015715.57-3-andrea.mayer@uniroma2.it> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261105015715.57-1-andrea.mayer@uniroma2.it> References: <20261105015715.57-1-andrea.mayer@uniroma2.it> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: clamav-milter 0.100.0 at smtp-2015 X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" With the seg6 inline mode, a packet can carry more than one SRH. The SRHs with Segments Left 0 are considered consumed SRHs, and they can come before the SRH to process (Segments Left > 0), as in this packet: +------+----------------------+----------------------+---------+ | IPv6 | SRH, Segments Left 0 | SRH, Segments Left 1 | payload | +------+----------------------+----------------------+---------+ End without flavors skips the consumed SRH and processes the next one [1]. With the PSP flavor, End should do the same. When the SRH to process arrives with Segments Left 1, as in the diagram, End with PSP should then also remove it [2]. However, End with PSP alone currently looks only at the first routing header of the packet, finds Segments Left 0 there, and drops the packet. Make End with PSP alone skip the consumed SRHs, and any other routing header with Segments Left 0, and process the SRH that follows them. If there is no SRH to process, the packet is dropped as before. When the SRH to process arrives with Segments Left 1, End with PSP now removes it even if consumed SRHs come before it. Found by manual code inspection and reproduced in a VM without kernel changes or error injection. A following commit adds tests for this case to srv6_end_flavors_test.sh. Without this change, the new tests with a consumed SRH fail for End with PSP alone. With this series, all tests pass and KASAN reports no error. [1] - https://datatracker.ietf.org/doc/html/rfc8986#section-4.1 [2] - https://datatracker.ietf.org/doc/html/rfc8986#section-4.16.1.2 Fixes: bdf3c0b9c10b ("seg6: add PSP flavor support for SRv6 End behavior") Reviewed-by: Hangbin Liu Signed-off-by: Andrea Mayer --- net/ipv6/seg6_local.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index da8225591fe3..26cd4facbe36 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -775,11 +775,14 @@ static bool seg6_pop_srh(struct sk_buff *skb, int srh= off) skb_set_transport_header(skb, thoff); =20 iph =3D ipv6_hdr(skb); - if (iph->nexthdr =3D=3D NEXTHDR_ROUTING) { + if (srhoff =3D=3D sizeof(*iph)) { iph->nexthdr =3D srh_nexthdr; } else { /* we must look for the extension header (EXTH, for short) that - * immediately precedes the SRH we have just removed. + * immediately precedes the SRH we have just removed, i.e. the + * EXTH that ends at srhoff. We find it by its position and not + * by its nexthdr, since another routing header (e.g. an SRH + * with SL =3D 0) may come before the removed SRH. * Then, we update the value of the EXTH nexthdr with the one * contained in the SRH nexthdr. */ @@ -807,7 +810,7 @@ static bool seg6_pop_srh(struct sk_buff *skb, int srhof= f) break; } =20 - if (hp->nexthdr =3D=3D NEXTHDR_ROUTING) { + if (off =3D=3D srhoff) { hp->nexthdr =3D srh_nexthdr; break; } @@ -823,6 +826,24 @@ static bool seg6_pop_srh(struct sk_buff *skb, int srho= ff) return true; } =20 +/* look up the SRH to be processed by the RFC8986 flavors. As End does, a + * routing header with SL =3D 0 is skipped (e.g. an SRH already consumed). + * This function returns NULL when no valid SRH is found. + */ +static struct ipv6_sr_hdr *seg6_flv8986_get_srh(struct sk_buff *skb) +{ + struct ipv6_sr_hdr *srh; + + srh =3D seg6_get_srh(skb, IP6_FH_F_SKIP_RH); + if (srh) + return srh; + + /* we take the first routing header without skipping it. In this way, + * seg6_get_srh_pktinfo() reports SL =3D 0 and not a missing SRH. + */ + return seg6_get_srh(skb, 0); +} + /* process the packet on the basis of the RFC8986 flavors set for the given * SRv6 End behavior instance. */ @@ -837,7 +858,7 @@ static int end_flv8986_core(struct sk_buff *skb, struct= seg6_local_lwt *slwt) __u32 flvmask; int srhoff; =20 - srh =3D seg6_get_srh(skb, 0); + srh =3D seg6_flv8986_get_srh(skb); srhoff =3D srh ? ((unsigned char *)srh - skb->data) : 0; pinfo =3D seg6_get_srh_pktinfo(srh); #ifdef CONFIG_IPV6_SEG6_HMAC --=20 2.43.0 From nobody Thu Nov 5 05:41:49 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=160.80.4.35 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793843999; b=XEqscHAcRDNvQOf6m8nBSLW7qnDCpAi8SyX/cE/XrHRIEqwCci1vIX05CV9PJzT1Wqhn HWJUgVdIGamJ3R2Ni4yST2XKZi5lknf4dC1/llonHVBRi5ITU9qI8iUR3RNovXjhoqcKS KZAHX6VavAtR7+75MHsRdNsLeiLJ3fvYN71Zr/XG6y0QGj7wH4lEDqso7i1GR1L7eAjU4 sYjp7gTB8HCXMz/B6CqjDH6GtV9i3yG5OappdhKvcNDon76ig/cNtyBJe0tGf+ZwTQTjB JgmNoITiOfc/q+UcJHmTfSq3LEqJu6Bge08R2Vqvymz3nAc7wHdP/LWZWzdvPfYTXCQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793843999; h=DMARC-Filter:Received:Received:DKIM-Signature:DKIM-Signature:From:To: Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:X-Virus-Scanned: X-Virus-Status; bh=0uFUiNBADWLsVyespJGX9TFCNxcnQ1X32FvqWfAy6qA=; b=gHf3kyWY9jDfJpZWa4p/OxsSd5HwAWdZxuNgZs5u4mc+lwZvD200YQ4rObCpoVhdqtef VPXUFyEi6WwaPONQ+63DFF8XCY0cVoGxAy/Ze++Wua+R9lRoi4XzCK/ANFfZwBN6kbl1D xk3qH30uVc6ybTMIIGMyuHM13v3h/4Z2Z9FAuvg472xvf4vJtHrGEbit3ZKGj2qkusETD zrcyuFXF8jLRybOuFkNj6TYOoizVVO00IVouXmEA37RLBB1SwYYJcCvBXuEOCNaxWARqN 8aKjoEMBO7H2MD/qdBYvksBV1sQBWRRamn66vnwUAfyhJyEftnY7eAnnh0uPuf5pthQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=uniroma2.it; spf=pass smtp.mailfrom=uniroma2.it; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=D0NoUqyj; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=d9Mi9COX; arc=none smtp.remote-ip=160.80.4.35 Received: from smtp.uniroma2.it (smtp.uniroma2.it [160.80.4.35]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8842F606A329; Thu, 5 Nov 2026 01:59:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 8842F606A329 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=D0NoUqyj; dkim=pass (2048-bit key, unprotected) header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=d9Mi9COX Received: from smtpauth-2019-1.uniroma2.it (smtpauth.uniroma2.it [160.80.5.46]) by smtp-2015.uniroma2.it (8.14.4/8.14.4/Debian-8) with ESMTP id 6A51xC7J001498; Thu, 5 Nov 2026 02:59:17 +0100 Received: from localhost.localdomain (unknown [160.80.105.87]) by smtpauth-2019-1.uniroma2.it (Postfix) with ESMTPSA id 0133812294E; Thu, 5 Nov 2026 02:59:08 +0100 (CET) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=uniroma2.it; s=ed201904; t=1793843948; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0uFUiNBADWLsVyespJGX9TFCNxcnQ1X32FvqWfAy6qA=; b=D0NoUqyjm5QCmVNYW+kHed2EXGo25ym2KcxtSiTGSfA3qhhjiMM0ahlfmPpNZoLg7niDjA lpy/R2fDkePuZUDw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uniroma2.it; s=rsa201904; t=1793843948; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0uFUiNBADWLsVyespJGX9TFCNxcnQ1X32FvqWfAy6qA=; b=d9Mi9COX8dsnbov/p9nz8ZaP2FbUfn2yFtSZnVNUt/I5uMPtCDMBM5enL7UT2aAp6C0XXQ Zq6XWH6yj2qR4rYcQq3JLADj0W4gQA3SjGW1enmO1ypmsNDIxkK2AWjqLgQVAvQxaae7sO nC2foog+P2OACEsmFr7QHodfudFdDryCu3kpUqs0YrFKc7FP6DemiifO9tkdYMIIMrY6VP //TyK88wOytZCsmYhqZhtPhqr3bUuO1/d7VXIPUW/dsQgl9pLUKqXgkwYgX6oH848MR2Is UfQQVeVWaBU5LYAm2y88uErmQHUWKaRZylJ16DtjlMHitiaUl6W5aIlTxvCJ0g== From: Andrea Mayer To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Shuah Khan , Hangbin Liu , Justin Iurman , Nicolas Dichtel , Ahmed Abdelsalam , Stefano Salsano , Andrea Mayer , andrea@common-net.org, Hangbin Liu Subject: [PATCH net-next v2 3/5] seg6: apply the PSP flavor together with NEXT-C-SID in SRv6 End Date: Thu, 5 Nov 2026 02:57:13 +0100 Message-Id: <20261105015715.57-4-andrea.mayer@uniroma2.it> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261105015715.57-1-andrea.mayer@uniroma2.it> References: <20261105015715.57-1-andrea.mayer@uniroma2.it> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: clamav-milter 0.100.0 at smtp-2015 X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Since commit bdf3c0b9c10b ("seg6: add PSP flavor support for SRv6 End behavior"), an SRv6 End route can be set up with both the NEXT-C-SID and the PSP flavors, e.g.: ip -6 route add fcbb:0:100::/48 encap seg6local action End \ flavors next-csid,psp lblen 32 nflen 16 dev dum0 In RFC 9800, the NEXT-C-SID flavor (NEXT-CSID in the RFC) changes the End processing only when the Argument is not zero [1]. With a zero Argument (i.e. when the IPv6 DA carries no further C-SID), End is processed as in RFC 8986, and the PSP flavor (when set) applies unchanged [2]. If the packet arrives with Segments Left 1, PSP must then remove the SRH. However, on a route with both the NEXT-C-SID and PSP flavors, input_action_end() always uses the NEXT-C-SID processing. The NEXT-C-SID processing handles a packet with a zero Argument as End without flavors, ignoring PSP. Therefore, if this packet arrives with Segments Left 1, the SRH is not removed. Fix this by using the NEXT-C-SID processing only when the Argument is not zero or the route has no RFC 8986 flavor. Otherwise, the packet is processed as End with its RFC 8986 flavors, in end_flv8986_core(). With a zero Argument and Segments Left 1, PSP now removes the SRH before the packet is forwarded. If seg6_pop_srh() cannot remove the SRH, the packet is dropped, as on a route with the PSP flavor alone. Found by manual code inspection and reproduced in a VM without kernel changes or error injection. A following commit adds tests for this case to srv6_end_flavors_test.sh. The tests reproduce the issue: they fail without this change and pass with it. [1] - https://datatracker.ietf.org/doc/html/rfc9800#section-4.1.1 [2] - https://datatracker.ietf.org/doc/html/rfc9800#section-4.1.7 Fixes: bdf3c0b9c10b ("seg6: add PSP flavor support for SRv6 End behavior") Reviewed-by: Hangbin Liu Signed-off-by: Andrea Mayer --- net/ipv6/seg6_local.c | 50 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index 26cd4facbe36..427d12fedfc3 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -551,6 +551,47 @@ static bool seg6_next_csid_enabled(__u32 fops) return fops & SEG6_F_LOCAL_FLV_NEXT_CSID; } =20 +static bool seg6_flv8986_enabled(__u32 fops) +{ + return fops & SEG6_LOCAL_FLV8986_SUPP_OPS; +} + +/* check whether the NEXT-C-SID processing has to be used for the packet, + * instead of the RFC8986 flavors set for the given SRv6 End* behavior + * instance. + * + * This function returns: + * - true, when the packet has to go through the NEXT-C-SID processing; + * - false, when NEXT-C-SID is not configured or the packet has to be + * processed on the basis of the RFC8986 flavors. + */ +static bool seg6_use_next_csid(struct sk_buff *skb, + const struct seg6_flavors_info *finfo) +{ + const struct in6_addr *addr; + __u32 fops =3D finfo->flv_ops; + + if (!seg6_next_csid_enabled(fops)) + return false; + + addr =3D &ipv6_hdr(skb)->daddr; + + /* NEXT-C-SID and the RFC8986 flavors combine according to the + * DA.Argument (see RFC9800, sections 4.1.1 and 4.1.7): + * + * DA.Argument RFC8986 flavors processing + * (1) !=3D 0 any NEXT-C-SID only, SL unchanged + * (2) =3D=3D 0 none the behavior, e.g. End + * (3) =3D=3D 0 one or more the behavior with its flavor= s, + * e.g. End with PSP + * + * In (2), the packet still goes through the NEXT-C-SID processing, + * which runs the behavior (e.g. End) when the DA.Argument is zero. + */ + return !seg6_flv8986_enabled(fops) || + !seg6_next_csid_is_arg_zero(addr, finfo); +} + /* Processing of SRv6 End, End.X, and End.T behaviors can be extended thro= ugh * the flavors framework. These behaviors must report the subset of (flavo= r) * operations they currently implement. In this way, if a user specifies a @@ -865,7 +906,10 @@ static int end_flv8986_core(struct sk_buff *skb, struc= t seg6_local_lwt *slwt) if (srh && !seg6_hmac_validate_skb(skb, srh)) goto drop; #endif - flvmask =3D finfo->flv_ops; + /* NEXT-C-SID, when configured, has already been evaluated by the + * caller. Only the RFC8986 flavors are left here. + */ + flvmask =3D finfo->flv_ops & ~SEG6_F_LOCAL_FLV_NEXT_CSID; if (unlikely(flvmask & ~SEG6_LOCAL_FLV8986_SUPP_OPS)) { pr_warn_once("seg6local: invalid RFC8986 flavors\n"); goto drop; @@ -919,8 +963,8 @@ static int input_action_end(struct sk_buff *skb, struct= seg6_local_lwt *slwt) if (!fops) return input_action_end_core(skb, slwt); =20 - /* check for the presence of NEXT-C-SID since it applies first */ - if (seg6_next_csid_enabled(fops)) + /* NEXT-C-SID is evaluated first, when configured */ + if (seg6_use_next_csid(skb, finfo)) return end_next_csid_core(skb, slwt); =20 /* the specific processing function to be performed on the packet --=20 2.43.0 From nobody Thu Nov 5 05:41:49 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=160.80.4.35 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793843999; b=jNW2vblxIoXHRuWJZ063dmBCcjOnxiVJAg0sCFuBx7TzwpphKp+NPBc7gZ5SfGNNijJ6 WXjkN1X2oNdtc9eoOom3G/Dh0uj40f5IdxRJYMm8ZUtb1WPMk2H32n7uN+1/yqMaH1tkr bikj9TZh0oLQU3BUVcBVa+cO1K61m7SNU0jpoAXNzc6q9cYVPI6Fzh2EIZmQM5UVLgFcA 66kYmAGjfzhyo+qtGH0b91C2/1PYu+Wxobjs4oteADL4dxTiyoJhq+KCr4SAzjBjku1+O qYkMIb4xIBls5b2kFszmMzMC0U+1BBRQzC+f1jNMwOQE7JF0DMTM32APo1XTfZTiGtg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793843999; h=DMARC-Filter:Received:Received:DKIM-Signature:DKIM-Signature:From:To: Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:X-Virus-Scanned: X-Virus-Status; bh=Z/qvuCNxH+jptjge853VfySBFYPTsWP1Hkt7muobr8U=; b=oyg4VF940GIGRsbCFfmzSXQa0knvEL+5obukP26kPyS40bBJ9QZhFO1ZkrcNLWaPDKLI 0OO0FT2DyoZZSg4OpX4UHjf7mIYqwAPA8LShZ+iC5bxT26uIRyKXkzzn9R/szFGPCuSHY L9SPbsOY/GVwWS06MaGDbU1kwvqJp97OVCG/P3bRF48YD4fDJ0ldmIYTVPAjnPkhKWQGq scqK5L5COwn+55wetJoOdoh7iaUDaUWXxJbxD7xSwmeLDEr6eK8n2E1lKts3/gZRJXf6b BZyqrevfnYR3mzihb0xH8Z/G2f+PFBPjolfd74ryxFaqJXbrhol3RND9OqITjTtChZw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=uniroma2.it; spf=pass smtp.mailfrom=uniroma2.it; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=V6HEmneq; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=hHBbgK78; arc=none smtp.remote-ip=160.80.4.35 Received: from smtp.uniroma2.it (smtp.uniroma2.it [160.80.4.35]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 863EB606A328; Thu, 5 Nov 2026 01:59:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 863EB606A328 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=V6HEmneq; dkim=pass (2048-bit key, unprotected) header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=hHBbgK78 Received: from smtpauth-2019-1.uniroma2.it (smtpauth.uniroma2.it [160.80.5.46]) by smtp-2015.uniroma2.it (8.14.4/8.14.4/Debian-8) with ESMTP id 6A51xDLb001499; Thu, 5 Nov 2026 02:59:18 +0100 Received: from localhost.localdomain (unknown [160.80.105.87]) by smtpauth-2019-1.uniroma2.it (Postfix) with ESMTPSA id 15946122954; Thu, 5 Nov 2026 02:59:08 +0100 (CET) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=uniroma2.it; s=ed201904; t=1793843948; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z/qvuCNxH+jptjge853VfySBFYPTsWP1Hkt7muobr8U=; b=V6HEmneq4kjzhR/UHqtjwz/k19A2f4x7Fb2XCADjq6jh1Co35kNVavpH3ctkgeXdnKjnGs qFd4CWfidJDMeiDA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uniroma2.it; s=rsa201904; t=1793843948; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z/qvuCNxH+jptjge853VfySBFYPTsWP1Hkt7muobr8U=; b=hHBbgK78a8Wl5MIMQylDbxLSoFzkEaolY5xpa18moohERsh7jvK6gqYULuz5j8ks1nRsT1 /Q6ucp/MOy3OSIV89qhFqFy4tb64wEbLyVEQa8Nkvlma+H+2d5+Im9CINx5Er+3mUf7hkT kmtRLugwj4aYz7k19VhbJYnykiPqWgpFOWX2m5TEM4nJH59QeZ4Zk315eFVICo+okFo6Rv CMmrcb6Cs27cG+LcRAHotExEwqnbXxsktSSEPZb3bQ4JmPmJaWegbzZCXyCasEGLtNJTry lyirCJDXHx+EEzKd5keJBhVOD8VwlbfCRUVniuHBR7Ys17IKBzan78HFqjMQXQ== From: Andrea Mayer To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Shuah Khan , Hangbin Liu , Justin Iurman , Nicolas Dichtel , Ahmed Abdelsalam , Stefano Salsano , Andrea Mayer , andrea@common-net.org Subject: [PATCH net-next v2 4/5] selftests: seg6: add tests for PSP together with NEXT-C-SID Date: Thu, 5 Nov 2026 02:57:14 +0100 Message-Id: <20261105015715.57-5-andrea.mayer@uniroma2.it> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261105015715.57-1-andrea.mayer@uniroma2.it> References: <20261105015715.57-1-andrea.mayer@uniroma2.it> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: clamav-milter 0.100.0 at smtp-2015 X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Extend srv6_end_flavors_test.sh with tests for the SRv6 End behavior with both the NEXT-C-SID and PSP flavors. The tests use two SRv6 Policies with C-SID containers, where every router after the ingress one applies End with the NEXT-C-SID and PSP flavors. To check PSP, set net.ipv6.conf.all.seg6_enabled to 0 on the hosts in setup_hs(). The hosts then drop any packet that still carries an SRH, and a ping to an address on the loopback of a host succeeds only if the router connected to that host has removed the SRH. The tests fail when PSP is not applied together with NEXT-C-SID. Signed-off-by: Andrea Mayer --- .../selftests/net/srv6_end_flavors_test.sh | 344 +++++++++++++++++- 1 file changed, 326 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/net/srv6_end_flavors_test.sh b/tools/t= esting/selftests/net/srv6_end_flavors_test.sh index 30a939392eea..0355149bb7d6 100755 --- a/tools/testing/selftests/net/srv6_end_flavors_test.sh +++ b/tools/testing/selftests/net/srv6_end_flavors_test.sh @@ -16,8 +16,9 @@ # # The End, End.X, and End.T behaviors can support these flavors either # individually or in combinations. -# Currently in this selftest we consider only the PSP flavor for the SRv6 = End -# behavior. However, it is possible to extend the script as soon as other +# Currently in this selftest we consider the PSP flavor for the SRv6 End +# behavior, both alone and combined with the NEXT-C-SID flavor defined in +# RFC9800 [2]. However, it is possible to extend the script as soon as oth= er # flavors will be supported in the kernel. # # The purpose of the PSP flavor consists in instructing the penultimate no= de @@ -47,7 +48,20 @@ # "standard" End packet processing, ignoring the configured PSP flavor = at # all. # +# The NEXT-C-SID flavor (referred to as NEXT-CSID in RFC9800 [2]) and the +# C-SID containers are described in srv6_end_next_csid_l3vpn_test.sh, which +# also tests this flavor for the SRv6 End behavior. +# +# When the NEXT-C-SID flavor is combined with the PSP, USP or USD flavors,= these +# flavors are left unchanged [2]. The NEXT-C-SID processing comes first: w= ith a +# non-zero Argument, the IPv6 DA is updated with the next C-SID and the pa= cket +# is forwarded without changing the SRH, if any. The packet goes through t= he End +# behavior with the other flavors only when the Argument is zero, i.e. whe= n the +# IPv6 DA carries no further C-SID. For example, the PSP operation takes p= lace +# only for a C-SID container with a zero Argument and SL=3D1. +# # [1] RFC8986: https://datatracker.ietf.org/doc/html/rfc8986 +# [2] RFC9800: https://datatracker.ietf.org/doc/html/rfc9800 # # Network topology # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -115,12 +129,35 @@ # +---------------------------------------------------------------------+ # |fcff:x::e is associated with the SRv6 End behavior | # |fcff:x::ef1 is associated with the SRv6 End behavior with PSP flavor | +# |fcbb:0:xpyy::/48 is associated with the SRv6 behavior and flavors | +# | given by the Function yy, and with parameter p of the behavior | # +---------------------------------------------------------------------+ # # The fcff::/16 prefix is reserved by the operator for the SIDs. Reachabil= ity of # SIDs is ensured by proper configuration of the IPv6 operator's network a= nd # SRv6 routers. # +# Similarly, the fcbb:0::/32 prefix is reserved by the operator for the C-= SID +# containers and it is used as their Locator-Block. +# A C-SID (16 bits) is written as xpyy, where: +# - x is the Locator-Node (4 bits), i.e. the ID of the router; +# - p is a parameter of the behavior (4 bits), 0 for End, which has none; +# - yy is the Function (8 bits). Its first digit selects the SRv6 behavior +# (e for End, as in fcff:x::e). Its second digit is the set of flavors,= as +# a bit mask: 1 for PSP, 2 for USP, 4 for USD and 8 for NEXT-C-SID (as = the +# f1 of fcff:x::ef1 for PSP). +# In the terms of RFC9800 [2], p and yy together are the Function of the C= -SID +# (12 bits), and p is not part of the Argument: +# +# +----------+----------+--------------------+ +# | Function | behavior | flavors | +# +----------+----------+--------------------+ +# | e9 | End | NEXT-C-SID and PSP | +# +----------+----------+--------------------+ +# +# For example, fcbb:0:40e9:20e9:: is a C-SID container carrying the C-SID = of +# rt-4 followed by the C-SID of rt-2, both with the NEXT-C-SID and PSP fla= vors. +# # # SRv6 Policies # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -193,6 +230,39 @@ # set with the last SID; iii) the SRH is removed from the extension headers # after the IPv6 header. At this point, the packet with IPv6 DA=3Dcafe::1 = is sent # to the destination, i.e. hs-1. +# +# Traffic to the loopback addresses of the hosts +# ---------------------------------------------- +# +# Each host has an address on its loopback, cafe::x:e9. The traffic from t= he +# other host towards this address is steered with C-SID containers: after = the +# ingress router, every router crossed applies the SRv6 End behavior with = the +# NEXT-C-SID and PSP flavors. The following SRv6 Policies are applied by r= t-1 +# to the traffic towards cafe::2:e9 (i.c) and by rt-2 to the traffic towar= ds +# cafe::1:e9 (i.d): +# +# i.c) IPv6 traffic, SID List=3Dfcbb:0:30e9::,fcbb:0:40e9:20e9::,cafe::2= :e9 +# i.d) IPv6 traffic, SID List=3Dfcbb:0:40e9:30e9:10e9::,cafe::1:e9 +# +# In the Policy (i.c), rt-3 receives a zero Argument with SL=3D2 and appli= es the +# "standard" End processing. rt-4 receives a non-zero Argument with SL=3D1= : it +# advances to the next C-SID and does *NOT* apply the PSP operation. rt-2 +# receives a zero Argument with SL=3D1 and applies the PSP operation. +# +# In the Policy (i.d), a single C-SID container carries three C-SIDs. rt-4= and +# rt-3 receive a non-zero Argument with SL=3D1: they advance to the next C= -SID and +# do *NOT* apply the PSP operation. rt-1 receives a zero Argument with SL= =3D1 +# and applies the PSP operation. +# +# The hosts use cafe::x as the source address, not the loopback address. T= he +# replies are sent to cafe::x and follow the Policies (i.a) and (i.b), whi= ch +# are tested first. This way, each ping checks a single Policy with the +# NEXT-C-SID flavor, and a failure points directly to that Policy. +# +# The hosts drop the packets that carry an SRH (seg6_enabled is set to 0 on +# the hosts). The loopback address of a host is reached only through the +# router connected to that host: the ping succeeds only if the SRH is remo= ved +# by that router. =20 # shellcheck source=3Dlib.sh source lib.sh @@ -207,6 +277,20 @@ readonly IPv6_TESTS_ADDR=3D2001:db8::1 readonly LOCATOR_SERVICE=3Dfcff readonly END_FUNC=3D000e readonly END_PSP_FUNC=3D0ef1 +readonly END_CSID_PSP_FUNC=3De9 + +readonly LCBLOCK_ADDR=3Dfcbb:0 +readonly LCBLOCK_BLEN=3D32 +# do not add ':' as separator. The Locator-Node is followed by the paramet= er +# of the behavior, 0 for End. +readonly LCNODE_FMT=3D"%x0" +readonly LCNODE_BLEN=3D4 +readonly LCNODEFUNC_BLEN=3D16 + +readonly LCBLOCK_NODE_BLEN=3D$((LCBLOCK_BLEN + LCNODE_BLEN)) +readonly LCBLOCK_NODEFUNC_BLEN=3D$((LCBLOCK_BLEN + LCNODEFUNC_BLEN)) +# lengths of Locator-Block and C-SID of the NEXT-C-SID flavor +readonly CSID_CFG=3D"lblen ${LCBLOCK_BLEN} nflen ${LCNODEFUNC_BLEN}" =20 PING_TIMEOUT_SEC=3D4 PAUSE_ON_FAIL=3D${PAUSE_ON_FAIL:=3Dno} @@ -397,6 +481,45 @@ __get_srv6_rtcfg_op() xargs | sed 's/ /,/g' } =20 +# Return the C-SID of a router: the Locator-Node (4 bits), i.e. the ID of = the +# router, followed by the parameter of the behavior (4 bits, 0) and the +# Function (8 bits). +# args: +# $1 - router +# $2 - Function (e.g. "e9") +# e.g. input: "4" "e9" +# output: "40e9" +build_csid() +{ + local nodeid=3D"$1" + local func=3D"$2" + + printf "${LCNODE_FMT}%s" "${nodeid}" "${func}" +} + +# Return the C-SID container with the C-SIDs of the routers listed in a +# "next-csid," element, in the same order. +# args: +# $1 - of the element: a comma-separated list of routers +# $2 - Function (e.g. "e9") +# e.g. input: "4,2" "e9" +# output: "fcbb:0:40e9:20e9::" +build_csid_container() +{ + local nodeids=3D"$1" + local func=3D"$2" + local csids=3D'' + local nodes + local node + + nodes=3D"$(echo "${nodeids}" | sed 's/,/ /g')" + for node in ${nodes}; do + csids=3D"${csids}:$(build_csid "${node}" "${func}")" + done + + echo "${LCBLOCK_ADDR}${csids}::" +} + # Setup the basic networking for the routers setup_rt_networking() { @@ -439,6 +562,7 @@ setup_rt_local_sids() local devname local nsname local neigh + local csid =20 nsname=3D"$(get_rtname "${rt}")" =20 @@ -452,6 +576,15 @@ setup_rt_local_sids() add "${LOCATOR_SERVICE}:${neigh}::/32" \ table "${LOCALSID_TABLE_ID}" \ via "${net_prefix}::${neigh}" dev "${devname}" + + # set underlay network routes to reach the C-SID containers + # that start with a C-SID of the neighbor, for any parameter and + # Function. + csid=3D"$(build_csid "${neigh}" 00)" + ip -netns "${nsname}" -6 route \ + add "${LCBLOCK_ADDR}:${csid}::/${LCBLOCK_NODE_BLEN}" \ + table "${LOCALSID_TABLE_ID}" \ + via "${net_prefix}::${neigh}" dev "${devname}" done =20 # Local End behavior (note that "dev" is a dummy interface chosen for @@ -461,30 +594,135 @@ setup_rt_local_sids() table "${LOCALSID_TABLE_ID}" \ encap seg6local action End dev "${DUMMY_DEVNAME}" =20 - # all SIDs start with a common locator. Routes and SRv6 Endpoint # behavior instances are grouped together in the 'localsid' table. ip -netns "${nsname}" -6 rule \ add to "${LOCATOR_SERVICE}::/16" \ lookup "${LOCALSID_TABLE_ID}" prio 999 =20 + # the C-SID containers use their own Locator-Block. Their routes and + # SRv6 Endpoint behavior instances are in the 'localsid' table too. + ip -netns "${nsname}" -6 rule \ + add to "${LCBLOCK_ADDR}::/${LCBLOCK_BLEN}" \ + lookup "${LOCALSID_TABLE_ID}" prio 999 + # set default routes to unreachable ip -netns "${nsname}" -6 route \ add unreachable default metric 4278198272 \ dev "${DUMMY_DEVNAME}" } =20 +# Return success if the operation of an element contains the NEXT-C-S= ID +# flavor, i.e. the SIDs of the element are C-SIDs. +# e.g. input: "next-csid,psp" -> success; "psp" -> failure +op_has_next_csid() +{ + local op_type=3D"$1" + + case ",${op_type}," in + *,next-csid,*) + return 0 + ;; + esac + + return 1 +} + +# Return the SID to which the SRv6 Endpoint behavior of a router is bound. +# With NEXT-C-SID, it is the C-SID of the router as a prefix: on rt-4, +# fcbb:0:40e9::/48 also matches the DA fcbb:0:40e9:20e9::. +# args: +# $1 - router +# $2 - operation of the element (e.g. "next-csid,psp") +# $3 - Function (e.g. "0ef1", or "e9" with NEXT-C-SID) +# e.g. input: "4" "psp" "0ef1" +# output: "fcff:4::0ef1" +# input: "4" "next-csid,psp" "e9" +# output: "fcbb:0:40e9::/48" +get_rt_sid() +{ + local rt=3D"$1" + local op_type=3D"$2" + local func=3D"$3" + local csid + + if op_has_next_csid "${op_type}"; then + csid=3D"$(build_csid "${rt}" "${func}")" + echo "${LCBLOCK_ADDR}:${csid}::/${LCBLOCK_NODEFUNC_BLEN}" + return + fi + + echo "${LOCATOR_SERVICE}:${rt}::${func}" +} + +# Add an SRv6 Endpoint behavior to a router, bound to a SID. Nothing is ad= ded +# if the router already has a route for that SID. +# args: +# $1 - router +# $2 - SID, or C-SID of the router as a prefix +# $3 - SRv6 Endpoint behavior and flavors (e.g. "End flavors psp") +setup_rt_endpoint() +{ + local rt=3D"$1" + local sid=3D"$2" + local behavior_cfg=3D"$3" + local nsname + + nsname=3D"$(get_rtname "${rt}")" + + # the prefix length is part of the SID: two SIDs can have the same + # address and different lengths. + if [ -n "$(ip -netns "${nsname}" -6 route show \ + table "${LOCALSID_TABLE_ID}" exact "${sid}")" ]; then + return + fi + + ip -netns "${nsname}" -6 route \ + add "${sid}" table "${LOCALSID_TABLE_ID}" \ + encap seg6local action ${behavior_cfg} \ + dev "${DUMMY_DEVNAME}" +} + +# Add an SRv6 Endpoint behavior to each router of a Policy element . +# args: +# $1 - of the element: one router, or a comma-separated list +# $2 - operation of the element (e.g. "next-csid,psp") +# $3 - Function (e.g. "0ef1", or "e9" with NEXT-C-SID) +# $4 - SRv6 Endpoint behavior and flavors (e.g. "End flavors psp") +# e.g. input: "4,2" "next-csid,psp" "e9" +# "End flavors next-csid,psp lblen 32 nflen 16" +# result: the behavior is added on rt-4, bound to fcbb:0:40e9::/48, a= nd +# on rt-2, bound to fcbb:0:20e9::/48 +setup_rt_endpoints() +{ + local node=3D"$1" + local op_type=3D"$2" + local func=3D"$3" + local behavior_cfg=3D"$4" + local sid + local rt + + for rt in $(echo "${node}" | sed 's/,/ /g'); do + sid=3D"$(get_rt_sid "${rt}" "${op_type}" "${func}")" + setup_rt_endpoint "${rt}" "${sid}" "${behavior_cfg}" + done +} + # This helper function builds and installs the SID List (i.e. SRv6 Policy) # to be applied on incoming packets at the ingress node. Moreover, it # configures the SRv6 nodes specified in the SID List to process the traff= ic # according to the operations required by the Policy itself. # args: -# $1 - destination host (i.e. cafe::x host) +# $1 - destination host x (i.e. the cafe::x host), or x:yy for the address +# cafe::x:yy on the loopback of the host (e.g. 2:e9) # $2 - SRv6 router configured for enforcing the SRv6 Policy # $3 - compact way to represent a list of SRv6 routers with their operati= ons # (i.e. behaviors) that each of them needs to perform. Every # element constructs a SID that is associated with the behavior = on # the node. The list of such elements forms an SRv6 Policy. +# For "next-csid,psp", is a comma-separated list of node ID= s. +# The element constructs a C-SID container with the C-SIDs of these +# nodes, e.g. "4,2:next-csid,psp" gives fcbb:0:40e9:20e9::. __setup_rt_policy() { local dst=3D"$1" @@ -492,10 +730,9 @@ __setup_rt_policy() local policy_rts=3D"$3" local behavior_cfg local in_nsname - local rt_nsname local policy=3D'' + local container local function - local fullsid local op_type local node local n @@ -505,7 +742,6 @@ __setup_rt_policy() for n in ${policy_rts}; do node=3D"$(__get_srv6_rtcfg_id "${n}")" op_type=3D"$(__get_srv6_rtcfg_op "${n}")" - rt_nsname=3D"$(get_rtname "${node}")" =20 case "${op_type}" in "noflv") @@ -520,22 +756,22 @@ __setup_rt_policy() behavior_cfg=3D"End flavors psp" ;; =20 + "next-csid,psp") + container=3D"$(build_csid_container "${node}" \ + "${END_CSID_PSP_FUNC}")" + policy=3D"${policy}${container}," + function=3D"${END_CSID_PSP_FUNC}" + behavior_cfg=3D"End flavors next-csid,psp ${CSID_CFG}" + ;; + *) break ;; esac =20 - fullsid=3D"${LOCATOR_SERVICE}:${node}::${function}" - - # add SRv6 Endpoint behavior to the selected router - if ! ip -netns "${rt_nsname}" -6 route get "${fullsid}" \ - &>/dev/null; then - ip -netns "${rt_nsname}" -6 route \ - add "${fullsid}" \ - table "${LOCALSID_TABLE_ID}" \ - encap seg6local action ${behavior_cfg} \ - dev "${DUMMY_DEVNAME}" - fi + # add SRv6 Endpoint behavior to the selected routers + setup_rt_endpoints "${node}" \ + "${op_type}" "${function}" "${behavior_cfg}" done =20 # we need to remove the trailing comma to avoid inserting an empty @@ -571,6 +807,7 @@ setup_hs() =20 ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.all.accept_dad=3D0 ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.default.accept_dad=3D0 + ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.all.seg6_enabled=3D0 =20 ip -netns "${hsname}" link add veth0 type veth \ peer name "${RT2HS_DEVNAME}" netns "${rtname}" @@ -590,6 +827,32 @@ setup_hs() sysctl -wq net.ipv6.conf."${RT2HS_DEVNAME}".proxy_ndp=3D1 } =20 +# Set up an address on the loopback of a host, and the route towards it on= the +# router connected to the host. +# args: +# $1 - host +# $2 - router connected to the host +# $3 - suffix of the address (i.e. cafe:::) +setup_hs_lo_addr() +{ + local hs=3D"$1" + local rt=3D"$2" + local suffix=3D"$3" + local hsname + local rtname + local addr + + hsname=3D"$(get_hsname "${hs}")" + rtname=3D"$(get_rtname "${rt}")" + addr=3D"${IPv6_HS_NETWORK}::${hs}:${suffix}" + + ip -netns "${hsname}" addr add "${addr}/128" dev lo nodad + + ip -netns "${rtname}" -6 route \ + add "${addr}" \ + via "${IPv6_HS_NETWORK}::${hs}" dev "${RT2HS_DEVNAME}" +} + setup() { local i @@ -622,6 +885,11 @@ setup() setup_hs 1 1 setup_hs 2 2 =20 + # set up the loopback addresses of the hosts used by the Policies (i.c) + # and (i.d). + setup_hs_lo_addr 1 1 "${END_CSID_PSP_FUNC}" + setup_hs_lo_addr 2 2 "${END_CSID_PSP_FUNC}" + # set up default SRv6 Endpoints (i.e. SRv6 End behavior) setup_rt_local_sids 1 "2 3 4" setup_rt_local_sids 2 "1 3 4" @@ -645,6 +913,21 @@ setup() setup_rt_policy_ipv6 2 1 "3:noflv 4:psp 2:psp" setup_rt_policy_ipv6 1 2 "1:psp" =20 + # Direction hs-1 -> hs-2 (cafe::2:e9, NEXT-C-SID and PSP flavors) + # - rt-1 (SRv6 H.Insert policy) + # - rt-3 (Argument=3D0 and SL>1, acting as an End behavior) + # - rt-4 (Argument!=3D0 and SL=3D1, advancing the C-SID) + # - rt-2 (Argument=3D0 and SL=3D1, PSP) + # + # Direction hs-2 -> hs-1 (cafe::1:e9, NEXT-C-SID and PSP flavors) + # - rt-2 (SRv6 H.Insert policy) + # - rt-4 (Argument!=3D0 and SL=3D1, advancing the C-SID) + # - rt-3 (Argument!=3D0 and SL=3D1, advancing the C-SID) + # - rt-1 (Argument=3D0 and SL=3D1, PSP) + setup_rt_policy_ipv6 "2:${END_CSID_PSP_FUNC}" 1 \ + "3:next-csid,psp 4,2:next-csid,psp" + setup_rt_policy_ipv6 "1:${END_CSID_PSP_FUNC}" 2 "4,3,1:next-csid,psp" + # testing environment was set up successfully SETUP_ERR=3D0 } @@ -710,6 +993,20 @@ check_and_log_hs_connectivity() check_and_log_hs_ipv6_connectivity "${hssrc}" "${hsdst}" } =20 +check_and_log_hs_lo_addr_connectivity() +{ + local hssrc=3D"$1" + local hsdst=3D"$2" + local suffix=3D"$3" + local dst + + dst=3D"${IPv6_HS_NETWORK}::${hsdst}:${suffix}" + + check_hs_ipv6_connectivity "${hssrc}" "${hsdst}:${suffix}" + log_test $? 0 \ + "IPv6 Hosts connectivity: hs-${hssrc} -> hs-${hsdst} (${dst})" +} + router_tests() { local i @@ -747,6 +1044,14 @@ host_srv6_end_flv_psp_tests() check_and_log_hs_connectivity 2 1 } =20 +host_srv6_end_flv_next_csid_psp_tests() +{ + log_section "SRv6 connectivity test hosts (h1 <-> h2, NEXT-C-SID,PSP)" + + check_and_log_hs_lo_addr_connectivity 1 2 "${END_CSID_PSP_FUNC}" + check_and_log_hs_lo_addr_connectivity 2 1 "${END_CSID_PSP_FUNC}" +} + test_iproute2_supp_or_ksft_skip() { local flavor=3D"$1" @@ -836,6 +1141,8 @@ test_command_or_ksft_skip sort test_command_or_ksft_skip xargs =20 test_dummy_dev_or_ksft_skip +# NEXT-C-SID is not checked: every kernel and iproute2 version that +# supports PSP also supports NEXT-C-SID. test_iproute2_supp_or_ksft_skip psp test_kernel_supp_or_ksft_skip psp =20 @@ -848,5 +1155,6 @@ set +e router_tests host2gateway_tests host_srv6_end_flv_psp_tests +host_srv6_end_flv_next_csid_psp_tests =20 print_log_test_results --=20 2.43.0 From nobody Thu Nov 5 05:41:49 2026 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=160.80.4.35 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793843999; b=Q5ZT+HImrrO5DSm9pNrQHg8Sb3e8EKI4g80a+HjsM/Q4tFIW2Q325iu+mDDKrCRIhO+N oOftC6r0eXuZniv9g2Ph4qsjZdPAlKspd+nSiwt4+BWainyM/1Nepq8wCe82541obSwbf Dag2wI22uZOY9YNaSHjXmfDknl2Y/VNhCAcQlL+hrn0fuUA8RFvoxrlvf7On80COq4vHK 3iUQoy5jW1pQeT+A7KuG2e/xgLVt3QtTHpWaENqH+a+cOTlxj2kZe+PHMr2QiQ3pVPoeV 8SsUtva/ZABFzCJzuP2UqEa55/kvhkSoU7YdpXc4oYPCamrt1BzDAFz/hxfMTevvwEg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793843999; h=DMARC-Filter:Received:Received:DKIM-Signature:DKIM-Signature:From:To: Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:X-Virus-Scanned: X-Virus-Status; bh=Wh3rkeiAMAtqT0dyAzB3R9VY7PKWSU32hBfsSb84LpA=; b=xeMP/y9KLHKKPJitGrSCkiYPNzYhgjCGAvTNkCzUkBUPpDmMwsaAM96v0ExIz1d2e0Ai OqD3Gqz726BzAH2d3MpHUkEEkbzSWhwu4+g2eoasatESM79EnbFP37E+51oqldsapODvC CR/zaHzzAH0oqb6VAJ7bgDpWpr+4LJKgf3gohIc2ojI/s/ILWUkO5QNBYDj8bVcFl31uI kgNuy3mIDh0bNrCrl16PpCQkvmzGSspKubCsIe7joj6RdR7JC5NgtB+ZZb5JgVJkPzgtC GLH/spCMZxFN5c/rStm8s7FMK6Se22S4qz2jEaPxWMaWc0qO1mg68eacLRKUcxHEZAQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=uniroma2.it; spf=pass smtp.mailfrom=uniroma2.it; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=DwAoBuMU; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=UsGimAXk; arc=none smtp.remote-ip=160.80.4.35 Received: from smtp.uniroma2.it (smtp.uniroma2.it [160.80.4.35]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D571A606A326; Thu, 5 Nov 2026 01:59:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org D571A606A326 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=uniroma2.it Authentication-Results: smtp.subspace.kernel.org; dkim=pass header.d=uniroma2.it header.i=@uniroma2.it header.a=ed25519-sha256 header.s=ed201904 header.b=DwAoBuMU; dkim=pass (2048-bit key, unprotected) header.d=uniroma2.it header.i=@uniroma2.it header.a=rsa-sha256 header.s=rsa201904 header.b=UsGimAXk Received: from smtpauth-2019-1.uniroma2.it (smtpauth-2019-1.uniroma2.it [160.80.5.46]) by smtp-2015.uniroma2.it (8.14.4/8.14.4/Debian-8) with ESMTP id 6A51xN1d001510; Thu, 5 Nov 2026 02:59:28 +0100 Received: from localhost.localdomain (unknown [160.80.105.87]) by smtpauth-2019-1.uniroma2.it (Postfix) with ESMTPSA id 30318122955; Thu, 5 Nov 2026 02:59:08 +0100 (CET) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=uniroma2.it; s=ed201904; t=1793843948; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wh3rkeiAMAtqT0dyAzB3R9VY7PKWSU32hBfsSb84LpA=; b=DwAoBuMUg/7owbjvenV/a33F1ywEjtRIhVyvbrAI+wJHQM0T1N8ubqCRcOBwGja6eVIzzy /xSfasdCK4zgEoDw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uniroma2.it; s=rsa201904; t=1793843948; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wh3rkeiAMAtqT0dyAzB3R9VY7PKWSU32hBfsSb84LpA=; b=UsGimAXk9n8HJFpt/EaoK+SQjyGBCstYaGPl6wDrhxdlYHEsuMUkufTpc64mKfQSTKoYDg 4bK/csN3xQ3uRIpdOcYDtH7YjV6ShPoCWpnd4u78XxbX+QtgXvA1UKlQdbnIQrCbarEUZb Z38azWDvTJ1gkkpWjtc4b3kuv+rmqYxAVQHTV55uMOvamqD4zfG6lazzBMl+780136j6Ri /ThwmZfCbWBi0AVEJkuS5yALusYWsSpflB9JfsxxTyEsRNtzSjgx+jVntmw7/OoejoNru0 +t7l7dfxNHYGSd3iqEA3R3yNeXa38Y+ARgBqMr/Pmdr7psbrLqde57yebzYc8g== From: Andrea Mayer To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Shuah Khan , Hangbin Liu , Justin Iurman , Nicolas Dichtel , Ahmed Abdelsalam , Stefano Salsano , Andrea Mayer , andrea@common-net.org Subject: [PATCH net-next v2 5/5] selftests: seg6: add tests for PSP with a consumed SRH Date: Thu, 5 Nov 2026 02:57:15 +0100 Message-Id: <20261105015715.57-6-andrea.mayer@uniroma2.it> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261105015715.57-1-andrea.mayer@uniroma2.it> References: <20261105015715.57-1-andrea.mayer@uniroma2.it> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: clamav-milter 0.100.0 at smtp-2015 X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Extend srv6_end_flavors_test.sh with tests for the SRv6 End behavior with the PSP flavor, alone and together with NEXT-C-SID, on packets that carry a consumed SRH in front of the SRH to process. Each test sends a ping along an existing SRv6 Policy, and a router on the path inserts an extra SRH in front of the Policy's SRH. An End behavior on another router consumes the extra SRH, and the router connected to the host must then remove only the Policy's SRH. These tests set seg6_enabled to 1 on the hosts, which must accept the extra SRH, and set it back to 0 at the end. With seg6_enabled set to 1, a host also accepts the packet when the Policy's SRH is not removed, or when the extra SRH is removed in its place. For this reason, the receiving host accepts the echo request only when its first SRH is the extra SRH, with Segments Left 0 and followed by the ICMPv6 header. Any other echo request is dropped, including one without any SRH. The extra SRH is recognized by its last segment, which is the SID that triggered its insertion. The check on the receiving host uses the ip6tables srh match. Without it, these tests are skipped. A test fails if the route that inserts the extra SRH, or the rules on the receiving host, cannot be added. Signed-off-by: Andrea Mayer --- tools/testing/selftests/net/config | 1 + .../selftests/net/srv6_end_flavors_test.sh | 280 +++++++++++++++++- 2 files changed, 279 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/n= et/config index 7a89e2618d4c..d5d2382b0b01 100644 --- a/tools/testing/selftests/net/config +++ b/tools/testing/selftests/net/config @@ -27,6 +27,7 @@ CONFIG_IP6_NF_IPTABLES=3Dm CONFIG_IP6_NF_IPTABLES_LEGACY=3Dm CONFIG_IP6_NF_MANGLE=3Dm CONFIG_IP6_NF_MATCH_RPFILTER=3Dm +CONFIG_IP6_NF_MATCH_SRH=3Dm CONFIG_IP6_NF_NAT=3Dm CONFIG_IP6_NF_RAW=3Dm CONFIG_IP6_NF_TARGET_REJECT=3Dm diff --git a/tools/testing/selftests/net/srv6_end_flavors_test.sh b/tools/t= esting/selftests/net/srv6_end_flavors_test.sh index 0355149bb7d6..157baa8ecb0b 100755 --- a/tools/testing/selftests/net/srv6_end_flavors_test.sh +++ b/tools/testing/selftests/net/srv6_end_flavors_test.sh @@ -22,8 +22,7 @@ # flavors will be supported in the kernel. # # The purpose of the PSP flavor consists in instructing the penultimate no= de -# listed in the SRv6 policy to remove (i.e. pop) the outermost SRH from th= e IPv6 -# header. +# listed in the SRv6 policy to remove (i.e. pop) the SRH from the IPv6 hea= der. # A PSP enabled SRv6 End behavior instance processes the SRH by: # - decrementing the Segment Left (SL) value from 1 to 0; # - copying the last SID from the SID List into the IPv6 Destination Addr= ess @@ -263,6 +262,68 @@ # the hosts). The loopback address of a host is reached only through the # router connected to that host: the ping succeeds only if the SRH is remo= ved # by that router. +# +# Traffic with a consumed SRH +# --------------------------- +# +# A packet can carry more than one SRH. The SRv6 End behavior skips an SRH= with +# SL=3D0 and processes the next header [1]. +# +# The traffic of this section reuses the Policies (i.a), (i.b), (i.c) and = (i.d). +# A router on the path inserts an extra SRH in front of the Policy's SRH, = and +# another router then consumes the extra SRH. +# +# The Policy (i.a) has SID List=3Dfcff:3::e,fcff:4::ef1,fcff:2::ef1,cafe::= 2. A +# packet from hs-1 to hs-2 goes as follows: +# +# - rt-1 applies the Policy and sends the packet to rt-3: +# IPv6 DA=3Dfcff:3::e | Policy's SRH, SL=3D3 | Payload +# +# - rt-3 (End) processes the Policy's SRH and sends the packet to rt-4: +# IPv6 DA=3Dfcff:4::ef1 | Policy's SRH, SL=3D2 | Payload +# +# - rt-4 (End with PSP and SL>1, acting as End) processes the Policy's SR= H. +# The new DA is fcff:2::ef1: +# IPv6 DA=3Dfcff:2::ef1 | Policy's SRH, SL=3D1 | Payload +# On rt-4, the route added by the test for fcff:2::ef1 then inserts the +# extra SRH, with SID List=3Dfcff:3::e,fcff:2::ef1, and the packet goes= back to +# rt-3: +# IPv6 DA=3Dfcff:3::e | extra SRH, SL=3D1 | Policy's SRH, SL=3D1 | Pa= yload +# +# - rt-3 (End) consumes the extra SRH and sets the DA back to fcff:2::ef1: +# IPv6 DA=3Dfcff:2::ef1 | extra SRH, SL=3D0 | Policy's SRH, SL=3D1 | = Payload +# +# - rt-2 (End with PSP) skips the extra SRH, processes the Policy's SRH a= nd +# removes it. The Next Header of the extra SRH now indicates the payload +# instead of the Policy's SRH: +# IPv6 DA=3Dcafe::2 | extra SRH, SL=3D0 | Payload +# +# The extra SRH reaches hs-2, which skips it as its SL is 0. The other +# Policies work in the same way: +# +# (i.b) hs-2 -> hs-1: on the packets with DA=3Dfcff:1::ef1, rt-2 inserts= the +# extra SRH with SID List=3Dfcff:3::e,fcff:1::ef1, and rt-3 consum= es it. +# (i.c) hs-1 -> hs-2: on the packets with DA=3Dfcbb:0:20e9::, rt-4 inser= ts the +# extra SRH with SID List=3Dfcff:3::e,fcbb:0:20e9::, and rt-3 cons= umes it. +# (i.d) hs-2 -> hs-1: on the packets with DA=3Dfcbb:0:10e9::, rt-3 inser= ts the +# extra SRH with SID List=3Dfcff:4::e,fcbb:0:10e9::, and rt-4 cons= umes it. +# +# The Policy (i.b) has no router between rt-2 and rt-1. For this reason, r= t-2 +# applies the Policy, inserts the extra SRH and sends the packet to rt-3: +# IPv6 DA=3Dfcff:3::e | extra SRH, SL=3D1 | Policy's SRH, SL=3D1 | Pa= yload +# rt-3 consumes the extra SRH, and rt-1 removes the Policy's SRH. +# +# The hosts need seg6_enabled set to 1 to accept the extra SRH, and it is = set +# back to 0 at the end. With seg6_enabled set to 1, a host also accepts the +# packet when the Policy's SRH is not removed, or when the extra SRH is re= moved +# in its place, as it skips every SRH with SL=3D0. For this reason, the re= ceiving +# host accepts the echo request only when its first SRH is the extra SRH, = with +# SL=3D0 and followed by the ICMPv6 header. Any other echo request is drop= ped, +# including one without any SRH. The extra SRH is recognized by its last s= egment +# (Segment List[0]), which is the SID that triggered its insertion (e.g. +# fcff:2::ef1 for the Policy (i.a)). +# These tests need ip6tables with the srh match, and they are skipped with= out +# it. =20 # shellcheck source=3Dlib.sh source lib.sh @@ -302,19 +363,35 @@ HOSTS=3D'' =20 SETUP_ERR=3D1 =20 +# set by check_srh_match_support +HAS_SRH_MATCH=3Dfalse + ret=3D${ksft_skip} nsuccess=3D0 nfail=3D0 +nskip=3D0 =20 log_test() { log_test_expected "$1" "$2" "$3" } =20 +# Log a test that is not run (same format as log_test_expected of lib.sh). +log_test_skipped() +{ + local msg=3D"$1" + + nskip=3D$((nskip+1)) + printf " TEST: %-60s [SKIP]\n" "${msg}" +} + print_log_test_results() { printf "\nTests passed: %3d\n" "${nsuccess}" printf "Tests failed: %3d\n" "${nfail}" + if [ "${nskip}" -gt 0 ]; then + printf "Tests skipped: %2d\n" "${nskip}" + fi =20 # when a test fails, the value of 'ret' is set to 1 (error code). # Conversely, when all tests are passed successfully, the 'ret' value @@ -1052,6 +1129,181 @@ host_srv6_end_flv_next_csid_psp_tests() check_and_log_hs_lo_addr_connectivity 2 1 "${END_CSID_PSP_FUNC}" } =20 +# On a router, add a route for a SID with seg6 encap in inline mode. The p= ackets +# that the router forwards to that SID get an extra SRH with the End SID o= f the +# router that consumes it. +# args: +# $1 - router on which the route is added +# $2 - SID of the route +# $3 - router with the SRv6 End behavior that consumes the extra SRH +setup_rt_consumed_srh() +{ + local rt=3D"$1" + local sid=3D"$2" + local end_rt=3D"$3" + local nsname + + nsname=3D"$(get_rtname "${rt}")" + + ip -netns "${nsname}" -6 route \ + add "${sid}" table "${LOCALSID_TABLE_ID}" \ + encap seg6 mode inline \ + segs "${LOCATOR_SERVICE}:${end_rt}::${END_FUNC}" \ + dev "${DUMMY_DEVNAME}" +} + +cleanup_rt_consumed_srh() +{ + local rt=3D"$1" + local sid=3D"$2" + local nsname + + nsname=3D"$(get_rtname "${rt}")" + + ip -netns "${nsname}" -6 route \ + del "${sid}" table "${LOCALSID_TABLE_ID}" +} + +set_hs_seg6_enabled() +{ + local val=3D"$1" + local hsname + local hs + + for hs in ${HOSTS}; do + hsname=3D"$(get_hsname "${hs}")" + + ip netns exec "${hsname}" \ + sysctl -wq net.ipv6.conf.all.seg6_enabled=3D"${val}" + ip netns exec "${hsname}" \ + sysctl -wq net.ipv6.conf.veth0.seg6_enabled=3D"${val}" + done +} + +# In a network namespace, accept the echo requests whose first SRH has the= given +# SID as last segment (Segment List[0]), SL=3D0 and the ICMPv6 header afte= r it, +# and drop any other echo request, including one without any SRH. +# args: +# $1 - network namespace in which the rules are added +# $2 - expected last segment of the first SRH +add_srh_check_rules() +{ + local nsname=3D"$1" + local sid=3D"$2" + + ip netns exec "${nsname}" ip6tables -A INPUT \ + -p ipv6-icmp --icmpv6-type echo-request \ + -m srh --srh-lsid "${sid}" --srh-segs-left-eq 0 \ + --srh-next-hdr 58 -j ACCEPT && + ip netns exec "${nsname}" ip6tables -A INPUT \ + -p ipv6-icmp --icmpv6-type echo-request -j DROP +} + +# On a host, check that the echo requests carry the extra SRH alone. +# args: +# $1 - host on which the rules are added +# $2 - expected last segment of the first SRH +setup_hs_srh_check() +{ + local hs=3D"$1" + local sid=3D"$2" + local hsname + + hsname=3D"$(get_hsname "${hs}")" + + add_srh_check_rules "${hsname}" "${sid}" +} + +cleanup_hs_srh_check() +{ + local hs=3D"$1" + local hsname + + hsname=3D"$(get_hsname "${hs}")" + + ip netns exec "${hsname}" ip6tables -F INPUT +} + +# Test a Policy with a consumed SRH: a router inserts the extra SRH on the +# packets towards a SID, and another router consumes it. The destination h= ost +# accepts only the echo requests that carry the extra SRH alone. +# args: +# $1 - router that inserts the extra SRH +# $2 - SID that triggers the insertion +# $3 - router with the SRv6 End behavior that consumes the extra SRH +# $4 - source host +# $5 - destination host +# $6 - suffix of the address on the loopback of the destination host +# (i.e. cafe:::), if any +check_and_log_consumed_srh() +{ + local rt=3D"$1" + local sid=3D"$2" + local end_rt=3D"$3" + local hssrc=3D"$4" + local hsdst=3D"$5" + local suffix=3D"$6" + local msg + + if ! ${HAS_SRH_MATCH}; then + msg=3D"IPv6 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}" + if [ -n "${suffix}" ]; then + msg=3D"${msg} (${IPv6_HS_NETWORK}::${hsdst}:${suffix})" + fi + log_test_skipped "${msg}" + return + fi + + if ! setup_rt_consumed_srh "${rt}" "${sid}" "${end_rt}"; then + log_test 1 0 "Extra SRH on rt-${rt} for ${sid}" + return + fi + + if ! setup_hs_srh_check "${hsdst}" "${sid}"; then + log_test 1 0 "SRH check on hs-${hsdst} for ${sid}" + elif [ -n "${suffix}" ]; then + check_and_log_hs_lo_addr_connectivity "${hssrc}" "${hsdst}" \ + "${suffix}" + else + check_and_log_hs_connectivity "${hssrc}" "${hsdst}" + fi + + cleanup_hs_srh_check "${hsdst}" + cleanup_rt_consumed_srh "${rt}" "${sid}" +} + +host_srv6_end_flv_consumed_srh_tests() +{ + local sid + + log_section \ + "SRv6 connectivity test hosts (h1 <-> h2, PSP with a consumed SRH)" + + if ! ${HAS_SRH_MATCH}; then + echo "SKIP: ip6tables srh match not available" + fi + + set_hs_seg6_enabled 1 + + # Policy (i.a): rt-4 inserts the extra SRH consumed by rt-3 + sid=3D"${LOCATOR_SERVICE}:2::${END_PSP_FUNC}" + check_and_log_consumed_srh 4 "${sid}" 3 1 2 + + # Policy (i.b): rt-2 inserts the extra SRH consumed by rt-3 + sid=3D"${LOCATOR_SERVICE}:1::${END_PSP_FUNC}" + check_and_log_consumed_srh 2 "${sid}" 3 2 1 + + # Policy (i.c): rt-4 inserts the extra SRH consumed by rt-3 + sid=3D"$(build_csid_container 2 "${END_CSID_PSP_FUNC}")" + check_and_log_consumed_srh 4 "${sid}" 3 1 2 "${END_CSID_PSP_FUNC}" + + # Policy (i.d): rt-3 inserts the extra SRH consumed by rt-4 + sid=3D"$(build_csid_container 1 "${END_CSID_PSP_FUNC}")" + check_and_log_consumed_srh 3 "${sid}" 4 2 1 "${END_CSID_PSP_FUNC}" + + set_hs_seg6_enabled 0 +} + test_iproute2_supp_or_ksft_skip() { local flavor=3D"$1" @@ -1102,6 +1354,28 @@ test_kernel_supp_or_ksft_skip() ip netns del "${test_netns}" } =20 +# Before enabling the tests with a consumed SRH, make sure that the rules = they +# use can be added. +check_srh_match_support() +{ + local srhm_ns + + if [ ! -x "$(command -v ip6tables)" ]; then + return + fi + + if ! setup_ns srhm_ns; then + return + fi + + if add_srh_check_rules "${srhm_ns}" "${IPv6_TESTS_ADDR}" \ + &>/dev/null; then + HAS_SRH_MATCH=3Dtrue + fi + + cleanup_ns "${srhm_ns}" +} + test_dummy_dev_or_ksft_skip() { local test_netns @@ -1145,6 +1419,7 @@ test_dummy_dev_or_ksft_skip # supports PSP also supports NEXT-C-SID. test_iproute2_supp_or_ksft_skip psp test_kernel_supp_or_ksft_skip psp +check_srh_match_support =20 set -e trap cleanup EXIT @@ -1156,5 +1431,6 @@ router_tests host2gateway_tests host_srv6_end_flv_psp_tests host_srv6_end_flv_next_csid_psp_tests +host_srv6_end_flv_consumed_srh_tests =20 print_log_test_results --=20 2.43.0