* [PATCH v2 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows
@ 2026-08-12 5:12 Ratheesh Kannoth
2026-08-14 8:56 ` Simon Horman
0 siblings, 1 reply; 2+ messages in thread
From: Ratheesh Kannoth @ 2026-08-12 5:12 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham,
Suman Ghosh, Geetha sowjanya, Ratheesh Kannoth
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>
---
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 | 38 ++++++++++++++++++-
.../marvell/octeontx2/nic/otx2_flows.c | 27 ++++++++++++-
5 files changed, 75 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..773097cd8534 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);
@@ -1805,6 +1821,26 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
req->features |= BIT_ULL(NPC_LXMB);
}
+ if ((req->features & BIT_ULL(NPC_GTPU_TEID)) &&
+ !npc_check_field(rvu, blkaddr, NPC_GTPU_TEID, req->intf)) {
+ 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)) {
+ 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;
+ }
+
process_flow:
if (from_vf && req->default_rule) {
rvu_npc_free_entry_for_flow_install(rvu, req->hdr.pcifunc,
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
index 99d78fc5a2c4..7f69e386638c 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,8 +1038,31 @@ 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;
+ switch (flow_type) {
+ case UDP_V4_FLOW:
+ case UDP_V6_FLOW:
+ case TCP_V4_FLOW:
+ case TCP_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.vlan_etype) {
/* Partial masks not supported */
if (be16_to_cpu(fsp->m_ext.vlan_etype) != 0xFFFF)
@@ -1076,7 +1101,7 @@ 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]) {
+ 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
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows
2026-08-12 5:12 [PATCH v2 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows Ratheesh Kannoth
@ 2026-08-14 8:56 ` Simon Horman
0 siblings, 0 replies; 2+ messages in thread
From: Simon Horman @ 2026-08-14 8:56 UTC (permalink / raw)
To: Ratheesh Kannoth
Cc: linux-kernel, netdev, andrew+netdev, davem, edumazet, kuba,
pabeni, sgoutham, Suman Ghosh, Geetha sowjanya
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev/#/patchset/20260812051215.456258-1-rkannoth@marvell.com?part=1
Simon says:
Thanks for the updates in v2.
There is another round of feedback from Sashiko.
I would appreciate it if you could take a look.
---
--- Patch [1]: [PATCH v2 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows ---
commit 58f64feb1709d91cb7f52c12d7e09c8779588a04
Author: Suman Ghosh <sumang@marvell.com>
octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows
This patch adds NPC_GTPU_TEID and NPC_GTPC_TEID key fields to the octeontx2
driver. It wires them through the AF MCAM path to allow ethtool Rx flow rules
to match on the TEID of GTP-U and GTP-C packets.
Link: https://sashiko.dev/#/patchset/20260810050436.1822566-1-rkannoth%40marvell.com
> 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 d422bdd5e8f80..773097cd85343 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
[ ... ]
> @@ -1805,6 +1821,26 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
> req->features |= BIT_ULL(NPC_LXMB);
> }
>
> + if ((req->features & BIT_ULL(NPC_GTPU_TEID)) &&
> + !npc_check_field(rvu, blkaddr, NPC_GTPU_TEID, req->intf)) {
> + dev_warn(rvu->dev,
> + "%s: mkex profile does not extract GTP-U TEID\n",
> + __func__);
[Severity: Medium]
Are these MKEX profile capability checks effectively dead code in the standard
execution path?
Looking earlier in rvu_mbox_handler_npc_install_flow(), there is a check:
if (npc_check_field(rvu, blkaddr, NPC_DMAC, req->intf))
goto process_flow;
Does this mean the new GTP TEID checks are completely bypassed if the profile
supports DMAC?
Also, if a profile without DMAC support is used, does this expose an
un-ratelimited warning log spam vector if a VF repeatedly requests GTP rules?
The preceding DMAC warnings check for is_pffunc_af(req->hdr.pcifunc) to limit
who can trigger them, but that seems to be missing here.
> + 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)) {
> + 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;
> + }
> +
> process_flow:
> if (from_vf && req->default_rule) {
> rvu_npc_free_entry_for_flow_install(rvu, req->hdr.pcifunc,
[ ... ]
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
> index 99d78fc5a2c4a..7f69e386638ce 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
[ ... ]
> @@ -1036,8 +1038,31 @@ 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;
>
> + switch (flow_type) {
> + case UDP_V4_FLOW:
> + case UDP_V6_FLOW:
> + case TCP_V4_FLOW:
> + case TCP_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);
[Severity: High]
Does this unconditional conversion hijack legitimate non-GTP rules and TCP
flows?
Since this logic runs for TCP_V4_FLOW and TCP_V6_FLOW, will it incorrectly
force GTP matching on TCP flows, breaking the rule completely?
Also, if a user specifies a non-GTP UDP rule with FLOW_EXT (e.g. providing a
VLAN or MAC address) but doesn't provide a TEID mask in m_ext.data[1], does
this still set skip_user_def to true and require hardware to identify a GTP
layer?
> + } 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.vlan_etype) {
> /* Partial masks not supported */
> if (be16_to_cpu(fsp->m_ext.vlan_etype) != 0xFFFF)
[ ... ]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-14 8:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 5:12 [PATCH v2 net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows Ratheesh Kannoth
2026-08-14 8:56 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox