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