1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(c) 2017 Intel Corporation.
3
4Flow Classification Library
5===========================
6
7DPDK provides a Flow Classification library that provides the ability
8to classify an input packet by matching it against a set of Flow rules.
9
10The initial implementation supports counting of IPv4 5-tuple packets which match
11a particular Flow rule only.
12
13Please refer to the
14:doc:`./rte_flow`
15for more information.
16
17The Flow Classification library uses the ``librte_table`` API for managing Flow
18rules and matching packets against the Flow rules.
19The library is table agnostic and can use the following tables:
20``Access Control List``, ``Hash`` and ``Longest Prefix Match(LPM)``.
21The ``Access Control List`` table is used in the initial implementation.
22
23Please refer to the
24:doc:`./packet_framework`
25for more information.on ``librte_table``.
26
27DPDK provides an Access Control List library that provides the ability to
28classify an input packet based on a set of classification rules.
29
30Please refer to the
31:doc:`./packet_classif_access_ctrl`
32library for more information on ``librte_acl``.
33
34There is also a Flow Classify sample application which demonstrates the use of
35the Flow Classification Library API's.
36
37Please refer to the
38:doc:`../sample_app_ug/flow_classify`
39for more information on the ``flow_classify`` sample application.
40
41Overview
42--------
43
44The library has the following API's
45
46.. code-block:: c
47
48    /**
49     * Flow classifier create
50     *
51     * @param params
52     *   Parameters for flow classifier creation
53     * @return
54     *   Handle to flow classifier instance on success or NULL otherwise
55     */
56    struct rte_flow_classifier *
57    rte_flow_classifier_create(struct rte_flow_classifier_params *params);
58
59    /**
60     * Flow classifier free
61     *
62     * @param cls
63     *   Handle to flow classifier instance
64     * @return
65     *   0 on success, error code otherwise
66     */
67    int
68    rte_flow_classifier_free(struct rte_flow_classifier *cls);
69
70    /**
71     * Flow classify table create
72     *
73     * @param cls
74     *   Handle to flow classifier instance
75     * @param params
76     *   Parameters for flow_classify table creation
77     * @return
78     *   0 on success, error code otherwise
79     */
80    int
81    rte_flow_classify_table_create(struct rte_flow_classifier *cls,
82           struct rte_flow_classify_table_params *params);
83
84    /**
85     * Validate the flow classify rule
86     *
87     * @param[in] cls
88     *   Handle to flow classifier instance
89     * @param[in] attr
90     *   Flow rule attributes
91     * @param[in] pattern
92     *   Pattern specification (list terminated by the END pattern item).
93     * @param[in] actions
94     *   Associated actions (list terminated by the END pattern item).
95     * @param[out] error
96     *   Perform verbose error reporting if not NULL. Structure
97     *   initialised in case of error only.
98     * @return
99     *   0 on success, error code otherwise
100     */
101    int
102    rte_flow_classify_validate(struct rte_flow_classifier *cls,
103            const struct rte_flow_attr *attr,
104            const struct rte_flow_item pattern[],
105            const struct rte_flow_action actions[],
106            struct rte_flow_error *error);
107
108    /**
109     * Add a flow classify rule to the flow_classifier table.
110     *
111     * @param[in] cls
112     *   Flow classifier handle
113     * @param[in] attr
114     *   Flow rule attributes
115     * @param[in] pattern
116     *   Pattern specification (list terminated by the END pattern item).
117     * @param[in] actions
118     *   Associated actions (list terminated by the END pattern item).
119     * @param[out] key_found
120     *   returns 1 if rule present already, 0 otherwise.
121     * @param[out] error
122     *   Perform verbose error reporting if not NULL. Structure
123     *   initialised in case of error only.
124     * @return
125     *   A valid handle in case of success, NULL otherwise.
126     */
127    struct rte_flow_classify_rule *
128    rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls,
129            const struct rte_flow_attr *attr,
130            const struct rte_flow_item pattern[],
131            const struct rte_flow_action actions[],
132            int *key_found;
133            struct rte_flow_error *error);
134
135    /**
136     * Delete a flow classify rule from the flow_classifier table.
137     *
138     * @param[in] cls
139     *   Flow classifier handle
140     * @param[in] rule
141     *   Flow classify rule
142     * @return
143     *   0 on success, error code otherwise.
144     */
145    int
146    rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
147            struct rte_flow_classify_rule *rule);
148
149    /**
150     * Query flow classifier for given rule.
151     *
152     * @param[in] cls
153     *   Flow classifier handle
154     * @param[in] pkts
155     *   Pointer to packets to process
156     * @param[in] nb_pkts
157     *   Number of packets to process
158     * @param[in] rule
159     *   Flow classify rule
160     * @param[in] stats
161     *   Flow classify stats
162     *
163     * @return
164     *   0 on success, error code otherwise.
165     */
166    int
167    rte_flow_classifier_query(struct rte_flow_classifier *cls,
168            struct rte_mbuf **pkts,
169            const uint16_t nb_pkts,
170            struct rte_flow_classify_rule *rule,
171            struct rte_flow_classify_stats *stats);
172
173Classifier creation
174~~~~~~~~~~~~~~~~~~~
175
176The application creates the ``Classifier`` using the
177``rte_flow_classifier_create`` API.
178The ``rte_flow_classify_params`` structure must be initialised by the
179application before calling the API.
180
181.. code-block:: c
182
183    struct rte_flow_classifier_params {
184        /** flow classifier name */
185        const char *name;
186
187        /** CPU socket ID where memory for the flow classifier and its */
188        /** elements (tables) should be allocated */
189        int socket_id;
190    };
191
192The ``Classifier`` has the following internal structures:
193
194.. code-block:: c
195
196    struct rte_cls_table {
197        /* Input parameters */
198        struct rte_table_ops ops;
199        uint32_t entry_size;
200        enum rte_flow_classify_table_type type;
201
202        /* Handle to the low-level table object */
203        void *h_table;
204    };
205
206    #define RTE_FLOW_CLASSIFIER_MAX_NAME_SZ 256
207
208    struct rte_flow_classifier {
209        /* Input parameters */
210        char name[RTE_FLOW_CLASSIFIER_MAX_NAME_SZ];
211        int socket_id;
212
213        /* Internal */
214        /* ntuple_filter */
215        struct rte_eth_ntuple_filter ntuple_filter;
216
217        /* classifier tables */
218        struct rte_cls_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX];
219        uint32_t table_mask;
220        uint32_t num_tables;
221
222        uint16_t nb_pkts;
223        struct rte_flow_classify_table_entry
224            *entries[RTE_PORT_IN_BURST_SIZE_MAX];
225    } __rte_cache_aligned;
226
227Adding a table to the Classifier
228~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229
230The application adds a table to the ``Classifier`` using the
231``rte_flow_classify_table_create`` API.
232The ``rte_flow_classify_table_params`` structure must be initialised by the
233application before calling the API.
234
235.. code-block:: c
236
237    struct rte_flow_classify_table_params {
238        /** Table operations (specific to each table type) */
239        struct rte_table_ops *ops;
240
241        /** Opaque param to be passed to the table create operation */
242        void *arg_create;
243
244        /** Classifier table type */
245        enum rte_flow_classify_table_type type;
246     };
247
248To create an ACL table the ``rte_table_acl_params`` structure must be
249initialised and assigned to ``arg_create`` in the
250``rte_flow_classify_table_params`` structure.
251
252.. code-block:: c
253
254    struct rte_table_acl_params {
255        /** Name */
256        const char *name;
257
258        /** Maximum number of ACL rules in the table */
259        uint32_t n_rules;
260
261        /** Number of fields in the ACL rule specification */
262        uint32_t n_rule_fields;
263
264        /** Format specification of the fields of the ACL rule */
265        struct rte_acl_field_def field_format[RTE_ACL_MAX_FIELDS];
266    };
267
268The fields for the ACL rule must also be initialised by the application.
269
270An ACL table can be added to the ``Classifier`` for each ACL rule, for example
271another table could be added for the IPv6 5-tuple rule.
272
273Flow Parsing
274~~~~~~~~~~~~
275
276The library currently supports three IPv4 5-tuple flow patterns, for UDP, TCP
277and SCTP.
278
279.. code-block:: c
280
281    /* Pattern for IPv4 5-tuple UDP filter */
282    static enum rte_flow_item_type pattern_ntuple_1[] = {
283        RTE_FLOW_ITEM_TYPE_ETH,
284        RTE_FLOW_ITEM_TYPE_IPV4,
285        RTE_FLOW_ITEM_TYPE_UDP,
286        RTE_FLOW_ITEM_TYPE_END,
287    };
288
289    /* Pattern for IPv4 5-tuple TCP filter */
290    static enum rte_flow_item_type pattern_ntuple_2[] = {
291        RTE_FLOW_ITEM_TYPE_ETH,
292        RTE_FLOW_ITEM_TYPE_IPV4,
293        RTE_FLOW_ITEM_TYPE_TCP,
294        RTE_FLOW_ITEM_TYPE_END,
295    };
296
297    /* Pattern for IPv4 5-tuple SCTP filter */
298    static enum rte_flow_item_type pattern_ntuple_3[] = {
299        RTE_FLOW_ITEM_TYPE_ETH,
300        RTE_FLOW_ITEM_TYPE_IPV4,
301        RTE_FLOW_ITEM_TYPE_SCTP,
302        RTE_FLOW_ITEM_TYPE_END,
303    };
304
305The API function ``rte_flow_classify_validate`` parses the
306IPv4 5-tuple pattern, attributes and actions and returns the 5-tuple data in the
307``rte_eth_ntuple_filter`` structure.
308
309.. code-block:: c
310
311    static int
312    rte_flow_classify_validate(struct rte_flow_classifier *cls,
313                   const struct rte_flow_attr *attr,
314                   const struct rte_flow_item pattern[],
315                   const struct rte_flow_action actions[],
316                   struct rte_flow_error *error)
317
318Adding Flow Rules
319~~~~~~~~~~~~~~~~~
320
321The ``rte_flow_classify_table_entry_add`` API creates an
322``rte_flow_classify`` object which contains the flow_classify id and type, the
323action, a union of add and delete keys and a union of rules.
324It uses the ``rte_flow_classify_validate`` API function for parsing the
325flow parameters.
326The 5-tuple ACL key data is obtained from the ``rte_eth_ntuple_filter``
327structure populated by the ``classify_parse_ntuple_filter`` function which
328parses the Flow rule.
329
330.. code-block:: c
331
332    struct acl_keys {
333        struct rte_table_acl_rule_add_params key_add; /* add key */
334        struct rte_table_acl_rule_delete_params key_del; /* delete key */
335    };
336
337    struct classify_rules {
338        enum rte_flow_classify_rule_type type;
339        union {
340            struct rte_flow_classify_ipv4_5tuple ipv4_5tuple;
341        } u;
342    };
343
344    struct rte_flow_classify {
345        uint32_t id;  /* unique ID of classify object */
346        enum rte_flow_classify_table_type tbl_type; /* rule table */
347        struct classify_rules rules; /* union of rules */
348        union {
349            struct acl_keys key;
350        } u;
351        int key_found; /* rule key found in table */
352        struct rte_flow_classify_table_entry entry;  /* rule meta data */
353        void *entry_ptr; /* handle to the table entry for rule meta data */
354    };
355
356It then calls the ``table.ops.f_add`` API to add the rule to the ACL
357table.
358
359Deleting Flow Rules
360~~~~~~~~~~~~~~~~~~~
361
362The ``rte_flow_classify_table_entry_delete`` API calls the
363``table.ops.f_delete`` API to delete a rule from the ACL table.
364
365Packet Matching
366~~~~~~~~~~~~~~~
367
368The ``rte_flow_classifier_query`` API is used to find packets which match a
369given flow Flow rule in the table.
370This API calls the flow_classify_run internal function which calls the
371``table.ops.f_lookup`` API to see if any packets in a burst match any
372of the Flow rules in the table.
373The meta data for the highest priority rule matched for each packet is returned
374in the entries array in the ``rte_flow_classify`` object.
375The internal function ``action_apply`` implements the ``Count`` action which is
376used to return data which matches a particular Flow rule.
377
378The rte_flow_classifier_query API uses the following structures to return data
379to the application.
380
381.. code-block:: c
382
383    /** IPv4 5-tuple data */
384    struct rte_flow_classify_ipv4_5tuple {
385        uint32_t dst_ip;         /**< Destination IP address in big endian. */
386        uint32_t dst_ip_mask;    /**< Mask of destination IP address. */
387        uint32_t src_ip;         /**< Source IP address in big endian. */
388        uint32_t src_ip_mask;    /**< Mask of destination IP address. */
389        uint16_t dst_port;       /**< Destination port in big endian. */
390        uint16_t dst_port_mask;  /**< Mask of destination port. */
391        uint16_t src_port;       /**< Source Port in big endian. */
392        uint16_t src_port_mask;  /**< Mask of source port. */
393        uint8_t proto;           /**< L4 protocol. */
394        uint8_t proto_mask;      /**< Mask of L4 protocol. */
395    };
396
397    /**
398     * Flow stats
399     *
400     * For the count action, stats can be returned by the query API.
401     *
402     * Storage for stats is provided by the application.
403     *
404     *
405     */
406    struct rte_flow_classify_stats {
407        void *stats;
408    };
409
410    struct rte_flow_classify_5tuple_stats {
411        /** count of packets that match IPv4 5tuple pattern */
412        uint64_t counter1;
413        /** IPv4 5tuple data */
414        struct rte_flow_classify_ipv4_5tuple ipv4_5tuple;
415    };
416