blob: 1cd03b2b675730c4cdecbc397dacc50e827dc9a5 [file] [log] [blame]
Chenmin Sun7f837382020-03-28 00:34:19 +08001From e9e33a31aa58293c0442ddbfb96f3b8badfad250 Mon Sep 17 00:00:00 2001
2From: Qi Zhang <qi.z.zhang@intel.com>
3Date: Thu, 9 Apr 2020 13:10:12 +0800
4Subject: [DPDK 06/17] common/iavf: add virtual channel protocol header
5
6To support advanced AVF's FDIR and RSS feature, we need to figure out
7what kind of data structure should be passed from VF to PF to describe
8an FDIR rule or RSS config rule. The common part of the requirement is
9we need a data structure to represent the input set selection of a rule's
10hash key.
11
12An input set selection is a group of fields be selected from one or more
13network protocol layers that could be identified as a specific flow.
14For example, select dst IP address from an IPv4 header combined with
15dst port from the TCP header as the input set for an IPv4/TCP flow.
16
17The patch adds a new data structure virtchnl_proto_hdrs to abstract
18a network protocol headers group which is composed of layers of network
19protocol header(virtchnl_proto_hdr).
20
21A protocol header contains a 32 bits mask (field_selector) to describe
22which fields are selected as input sets, as well as a header type
23(enum virtchnl_proto_hdr_type). Each bit is mapped to a field in
24enum virtchnl_proto_hdr_field guided by its header type.
25
26+------------+-----------+------------------------------+
27| | Proto Hdr | Header Type A |
28| | +------------------------------+
29| | | BIT 31 | ... | BIT 1 | BIT 0 |
30| |-----------+------------------------------+
31|Proto Hdrs | Proto Hdr | Header Type B |
32| | +------------------------------+
33| | | BIT 31 | ... | BIT 1 | BIT 0 |
34| |-----------+------------------------------+
35| | Proto Hdr | Header Type C |
36| | +------------------------------+
37| | | BIT 31 | ... | BIT 1 | BIT 0 |
38| |-----------+------------------------------+
39| | .... |
40+-------------------------------------------------------+
41
42All fields in enum virtchnl_proto_hdr_fields are grouped with header type
43and the value of the first field of a header type is always 32 aligned.
44
45enum proto_hdr_type {
46 header_type_A = 0;
47 header_type_B = 1;
48 ....
49}
50
51enum proto_hdr_field {
52 /* header type A */
53 header_A_field_0 = 0,
54 header_A_field_1 = 1,
55 header_A_field_2 = 2,
56 header_A_field_3 = 3,
57
58 /* header type B */
59 header_B_field_0 = 32, // = header_type_B << 5
60 header_B_field_0 = 33,
61 header_B_field_0 = 34
62 header_B_field_0 = 35,
63 ....
64};
65
66So we have:
67proto_hdr_type = proto_hdr_field / 32
68bit offset = proto_hdr_field % 32
69
70To simply the protocol header's operations, couple help macros are added.
71For example, to select src IP and dst port as input set for an IPv4/UDP
72flow.
73
74we have:
75struct virtchnl_proto_hdr hdr[2];
76
77VIRTCHNL_SET_PROTO_HDR_TYPE(&hdr[0], IPV4)
78VIRTCHNL_ADD_PROTO_HDR_FIELD(&hdr[0], IPV4, SRC)
79
80VIRTCHNL_SET_PROTO_HDR_TYPE(&hdr[1], UDP)
81VIRTCHNL_ADD_PROTO_HDR_FIELD(&hdr[1], UDP, DST)
82
83A protocol header also contains a byte array, this field should only
84be used by an FDIR rule and should be ignored by RSS. For an FDIR rule,
85the byte array is used to store the protocol header of a training
86package. The byte array must be network order.
87
88Signed-off-by: Jeff Guo <jia.guo@intel.com>
89Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
90Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
91---
92 drivers/common/iavf/virtchnl.h | 156 +++++++++++++++++++++++++++++++++
93 1 file changed, 156 insertions(+)
94
95diff --git a/drivers/common/iavf/virtchnl.h b/drivers/common/iavf/virtchnl.h
96index e8d936843..667762643 100644
97--- a/drivers/common/iavf/virtchnl.h
98+++ b/drivers/common/iavf/virtchnl.h
99@@ -769,6 +769,162 @@ enum virtchnl_vfr_states {
100 VIRTCHNL_VFR_VFACTIVE,
101 };
102
103+#define VIRTCHNL_MAX_NUM_PROTO_HDRS 32
104+#define PROTO_HDR_SHIFT 5
105+#define PROTO_HDR_FIELD_START(proto_hdr_type) \
106+ (proto_hdr_type << PROTO_HDR_SHIFT)
107+#define PROTO_HDR_FIELD_MASK ((1UL << PROTO_HDR_SHIFT) - 1)
108+
109+/* VF use these macros to configure each protocol header.
110+ * Specify which protocol headers and protocol header fields base on
111+ * virtchnl_proto_hdr_type and virtchnl_proto_hdr_field.
112+ * @param hdr: a struct of virtchnl_proto_hdr
113+ * @param hdr_type: ETH/IPV4/TCP, etc
114+ * @param field: SRC/DST/TEID/SPI, etc
115+ */
116+#define VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, field) \
117+ ((hdr)->field_selector |= BIT((field) & PROTO_HDR_FIELD_MASK))
118+#define VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, field) \
119+ ((hdr)->field_selector &= ~BIT((field) & PROTO_HDR_FIELD_MASK))
120+#define VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val) \
121+ ((hdr)->field_selector & BIT((val) & PROTO_HDR_FIELD_MASK))
122+#define VIRTCHNL_GET_PROTO_HDR_FIELD(hdr) ((hdr)->field_selector)
123+
124+#define VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
125+ (VIRTCHNL_ADD_PROTO_HDR_FIELD(hdr, \
126+ VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
127+#define VIRTCHNL_DEL_PROTO_HDR_FIELD_BIT(hdr, hdr_type, field) \
128+ (VIRTCHNL_DEL_PROTO_HDR_FIELD(hdr, \
129+ VIRTCHNL_PROTO_HDR_ ## hdr_type ## _ ## field))
130+
131+#define VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, hdr_type) \
132+ ((hdr)->type = VIRTCHNL_PROTO_HDR_ ## hdr_type)
133+#define VIRTCHNL_GET_PROTO_HDR_TYPE(hdr) \
134+ (((hdr)->type) >> PROTO_HDR_SHIFT)
135+#define VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) \
136+ ((hdr)->type == ((val) >> PROTO_HDR_SHIFT))
137+#define VIRTCHNL_TEST_PROTO_HDR(hdr, val) \
138+ (VIRTCHNL_TEST_PROTO_HDR_TYPE(hdr, val) && \
139+ VIRTCHNL_TEST_PROTO_HDR_FIELD(hdr, val))
140+
141+/* Protocol header type within a packet segment. A segment consists of one or
142+ * more protocol headers that make up a logical group of protocol headers. Each
143+ * logical group of protocol headers encapsulates or is encapsulated using/by
144+ * tunneling or encapsulation protocols for network virtualization.
145+ */
146+enum virtchnl_proto_hdr_type {
147+ VIRTCHNL_PROTO_HDR_NONE,
148+ VIRTCHNL_PROTO_HDR_ETH,
149+ VIRTCHNL_PROTO_HDR_S_VLAN,
150+ VIRTCHNL_PROTO_HDR_C_VLAN,
151+ VIRTCHNL_PROTO_HDR_IPV4,
152+ VIRTCHNL_PROTO_HDR_IPV6,
153+ VIRTCHNL_PROTO_HDR_TCP,
154+ VIRTCHNL_PROTO_HDR_UDP,
155+ VIRTCHNL_PROTO_HDR_SCTP,
156+ VIRTCHNL_PROTO_HDR_GTPU_IP,
157+ VIRTCHNL_PROTO_HDR_GTPU_EH,
158+ VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_DWN,
159+ VIRTCHNL_PROTO_HDR_GTPU_EH_PDU_UP,
160+ VIRTCHNL_PROTO_HDR_PPPOE,
161+ VIRTCHNL_PROTO_HDR_L2TPV3,
162+ VIRTCHNL_PROTO_HDR_ESP,
163+ VIRTCHNL_PROTO_HDR_AH,
164+ VIRTCHNL_PROTO_HDR_PFCP,
165+};
166+
167+/* Protocol header field within a protocol header. */
168+enum virtchnl_proto_hdr_field {
169+ /* ETHER */
170+ VIRTCHNL_PROTO_HDR_ETH_SRC =
171+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ETH),
172+ VIRTCHNL_PROTO_HDR_ETH_DST,
173+ VIRTCHNL_PROTO_HDR_ETH_ETHERTYPE,
174+ /* S-VLAN */
175+ VIRTCHNL_PROTO_HDR_S_VLAN_ID =
176+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_S_VLAN),
177+ /* C-VLAN */
178+ VIRTCHNL_PROTO_HDR_C_VLAN_ID =
179+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_C_VLAN),
180+ /* IPV4 */
181+ VIRTCHNL_PROTO_HDR_IPV4_SRC =
182+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV4),
183+ VIRTCHNL_PROTO_HDR_IPV4_DST,
184+ VIRTCHNL_PROTO_HDR_IPV4_DSCP,
185+ VIRTCHNL_PROTO_HDR_IPV4_TTL,
186+ VIRTCHNL_PROTO_HDR_IPV4_PROT,
187+ /* IPV6 */
188+ VIRTCHNL_PROTO_HDR_IPV6_SRC =
189+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_IPV6),
190+ VIRTCHNL_PROTO_HDR_IPV6_DST,
191+ VIRTCHNL_PROTO_HDR_IPV6_TC,
192+ VIRTCHNL_PROTO_HDR_IPV6_HOP_LIMIT,
193+ VIRTCHNL_PROTO_HDR_IPV6_PROT,
194+ /* TCP */
195+ VIRTCHNL_PROTO_HDR_TCP_SRC_PORT =
196+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_TCP),
197+ VIRTCHNL_PROTO_HDR_TCP_DST_PORT,
198+ /* UDP */
199+ VIRTCHNL_PROTO_HDR_UDP_SRC_PORT =
200+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_UDP),
201+ VIRTCHNL_PROTO_HDR_UDP_DST_PORT,
202+ /* SCTP */
203+ VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT =
204+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_SCTP),
205+ VIRTCHNL_PROTO_HDR_SCTP_DST_PORT,
206+ /* GTPU_IP */
207+ VIRTCHNL_PROTO_HDR_GTPU_IP_TEID =
208+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_IP),
209+ /* GTPU_EH */
210+ VIRTCHNL_PROTO_HDR_GTPU_EH_PDU =
211+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_GTPU_EH),
212+ VIRTCHNL_PROTO_HDR_GTPU_EH_QFI,
213+ /* PPPOE */
214+ VIRTCHNL_PROTO_HDR_PPPOE_SESS_ID =
215+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PPPOE),
216+ /* L2TPV3 */
217+ VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID =
218+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_L2TPV3),
219+ /* ESP */
220+ VIRTCHNL_PROTO_HDR_ESP_SPI =
221+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_ESP),
222+ /* AH */
223+ VIRTCHNL_PROTO_HDR_AH_SPI =
224+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_AH),
225+ /* PFCP */
226+ VIRTCHNL_PROTO_HDR_PFCP_S_FIELD =
227+ PROTO_HDR_FIELD_START(VIRTCHNL_PROTO_HDR_PFCP),
228+ VIRTCHNL_PROTO_HDR_PFCP_SEID,
229+};
230+
231+struct virtchnl_proto_hdr {
232+ enum virtchnl_proto_hdr_type type;
233+ u32 field_selector; /* a bit mask to select field for header type */
234+ u8 buffer[64];
235+ /**
236+ * binary buffer in network order for specific header type.
237+ * For example, if type = VIRTCHNL_PROTO_HDR_IPV4, a IPv4
238+ * header is expected to be copied into the buffer.
239+ */
240+};
241+
242+VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_proto_hdr);
243+
244+struct virtchnl_proto_hdrs {
245+ u8 tunnel_level;
246+ /**
247+ * specify where protocol header start from.
248+ * 0 - from the outer layer
249+ * 1 - from the first inner layer
250+ * 2 - from the second inner layer
251+ * ....
252+ **/
253+ int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
254+ struct virtchnl_proto_hdr proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
255+};
256+
257+VIRTCHNL_CHECK_STRUCT_LEN(2312, virtchnl_proto_hdrs);
258+
259 /**
260 * virtchnl_vc_validate_vf_msg
261 * @ver: Virtchnl version info
262--
2632.17.1
264