Commit dce677da authored by Subbaraya Sundeep's avatar Subbaraya Sundeep Committed by David S. Miller

octeontx2-pf: Add vlan-etype to ntuple filters

NPC extraction profile marks layer types
NPC_LT_LB_CTAG for CTAG and NPC_LT_LB_STAG_QINQ for
STAG after parsing input packet. Those layer types
can be used to install ntuple filters using
vlan-etype option. Below are the commands and
corresponding behavior with this patch in place.

> alias nt "ethtool -U eth0 flow-type ether"

> nt vlan 5 m 0xf000 action 0
Input packets with outer VLAN id as 5 i.e,
stag packets with VLAN id 5 and ctag packets with
VLAN id as 5 are hit.

> nt vlan-etype 0x8100 action 0
All input ctag packets with any VLAN id are hit.

> nt vlan-etype 0x88A8 action 0
All input stag packets with any VLAN id are hit.

> nt vlan-etype 0x8100 vlan 5 m 0xf000 action 0
All input ctag packets with VLAN id 5 are hit.

> nt vlan-etype 0x88A8 vlan 5 m 0xf000 action 0
All input stag packets with VLAN id 5 are hit.
Signed-off-by: default avatarSubbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c7cd6c5a
...@@ -169,6 +169,8 @@ enum key_fields { ...@@ -169,6 +169,8 @@ enum key_fields {
NPC_DMAC, NPC_DMAC,
NPC_SMAC, NPC_SMAC,
NPC_ETYPE, NPC_ETYPE,
NPC_VLAN_ETYPE_CTAG, /* 0x8100 */
NPC_VLAN_ETYPE_STAG, /* 0x88A8 */
NPC_OUTER_VID, NPC_OUTER_VID,
NPC_TOS, NPC_TOS,
NPC_SIP_IPV4, NPC_SIP_IPV4,
......
...@@ -20,6 +20,8 @@ static const char * const npc_flow_names[] = { ...@@ -20,6 +20,8 @@ static const char * const npc_flow_names[] = {
[NPC_DMAC] = "dmac", [NPC_DMAC] = "dmac",
[NPC_SMAC] = "smac", [NPC_SMAC] = "smac",
[NPC_ETYPE] = "ether type", [NPC_ETYPE] = "ether type",
[NPC_VLAN_ETYPE_CTAG] = "vlan ether type ctag",
[NPC_VLAN_ETYPE_STAG] = "vlan ether type stag",
[NPC_OUTER_VID] = "outer vlan id", [NPC_OUTER_VID] = "outer vlan id",
[NPC_TOS] = "tos", [NPC_TOS] = "tos",
[NPC_SIP_IPV4] = "ipv4 source ip", [NPC_SIP_IPV4] = "ipv4 source ip",
...@@ -492,6 +494,11 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf) ...@@ -492,6 +494,11 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
if (*features & BIT_ULL(NPC_OUTER_VID)) if (*features & BIT_ULL(NPC_OUTER_VID))
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);
/* 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) |
BIT_ULL(NPC_VLAN_ETYPE_STAG);
} }
/* Scan key extraction profile and record how fields of our interest /* Scan key extraction profile and record how fields of our interest
...@@ -747,6 +754,28 @@ static void npc_update_ipv6_flow(struct rvu *rvu, struct mcam_entry *entry, ...@@ -747,6 +754,28 @@ static void npc_update_ipv6_flow(struct rvu *rvu, struct mcam_entry *entry,
} }
} }
static void npc_update_vlan_features(struct rvu *rvu, struct mcam_entry *entry,
u64 features, u8 intf)
{
bool ctag = !!(features & BIT_ULL(NPC_VLAN_ETYPE_CTAG));
bool stag = !!(features & BIT_ULL(NPC_VLAN_ETYPE_STAG));
bool vid = !!(features & BIT_ULL(NPC_OUTER_VID));
/* If only VLAN id is given then always match outer VLAN id */
if (vid && !ctag && !stag) {
npc_update_entry(rvu, NPC_LB, entry,
NPC_LT_LB_STAG_QINQ | NPC_LT_LB_CTAG, 0,
NPC_LT_LB_STAG_QINQ & NPC_LT_LB_CTAG, 0, intf);
return;
}
if (ctag)
npc_update_entry(rvu, NPC_LB, entry, NPC_LT_LB_CTAG, 0,
~0ULL, 0, intf);
if (stag)
npc_update_entry(rvu, NPC_LB, entry, NPC_LT_LB_STAG_QINQ, 0,
~0ULL, 0, intf);
}
static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry, static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,
u64 features, struct flow_msg *pkt, u64 features, struct flow_msg *pkt,
struct flow_msg *mask, struct flow_msg *mask,
...@@ -779,11 +808,6 @@ static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry, ...@@ -779,11 +808,6 @@ static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,
npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_ICMP6, npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_ICMP6,
0, ~0ULL, 0, intf); 0, ~0ULL, 0, intf);
if (features & BIT_ULL(NPC_OUTER_VID))
npc_update_entry(rvu, NPC_LB, entry,
NPC_LT_LB_STAG_QINQ | NPC_LT_LB_CTAG, 0,
NPC_LT_LB_STAG_QINQ & NPC_LT_LB_CTAG, 0, intf);
/* For AH, LTYPE should be present in entry */ /* For AH, LTYPE should be present in entry */
if (features & BIT_ULL(NPC_IPPROTO_AH)) if (features & BIT_ULL(NPC_IPPROTO_AH))
npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_AH, npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_AH,
...@@ -829,6 +853,7 @@ do { \ ...@@ -829,6 +853,7 @@ do { \
ntohs(mask->vlan_tci), 0); ntohs(mask->vlan_tci), 0);
npc_update_ipv6_flow(rvu, entry, features, pkt, mask, output, intf); npc_update_ipv6_flow(rvu, entry, features, pkt, mask, output, intf);
npc_update_vlan_features(rvu, entry, features, intf);
} }
static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam, static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam,
......
...@@ -835,8 +835,6 @@ int otx2_get_all_flows(struct otx2_nic *pfvf, ...@@ -835,8 +835,6 @@ int otx2_get_all_flows(struct otx2_nic *pfvf,
int otx2_add_flow(struct otx2_nic *pfvf, int otx2_add_flow(struct otx2_nic *pfvf,
struct ethtool_rxnfc *nfc); struct ethtool_rxnfc *nfc);
int otx2_remove_flow(struct otx2_nic *pfvf, u32 location); int otx2_remove_flow(struct otx2_nic *pfvf, u32 location);
int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
struct npc_install_flow_req *req);
int otx2_get_maxflows(struct otx2_flow_config *flow_cfg); int otx2_get_maxflows(struct otx2_flow_config *flow_cfg);
void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id); void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id);
int otx2_del_macfilter(struct net_device *netdev, const u8 *mac); int otx2_del_macfilter(struct net_device *netdev, const u8 *mac);
......
...@@ -763,7 +763,7 @@ static int otx2_prepare_ipv6_flow(struct ethtool_rx_flow_spec *fsp, ...@@ -763,7 +763,7 @@ static int otx2_prepare_ipv6_flow(struct ethtool_rx_flow_spec *fsp,
return 0; return 0;
} }
int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
struct npc_install_flow_req *req) struct npc_install_flow_req *req)
{ {
struct ethhdr *eth_mask = &fsp->m_u.ether_spec; struct ethhdr *eth_mask = &fsp->m_u.ether_spec;
...@@ -819,8 +819,30 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, ...@@ -819,8 +819,30 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (fsp->flow_type & FLOW_EXT) { if (fsp->flow_type & FLOW_EXT) {
if (fsp->m_ext.vlan_etype) u16 vlan_etype;
return -EINVAL;
if (fsp->m_ext.vlan_etype) {
/* Partial masks not supported */
if (be16_to_cpu(fsp->m_ext.vlan_etype) != 0xFFFF)
return -EINVAL;
vlan_etype = be16_to_cpu(fsp->h_ext.vlan_etype);
/* Only ETH_P_8021Q and ETH_P_802AD types supported */
if (vlan_etype != ETH_P_8021Q &&
vlan_etype != ETH_P_8021AD)
return -EINVAL;
memcpy(&pkt->vlan_etype, &fsp->h_ext.vlan_etype,
sizeof(pkt->vlan_etype));
memcpy(&pmask->vlan_etype, &fsp->m_ext.vlan_etype,
sizeof(pmask->vlan_etype));
if (vlan_etype == ETH_P_8021Q)
req->features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG);
else
req->features |= BIT_ULL(NPC_VLAN_ETYPE_STAG);
}
if (fsp->m_ext.vlan_tci) { if (fsp->m_ext.vlan_tci) {
memcpy(&pkt->vlan_tci, &fsp->h_ext.vlan_tci, memcpy(&pkt->vlan_tci, &fsp->h_ext.vlan_tci,
sizeof(pkt->vlan_tci)); sizeof(pkt->vlan_tci));
...@@ -996,6 +1018,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) ...@@ -996,6 +1018,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
if (!flow) if (!flow)
return -ENOMEM; return -ENOMEM;
flow->location = fsp->location; flow->location = fsp->location;
flow->entry = flow_cfg->flow_ent[flow->location];
new = true; new = true;
} }
/* struct copy */ /* struct copy */
...@@ -1047,7 +1070,6 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) ...@@ -1047,7 +1070,6 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
flow_cfg->max_flows - 1); flow_cfg->max_flows - 1);
err = -EINVAL; err = -EINVAL;
} else { } else {
flow->entry = flow_cfg->flow_ent[flow->location];
err = otx2_add_flow_msg(pfvf, flow); err = otx2_add_flow_msg(pfvf, flow);
} }
} }
......
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