aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/avf/avf_advanced_flow.h
diff options
context:
space:
mode:
authorChenmin Sun <chenmin.sun@intel.com>2020-11-19 23:13:30 +0800
committerDamjan Marion <dmarion@me.com>2021-03-26 08:30:54 +0000
commitffe9a5489499467dfb5a2ee0fed14e397f5f825c (patch)
tree317bc75b046ebe13f27a99b6929a706140a5183a /src/plugins/avf/avf_advanced_flow.h
parent89c98a4bff101ad4270724bde7ca6f21ba4c8482 (diff)
avf: add avf flow framework
This patch adds the flow support to VPP avf_plugin. Currently only IP4-N-TUPLE and GTPU flow are supported as a reference. More flows will be added later. Type: feature Signed-off-by: Chenmin Sun <chenmin.sun@intel.com> Change-Id: I563dbfacecd3eba31e8c3c7769142ea6adba54b6
Diffstat (limited to 'src/plugins/avf/avf_advanced_flow.h')
-rw-r--r--src/plugins/avf/avf_advanced_flow.h1068
1 files changed, 1068 insertions, 0 deletions
diff --git a/src/plugins/avf/avf_advanced_flow.h b/src/plugins/avf/avf_advanced_flow.h
new file mode 100644
index 00000000000..42288b7163b
--- /dev/null
+++ b/src/plugins/avf/avf_advanced_flow.h
@@ -0,0 +1,1068 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2020 Intel and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#ifndef _AVF_ADVANCED_FLOW_H_
+#define _AVF_ADVANCED_FLOW_H_
+
+#define AVF_SUCCESS (0)
+#define AVF_FAILURE (-1)
+
+#define BIT(a) (1UL << (a))
+#define BIT_ULL(a) (1ULL << (a))
+
+/* These macros are used to generate compilation errors if a structure/union
+ * is not exactly the correct length. It gives a divide by zero error if the
+ * structure/union is not of the correct size, otherwise it creates an enum
+ * that is never used.
+ */
+#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) \
+ enum virtchnl_static_assert_enum_##X \
+ { \
+ virtchnl_static_assert_##X = (n) / ((sizeof (struct X) == (n)) ? 1 : 0) \
+ }
+#define VIRTCHNL_CHECK_UNION_LEN(n, X) \
+ enum virtchnl_static_asset_enum_##X \
+ { \
+ virtchnl_static_assert_##X = (n) / ((sizeof (union X) == (n)) ? 1 : 0) \
+ }
+
+/* AVF ethernet frame types */
+#define AVF_ETHER_TYPE_IPV4 0x0800 /**< IPv4 Protocol. */
+#define AVF_ETHER_TYPE_IPV6 0x86DD /**< IPv6 Protocol. */
+
+#define VIRTCHNL_MAX_NUM_PROTO_HDRS 32
+#define PROTO_HDR_SHIFT 5
+#define PROTO_HDR_FIELD_START(proto_hdr_type) \
+ (proto_hdr_type << PROTO_HDR_SHIFT)
+#define PROTO_HDR_FIELD_MASK ((1UL << PROTO_HDR_SHIFT) - 1)
+
+/* VF use these macros to configure each protocol header.
+ * Specify which protocol headers and protocol header fields base on
+ * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field.
+ * @param hdr: a struct of virtchnl_proto_hdr
+ * @param hdr_type: ETH/IPV4/TCP, etc
+ * @param field: SRC/DST/TEID/SPI, etc
+ */
+#define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \
+ ((hdr)->field_selector |= BIT ((field) &PROTO_HDR_FIELD_MASK))
+#define VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \
+ ((hdr)->field_selector &= ~BIT ((field) &PROTO_HDR_FIELD_MASK))
+#define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \
+ ((hdr)->field_selector & BIT ((val) &PROTO_HDR_FIELD_MASK))
+#define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr) ((hdr)->field_selector)
+
+#define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
+ (VIRTCHNL_ADD_PROTO_HDR_FIELD (hdr, VIRTCHNL_PROTO_HDR_##hdr_type##_##field))
+#define VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
+ (VIRTCHNL_DEL_PROTO_HDR_FIELD (hdr, VIRTCHNL_PROTO_HDR_##hdr_type##_##field))
+
+#define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \
+ ((hdr)->type = VIRTCHNL_PROTO_HDR_##hdr_type)
+#define VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) (((hdr)->type) >> PROTO_HDR_SHIFT)
+#define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \
+ ((hdr)->type == ((val) >> PROTO_HDR_SHIFT))
+#define VIRTCHNL_TEST_PROTO_HDR(hdr, val) \
+ (VIRTCHNL_TEST_PROTO_HDR_TYPE (hdr, val) && \
+ VIRTCHNL_TEST_PROTO_HDR_FIELD (hdr, val))
+
+/* protocol */
+
+#define AVF_PROT_MAC_INNER (1ULL << 1)
+#define AVF_PROT_MAC_OUTER (1ULL << 2)
+#define AVF_PROT_VLAN_INNER (1ULL << 3)
+#define AVF_PROT_VLAN_OUTER (1ULL << 4)
+#define AVF_PROT_IPV4_INNER (1ULL << 5)
+#define AVF_PROT_IPV4_OUTER (1ULL << 6)
+#define AVF_PROT_IPV6_INNER (1ULL << 7)
+#define AVF_PROT_IPV6_OUTER (1ULL << 8)
+#define AVF_PROT_TCP_INNER (1ULL << 9)
+#define AVF_PROT_TCP_OUTER (1ULL << 10)
+#define AVF_PROT_UDP_INNER (1ULL << 11)
+#define AVF_PROT_UDP_OUTER (1ULL << 12)
+#define AVF_PROT_SCTP_INNER (1ULL << 13)
+#define AVF_PROT_SCTP_OUTER (1ULL << 14)
+#define AVF_PROT_ICMP4_INNER (1ULL << 15)
+#define AVF_PROT_ICMP4_OUTER (1ULL << 16)
+#define AVF_PROT_ICMP6_INNER (1ULL << 17)
+#define AVF_PROT_ICMP6_OUTER (1ULL << 18)
+#define AVF_PROT_VXLAN (1ULL << 19)
+#define AVF_PROT_NVGRE (1ULL << 20)
+#define AVF_PROT_GTPU (1ULL << 21)
+#define AVF_PROT_ESP (1ULL << 22)
+#define AVF_PROT_AH (1ULL << 23)
+#define AVF_PROT_L2TPV3OIP (1ULL << 24)
+#define AVF_PROT_PFCP (1ULL << 25)
+
+/* field */
+
+#define AVF_SMAC (1ULL << 63)
+#define AVF_DMAC (1ULL << 62)
+#define AVF_ETHERTYPE (1ULL << 61)
+#define AVF_IP_SRC (1ULL << 60)
+#define AVF_IP_DST (1ULL << 59)
+#define AVF_IP_PROTO (1ULL << 58)
+#define AVF_IP_TTL (1ULL << 57)
+#define AVF_IP_TOS (1ULL << 56)
+#define AVF_SPORT (1ULL << 55)
+#define AVF_DPORT (1ULL << 54)
+#define AVF_ICMP_TYPE (1ULL << 53)
+#define AVF_ICMP_CODE (1ULL << 52)
+#define AVF_VXLAN_VNI (1ULL << 51)
+#define AVF_NVGRE_TNI (1ULL << 50)
+#define AVF_GTPU_TEID (1ULL << 49)
+#define AVF_GTPU_QFI (1ULL << 48)
+#define AVF_ESP_SPI (1ULL << 47)
+#define AVF_AH_SPI (1ULL << 46)
+#define AVF_L2TPV3OIP_SESSION_ID (1ULL << 45)
+#define AVF_PFCP_S_FIELD (1ULL << 44)
+#define AVF_PFCP_SEID (1ULL << 43)
+
+/* input set */
+
+#define AVF_INSET_NONE 0ULL
+
+/* non-tunnel */
+
+#define AVF_INSET_SMAC (AVF_PROT_MAC_OUTER | AVF_SMAC)
+#define AVF_INSET_DMAC (AVF_PROT_MAC_OUTER | AVF_DMAC)
+#define AVF_INSET_VLAN_INNER (AVF_PROT_VLAN_INNER)
+#define AVF_INSET_VLAN_OUTER (AVF_PROT_VLAN_OUTER)
+#define AVF_INSET_ETHERTYPE (AVF_ETHERTYPE)
+
+#define AVF_INSET_IPV4_SRC (AVF_PROT_IPV4_OUTER | AVF_IP_SRC)
+#define AVF_INSET_IPV4_DST (AVF_PROT_IPV4_OUTER | AVF_IP_DST)
+#define AVF_INSET_IPV4_TOS (AVF_PROT_IPV4_OUTER | AVF_IP_TOS)
+#define AVF_INSET_IPV4_PROTO (AVF_PROT_IPV4_OUTER | AVF_IP_PROTO)
+#define AVF_INSET_IPV4_TTL (AVF_PROT_IPV4_OUTER | AVF_IP_TTL)
+#define AVF_INSET_IPV6_SRC (AVF_PROT_IPV6_OUTER | AVF_IP_SRC)
+#define AVF_INSET_IPV6_DST (AVF_PROT_IPV6_OUTER | AVF_IP_DST)
+#define AVF_INSET_IPV6_NEXT_HDR (AVF_PROT_IPV6_OUTER | AVF_IP_PROTO)
+#define AVF_INSET_IPV6_HOP_LIMIT (AVF_PROT_IPV6_OUTER | AVF_IP_TTL)
+#define AVF_INSET_IPV6_TC (AVF_PROT_IPV6_OUTER | AVF_IP_TOS)
+
+#define AVF_INSET_TCP_SRC_PORT (AVF_PROT_TCP_OUTER | AVF_SPORT)
+#define AVF_INSET_TCP_DST_PORT (AVF_PROT_TCP_OUTER | AVF_DPORT)
+#define AVF_INSET_UDP_SRC_PORT (AVF_PROT_UDP_OUTER | AVF_SPORT)
+#define AVF_INSET_UDP_DST_PORT (AVF_PROT_UDP_OUTER | AVF_DPORT)
+#define AVF_INSET_SCTP_SRC_PORT (AVF_PROT_SCTP_OUTER | AVF_SPORT)
+#define AVF_INSET_SCTP_DST_PORT (AVF_PROT_SCTP_OUTER | AVF_DPORT)
+#define AVF_INSET_ICMP4_SRC_PORT (AVF_PROT_ICMP4_OUTER | AVF_SPORT)
+#define AVF_INSET_ICMP4_DST_PORT (AVF_PROT_ICMP4_OUTER | AVF_DPORT)
+#define AVF_INSET_ICMP6_SRC_PORT (AVF_PROT_ICMP6_OUTER | AVF_SPORT)
+#define AVF_INSET_ICMP6_DST_PORT (AVF_PROT_ICMP6_OUTER | AVF_DPORT)
+#define AVF_INSET_ICMP4_TYPE (AVF_PROT_ICMP4_OUTER | AVF_ICMP_TYPE)
+#define AVF_INSET_ICMP4_CODE (AVF_PROT_ICMP4_OUTER | AVF_ICMP_CODE)
+#define AVF_INSET_ICMP6_TYPE (AVF_PROT_ICMP6_OUTER | AVF_ICMP_TYPE)
+#define AVF_INSET_ICMP6_CODE (AVF_PROT_ICMP6_OUTER | AVF_ICMP_CODE)
+#define AVF_INSET_GTPU_TEID (AVF_PROT_GTPU | AVF_GTPU_TEID)
+#define AVF_INSET_GTPU_QFI (AVF_PROT_GTPU | AVF_GTPU_QFI)
+#define AVF_INSET_ESP_SPI (AVF_PROT_ESP | AVF_ESP_SPI)
+#define AVF_INSET_AH_SPI (AVF_PROT_AH | AVF_AH_SPI)
+#define AVF_INSET_L2TPV3OIP_SESSION_ID \
+ (AVF_PROT_L2TPV3OIP | AVF_L2TPV3OIP_SESSION_ID)
+#define AVF_INSET_PFCP_S_FIELD (AVF_PROT_PFCP | AVF_PFCP_S_FIELD)
+#define AVF_INSET_PFCP_SEID (AVF_PROT_PFCP | AVF_PFCP_S_FIELD | AVF_PFCP_SEID)
+
+/* Protocol header type within a packet segment. A segment consists of one or
+ * more protocol headers that make up a logical group of protocol headers. Each
+ * logical group of protocol headers encapsulates or is encapsulated using/by
+ * tunneling or encapsulation protocols for network virtualization.
+ */
+enum virtchnl_proto_hdr_type
+{
+ VIRTCHNL_PROTO_HDR_NONE,
+ VIRTCHNL_PROTO_HDR_ETH,
+ VIRTCHNL_PROTO_HDR_S_VLAN,
+ VIRTCHNL_PROTO_HDR_C_VLAN,
+ VIRTCHNL_PROTO_HDR_IPV4,
+ VIRTCHNL_PROTO_HDR_IPV6,
+ VIRTCHNL_PROTO_HDR_TCP,
+ VIRTCHNL_PROTO_HDR_UDP,
+ VIRTCHNL_PROTO_HDR_SCTP,
+ VIRTCHNL_PROTO_HDR_GTPU_IP,
+ VIRTCHNL_PROTO_HDR_GTPU_EH,
+ VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
+ VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
+ VIRTCHNL_PROTO_HDR_PPPOE,
+ VIRTCHNL_PROTO_HDR_L2TPV3,
+ VIRTCHNL_PROTO_HDR_ESP,
+ VIRTCHNL_PROTO_HDR_AH,
+ VIRTCHNL_PROTO_HDR_PFCP,
+};
+
+/* Protocol header field within a protocol header. */
+enum virtchnl_proto_hdr_field
+{
+ /* ETHER */
+ VIRTCHNL_PROTO_HDR_ETH_SRC = PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_ETH),
+ VIRTCHNL_PROTO_HDR_ETH_DST,
+ VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE,
+ /* S-VLAN */
+ VIRTCHNL_PROTO_HDR_S_VLAN_ID =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_S_VLAN),
+ /* C-VLAN */
+ VIRTCHNL_PROTO_HDR_C_VLAN_ID =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_C_VLAN),
+ /* IPV4 */
+ VIRTCHNL_PROTO_HDR_IPV4_SRC =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_IPV4),
+ VIRTCHNL_PROTO_HDR_IPV4_DST,
+ VIRTCHNL_PROTO_HDR_IPV4_DSCP,
+ VIRTCHNL_PROTO_HDR_IPV4_TTL,
+ VIRTCHNL_PROTO_HDR_IPV4_PROT,
+ /* IPV6 */
+ VIRTCHNL_PROTO_HDR_IPV6_SRC =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_IPV6),
+ VIRTCHNL_PROTO_HDR_IPV6_DST,
+ VIRTCHNL_PROTO_HDR_IPV6_TC,
+ VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
+ VIRTCHNL_PROTO_HDR_IPV6_PROT,
+ /* TCP */
+ VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_TCP),
+ VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
+ /* UDP */
+ VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_UDP),
+ VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
+ /* SCTP */
+ VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_SCTP),
+ VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
+ /* GTPU_IP */
+ VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_GTPU_IP),
+ /* GTPU_EH */
+ VIRTCHNL_PROTO_HDR_GTPU_EH_PDU =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_GTPU_EH),
+ VIRTCHNL_PROTO_HDR_GTPU_EH_QFI,
+ /* PPPOE */
+ VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_PPPOE),
+ /* L2TPV3 */
+ VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_L2TPV3),
+ /* ESP */
+ VIRTCHNL_PROTO_HDR_ESP_SPI = PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_ESP),
+ /* AH */
+ VIRTCHNL_PROTO_HDR_AH_SPI = PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_AH),
+ /* PFCP */
+ VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
+ PROTO_HDR_FIELD_START (VIRTCHNL_PROTO_HDR_PFCP),
+ VIRTCHNL_PROTO_HDR_PFCP_SEID,
+};
+
+struct virtchnl_proto_hdr
+{
+ enum virtchnl_proto_hdr_type type;
+ u32 field_selector; /* a bit mask to select field for header type */
+ u8 buffer[64];
+ /**
+ * binary buffer in network order for specific header type.
+ * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4
+ * header is expected to be copied into the buffer.
+ */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (72, virtchnl_proto_hdr);
+
+struct virtchnl_proto_hdrs
+{
+ u8 tunnel_level;
+ /**
+ * specify where protocol header start from.
+ * 0 - from the outer layer
+ * 1 - from the first inner layer
+ * 2 - from the second inner layer
+ * ....
+ **/
+ int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
+ struct virtchnl_proto_hdr proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (2312, virtchnl_proto_hdrs);
+
+/* VIRTCHNL_OP_CONFIG_RSS_KEY
+ * VIRTCHNL_OP_CONFIG_RSS_LUT
+ * VF sends these messages to configure RSS. Only supported if both PF
+ * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during
+ * configuration negotiation. If this is the case, then the RSS fields in
+ * the VF resource struct are valid.
+ * Both the key and LUT are initialized to 0 by the PF, meaning that
+ * RSS is effectively disabled until set up by the VF.
+ */
+struct virtchnl_rss_key
+{
+ u16 vsi_id;
+ u16 key_len;
+ u8 key[1]; /* RSS hash key, packed bytes */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (6, virtchnl_rss_key);
+
+struct virtchnl_rss_lut
+{
+ u16 vsi_id;
+ u16 lut_entries;
+ u8 lut[1]; /* RSS lookup table */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (6, virtchnl_rss_lut);
+
+/* VIRTCHNL_OP_GET_RSS_HENA_CAPS
+ * VIRTCHNL_OP_SET_RSS_HENA
+ * VF sends these messages to get and set the hash filter enable bits for RSS.
+ * By default, the PF sets these to all possible traffic types that the
+ * hardware supports. The VF can query this value if it wants to change the
+ * traffic types that are hashed by the hardware.
+ */
+struct virtchnl_rss_hena
+{
+ u64 hena;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (8, virtchnl_rss_hena);
+
+/* Type of RSS algorithm */
+enum virtchnl_rss_algorithm
+{
+ VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC = 0,
+ VIRTCHNL_RSS_ALG_XOR_ASYMMETRIC = 1,
+ VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC = 2,
+ VIRTCHNL_RSS_ALG_XOR_SYMMETRIC = 3,
+};
+
+struct virtchnl_rss_cfg
+{
+ struct virtchnl_proto_hdrs proto_hdrs; /* protocol headers */
+ enum virtchnl_rss_algorithm rss_algorithm; /* rss algorithm type */
+ u8 reserved[128]; /* reserve for future */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (2444, virtchnl_rss_cfg);
+
+enum virtchnl_action
+{
+ /* action types */
+ VIRTCHNL_ACTION_DROP = 0,
+ VIRTCHNL_ACTION_TC_REDIRECT,
+ VIRTCHNL_ACTION_PASSTHRU,
+ VIRTCHNL_ACTION_QUEUE,
+ VIRTCHNL_ACTION_Q_REGION,
+ VIRTCHNL_ACTION_MARK,
+ VIRTCHNL_ACTION_COUNT,
+ VIRTCHNL_ACTION_NONE,
+};
+
+/* action configuration for FDIR */
+struct virtchnl_filter_action
+{
+ enum virtchnl_action type;
+ union
+ {
+ /* used for queue and qgroup action */
+ struct
+ {
+ u16 index;
+ u8 region;
+ } queue;
+ /* used for count action */
+ struct
+ {
+ /* share counter ID with other flow rules */
+ u8 shared;
+ u32 id; /* counter ID */
+ } count;
+ /* used for mark action */
+ u32 mark_id;
+ u8 reserve[32];
+ } act_conf;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (36, virtchnl_filter_action);
+
+#define VIRTCHNL_MAX_NUM_ACTIONS 8
+
+struct virtchnl_filter_action_set
+{
+ /* action number must be less then VIRTCHNL_MAX_NUM_ACTIONS */
+ int count;
+ struct virtchnl_filter_action actions[VIRTCHNL_MAX_NUM_ACTIONS];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (292, virtchnl_filter_action_set);
+
+/* pattern and action for FDIR rule */
+struct virtchnl_fdir_rule
+{
+ struct virtchnl_proto_hdrs proto_hdrs;
+ struct virtchnl_filter_action_set action_set;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (2604, virtchnl_fdir_rule);
+
+/* query information to retrieve fdir rule counters.
+ * PF will fill out this structure to reset counter.
+ */
+struct virtchnl_fdir_query_info
+{
+ u32 match_packets_valid : 1;
+ u32 match_bytes_valid : 1;
+ u32 reserved : 30; /* Reserved, must be zero. */
+ u32 pad;
+ u64 matched_packets; /* Number of packets for this rule. */
+ u64 matched_bytes; /* Number of bytes through this rule. */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (24, virtchnl_fdir_query_info);
+
+/* Status returned to VF after VF requests FDIR commands
+ * VIRTCHNL_FDIR_SUCCESS
+ * VF FDIR related request is successfully done by PF
+ * The request can be OP_ADD/DEL/QUERY_FDIR_FILTER.
+ *
+ * VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE
+ * OP_ADD_FDIR_FILTER request is failed due to no Hardware resource.
+ *
+ * VIRTCHNL_FDIR_FAILURE_RULE_EXIST
+ * OP_ADD_FDIR_FILTER request is failed due to the rule is already existed.
+ *
+ * VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT
+ * OP_ADD_FDIR_FILTER request is failed due to conflict with existing rule.
+ *
+ * VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST
+ * OP_DEL_FDIR_FILTER request is failed due to this rule doesn't exist.
+ *
+ * VIRTCHNL_FDIR_FAILURE_RULE_INVALID
+ * OP_ADD_FDIR_FILTER request is failed due to parameters validation
+ * or HW doesn't support.
+ *
+ * VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT
+ * OP_ADD/DEL_FDIR_FILTER request is failed due to timing out
+ * for programming.
+ *
+ * VIRTCHNL_FDIR_FAILURE_QUERY_INVALID
+ * OP_QUERY_FDIR_FILTER request is failed due to parameters validation,
+ * for example, VF query counter of a rule who has no counter action.
+ */
+enum virtchnl_fdir_prgm_status
+{
+ VIRTCHNL_FDIR_SUCCESS = 0,
+ VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE,
+ VIRTCHNL_FDIR_FAILURE_RULE_EXIST,
+ VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT,
+ VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST,
+ VIRTCHNL_FDIR_FAILURE_RULE_INVALID,
+ VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT,
+ VIRTCHNL_FDIR_FAILURE_QUERY_INVALID,
+ VIRTCHNL_FDIR_FAILURE_MAX,
+};
+
+/* VIRTCHNL_OP_ADD_FDIR_FILTER
+ * VF sends this request to PF by filling out vsi_id,
+ * validate_only and rule_cfg. PF will return flow_id
+ * if the request is successfully done and return add_status to VF.
+ */
+struct virtchnl_fdir_add
+{
+ u16 vsi_id; /* INPUT */
+ /*
+ * 1 for validating a fdir rule, 0 for creating a fdir rule.
+ * Validate and create share one ops: VIRTCHNL_OP_ADD_FDIR_FILTER.
+ */
+ u16 validate_only; /* INPUT */
+ u32 flow_id; /* OUTPUT */
+ struct virtchnl_fdir_rule rule_cfg; /* INPUT */
+ enum virtchnl_fdir_prgm_status status; /* OUTPUT */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (2616, virtchnl_fdir_add);
+
+/* VIRTCHNL_OP_DEL_FDIR_FILTER
+ * VF sends this request to PF by filling out vsi_id
+ * and flow_id. PF will return del_status to VF.
+ */
+struct virtchnl_fdir_del
+{
+ u16 vsi_id; /* INPUT */
+ u16 pad;
+ u32 flow_id; /* INPUT */
+ enum virtchnl_fdir_prgm_status status; /* OUTPUT */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (12, virtchnl_fdir_del);
+
+/* VIRTCHNL_OP_QUERY_FDIR_FILTER
+ * VF sends this request to PF by filling out vsi_id,
+ * flow_id and reset_counter. PF will return query_info
+ * and query_status to VF.
+ */
+struct virtchnl_fdir_query
+{
+ u16 vsi_id; /* INPUT */
+ u16 pad1[3];
+ u32 flow_id; /* INPUT */
+ u32 reset_counter : 1; /* INPUT */
+ struct virtchnl_fdir_query_info query_info; /* OUTPUT */
+ enum virtchnl_fdir_prgm_status status; /* OUTPUT */
+ u32 pad2;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN (48, virtchnl_fdir_query);
+
+/**
+ * Those headers used temporary, maybe OS packet
+ * definition can replace. Add flow error, pattern
+ * and action definition.
+ */
+
+/**
+ * Verbose error types.
+ *
+ * Most of them provide the type of the object referenced by struct
+ * rte_flow_error.cause.
+ */
+enum avf_flow_error_type
+{
+ AVF_FLOW_ERROR_TYPE_NONE, /**< No error. */
+ AVF_FLOW_ERROR_TYPE_UNSPECIFIED, /**< Cause unspecified. */
+ AVF_FLOW_ERROR_TYPE_HANDLE, /**< Flow rule (handle). */
+ AVF_FLOW_ERROR_TYPE_ATTR_GROUP, /**< Group field. */
+ AVF_FLOW_ERROR_TYPE_ATTR_PRIORITY, /**< Priority field. */
+ AVF_FLOW_ERROR_TYPE_ATTR_INGRESS, /**< Ingress field. */
+ AVF_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */
+ AVF_FLOW_ERROR_TYPE_ATTR_TRANSFER, /**< Transfer field. */
+ AVF_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */
+ AVF_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */
+ AVF_FLOW_ERROR_TYPE_ITEM_SPEC, /**< Item specification. */
+ AVF_FLOW_ERROR_TYPE_ITEM_LAST, /**< Item specification range. */
+ AVF_FLOW_ERROR_TYPE_ITEM_MASK, /**< Item specification mask. */
+ AVF_FLOW_ERROR_TYPE_ITEM, /**< Specific pattern item. */
+ AVF_FLOW_ERROR_TYPE_ACTION_NUM, /**< Number of actions. */
+ AVF_FLOW_ERROR_TYPE_ACTION_CONF, /**< Action configuration. */
+ AVF_FLOW_ERROR_TYPE_ACTION, /**< Specific action. */
+};
+
+/**
+ * Verbose error structure definition.
+ * Both cause and message may be NULL regardless of the error type.
+ */
+struct avf_flow_error
+{
+ enum avf_flow_error_type type; /**< Cause field and error types. */
+ const void *cause; /**< Object responsible for the error. */
+ const char *message; /**< Human-readable error message. */
+};
+
+#define AVF_ETHER_ADDR_LEN 6
+struct avf_ether_addr
+{
+ u8 addr_bytes[AVF_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+} __attribute__ ((__aligned__ (2)));
+
+struct avf_flow_eth_hdr
+{
+ struct avf_ether_addr dst; /**< Destination MAC. */
+ struct avf_ether_addr src; /**< Source MAC. */
+ u16 type; /**< EtherType or TPID. */
+};
+
+/**
+ * IPv4 Header
+ */
+struct avf_ipv4_hdr
+{
+ u8 version_ihl; /**< version and header length */
+ u8 type_of_service; /**< type of service */
+ u16 total_length; /**< length of packet */
+ u16 packet_id; /**< packet ID */
+ u16 fragment_offset; /**< fragmentation offset */
+ u8 time_to_live; /**< time to live */
+ u8 next_proto_id; /**< protocol ID */
+ u16 hdr_checksum; /**< header checksum */
+ u32 src_addr; /**< source address */
+ u32 dst_addr; /**< destination address */
+} __attribute__ ((__packed__));
+
+/**
+ * IPv6 Header
+ */
+struct avf_ipv6_hdr
+{
+ u32 vtc_flow; /**< IP version, traffic class & flow label. */
+ u16 payload_len; /**< IP packet length - includes header size */
+ u8 proto; /**< Protocol, next header. */
+ u8 hop_limits; /**< Hop limits. */
+ u8 src_addr[16]; /**< IP address of source host. */
+ u8 dst_addr[16]; /**< IP address of destination host(s). */
+} __attribute__ ((__packed__));
+
+/**
+ * TCP Header
+ */
+struct avf_tcp_hdr
+{
+ u16 src_port; /**< TCP source port. */
+ u16 dst_port; /**< TCP destination port. */
+ u32 sent_seq; /**< TX data sequence number. */
+ u32 recv_ack; /**< RX data acknowledgment sequence number. */
+ u8 data_off; /**< Data offset. */
+ u8 tcp_flags; /**< TCP flags */
+ u16 rx_win; /**< RX flow control window. */
+ u16 cksum; /**< TCP checksum. */
+ u16 tcp_urp; /**< TCP urgent pointer, if any. */
+} __attribute__ ((__packed__));
+
+/**
+ * UDP Header
+ */
+struct avf_udp_hdr
+{
+ u16 src_port; /**< UDP source port. */
+ u16 dst_port; /**< UDP destination port. */
+ u16 dgram_len; /**< UDP datagram length */
+ u16 dgram_cksum; /**< UDP datagram checksum */
+} __attribute__ ((__packed__));
+
+/**
+ * Match IP Authentication Header (AH), RFC 4302
+ */
+struct avf_ah_hdr
+{
+ u32 next_hdr : 8;
+ u32 payload_len : 8;
+ u32 reserved : 16;
+ u32 spi;
+ u32 seq_num;
+};
+
+/**
+ * ESP Header
+ */
+struct avf_esp_hdr
+{
+ u32 spi; /**< Security Parameters Index */
+ u32 seq; /**< packet sequence number */
+} __attribute__ ((__packed__));
+
+/**
+ * Match PFCP Header
+ */
+struct avf_pfcp_hdr
+{
+ u8 s_field;
+ u8 msg_type;
+ u16 msg_len;
+ u64 seid;
+};
+
+/**
+ * Matches a L2TPv3 over IP header.
+ */
+struct avf_l2tpv3oip_hdr
+{
+ u32 session_id; /**< Session ID. */
+};
+
+/**
+ * Matches a GTP PDU extension header with type 0x85.
+ */
+struct avf_gtp_psc_hdr
+{
+ u8 pdu_type; /**< PDU type. */
+ u8 qfi; /**< QoS flow identifier. */
+};
+
+/**
+ * Matches a GTPv1 header.
+ */
+struct avf_gtp_hdr
+{
+ /**
+ * Version (3b), protocol type (1b), reserved (1b),
+ * Extension header flag (1b),
+ * Sequence number flag (1b),
+ * N-PDU number flag (1b).
+ */
+ u8 v_pt_rsv_flags;
+ u8 msg_type; /**< Message type. */
+ u16 msg_len; /**< Message length. */
+ u32 teid; /**< Tunnel endpoint identifier. */
+};
+
+/**
+ * SCTP Header
+ */
+struct avf_sctp_hdr
+{
+ u16 src_port; /**< Source port. */
+ u16 dst_port; /**< Destin port. */
+ u32 tag; /**< Validation tag. */
+ u32 cksum; /**< Checksum. */
+} __attribute__ ((__packed__));
+
+/**
+ * Hash function types.
+ */
+enum avf_eth_hash_function
+{
+ AVF_ETH_HASH_FUNCTION_DEFAULT = 0,
+ AVF_ETH_HASH_FUNCTION_TOEPLITZ, /**< Toeplitz */
+ AVF_ETH_HASH_FUNCTION_SIMPLE_XOR, /**< Simple XOR */
+ /**
+ * Symmetric Toeplitz: src, dst will be replaced by
+ * xor(src, dst). For the case with src/dst only,
+ * src or dst address will xor with zero pair.
+ */
+ AVF_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ,
+ AVF_ETH_HASH_FUNCTION_MAX,
+};
+
+struct avf_flow_action_rss
+{
+ enum avf_eth_hash_function func; /**< RSS hash function to apply. */
+
+ u32 level;
+ u64 types; /**< Specific RSS hash types (see ETH_RSS_*). */
+ u32 key_len; /**< Hash key length in bytes. */
+ u32 queue_num; /**< Number of entries in @p queue. */
+ const u8 *key; /**< Hash key. */
+ const u16 *queue; /**< Queue indices to use. */
+};
+
+struct avf_flow_action_queue
+{
+ u16 index; /**< Queue index to use. */
+};
+
+struct avf_flow_action_mark
+{
+ u32 id; /**< Integer value to return with packets. */
+};
+
+struct avf_flow_action
+{
+ enum virtchnl_action type; /**< Action type. */
+ const void *conf; /**< Pointer to action configuration object. */
+};
+
+struct avf_flow_item
+{
+ enum virtchnl_proto_hdr_type type; /**< Item type. */
+ const void *spec; /**< Pointer to item specification structure. */
+ const void *mask; /**< Bit-mask applied to spec and last. */
+};
+
+struct avf_fdir_conf
+{
+ struct virtchnl_fdir_add add_fltr;
+ struct virtchnl_fdir_del del_fltr;
+ u64 input_set;
+ u32 flow_id;
+ u32 mark_flag;
+ u32 vsi;
+ u32 nb_rx_queues;
+};
+
+enum virthnl_adv_ops
+{
+ VIRTCHNL_ADV_OP_ADD_FDIR_FILTER = 0,
+ VIRTCHNL_ADV_OP_DEL_FDIR_FILTER,
+ VIRTCHNL_ADV_OP_QUERY_FDIR_FILTER,
+ VIRTCHNL_ADV_OP_MAX
+};
+
+/* virtual channel op handler */
+typedef int (*avf_fdir_vc_op_t) (void *vc_hdl, enum virthnl_adv_ops vc_op,
+ void *in, u32 in_len, void *out, u32 out_len);
+
+/* virtual channel context object */
+struct avf_fdir_vc_ctx
+{
+ void *vc_hdl; /* virtual channel handler */
+ avf_fdir_vc_op_t vc_op;
+};
+
+/**
+ * Create a rule cfg object.
+ *
+ * @param rcfg
+ * created rule cfg object.
+ * @param tunnel
+ * tunnel level where protocol header start from
+ * 0 from moster outer layer.
+ * 1 from first inner layer.
+ * 2 form second inner layer.
+ * ...
+ * @param vsi
+ * avf vsi id
+ *
+ * @param nrxq
+ * the rx queue number of the avf
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_create (struct avf_fdir_conf **rcfg, int tunnel_level,
+ u16 vsi, u16 nrxq);
+
+/**
+ * Destroy a rule cfg object.
+ *
+ * @param rcfg
+ * the cfg object to destroy.
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_destroy (struct avf_fdir_conf *rcfg);
+
+/**
+ * Set match potocol header on specific layer, it will overwrite is already be
+ * set.
+ *
+ * @param rcfg
+ * the rule cfg object
+ * @param layer
+ * layer of the protocol header.
+ * @param hdr
+ * protocol header type.
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_set_hdr (struct avf_fdir_conf *rcfg, int layer,
+ enum virtchnl_proto_hdr_type hdr);
+
+/**
+ * Set a match field on specific protocol layer, if any match field already be
+ * set on this layer, it will be overwritten.
+ *
+ * @param rcfg
+ * the rule cfg object
+ * @param layer
+ * layer of the protocol header.
+ * @param item
+ * flow item
+ * @param error
+ * save error cause
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_set_field (struct avf_fdir_conf *rcfg, int layer,
+ struct avf_flow_item *item,
+ struct avf_flow_error *error);
+
+/**
+ * Set action as to queue(group), conflict with drop action.
+ *
+ * @param rcfg
+ * rule cfg object
+ * @param queue
+ * queue id.
+ * @param size
+ * queue group size, must be 2^n. 1 means only to single queue.
+ * @param act_idx
+ * action index
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_act_queue (struct avf_fdir_conf *rcfg, int queue, int size,
+ int act_idx);
+
+/**
+ * Set action as to queue group, conflict with drop action.
+ *
+ * @param rcfg
+ * the rule cfg object
+ * @param act
+ * flow actions
+ * @param act_idx
+ * action index
+ * @error
+ * save error cause
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_parse_action_qregion (struct avf_fdir_conf *rcfg,
+ const struct avf_flow_action *act,
+ int act_idx, struct avf_flow_error *error);
+
+/**
+ * Set action as as drop, conflict with to queue(gropu) action.
+ *
+ * @param rcfg
+ * the rule cfg object
+ * @param act_idx
+ * action index
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_act_drop (struct avf_fdir_conf *rcfg, int act_idx);
+
+/**
+ * Set action as mark, it can co-exist with to queue(group) or drop action.
+ *
+ * @param rcfg
+ * the rule cfg object
+ * @param mark
+ * a 32 bit flow mark
+ * @param act_idx
+ * action index
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_act_mark (struct avf_fdir_conf *rcfg, const u32 mark,
+ int act_idx);
+
+/**
+ * Validate a flow rule cfg, check with PF driver if the rule cfg is supportted
+ *or not.
+ *
+ * @param ctx
+ * virtual channel context
+ * @param rcfg
+ * the rule cfg object.
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure.
+ */
+int avf_fdir_rcfg_validate (struct avf_fdir_vc_ctx *ctx,
+ struct avf_fdir_conf *rcfg);
+
+/**
+ * Create a flow rule, a FDIR rule is expected to be programmed into hardware
+ *if return success.
+ *
+ * @param ctx
+ * virtual channel context
+ * @param rcfg
+ * rule cfg object.
+ *
+ * @return
+ * 0 = successfule.
+ * < 0 = failure.
+ */
+int avf_fdir_rule_create (struct avf_fdir_vc_ctx *ctx,
+ struct avf_fdir_conf *rcfg);
+
+/**
+ * Destroy a flow rule.
+ *
+ * @param ctx
+ * virtual channel context
+ * @param rcfg
+ * the rule cfg object.
+ *
+ * @return
+ * 0 = successfule.
+ * < 0 = failure.
+ */
+int avf_fdir_rule_destroy (struct avf_fdir_vc_ctx *ctx,
+ struct avf_fdir_conf *rcfg);
+
+/*
+ * Parse avf patterns and set pattern fields.
+ *
+ * @param rcfg
+ * flow config
+ * @param avf_items
+ * pattern items
+ * @param error
+ * save error cause
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure
+ */
+int avf_fdir_parse_pattern (struct avf_fdir_conf *rcfg,
+ struct avf_flow_item avf_items[],
+ struct avf_flow_error *error);
+
+/*
+ * Parse flow actions, set actions.
+ *
+ * @param actions
+ * flow actions
+ * @param rcfg
+ * flow config
+ * @param error
+ * save error cause
+ *
+ * @return
+ * 0 = successful.
+ * < 0 = failure
+ */
+int avf_fdir_parse_action (const struct avf_flow_action actions[],
+ struct avf_fdir_conf *rcfg,
+ struct avf_flow_error *error);
+
+/**
+ * Initialize flow error structure.
+ *
+ * @param[out] error
+ * Pointer to flow error structure (may be NULL).
+ * @param code
+ * Related error code
+ * @param type
+ * Cause field and error types.
+ * @param cause
+ * Object responsible for the error.
+ * @param message
+ * Human-readable error message.
+ *
+ * @return
+ * Negative error code (errno value)
+ */
+int avf_flow_error_set (struct avf_flow_error *error, int code,
+ enum avf_flow_error_type type, const void *cause,
+ const char *message);
+
+/*
+ * decode the error number to Verbose error string
+ *
+ * @param err_no
+ * error number
+ *
+ * @return
+ * Verbose error string
+ */
+char *avf_fdir_prgm_error_decode (int err_no);
+
+#endif /* _AVF_ADVANCED_FLOW_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */