octeontx2-pf: TC flower offload support for SPI field

Driver support to offload TC flower rules which matches
against SPI field of IPSEC packets (AH/ESP).

Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ratheesh Kannoth 2023-08-01 07:11:01 +05:30 committed by David S. Miller
parent c8915d7329
commit 73b4c04e2e
5 changed files with 47 additions and 0 deletions

View file

@ -1451,6 +1451,10 @@ struct flow_msg {
__be32 ip4dst;
__be32 ip6dst[4];
};
union {
__be32 spi;
};
u8 tos;
u8 ip_ver;
u8 ip_proto;

View file

@ -204,6 +204,7 @@ enum key_fields {
NPC_DPORT_UDP,
NPC_SPORT_SCTP,
NPC_DPORT_SCTP,
NPC_IPSEC_SPI,
NPC_HEADER_FIELDS_MAX,
NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
NPC_PF_FUNC, /* Valid when Tx */

View file

@ -2827,6 +2827,10 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
seq_printf(s, "%d ", ntohs(rule->packet.dport));
seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.dport));
break;
case NPC_IPSEC_SPI:
seq_printf(s, "0x%x ", ntohl(rule->packet.spi));
seq_printf(s, "mask 0x%x\n", ntohl(rule->mask.spi));
break;
default:
seq_puts(s, "\n");
break;

View file

@ -41,6 +41,7 @@ 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_IPSEC_SPI] = "SPI ",
[NPC_UNKNOWN] = "unknown",
};
@ -513,6 +514,10 @@ 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_DMAC, NPC_LID_LA, la_ltype, la_start, 6);
NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LD, NPC_LT_LD_AH, 4, 4);
NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LE, NPC_LT_LE_ESP, 0, 4);
/* SMAC follows the DMAC(which is 6 bytes) */
NPC_SCAN_HDR(NPC_SMAC, NPC_LID_LA, la_ltype, la_start + 6, 6);
/* PF_FUNC is 2 bytes at 0th byte of NPC_LT_LA_IH_NIX_ETHER */
@ -564,6 +569,9 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
*features &= ~BIT_ULL(NPC_OUTER_VID);
if (*features & (BIT_ULL(NPC_IPPROTO_AH) | BIT_ULL(NPC_IPPROTO_ESP)))
*features |= BIT_ULL(NPC_IPSEC_SPI);
/* for vlan ethertypes corresponding layer type should be in the key */
if (npc_check_field(rvu, blkaddr, NPC_LB, intf))
*features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG) |
@ -930,6 +938,9 @@ do { \
NPC_WRITE_FLOW(NPC_DPORT_SCTP, dport, ntohs(pkt->dport), 0,
ntohs(mask->dport), 0);
NPC_WRITE_FLOW(NPC_IPSEC_SPI, spi, ntohl(pkt->spi), 0,
ntohl(mask->spi), 0);
NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
ntohs(mask->vlan_tci), 0);

View file

@ -461,6 +461,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
BIT(FLOW_DISSECTOR_KEY_IPSEC) |
BIT_ULL(FLOW_DISSECTOR_KEY_IP)))) {
netdev_info(nic->netdev, "unsupported flow used key 0x%llx",
dissector->used_keys);
@ -482,6 +483,8 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
match.key->ip_proto != IPPROTO_UDP &&
match.key->ip_proto != IPPROTO_SCTP &&
match.key->ip_proto != IPPROTO_ICMP &&
match.key->ip_proto != IPPROTO_ESP &&
match.key->ip_proto != IPPROTO_AH &&
match.key->ip_proto != IPPROTO_ICMPV6)) {
netdev_info(nic->netdev,
"ip_proto=0x%x not supported\n",
@ -501,6 +504,10 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
req->features |= BIT_ULL(NPC_IPPROTO_ICMP);
else if (ip_proto == IPPROTO_ICMPV6)
req->features |= BIT_ULL(NPC_IPPROTO_ICMP6);
else if (ip_proto == IPPROTO_ESP)
req->features |= BIT_ULL(NPC_IPPROTO_ESP);
else if (ip_proto == IPPROTO_AH)
req->features |= BIT_ULL(NPC_IPPROTO_AH);
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
@ -545,6 +552,26 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
}
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPSEC)) {
struct flow_match_ipsec match;
flow_rule_match_ipsec(rule, &match);
if (!match.mask->spi) {
NL_SET_ERR_MSG_MOD(extack, "spi index not specified");
return -EOPNOTSUPP;
}
if (ip_proto != IPPROTO_ESP &&
ip_proto != IPPROTO_AH) {
NL_SET_ERR_MSG_MOD(extack,
"SPI index is valid only for ESP/AH proto");
return -EOPNOTSUPP;
}
flow_spec->spi = match.key->spi;
flow_mask->spi = match.mask->spi;
req->features |= BIT_ULL(NPC_IPSEC_SPI);
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
struct flow_match_ip match;