#include <rte_ether.h>
#include <rte_ethdev_driver.h>
#include <rte_malloc.h>
+#include <rte_tailq.h>
#include "ice_ethdev.h"
#include "ice_generic_flow.h"
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint64_t input_set = ICE_INSET_NONE;
- bool outer_ip = true;
- bool outer_l4 = true;
+ bool is_tunnel = false;
for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
if (item->last) {
ipv4_spec = item->spec;
ipv4_mask = item->mask;
- if (!(ipv4_spec && ipv4_mask)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item,
- "Invalid IPv4 spec or mask.");
- return 0;
- }
+ if (!(ipv4_spec && ipv4_mask))
+ break;
/* Check IPv4 mask and update input set */
if (ipv4_mask->hdr.version_ihl ||
return 0;
}
- if (outer_ip) {
+ if (is_tunnel) {
if (ipv4_mask->hdr.src_addr == UINT32_MAX)
- input_set |= ICE_INSET_IPV4_SRC;
+ input_set |= ICE_INSET_TUN_IPV4_SRC;
if (ipv4_mask->hdr.dst_addr == UINT32_MAX)
- input_set |= ICE_INSET_IPV4_DST;
- if (ipv4_mask->hdr.type_of_service == UINT8_MAX)
- input_set |= ICE_INSET_IPV4_TOS;
+ input_set |= ICE_INSET_TUN_IPV4_DST;
if (ipv4_mask->hdr.time_to_live == UINT8_MAX)
- input_set |= ICE_INSET_IPV4_TTL;
+ input_set |= ICE_INSET_TUN_IPV4_TTL;
if (ipv4_mask->hdr.next_proto_id == UINT8_MAX)
- input_set |= ICE_INSET_IPV4_PROTO;
- outer_ip = false;
+ input_set |= ICE_INSET_TUN_IPV4_PROTO;
} else {
if (ipv4_mask->hdr.src_addr == UINT32_MAX)
- input_set |= ICE_INSET_TUN_IPV4_SRC;
+ input_set |= ICE_INSET_IPV4_SRC;
if (ipv4_mask->hdr.dst_addr == UINT32_MAX)
- input_set |= ICE_INSET_TUN_IPV4_DST;
+ input_set |= ICE_INSET_IPV4_DST;
if (ipv4_mask->hdr.time_to_live == UINT8_MAX)
- input_set |= ICE_INSET_TUN_IPV4_TTL;
+ input_set |= ICE_INSET_IPV4_TTL;
if (ipv4_mask->hdr.next_proto_id == UINT8_MAX)
- input_set |= ICE_INSET_TUN_IPV4_PROTO;
+ input_set |= ICE_INSET_IPV4_PROTO;
+ if (ipv4_mask->hdr.type_of_service == UINT8_MAX)
+ input_set |= ICE_INSET_IPV4_TOS;
}
break;
case RTE_FLOW_ITEM_TYPE_IPV6:
ipv6_spec = item->spec;
ipv6_mask = item->mask;
- if (!(ipv6_spec && ipv6_mask)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item, "Invalid IPv6 spec or mask");
- return 0;
- }
+ if (!(ipv6_spec && ipv6_mask))
+ break;
- if (ipv6_mask->hdr.payload_len ||
- ipv6_mask->hdr.vtc_flow) {
+ if (ipv6_mask->hdr.payload_len) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM,
item,
return 0;
}
- if (outer_ip) {
+ if (is_tunnel) {
if (!memcmp(ipv6_mask->hdr.src_addr,
ipv6_addr_mask,
RTE_DIM(ipv6_mask->hdr.src_addr)))
- input_set |= ICE_INSET_IPV6_SRC;
+ input_set |= ICE_INSET_TUN_IPV6_SRC;
if (!memcmp(ipv6_mask->hdr.dst_addr,
ipv6_addr_mask,
RTE_DIM(ipv6_mask->hdr.dst_addr)))
- input_set |= ICE_INSET_IPV6_DST;
+ input_set |= ICE_INSET_TUN_IPV6_DST;
if (ipv6_mask->hdr.proto == UINT8_MAX)
- input_set |= ICE_INSET_IPV6_PROTO;
+ input_set |= ICE_INSET_TUN_IPV6_PROTO;
if (ipv6_mask->hdr.hop_limits == UINT8_MAX)
- input_set |= ICE_INSET_IPV6_HOP_LIMIT;
- outer_ip = false;
+ input_set |= ICE_INSET_TUN_IPV6_TTL;
} else {
if (!memcmp(ipv6_mask->hdr.src_addr,
ipv6_addr_mask,
RTE_DIM(ipv6_mask->hdr.src_addr)))
- input_set |= ICE_INSET_TUN_IPV6_SRC;
+ input_set |= ICE_INSET_IPV6_SRC;
if (!memcmp(ipv6_mask->hdr.dst_addr,
ipv6_addr_mask,
RTE_DIM(ipv6_mask->hdr.dst_addr)))
- input_set |= ICE_INSET_TUN_IPV6_DST;
+ input_set |= ICE_INSET_IPV6_DST;
if (ipv6_mask->hdr.proto == UINT8_MAX)
- input_set |= ICE_INSET_TUN_IPV6_PROTO;
+ input_set |= ICE_INSET_IPV6_PROTO;
if (ipv6_mask->hdr.hop_limits == UINT8_MAX)
- input_set |= ICE_INSET_TUN_IPV6_TTL;
+ input_set |= ICE_INSET_IPV6_HOP_LIMIT;
+ if ((ipv6_mask->hdr.vtc_flow &
+ rte_cpu_to_be_32(RTE_IPV6_HDR_TC_MASK))
+ == rte_cpu_to_be_32
+ (RTE_IPV6_HDR_TC_MASK))
+ input_set |= ICE_INSET_IPV6_TOS;
}
break;
udp_spec = item->spec;
udp_mask = item->mask;
- if (!(udp_spec && udp_mask)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item, "Invalid UDP mask");
- return 0;
- }
+ if (!(udp_spec && udp_mask))
+ break;
/* Check UDP mask and update input set*/
if (udp_mask->hdr.dgram_len ||
return 0;
}
- if (outer_l4) {
+ if (is_tunnel) {
if (udp_mask->hdr.src_port == UINT16_MAX)
- input_set |= ICE_INSET_SRC_PORT;
+ input_set |= ICE_INSET_TUN_SRC_PORT;
if (udp_mask->hdr.dst_port == UINT16_MAX)
- input_set |= ICE_INSET_DST_PORT;
- outer_l4 = false;
+ input_set |= ICE_INSET_TUN_DST_PORT;
} else {
if (udp_mask->hdr.src_port == UINT16_MAX)
- input_set |= ICE_INSET_TUN_SRC_PORT;
+ input_set |= ICE_INSET_SRC_PORT;
if (udp_mask->hdr.dst_port == UINT16_MAX)
- input_set |= ICE_INSET_TUN_DST_PORT;
+ input_set |= ICE_INSET_DST_PORT;
}
break;
tcp_spec = item->spec;
tcp_mask = item->mask;
- if (!(tcp_spec && tcp_mask)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item, "Invalid TCP mask");
- return 0;
- }
+ if (!(tcp_spec && tcp_mask))
+ break;
/* Check TCP mask and update input set */
if (tcp_mask->hdr.sent_seq ||
return 0;
}
- if (outer_l4) {
+ if (is_tunnel) {
if (tcp_mask->hdr.src_port == UINT16_MAX)
- input_set |= ICE_INSET_SRC_PORT;
+ input_set |= ICE_INSET_TUN_SRC_PORT;
if (tcp_mask->hdr.dst_port == UINT16_MAX)
- input_set |= ICE_INSET_DST_PORT;
- outer_l4 = false;
+ input_set |= ICE_INSET_TUN_DST_PORT;
} else {
if (tcp_mask->hdr.src_port == UINT16_MAX)
- input_set |= ICE_INSET_TUN_SRC_PORT;
+ input_set |= ICE_INSET_SRC_PORT;
if (tcp_mask->hdr.dst_port == UINT16_MAX)
- input_set |= ICE_INSET_TUN_DST_PORT;
+ input_set |= ICE_INSET_DST_PORT;
}
break;
sctp_spec = item->spec;
sctp_mask = item->mask;
- if (!(sctp_spec && sctp_mask)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- item, "Invalid SCTP mask");
- return 0;
- }
+ if (!(sctp_spec && sctp_mask))
+ break;
/* Check SCTP mask and update input set */
if (sctp_mask->hdr.cksum) {
return 0;
}
- if (outer_l4) {
+ if (is_tunnel) {
if (sctp_mask->hdr.src_port == UINT16_MAX)
- input_set |= ICE_INSET_SRC_PORT;
+ input_set |= ICE_INSET_TUN_SRC_PORT;
if (sctp_mask->hdr.dst_port == UINT16_MAX)
- input_set |= ICE_INSET_DST_PORT;
- outer_l4 = false;
+ input_set |= ICE_INSET_TUN_DST_PORT;
} else {
if (sctp_mask->hdr.src_port == UINT16_MAX)
- input_set |= ICE_INSET_TUN_SRC_PORT;
+ input_set |= ICE_INSET_SRC_PORT;
if (sctp_mask->hdr.dst_port == UINT16_MAX)
- input_set |= ICE_INSET_TUN_DST_PORT;
+ input_set |= ICE_INSET_DST_PORT;
}
break;
"Invalid VXLAN item");
return 0;
}
+ if (vxlan_mask && vxlan_mask->vni[0] == UINT8_MAX &&
+ vxlan_mask->vni[1] == UINT8_MAX &&
+ vxlan_mask->vni[2] == UINT8_MAX)
+ input_set |= ICE_INSET_TUN_ID;
+ is_tunnel = 1;
break;
case RTE_FLOW_ITEM_TYPE_NVGRE:
nvgre_spec = item->spec;
nvgre_mask = item->mask;
- /* Check if VXLAN item is used to describe protocol.
+ /* Check if NVGRE item is used to describe protocol.
* If yes, both spec and mask should be NULL.
* If no, both spec and mask shouldn't be NULL.
*/
"Invalid NVGRE item");
return 0;
}
+ if (nvgre_mask && nvgre_mask->tni[0] == UINT8_MAX &&
+ nvgre_mask->tni[1] == UINT8_MAX &&
+ nvgre_mask->tni[2] == UINT8_MAX)
+ input_set |= ICE_INSET_TUN_ID;
+ is_tunnel = 1;
+ break;
+ case RTE_FLOW_ITEM_TYPE_VOID:
break;
default:
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM,
item,
- "Invalid mask no exist");
+ "Invalid pattern");
break;
}
}
{
const struct rte_flow_action_queue *act_q;
uint16_t queue;
-
- switch (actions->type) {
- case RTE_FLOW_ACTION_TYPE_QUEUE:
- act_q = actions->conf;
- queue = act_q->index;
- if (queue >= dev->data->nb_rx_queues) {
+ const struct rte_flow_action *action;
+ for (action = actions; action->type !=
+ RTE_FLOW_ACTION_TYPE_END; action++) {
+ switch (action->type) {
+ case RTE_FLOW_ACTION_TYPE_QUEUE:
+ act_q = action->conf;
+ queue = act_q->index;
+ if (queue >= dev->data->nb_rx_queues) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ actions, "Invalid queue ID for"
+ " switch filter.");
+ return -rte_errno;
+ }
+ break;
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ case RTE_FLOW_ACTION_TYPE_VOID:
+ break;
+ default:
rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- actions, "Invalid queue ID for"
- " ethertype_filter.");
+ RTE_FLOW_ERROR_TYPE_ACTION, actions,
+ "Invalid action.");
return -rte_errno;
}
- break;
- case RTE_FLOW_ACTION_TYPE_DROP:
- break;
- default:
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, actions,
- "Invalid action.");
- return -rte_errno;
}
-
return 0;
}
}
ret = ice_flow_valid_attr(attr, error);
- if (!ret)
+ if (ret)
return ret;
inset = ice_flow_valid_pattern(pattern, error);
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct rte_flow *p_flow;
+ void *temp;
int ret = 0;
- TAILQ_FOREACH(p_flow, &pf->flow_list, node) {
+ TAILQ_FOREACH_SAFE(p_flow, &pf->flow_list, node, temp) {
ret = ice_flow_destroy(dev, p_flow, error);
if (ret) {
rte_flow_error_set(error, -ret,