net/enic: flow API for NICs with advanced filters disabled
Flow support for 1300 series adapters with the 'Advanced Filter' mode disabled via the UCS management interface. This allows: Attributes: ingress Items: Outer eth, ipv4, ipv6, udp, sctp, tcp, vxlan. Inner eth, ipv4, ipv6, udp, tcp. Actions: queue and void Selectors: 'is', 'spec' and 'mask'. 'last' is not supported With advanced filters disabled, an IPv4 or IPv6 item must be specified in the pattern. Signed-off-by: John Daley <johndale@cisco.com> Reviewed-by: Nelson Escobar <neescoba@cisco.com>
This commit is contained in:
parent
2bbfbd48b7
commit
26faa126d8
@ -98,8 +98,85 @@ static enic_copy_item_fn enic_copy_item_tcp_v2;
|
||||
static enic_copy_item_fn enic_copy_item_sctp_v2;
|
||||
static enic_copy_item_fn enic_copy_item_sctp_v2;
|
||||
static enic_copy_item_fn enic_copy_item_vxlan_v2;
|
||||
static copy_action_fn enic_copy_action_v1;
|
||||
static copy_action_fn enic_copy_action_v2;
|
||||
|
||||
/**
|
||||
* NICs have Advanced Filters capability but they are disabled. This means
|
||||
* that layer 3 must be specified.
|
||||
*/
|
||||
static const struct enic_items enic_items_v2[] = {
|
||||
[RTE_FLOW_ITEM_TYPE_ETH] = {
|
||||
.copy_item = enic_copy_item_eth_v2,
|
||||
.valid_start_item = 1,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_VXLAN,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_VLAN] = {
|
||||
.copy_item = enic_copy_item_vlan_v2,
|
||||
.valid_start_item = 1,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_ETH,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_IPV4] = {
|
||||
.copy_item = enic_copy_item_ipv4_v2,
|
||||
.valid_start_item = 1,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_ETH,
|
||||
RTE_FLOW_ITEM_TYPE_VLAN,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_IPV6] = {
|
||||
.copy_item = enic_copy_item_ipv6_v2,
|
||||
.valid_start_item = 1,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_ETH,
|
||||
RTE_FLOW_ITEM_TYPE_VLAN,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_UDP] = {
|
||||
.copy_item = enic_copy_item_udp_v2,
|
||||
.valid_start_item = 0,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_IPV4,
|
||||
RTE_FLOW_ITEM_TYPE_IPV6,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_TCP] = {
|
||||
.copy_item = enic_copy_item_tcp_v2,
|
||||
.valid_start_item = 0,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_IPV4,
|
||||
RTE_FLOW_ITEM_TYPE_IPV6,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_SCTP] = {
|
||||
.copy_item = enic_copy_item_sctp_v2,
|
||||
.valid_start_item = 0,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_IPV4,
|
||||
RTE_FLOW_ITEM_TYPE_IPV6,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
[RTE_FLOW_ITEM_TYPE_VXLAN] = {
|
||||
.copy_item = enic_copy_item_vxlan_v2,
|
||||
.valid_start_item = 0,
|
||||
.prev_items = (const enum rte_flow_item_type[]) {
|
||||
RTE_FLOW_ITEM_TYPE_UDP,
|
||||
RTE_FLOW_ITEM_TYPE_END,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/** NICs with Advanced filters enabled */
|
||||
static const struct enic_items enic_items_v3[] = {
|
||||
[RTE_FLOW_ITEM_TYPE_ETH] = {
|
||||
@ -175,11 +252,20 @@ static const struct enic_items enic_items_v3[] = {
|
||||
|
||||
/** Filtering capabilities indexed this NICs supported filter type. */
|
||||
static const struct enic_filter_cap enic_filter_cap[] = {
|
||||
[FILTER_USNIC_IP] = {
|
||||
.item_info = enic_items_v2,
|
||||
},
|
||||
[FILTER_DPDK_1] = {
|
||||
.item_info = enic_items_v3,
|
||||
},
|
||||
};
|
||||
|
||||
/** Supported actions for older NICs */
|
||||
static const enum rte_flow_action_type enic_supported_actions_v1[] = {
|
||||
RTE_FLOW_ACTION_TYPE_QUEUE,
|
||||
RTE_FLOW_ACTION_TYPE_END,
|
||||
};
|
||||
|
||||
/** Supported actions for newer NICs */
|
||||
static const enum rte_flow_action_type enic_supported_actions_v2[] = {
|
||||
RTE_FLOW_ACTION_TYPE_QUEUE,
|
||||
@ -190,6 +276,10 @@ static const enum rte_flow_action_type enic_supported_actions_v2[] = {
|
||||
|
||||
/** Action capabilities indexed by NIC version information */
|
||||
static const struct enic_action_cap enic_action_cap[] = {
|
||||
[FILTER_ACTION_RQ_STEERING_FLAG] = {
|
||||
.actions = enic_supported_actions_v1,
|
||||
.copy_fn = enic_copy_action_v1,
|
||||
},
|
||||
[FILTER_ACTION_V2_ALL] = {
|
||||
.actions = enic_supported_actions_v2,
|
||||
.copy_fn = enic_copy_action_v2,
|
||||
@ -640,7 +730,6 @@ enic_copy_filter(const struct rte_flow_item pattern[],
|
||||
enum rte_flow_item_type prev_item;
|
||||
const struct enic_items *item_info;
|
||||
|
||||
enic_filter->type = FILTER_DPDK_1;
|
||||
u8 is_first_item = 1;
|
||||
|
||||
FLOW_TRACE();
|
||||
@ -678,6 +767,44 @@ enic_copy_filter(const struct rte_flow_item pattern[],
|
||||
item, "stacking error");
|
||||
return -rte_errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the intenal version 1 NIC action structure from the provided pattern.
|
||||
* The pattern is validated as the items are copied.
|
||||
*
|
||||
* @param actions[in]
|
||||
* @param enic_action[out]
|
||||
* NIC specfilc actions derived from the actions.
|
||||
* @param error[out]
|
||||
*/
|
||||
static int
|
||||
enic_copy_action_v1(const struct rte_flow_action actions[],
|
||||
struct filter_action_v2 *enic_action)
|
||||
{
|
||||
FLOW_TRACE();
|
||||
|
||||
for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
|
||||
if (actions->type == RTE_FLOW_ACTION_TYPE_VOID)
|
||||
continue;
|
||||
|
||||
switch (actions->type) {
|
||||
case RTE_FLOW_ACTION_TYPE_QUEUE: {
|
||||
const struct rte_flow_action_queue *queue =
|
||||
(const struct rte_flow_action_queue *)
|
||||
actions->conf;
|
||||
enic_action->rq_idx =
|
||||
enic_rte_rq_idx_to_sop_idx(queue->index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
RTE_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enic_action->type = FILTER_ACTION_RQ_STEERING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the intenal version 2 NIC action structure from the provided pattern.
|
||||
* The pattern is validated as the items are copied.
|
||||
@ -752,7 +879,8 @@ static const struct enic_filter_cap *
|
||||
enic_get_filter_cap(struct enic *enic)
|
||||
{
|
||||
/* FIXME: only support advanced filters for now */
|
||||
if (enic->flow_filter_mode != FILTER_DPDK_1)
|
||||
if ((enic->flow_filter_mode != FILTER_DPDK_1) &&
|
||||
(enic->flow_filter_mode != FILTER_USNIC_IP))
|
||||
return (const struct enic_filter_cap *)NULL;
|
||||
|
||||
if (enic->flow_filter_mode)
|
||||
@ -769,6 +897,8 @@ enic_get_action_cap(struct enic *enic)
|
||||
|
||||
if (enic->filter_tags)
|
||||
ea = &enic_action_cap[FILTER_ACTION_V2_ALL];
|
||||
else
|
||||
ea = &enic_action_cap[FILTER_ACTION_RQ_STEERING_FLAG];
|
||||
return ea;
|
||||
}
|
||||
/**
|
||||
@ -881,6 +1011,7 @@ enic_flow_parse(struct rte_eth_dev *dev,
|
||||
NULL, "Flow API not available");
|
||||
return -rte_errno;
|
||||
}
|
||||
enic_filter->type = enic->flow_filter_mode;
|
||||
ret = enic_copy_filter(pattern, enic_filter_cap->item_info,
|
||||
enic_filter, error);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user