#include "iavf.h"
#include "iavf_generic_flow.h"
#include "virtchnl.h"
+#include "iavf_rxtx.h"
#define IAVF_FDIR_MAX_QREGION_SIZE 128
IAVF_INSET_IPV6_TC | IAVF_INSET_IPV6_HOP_LIMIT | \
IAVF_INSET_SCTP_SRC_PORT | IAVF_INSET_SCTP_DST_PORT)
-#define IAVF_FDIR_INSET_GTPU (\
+#define IAVF_FDIR_INSET_IPV4_GTPU (\
IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
IAVF_INSET_GTPU_TEID)
-#define IAVF_FDIR_INSET_GTPU_EH (\
+#define IAVF_FDIR_INSET_IPV4_GTPU_EH (\
IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
IAVF_INSET_GTPU_TEID | IAVF_INSET_GTPU_QFI)
+#define IAVF_FDIR_INSET_IPV6_GTPU (\
+ IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
+ IAVF_INSET_GTPU_TEID)
+
+#define IAVF_FDIR_INSET_IPV6_GTPU_EH (\
+ IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
+ IAVF_INSET_GTPU_TEID | IAVF_INSET_GTPU_QFI)
+
#define IAVF_FDIR_INSET_L2TPV3OIP (\
IAVF_L2TPV3OIP_SESSION_ID)
{iavf_pattern_eth_ipv6_udp, IAVF_FDIR_INSET_ETH_IPV6_UDP, IAVF_INSET_NONE},
{iavf_pattern_eth_ipv6_tcp, IAVF_FDIR_INSET_ETH_IPV6_TCP, IAVF_INSET_NONE},
{iavf_pattern_eth_ipv6_sctp, IAVF_FDIR_INSET_ETH_IPV6_SCTP, IAVF_INSET_NONE},
- {iavf_pattern_eth_ipv4_gtpu, IAVF_FDIR_INSET_GTPU, IAVF_INSET_NONE},
- {iavf_pattern_eth_ipv4_gtpu_eh, IAVF_FDIR_INSET_GTPU_EH, IAVF_INSET_NONE},
+ {iavf_pattern_eth_ipv4_gtpu, IAVF_FDIR_INSET_IPV4_GTPU, IAVF_INSET_NONE},
+ {iavf_pattern_eth_ipv4_gtpu_eh, IAVF_FDIR_INSET_IPV4_GTPU_EH, IAVF_INSET_NONE},
+ {iavf_pattern_eth_ipv6_gtpu, IAVF_FDIR_INSET_IPV6_GTPU, IAVF_INSET_NONE},
+ {iavf_pattern_eth_ipv6_gtpu_eh, IAVF_FDIR_INSET_IPV6_GTPU_EH, IAVF_INSET_NONE},
{iavf_pattern_eth_ipv4_l2tpv3, IAVF_FDIR_INSET_L2TPV3OIP, IAVF_INSET_NONE},
{iavf_pattern_eth_ipv6_l2tpv3, IAVF_FDIR_INSET_L2TPV3OIP, IAVF_INSET_NONE},
{iavf_pattern_eth_ipv4_esp, IAVF_FDIR_INSET_ESP, IAVF_INSET_NONE},
goto free_entry;
}
+ if (filter->mark_flag == 1)
+ iavf_fdir_rx_proc_enable(ad, 1);
+
rte_memcpy(rule, filter, sizeof(*rule));
flow->rule = rule;
return -rte_errno;
}
+ if (filter->mark_flag == 1)
+ iavf_fdir_rx_proc_enable(ad, 0);
+
flow->rule = NULL;
rte_free(filter);
struct iavf_fdir_conf *filter)
{
const struct rte_flow_action_queue *act_q;
+ const struct rte_flow_action_mark *mark_spec = NULL;
uint32_t dest_num = 0;
+ uint32_t mark_num = 0;
int ret;
int number = 0;
filter->add_fltr.rule_cfg.action_set.count = ++number;
break;
+ case RTE_FLOW_ACTION_TYPE_MARK:
+ mark_num++;
+
+ filter->mark_flag = 1;
+ mark_spec = actions->conf;
+ filter_action = &filter->add_fltr.rule_cfg.action_set.actions[number];
+
+ filter_action->type = VIRTCHNL_ACTION_MARK;
+ filter_action->act_conf.mark_id = mark_spec->id;
+
+ filter->add_fltr.rule_cfg.action_set.count = ++number;
+ break;
+
default:
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, actions,
return -rte_errno;
}
- if (dest_num == 0 || dest_num >= 2) {
+ if (dest_num >= 2) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, actions,
"Unsupported action combination");
return -rte_errno;
}
+ if (mark_num >= 2) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, actions,
+ "Too many mark actions");
+ return -rte_errno;
+ }
+
+ if (dest_num + mark_num == 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, actions,
+ "Empty action");
+ return -rte_errno;
+ }
+
+ /* Mark only is equal to mark + passthru. */
+ if (dest_num == 0) {
+ filter_action = &filter->add_fltr.rule_cfg.action_set.actions[number];
+ filter_action->type = VIRTCHNL_ACTION_PASSTHRU;
+ filter->add_fltr.rule_cfg.action_set.count = ++number;
+ }
+
return 0;
}