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