common/cnxk: support extensions attributes in IPv6 item
Support matching existence of specific extension headers after RTE_FLOW_ITEM_TYPE_IPV6 item. Signed-off-by: Satheesh Paul <psatheesh@marvell.com> Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
This commit is contained in:
parent
b8ac8b089c
commit
474e275b1b
@ -320,6 +320,23 @@ enum npc_kpu_lc_uflag {
|
||||
NPC_F_LC_U_IP6_FRAG = 0x40,
|
||||
};
|
||||
|
||||
enum npc_kpu_lc_lflag {
|
||||
NPC_F_LC_L_IP_IN_IP = 1,
|
||||
NPC_F_LC_L_6TO4,
|
||||
NPC_F_LC_L_MPLS_IN_IP,
|
||||
NPC_F_LC_L_IP6_TUN_IP6,
|
||||
NPC_F_LC_L_IP6_MPLS_IN_IP,
|
||||
NPC_F_LC_L_MPLS_4_LABELS,
|
||||
NPC_F_LC_L_MPLS_3_LABELS,
|
||||
NPC_F_LC_L_MPLS_2_LABELS,
|
||||
NPC_F_LC_L_EXT_HOP,
|
||||
NPC_F_LC_L_EXT_DEST,
|
||||
NPC_F_LC_L_EXT_ROUT,
|
||||
NPC_F_LC_L_EXT_MOBILITY,
|
||||
NPC_F_LC_L_EXT_HOSTID,
|
||||
NPC_F_LC_L_EXT_SHIM6,
|
||||
};
|
||||
|
||||
/* Structures definitions */
|
||||
struct npc_kpu_profile_cam {
|
||||
uint8_t state;
|
||||
|
@ -112,6 +112,39 @@ struct roc_npc_flow_item_vlan {
|
||||
uint32_t reserved : 31; /**< Reserved, must be zero. */
|
||||
};
|
||||
|
||||
struct roc_ipv6_hdr {
|
||||
uint32_t vtc_flow; /**< IP version, traffic class & flow label. */
|
||||
uint16_t payload_len; /**< IP payload size, including ext. headers */
|
||||
uint8_t proto; /**< Protocol, next header. */
|
||||
uint8_t hop_limits; /**< Hop limits. */
|
||||
uint8_t src_addr[16]; /**< IP address of source host. */
|
||||
uint8_t dst_addr[16]; /**< IP address of destination host(s). */
|
||||
} __plt_packed;
|
||||
|
||||
struct roc_npc_flow_item_ipv6 {
|
||||
struct roc_ipv6_hdr hdr; /**< IPv6 header definition. */
|
||||
uint32_t has_hop_ext : 1;
|
||||
/**< Header contains Hop-by-Hop Options extension header. */
|
||||
uint32_t has_route_ext : 1;
|
||||
/**< Header contains Routing extension header. */
|
||||
uint32_t has_frag_ext : 1;
|
||||
/**< Header contains Fragment extension header. */
|
||||
uint32_t has_auth_ext : 1;
|
||||
/**< Header contains Authentication extension header. */
|
||||
uint32_t has_esp_ext : 1;
|
||||
/**< Header contains Encapsulation Security Payload extension header. */
|
||||
uint32_t has_dest_ext : 1;
|
||||
/**< Header contains Destination Options extension header. */
|
||||
uint32_t has_mobil_ext : 1;
|
||||
/**< Header contains Mobility extension header. */
|
||||
uint32_t has_hip_ext : 1;
|
||||
/**< Header contains Host Identity Protocol extension header. */
|
||||
uint32_t has_shim6_ext : 1;
|
||||
/**< Header contains Shim6 Protocol extension header. */
|
||||
uint32_t reserved : 23;
|
||||
/**< Reserved for future extension headers, must be zero. */
|
||||
};
|
||||
|
||||
#define ROC_NPC_MAX_ACTION_COUNT 19
|
||||
|
||||
enum roc_npc_action_type {
|
||||
|
@ -635,6 +635,46 @@ npc_set_vlan_ltype(struct npc_parse_state *pst)
|
||||
pst->flow->mcam_mask[0] |= (0xeULL << lb_offset);
|
||||
}
|
||||
|
||||
static void
|
||||
npc_set_ipv6ext_ltype_mask(struct npc_parse_state *pst)
|
||||
{
|
||||
uint8_t lc_offset, lcflag_offset;
|
||||
uint64_t val, mask;
|
||||
|
||||
lc_offset =
|
||||
__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
|
||||
((1ULL << NPC_LTYPE_LC_OFFSET) - 1));
|
||||
lc_offset *= 4;
|
||||
|
||||
mask = ~((0xfULL << lc_offset));
|
||||
pst->flow->mcam_data[0] &= mask;
|
||||
pst->flow->mcam_mask[0] &= mask;
|
||||
/* NPC_LT_LC_IP6: 0b0100, NPC_LT_LC_IP6_EXT: 0b0101
|
||||
* Set LC layertype/mask as 0b0100/0b1110 to match both.
|
||||
*/
|
||||
val = ((uint64_t)(NPC_LT_LC_IP6 & NPC_LT_LC_IP6_EXT)) << lc_offset;
|
||||
pst->flow->mcam_data[0] |= val;
|
||||
pst->flow->mcam_mask[0] |= (0xeULL << lc_offset);
|
||||
|
||||
/* If LC LFLAG is non-zero, set the LC LFLAG mask to 0xF. In general
|
||||
* case flag mask is set same as the value in data. For example, to
|
||||
* match 3 VLANs, flags have to match a range of values. But, for IPv6
|
||||
* extended attributes matching, we need an exact match. Hence, set the
|
||||
* mask as 0xF. This is done only if LC LFLAG value is non-zero,
|
||||
* because for AH and ESP, LC LFLAG is zero and we don't want to match
|
||||
* zero in LFLAG.
|
||||
*/
|
||||
lcflag_offset =
|
||||
__builtin_popcount(pst->npc->keyx_supp_nmask[pst->nix_intf] &
|
||||
((1ULL << NPC_LFLAG_LC_OFFSET) - 1));
|
||||
lcflag_offset *= 4;
|
||||
|
||||
mask = (0xfULL << lcflag_offset);
|
||||
val = pst->flow->mcam_data[0] & mask;
|
||||
if (val)
|
||||
pst->flow->mcam_mask[0] |= mask;
|
||||
}
|
||||
|
||||
int
|
||||
npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
|
||||
{
|
||||
@ -709,6 +749,9 @@ npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alloc)
|
||||
if (pst->set_vlan_ltype_mask)
|
||||
npc_set_vlan_ltype(pst);
|
||||
|
||||
if (pst->set_ipv6ext_ltype_mask)
|
||||
npc_set_ipv6ext_ltype_mask(pst);
|
||||
|
||||
if (pst->is_vf) {
|
||||
(void)mbox_alloc_msg_npc_read_base_steer_rule(npc->mbox);
|
||||
rc = mbox_process_msg(npc->mbox, (void *)&base_rule_rsp);
|
||||
|
@ -480,16 +480,69 @@ npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
|
||||
pst->tunnel = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
npc_handle_ipv6ext_attr(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
|
||||
struct npc_parse_state *pst, uint8_t *flags)
|
||||
{
|
||||
int flags_count = 0;
|
||||
|
||||
if (ipv6_spec->has_hop_ext) {
|
||||
*flags = NPC_F_LC_L_EXT_HOP;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_route_ext) {
|
||||
*flags = NPC_F_LC_L_EXT_ROUT;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_frag_ext) {
|
||||
*flags = NPC_F_LC_U_IP6_FRAG;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_dest_ext) {
|
||||
*flags = NPC_F_LC_L_EXT_DEST;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_mobil_ext) {
|
||||
*flags = NPC_F_LC_L_EXT_MOBILITY;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_hip_ext) {
|
||||
*flags = NPC_F_LC_L_EXT_HOSTID;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_shim6_ext) {
|
||||
*flags = NPC_F_LC_L_EXT_SHIM6;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_auth_ext) {
|
||||
pst->lt[NPC_LID_LD] = NPC_LT_LD_AH;
|
||||
flags_count++;
|
||||
}
|
||||
if (ipv6_spec->has_esp_ext) {
|
||||
pst->lt[NPC_LID_LE] = NPC_LT_LE_ESP;
|
||||
flags_count++;
|
||||
}
|
||||
|
||||
if (flags_count > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags_count)
|
||||
pst->set_ipv6ext_ltype_mask = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npc_parse_lc(struct npc_parse_state *pst)
|
||||
{
|
||||
const struct roc_npc_flow_item_ipv6 *ipv6_spec;
|
||||
const struct roc_npc_flow_item_raw *raw_spec;
|
||||
uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
|
||||
uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
|
||||
uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
|
||||
struct npc_parse_item_info info;
|
||||
int lid, lt, len = 0;
|
||||
int rc;
|
||||
int rc, lid, lt, len = 0;
|
||||
uint8_t flags = 0;
|
||||
|
||||
if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
|
||||
return npc_parse_mpls(pst, NPC_LID_LC);
|
||||
@ -506,9 +559,13 @@ npc_parse_lc(struct npc_parse_state *pst)
|
||||
info.len = pst->pattern->size;
|
||||
break;
|
||||
case ROC_NPC_ITEM_TYPE_IPV6:
|
||||
ipv6_spec = pst->pattern->spec;
|
||||
lid = NPC_LID_LC;
|
||||
lt = NPC_LT_LC_IP6;
|
||||
info.len = pst->pattern->size;
|
||||
rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags);
|
||||
if (rc)
|
||||
return rc;
|
||||
info.len = sizeof(ipv6_spec->hdr);
|
||||
break;
|
||||
case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
|
||||
lt = NPC_LT_LC_ARP;
|
||||
@ -558,7 +615,7 @@ npc_parse_lc(struct npc_parse_state *pst)
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
return npc_update_parse_state(pst, &info, lid, lt, 0);
|
||||
return npc_update_parse_state(pst, &info, lid, lt, flags);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -71,6 +71,11 @@
|
||||
/* LB OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags) */
|
||||
#define NPC_LTYPE_LB_OFFSET (NPC_LTYPE_OFFSET_START + 5)
|
||||
#define NPC_LFLAG_LB_OFFSET (NPC_LTYPE_OFFSET_START + 3)
|
||||
/* LC OFFSET : START + LA (2b flags + 1b ltype) + LB (2b flags + 1b ltype) + LC
|
||||
* (2b flags)
|
||||
*/
|
||||
#define NPC_LFLAG_LC_OFFSET (NPC_LTYPE_OFFSET_START + 6)
|
||||
#define NPC_LTYPE_LC_OFFSET (NPC_LTYPE_OFFSET_START + 8)
|
||||
|
||||
struct npc_action_vtag_info {
|
||||
uint16_t vlan_id;
|
||||
@ -183,6 +188,7 @@ struct npc_parse_state {
|
||||
bool is_vf;
|
||||
/* adjust ltype in MCAM to match at least one vlan */
|
||||
bool set_vlan_ltype_mask;
|
||||
bool set_ipv6ext_ltype_mask;
|
||||
};
|
||||
|
||||
enum npc_kpu_parser_flag {
|
||||
|
Loading…
Reference in New Issue
Block a user