Commit 73b4c04e authored by Ratheesh Kannoth's avatar Ratheesh Kannoth Committed by David S. Miller

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: default avatarRatheesh Kannoth <rkannoth@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c8915d73
...@@ -1451,6 +1451,10 @@ struct flow_msg { ...@@ -1451,6 +1451,10 @@ struct flow_msg {
__be32 ip4dst; __be32 ip4dst;
__be32 ip6dst[4]; __be32 ip6dst[4];
}; };
union {
__be32 spi;
};
u8 tos; u8 tos;
u8 ip_ver; u8 ip_ver;
u8 ip_proto; u8 ip_proto;
......
...@@ -204,6 +204,7 @@ enum key_fields { ...@@ -204,6 +204,7 @@ enum key_fields {
NPC_DPORT_UDP, NPC_DPORT_UDP,
NPC_SPORT_SCTP, NPC_SPORT_SCTP,
NPC_DPORT_SCTP, NPC_DPORT_SCTP,
NPC_IPSEC_SPI,
NPC_HEADER_FIELDS_MAX, NPC_HEADER_FIELDS_MAX,
NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */ NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
NPC_PF_FUNC, /* Valid when Tx */ NPC_PF_FUNC, /* Valid when Tx */
......
...@@ -2827,6 +2827,10 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s, ...@@ -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, "%d ", ntohs(rule->packet.dport));
seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.dport)); seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.dport));
break; 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: default:
seq_puts(s, "\n"); seq_puts(s, "\n");
break; break;
......
...@@ -41,6 +41,7 @@ static const char * const npc_flow_names[] = { ...@@ -41,6 +41,7 @@ static const char * const npc_flow_names[] = {
[NPC_SPORT_SCTP] = "sctp source port", [NPC_SPORT_SCTP] = "sctp source port",
[NPC_DPORT_SCTP] = "sctp destination port", [NPC_DPORT_SCTP] = "sctp destination port",
[NPC_LXMB] = "Mcast/Bcast header ", [NPC_LXMB] = "Mcast/Bcast header ",
[NPC_IPSEC_SPI] = "SPI ",
[NPC_UNKNOWN] = "unknown", [NPC_UNKNOWN] = "unknown",
}; };
...@@ -513,6 +514,10 @@ do { \ ...@@ -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_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_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_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) */ /* SMAC follows the DMAC(which is 6 bytes) */
NPC_SCAN_HDR(NPC_SMAC, NPC_LID_LA, la_ltype, la_start + 6, 6); 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 */ /* 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) ...@@ -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)) if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
*features &= ~BIT_ULL(NPC_OUTER_VID); *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 */ /* for vlan ethertypes corresponding layer type should be in the key */
if (npc_check_field(rvu, blkaddr, NPC_LB, intf)) if (npc_check_field(rvu, blkaddr, NPC_LB, intf))
*features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG) | *features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG) |
...@@ -930,6 +938,9 @@ do { \ ...@@ -930,6 +938,9 @@ do { \
NPC_WRITE_FLOW(NPC_DPORT_SCTP, dport, ntohs(pkt->dport), 0, NPC_WRITE_FLOW(NPC_DPORT_SCTP, dport, ntohs(pkt->dport), 0,
ntohs(mask->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, NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
ntohs(mask->vlan_tci), 0); ntohs(mask->vlan_tci), 0);
......
...@@ -461,6 +461,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, ...@@ -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_IPV4_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) | BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
BIT(FLOW_DISSECTOR_KEY_IPSEC) |
BIT_ULL(FLOW_DISSECTOR_KEY_IP)))) { BIT_ULL(FLOW_DISSECTOR_KEY_IP)))) {
netdev_info(nic->netdev, "unsupported flow used key 0x%llx", netdev_info(nic->netdev, "unsupported flow used key 0x%llx",
dissector->used_keys); dissector->used_keys);
...@@ -482,6 +483,8 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, ...@@ -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_UDP &&
match.key->ip_proto != IPPROTO_SCTP && match.key->ip_proto != IPPROTO_SCTP &&
match.key->ip_proto != IPPROTO_ICMP && match.key->ip_proto != IPPROTO_ICMP &&
match.key->ip_proto != IPPROTO_ESP &&
match.key->ip_proto != IPPROTO_AH &&
match.key->ip_proto != IPPROTO_ICMPV6)) { match.key->ip_proto != IPPROTO_ICMPV6)) {
netdev_info(nic->netdev, netdev_info(nic->netdev,
"ip_proto=0x%x not supported\n", "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, ...@@ -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); req->features |= BIT_ULL(NPC_IPPROTO_ICMP);
else if (ip_proto == IPPROTO_ICMPV6) else if (ip_proto == IPPROTO_ICMPV6)
req->features |= BIT_ULL(NPC_IPPROTO_ICMP6); 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)) { 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, ...@@ -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)) { if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
struct flow_match_ip match; struct flow_match_ip match;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment