octeontx2-pf: Add ip tos and ip proto icmp/icmpv6 flow offload support
Add support for programming the HW MCAM match key with IP tos, IP(v6) proto icmp/icmpv6, allowing flow offload rules to be installed using those fields. The NPC HW extracts layer type, which will be used as a matching criteria for different IP protocols. The ethtool n-tuple filter logic has been updated to parse the IP tos and l4proto for HW offloading. l4proto tcp/udp/sctp/ah/esp/icmp are supported. See example usage below. Ex: Redirect l4proto icmp to vf 0 queue 0 ethtool -U eth0 flow-type ip4 l4proto 1 action vf 0 queue 0 Ex: Redirect flow with ip tos 8 to vf 0 queue 0 ethtool -U eth0 flow-type ip4 tos 8 vf 0 queue 0 Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a04be4b6b5
commit
2b9cef6679
@ -167,6 +167,8 @@ enum key_fields {
|
||||
NPC_IPPROTO_SCTP,
|
||||
NPC_IPPROTO_AH,
|
||||
NPC_IPPROTO_ESP,
|
||||
NPC_IPPROTO_ICMP,
|
||||
NPC_IPPROTO_ICMP6,
|
||||
NPC_SPORT_TCP,
|
||||
NPC_DPORT_TCP,
|
||||
NPC_SPORT_UDP,
|
||||
|
@ -29,6 +29,8 @@ static const char * const npc_flow_names[] = {
|
||||
[NPC_IPPROTO_TCP] = "ip proto tcp",
|
||||
[NPC_IPPROTO_UDP] = "ip proto udp",
|
||||
[NPC_IPPROTO_SCTP] = "ip proto sctp",
|
||||
[NPC_IPPROTO_ICMP] = "ip proto icmp",
|
||||
[NPC_IPPROTO_ICMP6] = "ip proto icmp6",
|
||||
[NPC_IPPROTO_AH] = "ip proto AH",
|
||||
[NPC_IPPROTO_ESP] = "ip proto ESP",
|
||||
[NPC_SPORT_TCP] = "tcp source port",
|
||||
@ -427,6 +429,7 @@ do { \
|
||||
* packet header fields below.
|
||||
* Example: Source IP is 4 bytes and starts at 12th byte of IP header
|
||||
*/
|
||||
NPC_SCAN_HDR(NPC_TOS, NPC_LID_LC, NPC_LT_LC_IP, 1, 1);
|
||||
NPC_SCAN_HDR(NPC_SIP_IPV4, NPC_LID_LC, NPC_LT_LC_IP, 12, 4);
|
||||
NPC_SCAN_HDR(NPC_DIP_IPV4, NPC_LID_LC, NPC_LT_LC_IP, 16, 4);
|
||||
NPC_SCAN_HDR(NPC_SIP_IPV6, NPC_LID_LC, NPC_LT_LC_IP6, 8, 16);
|
||||
@ -477,9 +480,12 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
|
||||
BIT_ULL(NPC_IPPROTO_SCTP);
|
||||
}
|
||||
|
||||
/* for AH, check if corresponding layer type is present in the key */
|
||||
if (npc_check_field(rvu, blkaddr, NPC_LD, intf))
|
||||
/* for AH/ICMP/ICMPv6/, check if corresponding layer type is present in the key */
|
||||
if (npc_check_field(rvu, blkaddr, NPC_LD, intf)) {
|
||||
*features |= BIT_ULL(NPC_IPPROTO_AH);
|
||||
*features |= BIT_ULL(NPC_IPPROTO_ICMP);
|
||||
*features |= BIT_ULL(NPC_IPPROTO_ICMP6);
|
||||
}
|
||||
|
||||
/* for ESP, check if corresponding layer type is present in the key */
|
||||
if (npc_check_field(rvu, blkaddr, NPC_LE, intf))
|
||||
@ -769,6 +775,12 @@ static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,
|
||||
if (features & BIT_ULL(NPC_IPPROTO_SCTP))
|
||||
npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_SCTP,
|
||||
0, ~0ULL, 0, intf);
|
||||
if (features & BIT_ULL(NPC_IPPROTO_ICMP))
|
||||
npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_ICMP,
|
||||
0, ~0ULL, 0, intf);
|
||||
if (features & BIT_ULL(NPC_IPPROTO_ICMP6))
|
||||
npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_ICMP6,
|
||||
0, ~0ULL, 0, intf);
|
||||
|
||||
if (features & BIT_ULL(NPC_OUTER_VID))
|
||||
npc_update_entry(rvu, NPC_LB, entry,
|
||||
@ -798,6 +810,7 @@ do { \
|
||||
NPC_WRITE_FLOW(NPC_SMAC, smac, smac_val, 0, smac_mask, 0);
|
||||
NPC_WRITE_FLOW(NPC_ETYPE, etype, ntohs(pkt->etype), 0,
|
||||
ntohs(mask->etype), 0);
|
||||
NPC_WRITE_FLOW(NPC_TOS, tos, pkt->tos, 0, mask->tos, 0);
|
||||
NPC_WRITE_FLOW(NPC_SIP_IPV4, ip4src, ntohl(pkt->ip4src), 0,
|
||||
ntohl(mask->ip4src), 0);
|
||||
NPC_WRITE_FLOW(NPC_DIP_IPV4, ip4dst, ntohl(pkt->ip4dst), 0,
|
||||
|
@ -301,6 +301,35 @@ static int otx2_prepare_ipv4_flow(struct ethtool_rx_flow_spec *fsp,
|
||||
sizeof(pmask->ip4dst));
|
||||
req->features |= BIT_ULL(NPC_DIP_IPV4);
|
||||
}
|
||||
if (ipv4_usr_mask->tos) {
|
||||
pkt->tos = ipv4_usr_hdr->tos;
|
||||
pmask->tos = ipv4_usr_mask->tos;
|
||||
req->features |= BIT_ULL(NPC_TOS);
|
||||
}
|
||||
if (ipv4_usr_mask->proto) {
|
||||
switch (ipv4_usr_hdr->proto) {
|
||||
case IPPROTO_ICMP:
|
||||
req->features |= BIT_ULL(NPC_IPPROTO_ICMP);
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
req->features |= BIT_ULL(NPC_IPPROTO_TCP);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
req->features |= BIT_ULL(NPC_IPPROTO_UDP);
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
req->features |= BIT_ULL(NPC_IPPROTO_SCTP);
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
req->features |= BIT_ULL(NPC_IPPROTO_AH);
|
||||
break;
|
||||
case IPPROTO_ESP:
|
||||
req->features |= BIT_ULL(NPC_IPPROTO_ESP);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
pkt->etype = cpu_to_be16(ETH_P_IP);
|
||||
pmask->etype = cpu_to_be16(0xFFFF);
|
||||
req->features |= BIT_ULL(NPC_ETYPE);
|
||||
@ -325,6 +354,11 @@ static int otx2_prepare_ipv4_flow(struct ethtool_rx_flow_spec *fsp,
|
||||
sizeof(pmask->ip4dst));
|
||||
req->features |= BIT_ULL(NPC_DIP_IPV4);
|
||||
}
|
||||
if (ipv4_l4_mask->tos) {
|
||||
pkt->tos = ipv4_l4_hdr->tos;
|
||||
pmask->tos = ipv4_l4_mask->tos;
|
||||
req->features |= BIT_ULL(NPC_TOS);
|
||||
}
|
||||
if (ipv4_l4_mask->psrc) {
|
||||
memcpy(&pkt->sport, &ipv4_l4_hdr->psrc,
|
||||
sizeof(pkt->sport));
|
||||
@ -375,10 +409,14 @@ static int otx2_prepare_ipv4_flow(struct ethtool_rx_flow_spec *fsp,
|
||||
sizeof(pmask->ip4dst));
|
||||
req->features |= BIT_ULL(NPC_DIP_IPV4);
|
||||
}
|
||||
if (ah_esp_mask->tos) {
|
||||
pkt->tos = ah_esp_hdr->tos;
|
||||
pmask->tos = ah_esp_mask->tos;
|
||||
req->features |= BIT_ULL(NPC_TOS);
|
||||
}
|
||||
|
||||
/* NPC profile doesn't extract AH/ESP header fields */
|
||||
if ((ah_esp_mask->spi & ah_esp_hdr->spi) ||
|
||||
(ah_esp_mask->tos & ah_esp_mask->tos))
|
||||
if (ah_esp_mask->spi & ah_esp_hdr->spi)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (flow_type == AH_V4_FLOW)
|
||||
|
Loading…
x
Reference in New Issue
Block a user