From: Ratheesh Kannoth <rkannoth@marvell.com>
To: <linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>
Cc: <andrew+netdev@lunn.ch>, <davem@davemloft.net>,
<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
<sgoutham@marvell.com>, Suman Ghosh <sumang@marvell.com>,
Geetha sowjanya <gakula@marvell.com>,
Ratheesh Kannoth <rkannoth@marvell.com>
Subject: [PATCH v3 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows
Date: Mon, 17 Aug 2026 09:21:27 +0530 [thread overview]
Message-ID: <20260817035127.1782901-1-rkannoth@marvell.com> (raw)
From: Suman Ghosh <sumang@marvell.com>
Add NPC_GTPU_TEID and NPC_GTPC_TEID key fields and wire them through
the AF MCAM path so ethtool Rx flow rules can match on the TEID of
GTP-U and GTP-C packets.
In otx2_prepare_flow_request(), when a UDP or TCP v4/v6 ntuple rule
targets the well-known GTP-U (2152) or GTP-C (2123) destination port,
take the TEID value and mask from h_ext.data[1] and install the
corresponding LE layer match in NPC. Expose the new fields in debugfs
MCAM dumps.
Signed-off-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
v2 -> v3: Addressed Sashiko comments
https://sashiko.dev/#/patchset/20260812051215.456258-1-rkannoth%40marvell.com
v1 -> v2: Addressed Sashiko comments
https://sashiko.dev/#/patchset/20260810050436.1822566-1-rkannoth%40marvell.com
---
.../net/ethernet/marvell/octeontx2/af/mbox.h | 2 +
.../net/ethernet/marvell/octeontx2/af/npc.h | 2 +
.../marvell/octeontx2/af/rvu_debugfs.c | 8 ++++
.../marvell/octeontx2/af/rvu_npc_fs.c | 40 ++++++++++++++++++-
.../marvell/octeontx2/nic/otx2_flows.c | 29 +++++++++++++-
5 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 73f743e4a83d..7cf07f15bdae 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -1849,6 +1849,8 @@ struct flow_msg {
u8 icmp_code;
__be16 tcp_flags;
u16 sq_id;
+ __be32 gtpu_teid;
+ __be32 gtpc_teid;
};
struct npc_install_flow_req {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h
index 719b3618eeb5..187a50047617 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h
@@ -226,6 +226,8 @@ enum key_fields {
NPC_TYPE_ICMP,
NPC_CODE_ICMP,
NPC_TCP_FLAGS,
+ NPC_GTPU_TEID,
+ NPC_GTPC_TEID,
NPC_HEADER_FIELDS_MAX,
NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
NPC_PF_FUNC, /* Valid when Tx */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
index 3456313d3b3c..c0b0e4d14696 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
@@ -3437,6 +3437,14 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
seq_printf(s, "%d ", rule->packet.icmp_code);
seq_printf(s, "mask 0x%x\n", rule->mask.icmp_code);
break;
+ case NPC_GTPU_TEID:
+ seq_printf(s, "%u ", ntohl(rule->packet.gtpu_teid));
+ seq_printf(s, "mask 0x%x\n", ntohl(rule->mask.gtpu_teid));
+ break;
+ case NPC_GTPC_TEID:
+ seq_printf(s, "%u ", ntohl(rule->packet.gtpc_teid));
+ seq_printf(s, "mask 0x%x\n", ntohl(rule->mask.gtpc_teid));
+ break;
default:
seq_puts(s, "\n");
break;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
index d422bdd5e8f8..84be78ab7351 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -56,6 +56,8 @@ static const char * const npc_flow_names[] = {
[NPC_TYPE_ICMP] = "icmp type",
[NPC_CODE_ICMP] = "icmp code",
[NPC_TCP_FLAGS] = "tcp flags",
+ [NPC_GTPU_TEID] = "gtp-u teid ",
+ [NPC_GTPC_TEID] = "gtp-c teid ",
[NPC_UNKNOWN] = "unknown",
};
@@ -661,6 +663,8 @@ do { \
NPC_SCAN_HDR(NPC_VLAN_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 2, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 2, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG3, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 6, 2);
+ NPC_SCAN_HDR(NPC_GTPU_TEID, NPC_LID_LE, NPC_LT_LE_GTPU, 4, 4);
+ NPC_SCAN_HDR(NPC_GTPC_TEID, NPC_LID_LE, NPC_LT_LE_GTPC, 4, 4);
NPC_SCAN_HDR(NPC_DMAC, NPC_LID_LA, la_ltype, la_start, 6);
NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LD, NPC_LT_LD_AH, 4, 4);
@@ -720,7 +724,7 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
*features |= BIT_ULL(NPC_IPPROTO_ICMP6);
}
- /* for ESP, check if corresponding layer type is present in the key */
+ /* for ESP check if corresponding layer type is present in the key */
if (npc_check_field(rvu, blkaddr, NPC_LE, intf))
*features |= BIT_ULL(NPC_IPPROTO_ESP);
@@ -1113,6 +1117,14 @@ void npc_update_flow(struct rvu *rvu, struct mcam_entry_mdata *mdata,
npc_update_entry(rvu, NPC_LE, mdata, NPC_LT_LE_ESP,
0, ~0ULL, 0, intf);
+ if (features & BIT_ULL(NPC_GTPU_TEID))
+ npc_update_entry(rvu, NPC_LE, mdata, NPC_LT_LE_GTPU,
+ 0, ~0ULL, 0, intf);
+
+ if (features & BIT_ULL(NPC_GTPC_TEID))
+ npc_update_entry(rvu, NPC_LE, mdata, NPC_LT_LE_GTPC,
+ 0, ~0ULL, 0, intf);
+
if (features & BIT_ULL(NPC_LXMB)) {
output->lxmb = is_broadcast_ether_addr(pkt->dmac) ? 2 : 1;
npc_update_entry(rvu, NPC_LXMB, mdata, output->lxmb, 0,
@@ -1209,6 +1221,10 @@ do { \
NPC_WRITE_FLOW(NPC_IPFRAG_IPV6, next_header, pkt->next_header, 0,
mask->next_header, 0);
+ NPC_WRITE_FLOW(NPC_GTPU_TEID, gtpu_teid, ntohl(pkt->gtpu_teid), 0,
+ ntohl(mask->gtpu_teid), 0);
+ NPC_WRITE_FLOW(NPC_GTPC_TEID, gtpc_teid, ntohl(pkt->gtpc_teid), 0,
+ ntohl(mask->gtpc_teid), 0);
npc_update_ipv6_flow(rvu, mdata, features, pkt, mask, output, intf);
npc_update_vlan_features(rvu, mdata, features, intf);
@@ -1769,6 +1785,28 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
req->entry = npc_cn20k_vidx2idx(req->entry);
+ if ((req->features & BIT_ULL(NPC_GTPU_TEID)) &&
+ !npc_check_field(rvu, blkaddr, NPC_GTPU_TEID, req->intf)) {
+ if (is_pffunc_af(req->hdr.pcifunc))
+ dev_warn(rvu->dev,
+ "%s: mkex profile does not extract GTP-U TEID\n",
+ __func__);
+ rvu_npc_free_entry_for_flow_install(rvu, req->hdr.pcifunc,
+ allocated, req->entry);
+ return NPC_FLOW_NOT_SUPPORTED;
+ }
+
+ if ((req->features & BIT_ULL(NPC_GTPC_TEID)) &&
+ !npc_check_field(rvu, blkaddr, NPC_GTPC_TEID, req->intf)) {
+ if (is_pffunc_af(req->hdr.pcifunc))
+ dev_warn(rvu->dev,
+ "%s: mkex profile does not extract GTP-C TEID\n",
+ __func__);
+ rvu_npc_free_entry_for_flow_install(rvu, req->hdr.pcifunc,
+ allocated, req->entry);
+ return NPC_FLOW_NOT_SUPPORTED;
+ }
+
/* If DMAC is not extracted in MKEX, rules installed by AF
* can rely on L2MB bit set by hardware protocol checker for
* broadcast and multicast addresses.
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
index 99d78fc5a2c4..b374d8811bc8 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
@@ -11,6 +11,8 @@
#include "otx2_common.h"
#define OTX2_DEFAULT_ACTION 0x1
+#define GTPU_PORT 2152
+#define GTPC_PORT 2123
struct otx2_flow {
struct ethtool_rx_flow_spec flow_spec;
@@ -1036,6 +1038,7 @@ static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
return -EOPNOTSUPP;
}
if (fsp->flow_type & FLOW_EXT) {
+ int skip_user_def = false;
u16 vlan_etype;
if (fsp->m_ext.vlan_etype) {
@@ -1076,7 +1079,31 @@ static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
req->features |= BIT_ULL(NPC_OUTER_VID);
}
- if (fsp->m_ext.data[1]) {
+ /* GTP TEID uses FLOW_EXT data[1]; VLAN/MAC use other fields. */
+ if (fsp->m_ext.data[1] &&
+ fsp->h_ext.data[1] != cpu_to_be32(OTX2_DEFAULT_ACTION)) {
+ switch (flow_type) {
+ case UDP_V4_FLOW:
+ case UDP_V6_FLOW:
+ if (ntohs(pmask->dport) == 0xFFFF &&
+ ntohs(pkt->dport) == GTPU_PORT) {
+ /* Check for GTP-U packets */
+ skip_user_def = true;
+ pkt->gtpu_teid = fsp->h_ext.data[1];
+ pmask->gtpu_teid = fsp->m_ext.data[1];
+ req->features |= BIT_ULL(NPC_GTPU_TEID);
+ } else if (ntohs(pmask->dport) == 0xFFFF &&
+ ntohs(pkt->dport) == GTPC_PORT) {
+ /* Check for GTP-C packets */
+ skip_user_def = true;
+ pkt->gtpc_teid = fsp->h_ext.data[1];
+ pmask->gtpc_teid = fsp->m_ext.data[1];
+ req->features |= BIT_ULL(NPC_GTPC_TEID);
+ }
+ }
+ }
+
+ if (fsp->m_ext.data[1] && !skip_user_def) {
if (flow_type == IP_USER_FLOW) {
if (be32_to_cpu(fsp->h_ext.data[1]) != IPV4_FLAG_MORE)
return -EINVAL;
--
2.43.0
next reply other threads:[~2026-08-17 3:51 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-17 3:51 Ratheesh Kannoth [this message]
2026-08-17 15:41 ` [PATCH v3 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows Jakub Kicinski
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=20260817035127.1782901-1-rkannoth@marvell.com \
--to=rkannoth@marvell.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gakula@marvell.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sgoutham@marvell.com \
--cc=sumang@marvell.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.