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: Subbaraya Sundeep <sbhatta@marvell.com> Signed-off-by: Sunil Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c7cd6c5a46
Коммит
dce677da57
|
@ -169,6 +169,8 @@ enum key_fields {
|
|||
NPC_DMAC,
|
||||
NPC_SMAC,
|
||||
NPC_ETYPE,
|
||||
NPC_VLAN_ETYPE_CTAG, /* 0x8100 */
|
||||
NPC_VLAN_ETYPE_STAG, /* 0x88A8 */
|
||||
NPC_OUTER_VID,
|
||||
NPC_TOS,
|
||||
NPC_SIP_IPV4,
|
||||
|
|
|
@ -20,6 +20,8 @@ static const char * const npc_flow_names[] = {
|
|||
[NPC_DMAC] = "dmac",
|
||||
[NPC_SMAC] = "smac",
|
||||
[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_TOS] = "tos",
|
||||
[NPC_SIP_IPV4] = "ipv4 source ip",
|
||||
|
@ -492,6 +494,11 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
|
|||
if (*features & BIT_ULL(NPC_OUTER_VID))
|
||||
if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
|
||||
*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
|
||||
|
@ -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,
|
||||
u64 features, struct flow_msg *pkt,
|
||||
struct flow_msg *mask,
|
||||
|
@ -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,
|
||||
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 */
|
||||
if (features & BIT_ULL(NPC_IPPROTO_AH))
|
||||
npc_update_entry(rvu, NPC_LD, entry, NPC_LT_LD_AH,
|
||||
|
@ -829,6 +853,7 @@ do { \
|
|||
ntohs(mask->vlan_tci), 0);
|
||||
|
||||
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,
|
||||
|
|
|
@ -835,8 +835,6 @@ int otx2_get_all_flows(struct otx2_nic *pfvf,
|
|||
int otx2_add_flow(struct otx2_nic *pfvf,
|
||||
struct ethtool_rxnfc *nfc);
|
||||
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);
|
||||
void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id);
|
||||
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,
|
|||
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 ethhdr *eth_mask = &fsp->m_u.ether_spec;
|
||||
|
@ -819,8 +819,30 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (fsp->flow_type & FLOW_EXT) {
|
||||
if (fsp->m_ext.vlan_etype)
|
||||
return -EINVAL;
|
||||
u16 vlan_etype;
|
||||
|
||||
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) {
|
||||
memcpy(&pkt->vlan_tci, &fsp->h_ext.vlan_tci,
|
||||
sizeof(pkt->vlan_tci));
|
||||
|
@ -996,6 +1018,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
|||
if (!flow)
|
||||
return -ENOMEM;
|
||||
flow->location = fsp->location;
|
||||
flow->entry = flow_cfg->flow_ent[flow->location];
|
||||
new = true;
|
||||
}
|
||||
/* struct copy */
|
||||
|
@ -1047,7 +1070,6 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
|
|||
flow_cfg->max_flows - 1);
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
flow->entry = flow_cfg->flow_ent[flow->location];
|
||||
err = otx2_add_flow_msg(pfvf, flow);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче