Netdev List
 help / color / mirror / Atom feed
From: Todd Freed <toddfreed@meta.com>
To: <netdev@vger.kernel.org>, <toddfreed@meta.com>
Cc: David Ahern <dsahern@kernel.org>,
	Stephen Hemminger <stephen@networkplumber.org>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Jiri Pirko <jiri@resnulli.us>,
	Daniel Zahka <daniel.zahka@gmail.com>,
	Willem de Bruijn <willemdebruijn.kernel@gmail.com>,
	Jakub Kicinski <kuba@kernel.org>,
	<linux-kselftest@vger.kernel.org>
Subject: [PATCH iproute2-next 3/3] tc: flower: add matches psp_spi, psp_ver and psp_dev
Date: Wed, 11 Nov 2026 16:15:12 -0800	[thread overview]
Message-ID: <20261112001512.3598626-4-toddfreed@meta.com> (raw)
In-Reply-To: <20261112001512.3598626-1-toddfreed@meta.com>

Match on the PSP Rx state of a packet the device decrypted: the SPI it
was decrypted with (psp_spi, with an optional mask), the PSP version
(psp_ver), and the ID of the PSP device which decrypted it (psp_dev).

For example, to take the packets decrypted with one Rx SPI, from
rx-spi-alloc, and remove their PSP state:

  tc filter add dev eth0 ingress protocol ipv6 flower
      psp_spi 0x80000001 psp_ver 0 psp_dev 1
      action psp decap

These keys only match decrypted packets, even with a zero mask, so
"psp_spi 0/0" matches any decrypted PSP packet.

psp_spi and its mask are hexadecimal, like spi. tc-flower(8) documents
the keys.

Signed-off-by: Todd Freed <toddfreed@meta.com>
---
 man/man8/tc-flower.8 | 29 ++++++++++++++++++
 tc/f_flower.c        | 71 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+)

diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index 3f8ba4656ef4..88881671c693 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -56,6 +56,12 @@ flower \- flow based traffic control filter
 .IR TTL " | "
 .B l2tpv3_sid
 .IR LSID " | "
+.B psp_spi
+.IR SPI "[/" MASK "] | "
+.B psp_ver
+.IR VERSION " | "
+.B psp_dev
+.IR PSP_DEV_ID " | "
 .BR ip_proto " { " tcp " | " udp " | " sctp " | " icmp " | " icmpv6 " | " l2tp " | "
 .IR IP_PROTO " } | "
 .B ip_tos
@@ -323,6 +329,29 @@ Match on L2TPv3 session id field transported over IPv4 or IPv6.
 .I LSID
 is an unsigned 32 bit value in decimal format.
 .TP
+.BI psp_spi " SPI[/MASK]"
+Match on the SPI which a PSP device decrypted the packet with.
+.I SPI
+and
+.I MASK
+are unsigned 32 bit values in hexadecimal format.
+.TP
+.BI psp_ver " VERSION"
+Match on the PSP version which the packet was decrypted with, as numbered
+by the PSP netlink family (0 for hdr0-aes-gcm-128, 1 for hdr0-aes-gcm-256,
+2 for hdr0-aes-gmac-128, 3 for hdr0-aes-gmac-256).
+.TP
+.BI psp_dev " PSP_DEV_ID"
+Match on the ID of the PSP device which decrypted the packet, from the PSP
+netlink family.
+.IP
+The PSP keys only ever match packets which a PSP device decrypted, even with
+a zero mask:
+.B psp_spi 0/0
+matches any packet decrypted with PSP. See
+.BR tc-psp (8)
+for an example.
+.TP
 .BI ip_proto " IP_PROTO"
 Match on layer four protocol.
 .I IP_PROTO
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 6fc2c6a1ccc6..27244733e03a 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -73,6 +73,9 @@ static void explain(void)
 		"			mpls_bos BOS |\n"
 		"			mpls_ttl TTL |\n"
 		"			spi SPI-INDEX  |\n"
+		"			psp_spi SPI[/MASK] |\n"
+		"			psp_ver VERSION |\n"
+		"			psp_dev PSP-DEV-ID |\n"
 		"			l2tpv3_sid LSID |\n"
 		"			dst_ip PREFIX |\n"
 		"			src_ip PREFIX |\n"
@@ -678,6 +681,25 @@ static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
 	return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
 }
 
+static int flower_parse_psp_spi(char *str, struct nlmsghdr *n)
+{
+	__u32 spi, mask = UINT32_MAX;
+	char *slash;
+
+	slash = strchr(str, '/');
+	if (slash) {
+		*slash = '\0';
+		if (get_u32(&mask, slash + 1, 16))
+			return -1;
+	}
+	if (get_u32(&spi, str, 16))
+		return -1;
+
+	addattr32(n, MAX_MSG, TCA_FLOWER_KEY_PSP_SPI, htonl(spi));
+	addattr32(n, MAX_MSG, TCA_FLOWER_KEY_PSP_SPI_MASK, htonl(mask));
+	return 0;
+}
+
 static int flower_parse_spi(char *str, __u8 ip_proto, struct nlmsghdr *n)
 {
 	__be32 spi;
@@ -2074,6 +2096,31 @@ static int flower_parse_opt(const struct filter_util *qu, char *handle,
 			ret = flower_parse_l2tpv3(*argv, ip_proto, n);
 			if (ret < 0)
 				return -1;
+		} else if (!strcmp(*argv, "psp_spi")) {
+			NEXT_ARG();
+			ret = flower_parse_psp_spi(*argv, n);
+			if (ret < 0) {
+				fprintf(stderr, "Illegal \"psp_spi\"\n");
+				return -1;
+			}
+		} else if (!strcmp(*argv, "psp_ver")) {
+			__u8 ver;
+
+			NEXT_ARG();
+			if (get_u8(&ver, *argv, 0)) {
+				fprintf(stderr, "Illegal \"psp_ver\"\n");
+				return -1;
+			}
+			addattr8(n, MAX_MSG, TCA_FLOWER_KEY_PSP_VERSION, ver);
+		} else if (!strcmp(*argv, "psp_dev")) {
+			__u32 dev;
+
+			NEXT_ARG();
+			if (get_u32(&dev, *argv, 0)) {
+				fprintf(stderr, "Illegal \"psp_dev\"\n");
+				return -1;
+			}
+			addattr32(n, MAX_MSG, TCA_FLOWER_KEY_PSP_DEV, dev);
 		} else if (!strcmp(*argv, "spi")) {
 			NEXT_ARG();
 			ret = flower_parse_spi(*argv, ip_proto, n);
@@ -3236,6 +3283,30 @@ static int flower_print_opt(const struct filter_util *qu, FILE *f,
 			   rta_getattr_be32(attr));
 	}
 
+	if (tb[TCA_FLOWER_KEY_PSP_SPI]) {
+		__u32 mask = UINT32_MAX;
+
+		if (tb[TCA_FLOWER_KEY_PSP_SPI_MASK])
+			mask = rta_getattr_be32(tb[TCA_FLOWER_KEY_PSP_SPI_MASK]);
+		print_nl();
+		print_hex(PRINT_ANY, "psp_spi", "  psp_spi 0x%x",
+			  rta_getattr_be32(tb[TCA_FLOWER_KEY_PSP_SPI]));
+		if (mask != UINT32_MAX)
+			print_hex(PRINT_ANY, "psp_spi_mask", "/0x%x", mask);
+	}
+
+	if (tb[TCA_FLOWER_KEY_PSP_VERSION]) {
+		print_nl();
+		print_uint(PRINT_ANY, "psp_ver", "  psp_ver %u",
+			   rta_getattr_u8(tb[TCA_FLOWER_KEY_PSP_VERSION]));
+	}
+
+	if (tb[TCA_FLOWER_KEY_PSP_DEV]) {
+		print_nl();
+		print_uint(PRINT_ANY, "psp_dev", "  psp_dev %u",
+			   rta_getattr_u32(tb[TCA_FLOWER_KEY_PSP_DEV]));
+	}
+
 	flower_print_ip4_addr("arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
 			     tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
 	flower_print_ip4_addr("arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
-- 
2.53.0-Meta


  parent reply	other threads:[~2026-11-12  0:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12  0:15 [PATCH iproute2-next 0/3] tc: add the psp action and flower psp matches Todd Freed
2026-11-12  0:15 ` [PATCH iproute2-next 1/3] uapi: add the tc psp action and flower psp keys Todd Freed
2026-11-12  0:15 ` [PATCH iproute2-next 2/3] tc: add the psp action Todd Freed
2026-11-12  1:05   ` Stephen Hemminger
2026-11-12  0:15 ` Todd Freed [this message]
2026-11-12  1:06   ` [PATCH iproute2-next 3/3] tc: flower: add matches psp_spi, psp_ver and psp_dev Stephen Hemminger

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=20261112001512.3598626-4-toddfreed@meta.com \
    --to=toddfreed@meta.com \
    --cc=daniel.zahka@gmail.com \
    --cc=dsahern@kernel.org \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    --cc=willemdebruijn.kernel@gmail.com \
    /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