From a8d4879d5f1fac060719567d1a8e8f8e68a127fc Mon Sep 17 00:00:00 2001 From: Geetha sowjanya Date: Wed, 22 Nov 2023 17:11:42 +0530 Subject: [PATCH] octeontx2-pf: TC flower offload support for ICMP type and code Adds tc offload support for matching on ICMP type and code. Example usage: To enable adding tc ingress rules tc qdisc add dev eth0 ingress TC rule drop the ICMP echo reply: tc filter add dev eth0 protocol ip parent ffff: \ flower ip_proto icmp type 8 code 0 skip_sw action drop TC rule to drop ICMPv6 echo reply: tc filter add dev eth0 protocol ipv6 parent ffff: flower \ indev eth0 ip_proto icmpv6 type 128 code 0 action drop Signed-off-by: Geetha sowjanya Signed-off-by: David S. Miller --- .../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 | 23 ++++++++++++++----- .../ethernet/marvell/octeontx2/nic/otx2_tc.c | 14 +++++++++++ 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index 6845556581c3..b4ced739ae44 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1479,6 +1479,8 @@ struct flow_msg { #define OTX2_FLOWER_MASK_MPLS_TTL GENMASK(7, 0) #define OTX2_FLOWER_MASK_MPLS_NON_TTL GENMASK(31, 8) u32 mpls_lse[4]; + u8 icmp_type; + u8 icmp_code; }; 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 ab3e39eef2eb..ffc0aa0a7b47 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_MPLS3_TTL, NPC_MPLS4_LBTCBOS, NPC_MPLS4_TTL, + NPC_TYPE_ICMP, + NPC_CODE_ICMP, 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 bd817ee88735..468b6561ed3f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c @@ -2889,6 +2889,14 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s, RVU_DBG_PRINT_MPLS_TTL(rule->packet.mpls_lse[3], rule->mask.mpls_lse[3]); break; + case NPC_TYPE_ICMP: + seq_printf(s, "%d ", rule->packet.icmp_type); + seq_printf(s, "mask 0x%x\n", rule->mask.icmp_type); + break; + case NPC_CODE_ICMP: + seq_printf(s, "%d ", rule->packet.icmp_code); + seq_printf(s, "mask 0x%x\n", rule->mask.icmp_code); + 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 114e4ec21802..db8f151636af 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -51,6 +51,8 @@ static const char * const npc_flow_names[] = { [NPC_MPLS3_TTL] = "lse depth 3 ttl", [NPC_MPLS4_LBTCBOS] = "lse depth 4 label tc bos", [NPC_MPLS4_TTL] = "lse depth 4", + [NPC_TYPE_ICMP] = "icmp type", + [NPC_CODE_ICMP] = "icmp code", [NPC_UNKNOWN] = "unknown", }; @@ -526,6 +528,8 @@ do { \ NPC_SCAN_HDR(NPC_DPORT_TCP, NPC_LID_LD, NPC_LT_LD_TCP, 2, 2); NPC_SCAN_HDR(NPC_SPORT_SCTP, NPC_LID_LD, NPC_LT_LD_SCTP, 0, 2); NPC_SCAN_HDR(NPC_DPORT_SCTP, NPC_LID_LD, NPC_LT_LD_SCTP, 2, 2); + NPC_SCAN_HDR(NPC_TYPE_ICMP, NPC_LID_LD, NPC_LT_LD_ICMP, 0, 1); + NPC_SCAN_HDR(NPC_CODE_ICMP, NPC_LID_LD, NPC_LT_LD_ICMP, 1, 1); NPC_SCAN_HDR(NPC_ETYPE_ETHER, NPC_LID_LA, NPC_LT_LA_ETHER, 12, 2); NPC_SCAN_HDR(NPC_ETYPE_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 4, 2); NPC_SCAN_HDR(NPC_ETYPE_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 8, 2); @@ -555,7 +559,7 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf) { struct npc_mcam *mcam = &rvu->hw->mcam; u64 *features = &mcam->rx_features; - u64 tcp_udp_sctp; + u64 proto_flags; int hdr; if (is_npc_intf_tx(intf)) @@ -566,18 +570,21 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf) *features |= BIT_ULL(hdr); } - tcp_udp_sctp = BIT_ULL(NPC_SPORT_TCP) | BIT_ULL(NPC_SPORT_UDP) | + proto_flags = BIT_ULL(NPC_SPORT_TCP) | BIT_ULL(NPC_SPORT_UDP) | BIT_ULL(NPC_DPORT_TCP) | BIT_ULL(NPC_DPORT_UDP) | - BIT_ULL(NPC_SPORT_SCTP) | BIT_ULL(NPC_DPORT_SCTP); + BIT_ULL(NPC_SPORT_SCTP) | BIT_ULL(NPC_DPORT_SCTP) | + BIT_ULL(NPC_SPORT_SCTP) | BIT_ULL(NPC_DPORT_SCTP) | + BIT_ULL(NPC_TYPE_ICMP) | BIT_ULL(NPC_CODE_ICMP); /* for tcp/udp/sctp corresponding layer type should be in the key */ - if (*features & tcp_udp_sctp) { + if (*features & proto_flags) { if (!npc_check_field(rvu, blkaddr, NPC_LD, intf)) - *features &= ~tcp_udp_sctp; + *features &= ~proto_flags; else *features |= BIT_ULL(NPC_IPPROTO_TCP) | BIT_ULL(NPC_IPPROTO_UDP) | - BIT_ULL(NPC_IPPROTO_SCTP); + BIT_ULL(NPC_IPPROTO_SCTP) | + BIT_ULL(NPC_IPPROTO_ICMP); } /* for AH/ICMP/ICMPv6/, check if corresponding layer type is present in the key */ @@ -971,6 +978,10 @@ do { \ ntohs(mask->sport), 0); NPC_WRITE_FLOW(NPC_DPORT_SCTP, dport, ntohs(pkt->dport), 0, ntohs(mask->dport), 0); + NPC_WRITE_FLOW(NPC_TYPE_ICMP, icmp_type, pkt->icmp_type, 0, + mask->icmp_type, 0); + NPC_WRITE_FLOW(NPC_CODE_ICMP, icmp_code, pkt->icmp_code, 0, + mask->icmp_code, 0); NPC_WRITE_FLOW(NPC_IPSEC_SPI, spi, ntohl(pkt->spi), 0, ntohl(mask->spi), 0); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c index 8a5e3987a482..10657a7559d7 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c @@ -522,6 +522,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) | BIT(FLOW_DISSECTOR_KEY_IPSEC) | BIT_ULL(FLOW_DISSECTOR_KEY_MPLS) | + BIT_ULL(FLOW_DISSECTOR_KEY_ICMP) | BIT_ULL(FLOW_DISSECTOR_KEY_IP)))) { netdev_info(nic->netdev, "unsupported flow used key 0x%llx", dissector->used_keys); @@ -796,6 +797,19 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, } } + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ICMP)) { + struct flow_match_icmp match; + + flow_rule_match_icmp(rule, &match); + + flow_spec->icmp_type = match.key->type; + flow_mask->icmp_type = match.mask->type; + req->features |= BIT_ULL(NPC_TYPE_ICMP); + + flow_spec->icmp_code = match.key->code; + flow_mask->icmp_code = match.mask->code; + req->features |= BIT_ULL(NPC_CODE_ICMP); + } return otx2_tc_parse_actions(nic, &rule->action, req, f, node); }