xref: /dpdk/doc/guides/prog_guide/packet_classif_access_ctrl.rst (revision fba9875559906e04eaeb74532f4cfd51194259a2)
15630257fSFerruh Yigit..  SPDX-License-Identifier: BSD-3-Clause
25630257fSFerruh Yigit    Copyright(c) 2010-2015 Intel Corporation.
3fc1f2750SBernard Iremonger
441dd9a6bSDavid YoungPacket Classification and Access Control (ACL) Library
541dd9a6bSDavid Young======================================================
6fc1f2750SBernard Iremonger
748624fd9SSiobhan ButlerThe DPDK provides an Access Control library that gives the ability
8fc1f2750SBernard Iremongerto classify an input packet based on a set of classification rules.
9fc1f2750SBernard Iremonger
10fc1f2750SBernard IremongerThe ACL library is used to perform an N-tuple search over a set of rules with multiple categories
11fc1f2750SBernard Iremongerand find the best match (highest priority) for each category.
12fc1f2750SBernard IremongerThe library API provides the following basic operations:
13fc1f2750SBernard Iremonger
14fc1f2750SBernard Iremonger*   Create a new Access Control (AC) context.
15fc1f2750SBernard Iremonger
16fc1f2750SBernard Iremonger*   Add rules into the context.
17fc1f2750SBernard Iremonger
18fc1f2750SBernard Iremonger*   For all rules in the context, build the runtime structures necessary to perform packet classification.
19fc1f2750SBernard Iremonger
20fc1f2750SBernard Iremonger*   Perform input packet classifications.
21fc1f2750SBernard Iremonger
22fc1f2750SBernard Iremonger*   Destroy an AC context and its runtime structures and free the associated memory.
23fc1f2750SBernard Iremonger
24fc1f2750SBernard IremongerOverview
25fc1f2750SBernard Iremonger--------
26fc1f2750SBernard Iremonger
27fe1056d0SKonstantin AnanyevRule definition
28fe1056d0SKonstantin Ananyev~~~~~~~~~~~~~~~
29fe1056d0SKonstantin Ananyev
30fc1f2750SBernard IremongerThe current implementation allows the user for each AC context to specify its own rule (set of fields)
31fc1f2750SBernard Iremongerover which packet classification will be performed.
32fe1056d0SKonstantin AnanyevThough there are few restrictions on the rule fields layout:
33fe1056d0SKonstantin Ananyev
34fe1056d0SKonstantin Ananyev*  First field in the rule definition has to be one byte long.
35fe1056d0SKonstantin Ananyev*  All subsequent fields has to be grouped into sets of 4 consecutive bytes.
36fe1056d0SKonstantin Ananyev
37fe1056d0SKonstantin AnanyevThis is done mainly for performance reasons - search function processes the first input byte as part of the flow setup and then the inner loop of the search function is unrolled to process four input bytes at a time.
38fe1056d0SKonstantin Ananyev
39fc1f2750SBernard IremongerTo define each field inside an AC rule, the following structure is used:
40fc1f2750SBernard Iremonger
41fc1f2750SBernard Iremonger.. code-block:: c
42fc1f2750SBernard Iremonger
43fc1f2750SBernard Iremonger    struct rte_acl_field_def {
44fc1f2750SBernard Iremonger        uint8_t type;         /*< type - ACL_FIELD_TYPE. */
45fc1f2750SBernard Iremonger        uint8_t size;         /*< size of field 1,2,4, or 8. */
46fc1f2750SBernard Iremonger        uint8_t field_index;  /*< index of field inside the rule. */
47fc1f2750SBernard Iremonger        uint8_t input_index;  /*< 0-N input index. */
48fc1f2750SBernard Iremonger        uint32_t offset;      /*< offset to start of field. */
49fc1f2750SBernard Iremonger    };
50fc1f2750SBernard Iremonger
51fc1f2750SBernard Iremonger*   type
52fc1f2750SBernard Iremonger    The field type is one of three choices:
53fc1f2750SBernard Iremonger
54fc1f2750SBernard Iremonger    *   _MASK - for fields such as IP addresses that have a value and a mask defining the number of relevant bits.
55fc1f2750SBernard Iremonger
56fc1f2750SBernard Iremonger    *   _RANGE - for fields such as ports that have a lower and upper value for the field.
57fc1f2750SBernard Iremonger
58fc1f2750SBernard Iremonger    *   _BITMASK - for fields such as protocol identifiers that have a value and a bit mask.
59fc1f2750SBernard Iremonger
60fc1f2750SBernard Iremonger*   size
61fc1f2750SBernard Iremonger    The size parameter defines the length of the field in bytes. Allowable values are 1, 2, 4, or 8 bytes.
62fc1f2750SBernard Iremonger    Note that due to the grouping of input bytes, 1 or 2 byte fields must be defined as consecutive fields
63fc1f2750SBernard Iremonger    that make up 4 consecutive input bytes.
64fc1f2750SBernard Iremonger    Also, it is best to define fields of 8 or more bytes as 4 byte fields so that
65fc1f2750SBernard Iremonger    the build processes can eliminate fields that are all wild.
66fc1f2750SBernard Iremonger
67fc1f2750SBernard Iremonger*   field_index
68fc1f2750SBernard Iremonger    A zero-based value that represents the position of the field inside the rule; 0 to N-1 for N fields.
69fc1f2750SBernard Iremonger
70fc1f2750SBernard Iremonger*   input_index
71fe1056d0SKonstantin Ananyev    As mentioned above, all input fields, except the very first one, must be in groups of 4 consecutive bytes.
72fc1f2750SBernard Iremonger    The input index specifies to which input group that field belongs to.
73fc1f2750SBernard Iremonger
74fc1f2750SBernard Iremonger*   offset
75fc1f2750SBernard Iremonger    The offset field defines the offset for the field.
76fc1f2750SBernard Iremonger    This is the offset from the beginning of the buffer parameter for the search.
77fc1f2750SBernard Iremonger
78fc1f2750SBernard IremongerFor example, to define classification for the following IPv4 5-tuple structure:
79fc1f2750SBernard Iremonger
80fc1f2750SBernard Iremonger.. code-block:: c
81fc1f2750SBernard Iremonger
82fc1f2750SBernard Iremonger    struct ipv4_5tuple {
83fc1f2750SBernard Iremonger        uint8_t proto;
84fc1f2750SBernard Iremonger        uint32_t ip_src;
85fc1f2750SBernard Iremonger        uint32_t ip_dst;
86fc1f2750SBernard Iremonger        uint16_t port_src;
87fc1f2750SBernard Iremonger        uint16_t port_dst;
88fc1f2750SBernard Iremonger    };
89fc1f2750SBernard Iremonger
90fc1f2750SBernard IremongerThe following array of field definitions can be used:
91fc1f2750SBernard Iremonger
92fc1f2750SBernard Iremonger.. code-block:: c
93fc1f2750SBernard Iremonger
94fc1f2750SBernard Iremonger    struct rte_acl_field_def ipv4_defs[5] = {
95fc1f2750SBernard Iremonger        /* first input field - always one byte long. */
96fc1f2750SBernard Iremonger        {
97fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_BITMASK,
98fc1f2750SBernard Iremonger            .size = sizeof (uint8_t),
99fc1f2750SBernard Iremonger            .field_index = 0,
100fc1f2750SBernard Iremonger            .input_index = 0,
101fc1f2750SBernard Iremonger            .offset = offsetof (struct ipv4_5tuple, proto),
102fc1f2750SBernard Iremonger        },
103fc1f2750SBernard Iremonger
104fc1f2750SBernard Iremonger        /* next input field (IPv4 source address) - 4 consecutive bytes. */
105fc1f2750SBernard Iremonger        {
106fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_MASK,
107fc1f2750SBernard Iremonger            .size = sizeof (uint32_t),
108fc1f2750SBernard Iremonger            .field_index = 1,
109fc1f2750SBernard Iremonger            .input_index = 1,
110fc1f2750SBernard Iremonger           .offset = offsetof (struct ipv4_5tuple, ip_src),
111fc1f2750SBernard Iremonger        },
112fc1f2750SBernard Iremonger
113fc1f2750SBernard Iremonger        /* next input field (IPv4 destination address) - 4 consecutive bytes. */
114fc1f2750SBernard Iremonger        {
115fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_MASK,
116fc1f2750SBernard Iremonger            .size = sizeof (uint32_t),
117fc1f2750SBernard Iremonger            .field_index = 2,
118fc1f2750SBernard Iremonger            .input_index = 2,
119fc1f2750SBernard Iremonger           .offset = offsetof (struct ipv4_5tuple, ip_dst),
120fc1f2750SBernard Iremonger        },
121fc1f2750SBernard Iremonger
122fc1f2750SBernard Iremonger        /*
123fc1f2750SBernard Iremonger         * Next 2 fields (src & dst ports) form 4 consecutive bytes.
124fc1f2750SBernard Iremonger         * They share the same input index.
125fc1f2750SBernard Iremonger         */
126fc1f2750SBernard Iremonger        {
127fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_RANGE,
128fc1f2750SBernard Iremonger            .size = sizeof (uint16_t),
129fc1f2750SBernard Iremonger            .field_index = 3,
130fc1f2750SBernard Iremonger            .input_index = 3,
131fc1f2750SBernard Iremonger            .offset = offsetof (struct ipv4_5tuple, port_src),
132fc1f2750SBernard Iremonger        },
133fc1f2750SBernard Iremonger
134fc1f2750SBernard Iremonger        {
135fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_RANGE,
136fc1f2750SBernard Iremonger            .size = sizeof (uint16_t),
137fc1f2750SBernard Iremonger            .field_index = 4,
138fc1f2750SBernard Iremonger            .input_index = 3,
139fc1f2750SBernard Iremonger            .offset = offsetof (struct ipv4_5tuple, port_dst),
140fc1f2750SBernard Iremonger        },
141fc1f2750SBernard Iremonger    };
142fc1f2750SBernard Iremonger
143fc1f2750SBernard IremongerA typical example of such an IPv4 5-tuple rule is a follows:
144fc1f2750SBernard Iremonger
145fc1f2750SBernard Iremonger::
146fc1f2750SBernard Iremonger
147fc1f2750SBernard Iremonger    source addr/mask  destination addr/mask  source ports dest ports protocol/mask
148fc1f2750SBernard Iremonger    192.168.1.0/24    192.168.2.31/32        0:65535      1234:1234  17/0xff
149fc1f2750SBernard Iremonger
150fc1f2750SBernard IremongerAny IPv4 packets with protocol ID 17 (UDP), source address 192.168.1.[0-255], destination address 192.168.2.31,
151fc1f2750SBernard Iremongersource port [0-65535] and destination port 1234 matches the above rule.
152fc1f2750SBernard Iremonger
153fc1f2750SBernard IremongerTo define classification for the IPv6 2-tuple: <protocol, IPv6 source address> over the following IPv6 header structure:
154fc1f2750SBernard Iremonger
155fc1f2750SBernard Iremonger.. code-block:: c
156fc1f2750SBernard Iremonger
157*fba98755SAndre Muezerie    struct __rte_packed_begin rte_ipv6_hdr {
158fc1f2750SBernard Iremonger        uint32_t vtc_flow;     /* IP version, traffic class & flow label. */
159fc1f2750SBernard Iremonger        uint16_t payload_len;  /* IP packet length - includes sizeof(ip_header). */
160fc1f2750SBernard Iremonger        uint8_t proto;         /* Protocol, next header. */
161fc1f2750SBernard Iremonger        uint8_t hop_limits;    /* Hop limits. */
162fc1f2750SBernard Iremonger        uint8_t src_addr[16];  /* IP address of source host. */
163fc1f2750SBernard Iremonger        uint8_t dst_addr[16];  /* IP address of destination host(s). */
164*fba98755SAndre Muezerie    } __rte_packed_end;
165fc1f2750SBernard Iremonger
166fc1f2750SBernard IremongerThe following array of field definitions can be used:
167fc1f2750SBernard Iremonger
168fc1f2750SBernard Iremonger.. code-block:: c
169fc1f2750SBernard Iremonger
170f43d3dbbSDavid Marchand    struct rte_acl_field_def ipv6_2tuple_defs[5] = {
171fc1f2750SBernard Iremonger        {
172fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_BITMASK,
173fc1f2750SBernard Iremonger            .size = sizeof (uint8_t),
174fc1f2750SBernard Iremonger            .field_index = 0,
175fc1f2750SBernard Iremonger            .input_index = 0,
176a7c528e5SOlivier Matz            .offset = offsetof (struct rte_ipv6_hdr, proto),
177fc1f2750SBernard Iremonger        },
178fc1f2750SBernard Iremonger
179fc1f2750SBernard Iremonger        {
180fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_MASK,
181fc1f2750SBernard Iremonger            .size = sizeof (uint32_t),
182fc1f2750SBernard Iremonger            .field_index = 1,
183fc1f2750SBernard Iremonger            .input_index = 1,
184a7c528e5SOlivier Matz            .offset = offsetof (struct rte_ipv6_hdr, src_addr[0]),
185fc1f2750SBernard Iremonger        },
186fc1f2750SBernard Iremonger
187fc1f2750SBernard Iremonger        {
188fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_MASK,
189fc1f2750SBernard Iremonger            .size = sizeof (uint32_t),
190fc1f2750SBernard Iremonger            .field_index = 2,
191fc1f2750SBernard Iremonger            .input_index = 2,
192a7c528e5SOlivier Matz            .offset = offsetof (struct rte_ipv6_hdr, src_addr[4]),
193fc1f2750SBernard Iremonger        },
194fc1f2750SBernard Iremonger
195fc1f2750SBernard Iremonger        {
196fc1f2750SBernard Iremonger            .type = RTE_ACL_FIELD_TYPE_MASK,
197fc1f2750SBernard Iremonger            .size = sizeof (uint32_t),
198fc1f2750SBernard Iremonger            .field_index = 3,
199fc1f2750SBernard Iremonger            .input_index = 3,
200a7c528e5SOlivier Matz           .offset = offsetof (struct rte_ipv6_hdr, src_addr[8]),
201fc1f2750SBernard Iremonger        },
202fc1f2750SBernard Iremonger
203fc1f2750SBernard Iremonger        {
204fc1f2750SBernard Iremonger           .type = RTE_ACL_FIELD_TYPE_MASK,
205fc1f2750SBernard Iremonger           .size = sizeof (uint32_t),
206fc1f2750SBernard Iremonger           .field_index = 4,
207fc1f2750SBernard Iremonger           .input_index = 4,
208a7c528e5SOlivier Matz           .offset = offsetof (struct rte_ipv6_hdr, src_addr[12]),
209fc1f2750SBernard Iremonger        },
210fc1f2750SBernard Iremonger    };
211fc1f2750SBernard Iremonger
212fc1f2750SBernard IremongerA typical example of such an IPv6 2-tuple rule is a follows:
213fc1f2750SBernard Iremonger
214fc1f2750SBernard Iremonger::
215fc1f2750SBernard Iremonger
216fc1f2750SBernard Iremonger    source addr/mask                              protocol/mask
217fc1f2750SBernard Iremonger    2001:db8:1234:0000:0000:0000:0000:0000/48     6/0xff
218fc1f2750SBernard Iremonger
219fc1f2750SBernard IremongerAny IPv6 packets with protocol ID 6 (TCP), and source address inside the range
220fc1f2750SBernard Iremonger[2001:db8:1234:0000:0000:0000:0000:0000 - 2001:db8:1234:ffff:ffff:ffff:ffff:ffff] matches the above rule.
221fc1f2750SBernard Iremonger
2229c699fd8SAntonio FischettiIn the following example the last element of the search key is 8-bit long.
2239c699fd8SAntonio FischettiSo it is a case where the 4 consecutive bytes of an input field are not fully occupied.
2249c699fd8SAntonio FischettiThe structure for the classification is:
2259c699fd8SAntonio Fischetti
2269c699fd8SAntonio Fischetti.. code-block:: c
2279c699fd8SAntonio Fischetti
2289c699fd8SAntonio Fischetti    struct acl_key {
2299c699fd8SAntonio Fischetti        uint8_t ip_proto;
2309c699fd8SAntonio Fischetti        uint32_t ip_src;
2319c699fd8SAntonio Fischetti        uint32_t ip_dst;
2329c699fd8SAntonio Fischetti        uint8_t tos;      /*< This is partially using a 32-bit input element */
2339c699fd8SAntonio Fischetti    };
2349c699fd8SAntonio Fischetti
2359c699fd8SAntonio FischettiThe following array of field definitions can be used:
2369c699fd8SAntonio Fischetti
2379c699fd8SAntonio Fischetti.. code-block:: c
2389c699fd8SAntonio Fischetti
2399c699fd8SAntonio Fischetti    struct rte_acl_field_def ipv4_defs[4] = {
2409c699fd8SAntonio Fischetti        /* first input field - always one byte long. */
2419c699fd8SAntonio Fischetti        {
2429c699fd8SAntonio Fischetti            .type = RTE_ACL_FIELD_TYPE_BITMASK,
2439c699fd8SAntonio Fischetti            .size = sizeof (uint8_t),
2449c699fd8SAntonio Fischetti            .field_index = 0,
2459c699fd8SAntonio Fischetti            .input_index = 0,
2469c699fd8SAntonio Fischetti            .offset = offsetof (struct acl_key, ip_proto),
2479c699fd8SAntonio Fischetti        },
2489c699fd8SAntonio Fischetti
2499c699fd8SAntonio Fischetti        /* next input field (IPv4 source address) - 4 consecutive bytes. */
2509c699fd8SAntonio Fischetti        {
2519c699fd8SAntonio Fischetti            .type = RTE_ACL_FIELD_TYPE_MASK,
2529c699fd8SAntonio Fischetti            .size = sizeof (uint32_t),
2539c699fd8SAntonio Fischetti            .field_index = 1,
2549c699fd8SAntonio Fischetti            .input_index = 1,
2559c699fd8SAntonio Fischetti           .offset = offsetof (struct acl_key, ip_src),
2569c699fd8SAntonio Fischetti        },
2579c699fd8SAntonio Fischetti
2589c699fd8SAntonio Fischetti        /* next input field (IPv4 destination address) - 4 consecutive bytes. */
2599c699fd8SAntonio Fischetti        {
2609c699fd8SAntonio Fischetti            .type = RTE_ACL_FIELD_TYPE_MASK,
2619c699fd8SAntonio Fischetti            .size = sizeof (uint32_t),
2629c699fd8SAntonio Fischetti            .field_index = 2,
2639c699fd8SAntonio Fischetti            .input_index = 2,
2649c699fd8SAntonio Fischetti           .offset = offsetof (struct acl_key, ip_dst),
2659c699fd8SAntonio Fischetti        },
2669c699fd8SAntonio Fischetti
2679c699fd8SAntonio Fischetti        /*
2689c699fd8SAntonio Fischetti         * Next element of search key (Type of Service) is indeed 1 byte long.
2699c699fd8SAntonio Fischetti         * Anyway we need to allocate all the 4 consecutive bytes for it.
2709c699fd8SAntonio Fischetti         */
2719c699fd8SAntonio Fischetti        {
2729c699fd8SAntonio Fischetti            .type = RTE_ACL_FIELD_TYPE_BITMASK,
2739c699fd8SAntonio Fischetti            .size = sizeof (uint32_t), /* All the 4 consecutive bytes are allocated */
2749c699fd8SAntonio Fischetti            .field_index = 3,
2759c699fd8SAntonio Fischetti            .input_index = 3,
2769c699fd8SAntonio Fischetti            .offset = offsetof (struct acl_key, tos),
2779c699fd8SAntonio Fischetti        },
2789c699fd8SAntonio Fischetti    };
2799c699fd8SAntonio Fischetti
2809c699fd8SAntonio FischettiA typical example of such an IPv4 4-tuple rule is as follows:
2819c699fd8SAntonio Fischetti
2829c699fd8SAntonio Fischetti::
2839c699fd8SAntonio Fischetti
2849c699fd8SAntonio Fischetti    source addr/mask  destination addr/mask  tos/mask protocol/mask
2859c699fd8SAntonio Fischetti    192.168.1.0/24    192.168.2.31/32        1/0xff   6/0xff
2869c699fd8SAntonio Fischetti
2879c699fd8SAntonio FischettiAny IPv4 packets with protocol ID 6 (TCP), source address 192.168.1.[0-255], destination address 192.168.2.31,
2889c699fd8SAntonio FischettiToS 1 matches the above rule.
2899c699fd8SAntonio Fischetti
290fc1f2750SBernard IremongerWhen creating a set of rules, for each rule, additional information must be supplied also:
291fc1f2750SBernard Iremonger
292fc1f2750SBernard Iremonger*   **priority**: A weight to measure the priority of the rules (higher is better).
293fc1f2750SBernard Iremonger    If the input tuple matches more than one rule, then the rule with the higher priority is returned.
294fc1f2750SBernard Iremonger    Note that if the input tuple matches more than one rule and these rules have equal priority,
295fc1f2750SBernard Iremonger    it is undefined which rule is returned as a match.
296fc1f2750SBernard Iremonger    It is recommended to assign a unique priority for each rule.
297fc1f2750SBernard Iremonger
298fc1f2750SBernard Iremonger*   **category_mask**: Each rule uses a bit mask value to select the relevant category(s) for the rule.
299fc1f2750SBernard Iremonger    When a lookup is performed, the result for each category is returned.
300fc1f2750SBernard Iremonger    This effectively provides a "parallel lookup" by enabling a single search to return multiple results if,
301fc1f2750SBernard Iremonger    for example, there were four different sets of ACL rules, one for access control, one for routing, and so on.
302fc1f2750SBernard Iremonger    Each set could be assigned its own category and by combining them into a single database,
303fc1f2750SBernard Iremonger    one lookup returns a result for each of the four sets.
304fc1f2750SBernard Iremonger
305c6c7a8d7SMichał Mirosław*   **userdata**: A user-defined value.
306fc1f2750SBernard Iremonger    For each category, a successful match returns the userdata field of the highest priority matched rule.
307c6c7a8d7SMichał Mirosław    When no rules match, returned value is zero.
308fc1f2750SBernard Iremonger
309fc1f2750SBernard Iremonger.. note::
310fc1f2750SBernard Iremonger
311fc1f2750SBernard Iremonger    When adding new rules into an ACL context, all fields must be in host byte order (LSB).
312fc1f2750SBernard Iremonger    When the search is performed for an input tuple, all fields in that tuple must be in network byte order (MSB).
313fc1f2750SBernard Iremonger
314e14b969aSKonstantin AnanyevRT memory size limit
315e14b969aSKonstantin Ananyev~~~~~~~~~~~~~~~~~~~~
316e14b969aSKonstantin Ananyev
317e14b969aSKonstantin AnanyevBuild phase (rte_acl_build()) creates for a given set of rules internal structure for further run-time traversal.
318e14b969aSKonstantin AnanyevWith current implementation it is a set of multi-bit tries (with stride == 8).
319e14b969aSKonstantin AnanyevDepending on the rules set, that could consume significant amount of memory.
320e14b969aSKonstantin AnanyevIn attempt to conserve some space ACL build process tries to split the given
321e14b969aSKonstantin Ananyevrule-set into several non-intersecting subsets and construct a separate trie
322e14b969aSKonstantin Ananyevfor each of them.
323e14b969aSKonstantin AnanyevDepending on the rule-set, it might reduce RT memory requirements but might
324e14b969aSKonstantin Ananyevincrease classification time.
325e14b969aSKonstantin AnanyevThere is a possibility at build-time to specify maximum memory limit for internal RT structures for given AC context.
326fea1d908SJohn McNamaraIt could be done via **max_size** field of the **rte_acl_config** structure.
327e14b969aSKonstantin AnanyevSetting it to the value greater than zero, instructs rte_acl_build() to:
328e14b969aSKonstantin Ananyev
329fea1d908SJohn McNamara*   attempt to minimize number of tries in the RT table, but
330e14b969aSKonstantin Ananyev*   make sure that size of RT table wouldn't exceed given value.
331e14b969aSKonstantin Ananyev
332fea1d908SJohn McNamaraSetting it to zero makes rte_acl_build() to use the default behavior:
333fea1d908SJohn McNamaratry to minimize size of the RT structures, but doesn't expose any hard limit on it.
334e14b969aSKonstantin Ananyev
335e14b969aSKonstantin AnanyevThat gives the user the ability to decisions about performance/space trade-off.
336e14b969aSKonstantin AnanyevFor example:
337e14b969aSKonstantin Ananyev
338e14b969aSKonstantin Ananyev.. code-block:: c
339e14b969aSKonstantin Ananyev
340e14b969aSKonstantin Ananyev    struct rte_acl_ctx * acx;
341e14b969aSKonstantin Ananyev    struct rte_acl_config cfg;
342e14b969aSKonstantin Ananyev    int ret;
343e14b969aSKonstantin Ananyev
344e14b969aSKonstantin Ananyev    /*
345e14b969aSKonstantin Ananyev     * assuming that acx points to already created and
346e14b969aSKonstantin Ananyev     * populated with rules AC context and cfg filled properly.
347e14b969aSKonstantin Ananyev     */
348e14b969aSKonstantin Ananyev
349fea1d908SJohn McNamara     /* try to build AC context, with RT structures less then 8MB. */
350e14b969aSKonstantin Ananyev     cfg.max_size = 0x800000;
351e14b969aSKonstantin Ananyev     ret = rte_acl_build(acx, &cfg);
352e14b969aSKonstantin Ananyev
353e14b969aSKonstantin Ananyev     /*
354fea1d908SJohn McNamara      * RT structures can't fit into 8MB for given context.
355e14b969aSKonstantin Ananyev      * Try to build without exposing any hard limit.
356e14b969aSKonstantin Ananyev      */
357e14b969aSKonstantin Ananyev     if (ret == -ERANGE) {
358e14b969aSKonstantin Ananyev        cfg.max_size = 0;
359e14b969aSKonstantin Ananyev        ret = rte_acl_build(acx, &cfg);
360e14b969aSKonstantin Ananyev     }
361e14b969aSKonstantin Ananyev
362e14b969aSKonstantin Ananyev
363e14b969aSKonstantin Ananyev
364cb3b56daSKonstantin AnanyevClassification methods
365cb3b56daSKonstantin Ananyev~~~~~~~~~~~~~~~~~~~~~~
366cb3b56daSKonstantin Ananyev
367e14b969aSKonstantin AnanyevAfter rte_acl_build() over given AC context has finished successfully, it can be used to perform classification - search for a rule with highest priority over the input data.
368cb3b56daSKonstantin AnanyevThere are several implementations of classify algorithm:
369cb3b56daSKonstantin Ananyev
370cb3b56daSKonstantin Ananyev*   **RTE_ACL_CLASSIFY_SCALAR**: generic implementation, doesn't require any specific HW support.
3711e6a6613SCiara Power    Requires max SIMD bitwidth to be at least 64.
372cb3b56daSKonstantin Ananyev
373cb3b56daSKonstantin Ananyev*   **RTE_ACL_CLASSIFY_SSE**: vector implementation, can process up to 8 flows in parallel. Requires SSE 4.1 support.
3741e6a6613SCiara Power    Requires max SIMD bitwidth to be at least 128.
375cb3b56daSKonstantin Ananyev
376cb3b56daSKonstantin Ananyev*   **RTE_ACL_CLASSIFY_AVX2**: vector implementation, can process up to 16 flows in parallel. Requires AVX2 support.
3771e6a6613SCiara Power    Requires max SIMD bitwidth to be at least 256.
378cb3b56daSKonstantin Ananyev
37928377e37SKonstantin Ananyev*   **RTE_ACL_CLASSIFY_NEON**: vector implementation, can process up to 8 flows
3801e6a6613SCiara Power    in parallel. Requires NEON support. Requires max SIMD bitwidth to be at least 128.
38128377e37SKonstantin Ananyev
38228377e37SKonstantin Ananyev*   **RTE_ACL_CLASSIFY_ALTIVEC**: vector implementation, can process up to 8
3831e6a6613SCiara Power    flows in parallel. Requires ALTIVEC support. Requires max SIMD bitwidth to be at least 128.
38428377e37SKonstantin Ananyev
385b64c2295SKonstantin Ananyev*   **RTE_ACL_CLASSIFY_AVX512X16**: vector implementation, can process up to 16
386b64c2295SKonstantin Ananyev    flows in parallel. Uses 256-bit width SIMD registers.
3871e6a6613SCiara Power    Requires AVX512 support. Requires max SIMD bitwidth to be at least 256.
388b64c2295SKonstantin Ananyev
38945da22e4SKonstantin Ananyev*   **RTE_ACL_CLASSIFY_AVX512X32**: vector implementation, can process up to 32
39045da22e4SKonstantin Ananyev    flows in parallel. Uses 512-bit width SIMD registers.
3911e6a6613SCiara Power    Requires AVX512 support. Requires max SIMD bitwidth to be at least 512.
39245da22e4SKonstantin Ananyev
393cb3b56daSKonstantin AnanyevIt is purely a runtime decision which method to choose, there is no build-time difference.
394cb3b56daSKonstantin AnanyevAll implementations operates over the same internal RT structures and use similar principles. The main difference is that vector implementations can manually exploit IA SIMD instructions and process several input data flows in parallel.
395cb3b56daSKonstantin AnanyevAt startup ACL library determines the highest available classify method for the given platform and sets it as default one. Though the user has an ability to override the default classifier function for a given ACL context or perform particular search using non-default classify method. In that case it is user responsibility to make sure that given platform supports selected classify implementation.
396cb3b56daSKonstantin Ananyev
39745da22e4SKonstantin Ananyev.. note::
39845da22e4SKonstantin Ananyev
3991e6a6613SCiara Power     Runtime algorithm selection obeys EAL max SIMD bitwidth parameter.
4001e6a6613SCiara Power     For more details about expected behaviour please see :ref:`max_simd_bitwidth`
40145da22e4SKonstantin Ananyev
402fc1f2750SBernard IremongerApplication Programming Interface (API) Usage
403fc1f2750SBernard Iremonger---------------------------------------------
404fc1f2750SBernard Iremonger
405fc1f2750SBernard Iremonger.. note::
406fc1f2750SBernard Iremonger
40748624fd9SSiobhan Butler    For more details about the Access Control API, please refer to the *DPDK API Reference*.
408fc1f2750SBernard Iremonger
409fc1f2750SBernard IremongerThe following example demonstrates IPv4, 5-tuple classification for rules defined above
410fc1f2750SBernard Iremongerwith multiple categories in more detail.
411fc1f2750SBernard Iremonger
412fc1f2750SBernard IremongerClassify with Multiple Categories
413fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
414fc1f2750SBernard Iremonger
415fc1f2750SBernard Iremonger.. code-block:: c
416fc1f2750SBernard Iremonger
417fc1f2750SBernard Iremonger    struct rte_acl_ctx * acx;
418fc1f2750SBernard Iremonger    struct rte_acl_config cfg;
419fc1f2750SBernard Iremonger    int ret;
420fc1f2750SBernard Iremonger
421fc1f2750SBernard Iremonger    /* define a structure for the rule with up to 5 fields. */
422fc1f2750SBernard Iremonger
423fc1f2750SBernard Iremonger    RTE_ACL_RULE_DEF(acl_ipv4_rule, RTE_DIM(ipv4_defs));
424fc1f2750SBernard Iremonger
425fc1f2750SBernard Iremonger    /* AC context creation parameters. */
426fc1f2750SBernard Iremonger
427fc1f2750SBernard Iremonger    struct rte_acl_param prm = {
428fc1f2750SBernard Iremonger        .name = "ACL_example",
429fc1f2750SBernard Iremonger        .socket_id = SOCKET_ID_ANY,
430fc1f2750SBernard Iremonger        .rule_size = RTE_ACL_RULE_SZ(RTE_DIM(ipv4_defs)),
431fc1f2750SBernard Iremonger
432fc1f2750SBernard Iremonger        /* number of fields per rule. */
433fc1f2750SBernard Iremonger
434fc1f2750SBernard Iremonger        .max_rule_num = 8, /* maximum number of rules in the AC context. */
435fc1f2750SBernard Iremonger    };
436fc1f2750SBernard Iremonger
437fc1f2750SBernard Iremonger    struct acl_ipv4_rule acl_rules[] = {
438fc1f2750SBernard Iremonger
439fc1f2750SBernard Iremonger        /* matches all packets traveling to 192.168.0.0/16, applies for categories: 0,1 */
440fc1f2750SBernard Iremonger        {
441fc1f2750SBernard Iremonger            .data = {.userdata = 1, .category_mask = 3, .priority = 1},
442fc1f2750SBernard Iremonger
443fc1f2750SBernard Iremonger            /* destination IPv4 */
4440c9da755SDavid Marchand            .field[2] = {.value.u32 = RTE_IPV4(192,168,0,0),. mask_range.u32 = 16,},
445fc1f2750SBernard Iremonger
446fc1f2750SBernard Iremonger            /* source port */
447fc1f2750SBernard Iremonger            .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
448fc1f2750SBernard Iremonger
449fc1f2750SBernard Iremonger            /* destination port */
450fc1f2750SBernard Iremonger           .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
451fc1f2750SBernard Iremonger        },
452fc1f2750SBernard Iremonger
453fc1f2750SBernard Iremonger        /* matches all packets traveling to 192.168.1.0/24, applies for categories: 0 */
454fc1f2750SBernard Iremonger        {
455fc1f2750SBernard Iremonger            .data = {.userdata = 2, .category_mask = 1, .priority = 2},
456fc1f2750SBernard Iremonger
457fc1f2750SBernard Iremonger            /* destination IPv4 */
4580c9da755SDavid Marchand            .field[2] = {.value.u32 = RTE_IPV4(192,168,1,0),. mask_range.u32 = 24,},
459fc1f2750SBernard Iremonger
460fc1f2750SBernard Iremonger            /* source port */
461fc1f2750SBernard Iremonger            .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
462fc1f2750SBernard Iremonger
463fc1f2750SBernard Iremonger            /* destination port */
464fc1f2750SBernard Iremonger            .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
465fc1f2750SBernard Iremonger        },
466fc1f2750SBernard Iremonger
467fc1f2750SBernard Iremonger        /* matches all packets traveling from 10.1.1.1, applies for categories: 1 */
468fc1f2750SBernard Iremonger        {
469fc1f2750SBernard Iremonger            .data = {.userdata = 3, .category_mask = 2, .priority = 3},
470fc1f2750SBernard Iremonger
471fc1f2750SBernard Iremonger            /* source IPv4 */
4720c9da755SDavid Marchand            .field[1] = {.value.u32 = RTE_IPV4(10,1,1,1),. mask_range.u32 = 32,},
473fc1f2750SBernard Iremonger
474fc1f2750SBernard Iremonger            /* source port */
475fc1f2750SBernard Iremonger            .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
476fc1f2750SBernard Iremonger
477fc1f2750SBernard Iremonger            /* destination port */
478fc1f2750SBernard Iremonger            .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
479fc1f2750SBernard Iremonger        },
480fc1f2750SBernard Iremonger
481fc1f2750SBernard Iremonger    };
482fc1f2750SBernard Iremonger
483fc1f2750SBernard Iremonger
484fc1f2750SBernard Iremonger    /* create an empty AC context  */
485fc1f2750SBernard Iremonger
486fc1f2750SBernard Iremonger    if ((acx = rte_acl_create(&prm)) == NULL) {
487fc1f2750SBernard Iremonger
488fc1f2750SBernard Iremonger        /* handle context create failure. */
489fc1f2750SBernard Iremonger
490fc1f2750SBernard Iremonger    }
491fc1f2750SBernard Iremonger
492fc1f2750SBernard Iremonger    /* add rules to the context */
493fc1f2750SBernard Iremonger
494fc1f2750SBernard Iremonger    ret = rte_acl_add_rules(acx, acl_rules, RTE_DIM(acl_rules));
495fc1f2750SBernard Iremonger    if (ret != 0) {
496fc1f2750SBernard Iremonger       /* handle error at adding ACL rules. */
497fc1f2750SBernard Iremonger    }
498fc1f2750SBernard Iremonger
499fc1f2750SBernard Iremonger    /* prepare AC build config. */
500fc1f2750SBernard Iremonger
501fc1f2750SBernard Iremonger    cfg.num_categories = 2;
502fc1f2750SBernard Iremonger    cfg.num_fields = RTE_DIM(ipv4_defs);
503fc1f2750SBernard Iremonger
504fc1f2750SBernard Iremonger    memcpy(cfg.defs, ipv4_defs, sizeof (ipv4_defs));
505fc1f2750SBernard Iremonger
506fc1f2750SBernard Iremonger    /* build the runtime structures for added rules, with 2 categories. */
507fc1f2750SBernard Iremonger
508fc1f2750SBernard Iremonger    ret = rte_acl_build(acx, &cfg);
509fc1f2750SBernard Iremonger    if (ret != 0) {
510fc1f2750SBernard Iremonger       /* handle error at build runtime structures for ACL context. */
511fc1f2750SBernard Iremonger    }
512fc1f2750SBernard Iremonger
513fc1f2750SBernard IremongerFor a tuple with source IP address: 10.1.1.1 and destination IP address: 192.168.1.15,
514fc1f2750SBernard Iremongeronce the following lines are executed:
515fc1f2750SBernard Iremonger
516fc1f2750SBernard Iremonger.. code-block:: c
517fc1f2750SBernard Iremonger
518fc1f2750SBernard Iremonger    uint32_t results[4]; /* make classify for 4 categories. */
519fc1f2750SBernard Iremonger
520fc1f2750SBernard Iremonger    rte_acl_classify(acx, data, results, 1, 4);
521fc1f2750SBernard Iremonger
522fc1f2750SBernard Iremongerthen the results[] array contains:
523fc1f2750SBernard Iremonger
524fc1f2750SBernard Iremonger.. code-block:: c
525fc1f2750SBernard Iremonger
526fc1f2750SBernard Iremonger    results[4] = {2, 3, 0, 0};
527fc1f2750SBernard Iremonger
528fc1f2750SBernard Iremonger*   For category 0, both rules 1 and 2 match, but rule 2 has higher priority,
529fc1f2750SBernard Iremonger    therefore results[0] contains the userdata for rule 2.
530fc1f2750SBernard Iremonger
531fc1f2750SBernard Iremonger*   For category 1, both rules 1 and 3 match, but rule 3 has higher priority,
532fc1f2750SBernard Iremonger    therefore results[1] contains the userdata for rule 3.
533fc1f2750SBernard Iremonger
534fc1f2750SBernard Iremonger*   For categories 2 and 3, there are no matches, so results[2] and results[3] contain zero,
535fc1f2750SBernard Iremonger    which indicates that no matches were found for those categories.
536fc1f2750SBernard Iremonger
537fc1f2750SBernard IremongerFor a tuple with source IP address: 192.168.1.1 and destination IP address: 192.168.2.11,
538fc1f2750SBernard Iremongeronce the following lines are executed:
539fc1f2750SBernard Iremonger
540fc1f2750SBernard Iremonger.. code-block:: c
541fc1f2750SBernard Iremonger
542fc1f2750SBernard Iremonger    uint32_t results[4]; /* make classify by 4 categories. */
543fc1f2750SBernard Iremonger
544fc1f2750SBernard Iremonger    rte_acl_classify(acx, data, results, 1, 4);
545fc1f2750SBernard Iremonger
546fc1f2750SBernard Iremongerthe results[] array contains:
547fc1f2750SBernard Iremonger
548fc1f2750SBernard Iremonger.. code-block:: c
549fc1f2750SBernard Iremonger
550fc1f2750SBernard Iremonger    results[4] = {1, 1, 0, 0};
551fc1f2750SBernard Iremonger
552fc1f2750SBernard Iremonger*   For categories 0 and 1, only rule 1 matches.
553fc1f2750SBernard Iremonger
554fc1f2750SBernard Iremonger*   For categories 2 and 3, there are no matches.
555fc1f2750SBernard Iremonger
556fc1f2750SBernard IremongerFor a tuple with source IP address: 10.1.1.1 and destination IP address: 201.212.111.12,
557fc1f2750SBernard Iremongeronce the following lines are executed:
558fc1f2750SBernard Iremonger
559fc1f2750SBernard Iremonger.. code-block:: c
560fc1f2750SBernard Iremonger
561fc1f2750SBernard Iremonger    uint32_t results[4]; /* make classify by 4 categories. */
562fc1f2750SBernard Iremonger    rte_acl_classify(acx, data, results, 1, 4);
563fc1f2750SBernard Iremonger
564fc1f2750SBernard Iremongerthe results[] array contains:
565fc1f2750SBernard Iremonger
566fc1f2750SBernard Iremonger.. code-block:: c
567fc1f2750SBernard Iremonger
568fc1f2750SBernard Iremonger    results[4] = {0, 3, 0, 0};
569fc1f2750SBernard Iremonger
570fc1f2750SBernard Iremonger*   For category 1, only rule 3 matches.
571fc1f2750SBernard Iremonger
572fc1f2750SBernard Iremonger*   For categories 0, 2 and 3, there are no matches.
573