[PATCH net-next] octeontx2-af: add NPC TEID matching for GTP-U and GTP-C flows
Ratheesh Kannoth <[email protected]>
| Newsgroups | org.kernel.vger.netdev,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Suman Ghosh <[email protected]> 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 <[email protected]> Signed-off-by: Geetha sowjanya <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: Ratheesh Kannoth <[email protected]> --- .../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 | 21 +++++++++++++++-- .../marvell/octeontx2/nic/otx2_flows.c | 23 +++++++++++++++++++ 5 files changed, 54 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..1101e29328ac 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1839,6 +1839,8 @@ struct flow_msg { u8 next_header; }; __be16 vlan_itci; + __be32 gtpu_teid; + __be32 gtpc_teid; #define OTX2_FLOWER_MASK_MPLS_LB GENMASK(31, 12) #define OTX2_FLOWER_MASK_MPLS_TC GENMASK(11, 9) #define OTX2_FLOWER_MASK_MPLS_BOS BIT(8) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h index 719b3618eeb5..33277fc3d27e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h @@ -214,6 +214,8 @@ enum key_fields { NPC_DPORT_UDP, NPC_SPORT_SCTP, NPC_DPORT_SCTP, + NPC_GTPU_TEID, + NPC_GTPC_TEID, NPC_IPSEC_SPI, NPC_MPLS1_LBTCBOS, NPC_MPLS1_TTL, diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c index 3456313d3b3c..bb690890606c 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, "%d ", 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, "%d ", 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..1f9af70cf2f9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -44,6 +44,8 @@ static const char * const npc_flow_names[] = { [NPC_SPORT_SCTP] = "sctp source port", [NPC_DPORT_SCTP] = "sctp destination port", [NPC_LXMB] = "Mcast/Bcast header ", + [NPC_GTPU_TEID] = "gtp-u teid ", + [NPC_GTPC_TEID] = "gtp-c teid ", [NPC_IPSEC_SPI] = "SPI ", [NPC_MPLS1_LBTCBOS] = "lse depth 1 label tc bos", [NPC_MPLS1_TTL] = "lse depth 1 ttl", @@ -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,9 +724,10 @@ 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/GTP-U/GTP-C 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); + *features |= BIT_ULL(NPC_IPPROTO_ESP) | BIT_ULL(NPC_GTPU_TEID) | + BIT_ULL(NPC_GTPC_TEID); /* for vlan corresponding layer type should be in the key */ if (*features & BIT_ULL(NPC_OUTER_VID)) @@ -1113,6 +1118,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 +1222,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); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 99d78fc5a2c4..59ea2da33ae2 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,29 @@ 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(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(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) -- 2.43.0