net/tap: add basic flow API patterns and actions
[dpdk.git] / drivers / net / tap / tap_flow.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright 2017 6WIND S.A.
5  *   Copyright 2017 Mellanox.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of 6WIND S.A. nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <sys/queue.h>
35
36 #include <rte_byteorder.h>
37 #include <rte_jhash.h>
38 #include <rte_malloc.h>
39 #include <rte_eth_tap.h>
40 #include <tap_flow.h>
41 #include <tap_autoconf.h>
42 #include <tap_tcmsgs.h>
43
44 #ifndef HAVE_TC_FLOWER
45 /*
46  * For kernels < 4.2, this enum is not defined. Runtime checks will be made to
47  * avoid sending TC messages the kernel cannot understand.
48  */
49 enum {
50         TCA_FLOWER_UNSPEC,
51         TCA_FLOWER_CLASSID,
52         TCA_FLOWER_INDEV,
53         TCA_FLOWER_ACT,
54         TCA_FLOWER_KEY_ETH_DST,         /* ETH_ALEN */
55         TCA_FLOWER_KEY_ETH_DST_MASK,    /* ETH_ALEN */
56         TCA_FLOWER_KEY_ETH_SRC,         /* ETH_ALEN */
57         TCA_FLOWER_KEY_ETH_SRC_MASK,    /* ETH_ALEN */
58         TCA_FLOWER_KEY_ETH_TYPE,        /* be16 */
59         TCA_FLOWER_KEY_IP_PROTO,        /* u8 */
60         TCA_FLOWER_KEY_IPV4_SRC,        /* be32 */
61         TCA_FLOWER_KEY_IPV4_SRC_MASK,   /* be32 */
62         TCA_FLOWER_KEY_IPV4_DST,        /* be32 */
63         TCA_FLOWER_KEY_IPV4_DST_MASK,   /* be32 */
64         TCA_FLOWER_KEY_IPV6_SRC,        /* struct in6_addr */
65         TCA_FLOWER_KEY_IPV6_SRC_MASK,   /* struct in6_addr */
66         TCA_FLOWER_KEY_IPV6_DST,        /* struct in6_addr */
67         TCA_FLOWER_KEY_IPV6_DST_MASK,   /* struct in6_addr */
68         TCA_FLOWER_KEY_TCP_SRC,         /* be16 */
69         TCA_FLOWER_KEY_TCP_DST,         /* be16 */
70         TCA_FLOWER_KEY_UDP_SRC,         /* be16 */
71         TCA_FLOWER_KEY_UDP_DST,         /* be16 */
72 };
73 #endif
74 #ifndef HAVE_TC_VLAN_ID
75 enum {
76         /* TCA_FLOWER_FLAGS, */
77         TCA_FLOWER_KEY_VLAN_ID = TCA_FLOWER_KEY_UDP_DST + 2, /* be16 */
78         TCA_FLOWER_KEY_VLAN_PRIO,       /* u8   */
79         TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
80 };
81 #endif
82
83 struct rte_flow {
84         LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
85         struct nlmsg msg;
86 };
87
88 struct convert_data {
89         uint16_t eth_type;
90         uint16_t ip_proto;
91         uint8_t vlan;
92         struct rte_flow *flow;
93 };
94
95 static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
96 static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
97 static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
98 static int tap_flow_create_ipv6(const struct rte_flow_item *item, void *data);
99 static int tap_flow_create_udp(const struct rte_flow_item *item, void *data);
100 static int tap_flow_create_tcp(const struct rte_flow_item *item, void *data);
101 static int
102 tap_flow_validate(struct rte_eth_dev *dev,
103                   const struct rte_flow_attr *attr,
104                   const struct rte_flow_item items[],
105                   const struct rte_flow_action actions[],
106                   struct rte_flow_error *error);
107
108 static struct rte_flow *
109 tap_flow_create(struct rte_eth_dev *dev,
110                 const struct rte_flow_attr *attr,
111                 const struct rte_flow_item items[],
112                 const struct rte_flow_action actions[],
113                 struct rte_flow_error *error);
114
115 static int
116 tap_flow_destroy(struct rte_eth_dev *dev,
117                  struct rte_flow *flow,
118                  struct rte_flow_error *error);
119
120 static const struct rte_flow_ops tap_flow_ops = {
121         .validate = tap_flow_validate,
122         .create = tap_flow_create,
123         .destroy = tap_flow_destroy,
124         .flush = tap_flow_flush,
125 };
126
127 /* Static initializer for items. */
128 #define ITEMS(...) \
129         (const enum rte_flow_item_type []){ \
130                 __VA_ARGS__, RTE_FLOW_ITEM_TYPE_END, \
131         }
132
133 /* Structure to generate a simple graph of layers supported by the NIC. */
134 struct tap_flow_items {
135         /* Bit-mask corresponding to what is supported for this item. */
136         const void *mask;
137         const unsigned int mask_sz; /* Bit-mask size in bytes. */
138         /*
139          * Bit-mask corresponding to the default mask, if none is provided
140          * along with the item.
141          */
142         const void *default_mask;
143         /**
144          * Conversion function from rte_flow to netlink attributes.
145          *
146          * @param item
147          *   rte_flow item to convert.
148          * @param data
149          *   Internal structure to store the conversion.
150          *
151          * @return
152          *   0 on success, negative value otherwise.
153          */
154         int (*convert)(const struct rte_flow_item *item, void *data);
155         /** List of possible following items.  */
156         const enum rte_flow_item_type *const items;
157 };
158
159 /* Graph of supported items and associated actions. */
160 static const struct tap_flow_items tap_flow_items[] = {
161         [RTE_FLOW_ITEM_TYPE_END] = {
162                 .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH),
163         },
164         [RTE_FLOW_ITEM_TYPE_ETH] = {
165                 .items = ITEMS(
166                         RTE_FLOW_ITEM_TYPE_VLAN,
167                         RTE_FLOW_ITEM_TYPE_IPV4,
168                         RTE_FLOW_ITEM_TYPE_IPV6),
169                 .mask = &(const struct rte_flow_item_eth){
170                         .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
171                         .src.addr_bytes = "\xff\xff\xff\xff\xff\xff",
172                         .type = -1,
173                 },
174                 .mask_sz = sizeof(struct rte_flow_item_eth),
175                 .default_mask = &rte_flow_item_eth_mask,
176                 .convert = tap_flow_create_eth,
177         },
178         [RTE_FLOW_ITEM_TYPE_VLAN] = {
179                 .items = ITEMS(RTE_FLOW_ITEM_TYPE_IPV4,
180                                RTE_FLOW_ITEM_TYPE_IPV6),
181                 .mask = &(const struct rte_flow_item_vlan){
182                         .tpid = -1,
183                         /* DEI matching is not supported */
184 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
185                         .tci = 0xffef,
186 #else
187                         .tci = 0xefff,
188 #endif
189                 },
190                 .mask_sz = sizeof(struct rte_flow_item_vlan),
191                 .default_mask = &rte_flow_item_vlan_mask,
192                 .convert = tap_flow_create_vlan,
193         },
194         [RTE_FLOW_ITEM_TYPE_IPV4] = {
195                 .items = ITEMS(RTE_FLOW_ITEM_TYPE_UDP,
196                                RTE_FLOW_ITEM_TYPE_TCP),
197                 .mask = &(const struct rte_flow_item_ipv4){
198                         .hdr = {
199                                 .src_addr = -1,
200                                 .dst_addr = -1,
201                                 .next_proto_id = -1,
202                         },
203                 },
204                 .mask_sz = sizeof(struct rte_flow_item_ipv4),
205                 .default_mask = &rte_flow_item_ipv4_mask,
206                 .convert = tap_flow_create_ipv4,
207         },
208         [RTE_FLOW_ITEM_TYPE_IPV6] = {
209                 .items = ITEMS(RTE_FLOW_ITEM_TYPE_UDP,
210                                RTE_FLOW_ITEM_TYPE_TCP),
211                 .mask = &(const struct rte_flow_item_ipv6){
212                         .hdr = {
213                                 .src_addr = {
214                                         "\xff\xff\xff\xff\xff\xff\xff\xff"
215                                         "\xff\xff\xff\xff\xff\xff\xff\xff",
216                                 },
217                                 .dst_addr = {
218                                         "\xff\xff\xff\xff\xff\xff\xff\xff"
219                                         "\xff\xff\xff\xff\xff\xff\xff\xff",
220                                 },
221                                 .proto = -1,
222                         },
223                 },
224                 .mask_sz = sizeof(struct rte_flow_item_ipv6),
225                 .default_mask = &rte_flow_item_ipv6_mask,
226                 .convert = tap_flow_create_ipv6,
227         },
228         [RTE_FLOW_ITEM_TYPE_UDP] = {
229                 .mask = &(const struct rte_flow_item_udp){
230                         .hdr = {
231                                 .src_port = -1,
232                                 .dst_port = -1,
233                         },
234                 },
235                 .mask_sz = sizeof(struct rte_flow_item_udp),
236                 .default_mask = &rte_flow_item_udp_mask,
237                 .convert = tap_flow_create_udp,
238         },
239         [RTE_FLOW_ITEM_TYPE_TCP] = {
240                 .mask = &(const struct rte_flow_item_tcp){
241                         .hdr = {
242                                 .src_port = -1,
243                                 .dst_port = -1,
244                         },
245                 },
246                 .mask_sz = sizeof(struct rte_flow_item_tcp),
247                 .default_mask = &rte_flow_item_tcp_mask,
248                 .convert = tap_flow_create_tcp,
249         },
250 };
251
252 /**
253  * Make as much checks as possible on an Ethernet item, and if a flow is
254  * provided, fill it appropriately with Ethernet info.
255  *
256  * @param[in] item
257  *   Item specification.
258  * @param[in, out] data
259  *   Additional data structure to tell next layers we've been here.
260  *
261  * @return
262  *   0 if checks are alright, -1 otherwise.
263  */
264 static int
265 tap_flow_create_eth(const struct rte_flow_item *item, void *data)
266 {
267         struct convert_data *info = (struct convert_data *)data;
268         const struct rte_flow_item_eth *spec = item->spec;
269         const struct rte_flow_item_eth *mask = item->mask;
270         struct rte_flow *flow = info->flow;
271         struct nlmsg *msg;
272
273         /* use default mask if none provided */
274         if (!mask)
275                 mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_ETH].default_mask;
276         /* TC does not support eth_type masking. Only accept if exact match. */
277         if (mask->type && mask->type != 0xffff)
278                 return -1;
279         if (!spec)
280                 return 0;
281         /* store eth_type for consistency if ipv4/6 pattern item comes next */
282         if (spec->type & mask->type)
283                 info->eth_type = spec->type;
284         if (!flow)
285                 return 0;
286         msg = &flow->msg;
287         if (spec->type & mask->type)
288                 msg->t.tcm_info = TC_H_MAKE(msg->t.tcm_info,
289                                             (spec->type & mask->type));
290         if (!is_zero_ether_addr(&spec->dst)) {
291                 nlattr_add(&msg->nh, TCA_FLOWER_KEY_ETH_DST, ETHER_ADDR_LEN,
292                            &spec->dst.addr_bytes);
293                 nlattr_add(&msg->nh,
294                            TCA_FLOWER_KEY_ETH_DST_MASK, ETHER_ADDR_LEN,
295                            &mask->dst.addr_bytes);
296         }
297         if (!is_zero_ether_addr(&mask->src)) {
298                 nlattr_add(&msg->nh, TCA_FLOWER_KEY_ETH_SRC, ETHER_ADDR_LEN,
299                            &spec->src.addr_bytes);
300                 nlattr_add(&msg->nh,
301                            TCA_FLOWER_KEY_ETH_SRC_MASK, ETHER_ADDR_LEN,
302                            &mask->src.addr_bytes);
303         }
304         return 0;
305 }
306
307 /**
308  * Make as much checks as possible on a VLAN item, and if a flow is provided,
309  * fill it appropriately with VLAN info.
310  *
311  * @param[in] item
312  *   Item specification.
313  * @param[in, out] data
314  *   Additional data structure to tell next layers we've been here.
315  *
316  * @return
317  *   0 if checks are alright, -1 otherwise.
318  */
319 static int
320 tap_flow_create_vlan(const struct rte_flow_item *item, void *data)
321 {
322         struct convert_data *info = (struct convert_data *)data;
323         const struct rte_flow_item_vlan *spec = item->spec;
324         const struct rte_flow_item_vlan *mask = item->mask;
325         struct rte_flow *flow = info->flow;
326         struct nlmsg *msg;
327
328         /* use default mask if none provided */
329         if (!mask)
330                 mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_VLAN].default_mask;
331         /* TC does not support tpid masking. Only accept if exact match. */
332         if (mask->tpid && mask->tpid != 0xffff)
333                 return -1;
334         /* Double-tagging not supported. */
335         if (spec && mask->tpid && spec->tpid != htons(ETH_P_8021Q))
336                 return -1;
337         info->vlan = 1;
338         if (!flow)
339                 return 0;
340         msg = &flow->msg;
341         msg->t.tcm_info = TC_H_MAKE(msg->t.tcm_info, htons(ETH_P_8021Q));
342 #define VLAN_PRIO(tci) ((tci) >> 13)
343 #define VLAN_ID(tci) ((tci) & 0xfff)
344         if (!spec)
345                 return 0;
346         if (spec->tci) {
347                 uint16_t tci = ntohs(spec->tci) & mask->tci;
348                 uint16_t prio = VLAN_PRIO(tci);
349                 uint8_t vid = VLAN_ID(tci);
350
351                 if (prio)
352                         nlattr_add8(&msg->nh, TCA_FLOWER_KEY_VLAN_PRIO, prio);
353                 if (vid)
354                         nlattr_add16(&msg->nh, TCA_FLOWER_KEY_VLAN_ID, vid);
355         }
356         return 0;
357 }
358
359 /**
360  * Make as much checks as possible on an IPv4 item, and if a flow is provided,
361  * fill it appropriately with IPv4 info.
362  *
363  * @param[in] item
364  *   Item specification.
365  * @param[in, out] data
366  *   Additional data structure to tell next layers we've been here.
367  *
368  * @return
369  *   0 if checks are alright, -1 otherwise.
370  */
371 static int
372 tap_flow_create_ipv4(const struct rte_flow_item *item, void *data)
373 {
374         struct convert_data *info = (struct convert_data *)data;
375         const struct rte_flow_item_ipv4 *spec = item->spec;
376         const struct rte_flow_item_ipv4 *mask = item->mask;
377         struct rte_flow *flow = info->flow;
378         struct nlmsg *msg;
379
380         /* use default mask if none provided */
381         if (!mask)
382                 mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_IPV4].default_mask;
383         /* check that previous eth type is compatible with ipv4 */
384         if (info->eth_type && info->eth_type != htons(ETH_P_IP))
385                 return -1;
386         /* store ip_proto for consistency if udp/tcp pattern item comes next */
387         if (spec)
388                 info->ip_proto = spec->hdr.next_proto_id;
389         if (!flow)
390                 return 0;
391         msg = &flow->msg;
392         if (!info->eth_type)
393                 info->eth_type = htons(ETH_P_IP);
394         if (!info->vlan)
395                 msg->t.tcm_info = TC_H_MAKE(msg->t.tcm_info, htons(ETH_P_IP));
396         if (!spec)
397                 return 0;
398         if (spec->hdr.dst_addr) {
399                 nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST,
400                              spec->hdr.dst_addr);
401                 nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST_MASK,
402                              mask->hdr.dst_addr);
403         }
404         if (spec->hdr.src_addr) {
405                 nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC,
406                              spec->hdr.src_addr);
407                 nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC_MASK,
408                              mask->hdr.src_addr);
409         }
410         if (spec->hdr.next_proto_id)
411                 nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO,
412                             spec->hdr.next_proto_id);
413         return 0;
414 }
415
416 /**
417  * Make as much checks as possible on an IPv6 item, and if a flow is provided,
418  * fill it appropriately with IPv6 info.
419  *
420  * @param[in] item
421  *   Item specification.
422  * @param[in, out] data
423  *   Additional data structure to tell next layers we've been here.
424  *
425  * @return
426  *   0 if checks are alright, -1 otherwise.
427  */
428 static int
429 tap_flow_create_ipv6(const struct rte_flow_item *item, void *data)
430 {
431         struct convert_data *info = (struct convert_data *)data;
432         const struct rte_flow_item_ipv6 *spec = item->spec;
433         const struct rte_flow_item_ipv6 *mask = item->mask;
434         struct rte_flow *flow = info->flow;
435         uint8_t empty_addr[16] = { 0 };
436         struct nlmsg *msg;
437
438         /* use default mask if none provided */
439         if (!mask)
440                 mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_IPV6].default_mask;
441         /* check that previous eth type is compatible with ipv6 */
442         if (info->eth_type && info->eth_type != htons(ETH_P_IPV6))
443                 return -1;
444         /* store ip_proto for consistency if udp/tcp pattern item comes next */
445         if (spec)
446                 info->ip_proto = spec->hdr.proto;
447         if (!flow)
448                 return 0;
449         msg = &flow->msg;
450         if (!info->eth_type)
451                 info->eth_type = htons(ETH_P_IPV6);
452         if (!info->vlan)
453                 msg->t.tcm_info = TC_H_MAKE(msg->t.tcm_info, htons(ETH_P_IPV6));
454         if (!spec)
455                 return 0;
456         if (memcmp(spec->hdr.dst_addr, empty_addr, 16)) {
457                 nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST,
458                            sizeof(spec->hdr.dst_addr), &spec->hdr.dst_addr);
459                 nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST_MASK,
460                            sizeof(mask->hdr.dst_addr), &mask->hdr.dst_addr);
461         }
462         if (memcmp(spec->hdr.src_addr, empty_addr, 16)) {
463                 nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC,
464                            sizeof(spec->hdr.src_addr), &spec->hdr.src_addr);
465                 nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC_MASK,
466                            sizeof(mask->hdr.src_addr), &mask->hdr.src_addr);
467         }
468         if (spec->hdr.proto)
469                 nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, spec->hdr.proto);
470         return 0;
471 }
472
473 /**
474  * Make as much checks as possible on a UDP item, and if a flow is provided,
475  * fill it appropriately with UDP info.
476  *
477  * @param[in] item
478  *   Item specification.
479  * @param[in, out] data
480  *   Additional data structure to tell next layers we've been here.
481  *
482  * @return
483  *   0 if checks are alright, -1 otherwise.
484  */
485 static int
486 tap_flow_create_udp(const struct rte_flow_item *item, void *data)
487 {
488         struct convert_data *info = (struct convert_data *)data;
489         const struct rte_flow_item_udp *spec = item->spec;
490         const struct rte_flow_item_udp *mask = item->mask;
491         struct rte_flow *flow = info->flow;
492         struct nlmsg *msg;
493
494         /* use default mask if none provided */
495         if (!mask)
496                 mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_UDP].default_mask;
497         /* check that previous ip_proto is compatible with udp */
498         if (info->ip_proto && info->ip_proto != IPPROTO_UDP)
499                 return -1;
500         if (!flow)
501                 return 0;
502         msg = &flow->msg;
503         nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_UDP);
504         if (!spec)
505                 return 0;
506         if (spec->hdr.dst_port &&
507             (spec->hdr.dst_port & mask->hdr.dst_port) == spec->hdr.dst_port)
508                 nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_DST,
509                              spec->hdr.dst_port);
510         if (spec->hdr.src_port &&
511             (spec->hdr.src_port & mask->hdr.src_port) == spec->hdr.src_port)
512                 nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_SRC,
513                              spec->hdr.src_port);
514         return 0;
515 }
516
517 /**
518  * Make as much checks as possible on a TCP item, and if a flow is provided,
519  * fill it appropriately with TCP info.
520  *
521  * @param[in] item
522  *   Item specification.
523  * @param[in, out] data
524  *   Additional data structure to tell next layers we've been here.
525  *
526  * @return
527  *   0 if checks are alright, -1 otherwise.
528  */
529 static int
530 tap_flow_create_tcp(const struct rte_flow_item *item, void *data)
531 {
532         struct convert_data *info = (struct convert_data *)data;
533         const struct rte_flow_item_tcp *spec = item->spec;
534         const struct rte_flow_item_tcp *mask = item->mask;
535         struct rte_flow *flow = info->flow;
536         struct nlmsg *msg;
537
538         /* use default mask if none provided */
539         if (!mask)
540                 mask = tap_flow_items[RTE_FLOW_ITEM_TYPE_TCP].default_mask;
541         /* check that previous ip_proto is compatible with tcp */
542         if (info->ip_proto && info->ip_proto != IPPROTO_TCP)
543                 return -1;
544         if (!flow)
545                 return 0;
546         msg = &flow->msg;
547         nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_TCP);
548         if (!spec)
549                 return 0;
550         if (spec->hdr.dst_port &&
551             (spec->hdr.dst_port & mask->hdr.dst_port) == spec->hdr.dst_port)
552                 nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_DST,
553                              spec->hdr.dst_port);
554         if (spec->hdr.src_port &&
555             (spec->hdr.src_port & mask->hdr.src_port) == spec->hdr.src_port)
556                 nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_SRC,
557                              spec->hdr.src_port);
558         return 0;
559 }
560
561 /**
562  * Check support for a given item.
563  *
564  * @param[in] item
565  *   Item specification.
566  * @param size
567  *   Bit-Mask size in bytes.
568  * @param[in] supported_mask
569  *   Bit-mask covering supported fields to compare with spec, last and mask in
570  *   \item.
571  * @param[in] default_mask
572  *   Bit-mask default mask if none is provided in \item.
573  *
574  * @return
575  *   0 on success.
576  */
577 static int
578 tap_flow_item_validate(const struct rte_flow_item *item,
579                        unsigned int size,
580                        const uint8_t *supported_mask,
581                        const uint8_t *default_mask)
582 {
583         int ret = 0;
584
585         /* An empty layer is allowed, as long as all fields are NULL */
586         if (!item->spec && (item->mask || item->last))
587                 return -1;
588         /* Is the item spec compatible with what the NIC supports? */
589         if (item->spec && !item->mask) {
590                 unsigned int i;
591                 const uint8_t *spec = item->spec;
592
593                 for (i = 0; i < size; ++i)
594                         if ((spec[i] | supported_mask[i]) != supported_mask[i])
595                                 return -1;
596                 /* Is the default mask compatible with what the NIC supports? */
597                 for (i = 0; i < size; i++)
598                         if ((default_mask[i] | supported_mask[i]) !=
599                             supported_mask[i])
600                                 return -1;
601         }
602         /* Is the item last compatible with what the NIC supports? */
603         if (item->last && !item->mask) {
604                 unsigned int i;
605                 const uint8_t *spec = item->last;
606
607                 for (i = 0; i < size; ++i)
608                         if ((spec[i] | supported_mask[i]) != supported_mask[i])
609                                 return -1;
610         }
611         /* Is the item mask compatible with what the NIC supports? */
612         if (item->mask) {
613                 unsigned int i;
614                 const uint8_t *spec = item->mask;
615
616                 for (i = 0; i < size; ++i)
617                         if ((spec[i] | supported_mask[i]) != supported_mask[i])
618                                 return -1;
619         }
620         /**
621          * Once masked, Are item spec and item last equal?
622          * TC does not support range so anything else is invalid.
623          */
624         if (item->spec && item->last) {
625                 uint8_t spec[size];
626                 uint8_t last[size];
627                 const uint8_t *apply = default_mask;
628                 unsigned int i;
629
630                 if (item->mask)
631                         apply = item->mask;
632                 for (i = 0; i < size; ++i) {
633                         spec[i] = ((const uint8_t *)item->spec)[i] & apply[i];
634                         last[i] = ((const uint8_t *)item->last)[i] & apply[i];
635                 }
636                 ret = memcmp(spec, last, size);
637         }
638         return ret;
639 }
640
641 /**
642  * Transform a DROP/PASSTHRU action item in the provided flow for TC.
643  *
644  * @param[in, out] flow
645  *   Flow to be filled.
646  * @param[in] action
647  *   Appropriate action to be set in the TCA_GACT_PARMS structure.
648  *
649  * @return
650  *   0 if checks are alright, -1 otherwise.
651  */
652 static int
653 add_action_gact(struct rte_flow *flow, int action)
654 {
655         struct nlmsg *msg = &flow->msg;
656         size_t act_index = 1;
657         struct tc_gact p = {
658                 .action = action
659         };
660
661         if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
662                 return -1;
663         if (nlattr_nested_start(msg, act_index++) < 0)
664                 return -1;
665         nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
666         if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
667                 return -1;
668         nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
669         nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
670         nlattr_nested_finish(msg); /* nested act_index */
671         nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
672         return 0;
673 }
674
675 /**
676  * Transform a QUEUE action item in the provided flow for TC.
677  *
678  * @param[in, out] flow
679  *   Flow to be filled.
680  * @param[in] queue
681  *   Queue id to use.
682  *
683  * @return
684  *   0 if checks are alright, -1 otherwise.
685  */
686 static int
687 add_action_skbedit(struct rte_flow *flow, uint16_t queue)
688 {
689         struct nlmsg *msg = &flow->msg;
690         size_t act_index = 1;
691         struct tc_skbedit p = {
692                 .action = TC_ACT_PIPE
693         };
694
695         if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
696                 return -1;
697         if (nlattr_nested_start(msg, act_index++) < 0)
698                 return -1;
699         nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
700         if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
701                 return -1;
702         nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
703         nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
704         nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
705         nlattr_nested_finish(msg); /* nested act_index */
706         nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
707         return 0;
708 }
709
710 /**
711  * Validate a flow supported by TC.
712  * If flow param is not NULL, then also fill the netlink message inside.
713  *
714  * @param pmd
715  *   Pointer to private structure.
716  * @param[in] attr
717  *   Flow rule attributes.
718  * @param[in] pattern
719  *   Pattern specification (list terminated by the END pattern item).
720  * @param[in] actions
721  *   Associated actions (list terminated by the END action).
722  * @param[out] error
723  *   Perform verbose error reporting if not NULL.
724  * @param[in, out] flow
725  *   Flow structure to update.
726  *
727  * @return
728  *   0 on success, a negative errno value otherwise and rte_errno is set.
729  */
730 static int
731 priv_flow_process(struct pmd_internals *pmd,
732                   const struct rte_flow_attr *attr,
733                   const struct rte_flow_item items[],
734                   const struct rte_flow_action actions[],
735                   struct rte_flow_error *error,
736                   struct rte_flow *flow)
737 {
738         const struct tap_flow_items *cur_item = tap_flow_items;
739         struct convert_data data = {
740                 .eth_type = 0,
741                 .ip_proto = 0,
742                 .flow = flow,
743         };
744         int action = 0; /* Only one action authorized for now */
745
746         if (attr->group > MAX_GROUP) {
747                 rte_flow_error_set(
748                         error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
749                         NULL, "group value too big: cannot exceed 15");
750                 return -rte_errno;
751         }
752         if (attr->priority > MAX_PRIORITY) {
753                 rte_flow_error_set(
754                         error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
755                         NULL, "priority value too big");
756                 return -rte_errno;
757         } else if (flow) {
758                 uint16_t group = attr->group << GROUP_SHIFT;
759                 uint16_t prio = group | (attr->priority + PRIORITY_OFFSET);
760                 flow->msg.t.tcm_info = TC_H_MAKE(prio << 16,
761                                                  flow->msg.t.tcm_info);
762         }
763         if (!attr->ingress) {
764                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR,
765                                    NULL, "direction should be ingress");
766                 return -rte_errno;
767         }
768         /* rte_flow ingress is actually egress as seen in the kernel */
769         if (attr->ingress && flow)
770                 flow->msg.t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
771         if (flow) {
772                 /* use flower filter type */
773                 nlattr_add(&flow->msg.nh, TCA_KIND, sizeof("flower"), "flower");
774                 if (nlattr_nested_start(&flow->msg, TCA_OPTIONS) < 0)
775                         goto exit_item_not_supported;
776         }
777         for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) {
778                 const struct tap_flow_items *token = NULL;
779                 unsigned int i;
780                 int err = 0;
781
782                 if (items->type == RTE_FLOW_ITEM_TYPE_VOID)
783                         continue;
784                 for (i = 0;
785                      cur_item->items &&
786                      cur_item->items[i] != RTE_FLOW_ITEM_TYPE_END;
787                      ++i) {
788                         if (cur_item->items[i] == items->type) {
789                                 token = &tap_flow_items[items->type];
790                                 break;
791                         }
792                 }
793                 if (!token)
794                         goto exit_item_not_supported;
795                 cur_item = token;
796                 err = tap_flow_item_validate(
797                         items, cur_item->mask_sz,
798                         (const uint8_t *)cur_item->mask,
799                         (const uint8_t *)cur_item->default_mask);
800                 if (err)
801                         goto exit_item_not_supported;
802                 if (flow && cur_item->convert) {
803                         if (!pmd->flower_vlan_support &&
804                             cur_item->convert == tap_flow_create_vlan)
805                                 goto exit_item_not_supported;
806                         err = cur_item->convert(items, &data);
807                         if (err)
808                                 goto exit_item_not_supported;
809                 }
810         }
811         if (flow) {
812                 if (pmd->flower_vlan_support && data.vlan) {
813                         nlattr_add16(&flow->msg.nh, TCA_FLOWER_KEY_ETH_TYPE,
814                                      htons(ETH_P_8021Q));
815                         nlattr_add16(&flow->msg.nh,
816                                      TCA_FLOWER_KEY_VLAN_ETH_TYPE,
817                                      data.eth_type ?
818                                      data.eth_type : htons(ETH_P_ALL));
819                 } else if (data.eth_type) {
820                         nlattr_add16(&flow->msg.nh, TCA_FLOWER_KEY_ETH_TYPE,
821                                      data.eth_type);
822                 }
823         }
824         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) {
825                 int err = 0;
826
827                 if (actions->type == RTE_FLOW_ACTION_TYPE_VOID) {
828                         continue;
829                 } else if (actions->type == RTE_FLOW_ACTION_TYPE_DROP) {
830                         if (action)
831                                 goto exit_action_not_supported;
832                         action = 1;
833                         if (flow)
834                                 err = add_action_gact(flow, TC_ACT_SHOT);
835                 } else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
836                         if (action)
837                                 goto exit_action_not_supported;
838                         action = 1;
839                         if (flow)
840                                 err = add_action_gact(flow, TC_ACT_UNSPEC);
841                 } else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
842                         const struct rte_flow_action_queue *queue =
843                                 (const struct rte_flow_action_queue *)
844                                 actions->conf;
845                         if (action)
846                                 goto exit_action_not_supported;
847                         action = 1;
848                         if (!queue || (queue->index >= pmd->nb_queues))
849                                 goto exit_action_not_supported;
850                         if (flow)
851                                 err = add_action_skbedit(flow, queue->index);
852                 } else {
853                         goto exit_action_not_supported;
854                 }
855                 if (err)
856                         goto exit_action_not_supported;
857         }
858         if (flow)
859                 nlattr_nested_finish(&flow->msg); /* nested TCA_OPTIONS */
860         return 0;
861 exit_item_not_supported:
862         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
863                            items, "item not supported");
864         return -rte_errno;
865 exit_action_not_supported:
866         rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
867                            actions, "action not supported");
868         return -rte_errno;
869 }
870
871
872
873 /**
874  * Validate a flow.
875  *
876  * @see rte_flow_validate()
877  * @see rte_flow_ops
878  */
879 static int
880 tap_flow_validate(struct rte_eth_dev *dev,
881                   const struct rte_flow_attr *attr,
882                   const struct rte_flow_item items[],
883                   const struct rte_flow_action actions[],
884                   struct rte_flow_error *error)
885 {
886         struct pmd_internals *pmd = dev->data->dev_private;
887
888         return priv_flow_process(pmd, attr, items, actions, error, NULL);
889 }
890
891 /**
892  * Set a unique handle in a flow.
893  *
894  * The kernel supports TC rules with equal priority, as long as they use the
895  * same matching fields (e.g.: dst mac and ipv4) with different values (and
896  * full mask to ensure no collision is possible).
897  * In those rules, the handle (uint32_t) is the part that would identify
898  * specifically each rule.
899  *
900  * On 32-bit architectures, the handle can simply be the flow's pointer address.
901  * On 64-bit architectures, we rely on jhash(flow) to find a (sufficiently)
902  * unique handle.
903  *
904  * @param[in, out] flow
905  *   The flow that needs its handle set.
906  */
907 static void
908 tap_flow_set_handle(struct rte_flow *flow)
909 {
910         uint32_t handle = 0;
911
912         if (sizeof(flow) > 4)
913                 handle = rte_jhash(&flow, sizeof(flow), 1);
914         else
915                 handle = (uintptr_t)flow;
916         /* must be at least 1 to avoid letting the kernel choose one for us */
917         if (!handle)
918                 handle = 1;
919         flow->msg.t.tcm_handle = handle;
920 }
921
922 /**
923  * Create a flow.
924  *
925  * @see rte_flow_create()
926  * @see rte_flow_ops
927  */
928 static struct rte_flow *
929 tap_flow_create(struct rte_eth_dev *dev,
930                 const struct rte_flow_attr *attr,
931                 const struct rte_flow_item items[],
932                 const struct rte_flow_action actions[],
933                 struct rte_flow_error *error)
934 {
935         struct pmd_internals *pmd = dev->data->dev_private;
936         struct rte_flow *flow = NULL;
937         struct nlmsg *msg = NULL;
938         int err;
939
940         if (!pmd->if_index) {
941                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
942                                    NULL,
943                                    "can't create rule, ifindex not found");
944                 goto fail;
945         }
946         flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
947         if (!flow) {
948                 rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
949                                    NULL, "cannot allocate memory for rte_flow");
950                 goto fail;
951         }
952         msg = &flow->msg;
953         tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
954                     NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
955         msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
956         tap_flow_set_handle(flow);
957         if (priv_flow_process(pmd, attr, items, actions, error, flow))
958                 goto fail;
959         err = nl_send(pmd->nlsk_fd, &msg->nh);
960         if (err < 0) {
961                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
962                                    NULL, "couldn't send request to kernel");
963                 goto fail;
964         }
965         err = nl_recv_ack(pmd->nlsk_fd);
966         if (err < 0) {
967                 rte_flow_error_set(error, EEXIST, RTE_FLOW_ERROR_TYPE_HANDLE,
968                                    NULL, "overlapping rules");
969                 goto fail;
970         }
971         LIST_INSERT_HEAD(&pmd->flows, flow, next);
972         return flow;
973 fail:
974         if (flow)
975                 rte_free(flow);
976         return NULL;
977 }
978
979 /**
980  * Destroy a flow.
981  *
982  * @see rte_flow_destroy()
983  * @see rte_flow_ops
984  */
985 static int
986 tap_flow_destroy(struct rte_eth_dev *dev,
987                  struct rte_flow *flow,
988                  struct rte_flow_error *error)
989 {
990         struct pmd_internals *pmd = dev->data->dev_private;
991         int ret = 0;
992
993         LIST_REMOVE(flow, next);
994         flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
995         flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
996
997         ret = nl_send(pmd->nlsk_fd, &flow->msg.nh);
998         if (ret < 0) {
999                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
1000                                    NULL, "couldn't send request to kernel");
1001                 goto end;
1002         }
1003         ret = nl_recv_ack(pmd->nlsk_fd);
1004         if (ret < 0)
1005                 rte_flow_error_set(
1006                         error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1007                         "couldn't receive kernel ack to our request");
1008 end:
1009         rte_free(flow);
1010         return ret;
1011 }
1012
1013 /**
1014  * Destroy all flows.
1015  *
1016  * @see rte_flow_flush()
1017  * @see rte_flow_ops
1018  */
1019 int
1020 tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
1021 {
1022         struct pmd_internals *pmd = dev->data->dev_private;
1023         struct rte_flow *flow;
1024
1025         while (!LIST_EMPTY(&pmd->flows)) {
1026                 flow = LIST_FIRST(&pmd->flows);
1027                 if (tap_flow_destroy(dev, flow, error) < 0)
1028                         return -1;
1029         }
1030         return 0;
1031 }
1032
1033 /**
1034  * Manage filter operations.
1035  *
1036  * @param dev
1037  *   Pointer to Ethernet device structure.
1038  * @param filter_type
1039  *   Filter type.
1040  * @param filter_op
1041  *   Operation to perform.
1042  * @param arg
1043  *   Pointer to operation-specific structure.
1044  *
1045  * @return
1046  *   0 on success, negative errno value on failure.
1047  */
1048 int
1049 tap_dev_filter_ctrl(struct rte_eth_dev *dev,
1050                     enum rte_filter_type filter_type,
1051                     enum rte_filter_op filter_op,
1052                     void *arg)
1053 {
1054         struct pmd_internals *pmd = dev->data->dev_private;
1055
1056         if (!pmd->flower_support)
1057                 return -ENOTSUP;
1058         switch (filter_type) {
1059         case RTE_ETH_FILTER_GENERIC:
1060                 if (filter_op != RTE_ETH_FILTER_GET)
1061                         return -EINVAL;
1062                 *(const void **)arg = &tap_flow_ops;
1063                 return 0;
1064         default:
1065                 RTE_LOG(ERR, PMD, "%p: filter type (%d) not supported",
1066                         (void *)dev, filter_type);
1067         }
1068         return -EINVAL;
1069 }
1070