1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
10 #include <rte_string_fns.h>
12 #include <rte_byteorder.h>
15 #include <rte_common.h>
16 #include <rte_table_acl.h>
18 #include <rte_flow_classify.h>
20 #include "packet_burst_generator.h"
21 #include "test_flow_classify.h"
24 #define FLOW_CLASSIFY_MAX_RULE_NUM 100
25 struct flow_classifier_acl *cls;
27 struct flow_classifier_acl {
28 struct rte_flow_classifier *cls;
29 } __rte_cache_aligned;
32 * test functions by passing invalid or
33 * non-workable parameters.
36 test_invalid_parameters(void)
38 struct rte_flow_classify_rule *rule;
41 ret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL);
43 printf("Line %i: rte_flow_classify_validate",
45 printf(" with NULL param should have failed!\n");
49 rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL,
52 printf("Line %i: flow_classifier_table_entry_add", __LINE__);
53 printf(" with NULL param should have failed!\n");
57 ret = rte_flow_classify_table_entry_delete(NULL, NULL);
59 printf("Line %i: rte_flow_classify_table_entry_delete",
61 printf(" with NULL param should have failed!\n");
65 ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL);
67 printf("Line %i: flow_classifier_query", __LINE__);
68 printf(" with NULL param should have failed!\n");
72 rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL,
75 printf("Line %i: flow_classify_table_entry_add ", __LINE__);
76 printf("with NULL param should have failed!\n");
80 ret = rte_flow_classify_table_entry_delete(NULL, NULL);
82 printf("Line %i: rte_flow_classify_table_entry_delete",
84 printf("with NULL param should have failed!\n");
88 ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL);
90 printf("Line %i: flow_classifier_query", __LINE__);
91 printf(" with NULL param should have failed!\n");
98 test_valid_parameters(void)
100 struct rte_flow_classify_rule *rule;
105 * set up parameters for rte_flow_classify_validate,
106 * rte_flow_classify_table_entry_add and
107 * rte_flow_classify_table_entry_delete
112 pattern[0] = eth_item;
113 pattern[1] = ipv4_udp_item_1;
114 pattern[2] = udp_item_1;
115 pattern[3] = end_item;
116 actions[0] = count_action;
117 actions[1] = end_action;
119 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
122 printf("Line %i: rte_flow_classify_validate",
124 printf(" should not have failed!\n");
127 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
128 actions, &key_found, &error);
131 printf("Line %i: flow_classify_table_entry_add", __LINE__);
132 printf(" should not have failed!\n");
136 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
138 printf("Line %i: rte_flow_classify_table_entry_delete",
140 printf(" should not have failed!\n");
147 test_invalid_patterns(void)
149 struct rte_flow_classify_rule *rule;
154 * set up parameters for rte_flow_classify_validate,
155 * rte_flow_classify_table_entry_add and
156 * rte_flow_classify_table_entry_delete
161 pattern[0] = eth_item_bad;
162 pattern[1] = ipv4_udp_item_1;
163 pattern[2] = udp_item_1;
164 pattern[3] = end_item;
165 actions[0] = count_action;
166 actions[1] = end_action;
168 pattern[0] = eth_item;
169 pattern[1] = ipv4_udp_item_bad;
171 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
174 printf("Line %i: rte_flow_classify_validate", __LINE__);
175 printf(" should have failed!\n");
179 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
180 actions, &key_found, &error);
182 printf("Line %i: flow_classify_table_entry_add", __LINE__);
183 printf(" should have failed!\n");
187 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
189 printf("Line %i: rte_flow_classify_table_entry_delete",
191 printf(" should have failed!\n");
195 pattern[1] = ipv4_udp_item_1;
196 pattern[2] = udp_item_bad;
197 pattern[3] = end_item_bad;
199 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
202 printf("Line %i: rte_flow_classify_validate", __LINE__);
203 printf(" should have failed!\n");
207 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
208 actions, &key_found, &error);
210 printf("Line %i: flow_classify_table_entry_add", __LINE__);
211 printf(" should have failed!\n");
215 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
217 printf("Line %i: rte_flow_classify_table_entry_delete",
219 printf(" should have failed!\n");
226 test_invalid_actions(void)
228 struct rte_flow_classify_rule *rule;
233 * set up parameters for rte_flow_classify_validate,
234 * rte_flow_classify_table_entry_add and
235 * rte_flow_classify_table_entry_delete
240 pattern[0] = eth_item;
241 pattern[1] = ipv4_udp_item_1;
242 pattern[2] = udp_item_1;
243 pattern[3] = end_item;
244 actions[0] = count_action_bad;
245 actions[1] = end_action;
247 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
250 printf("Line %i: rte_flow_classify_validate", __LINE__);
251 printf(" should have failed!\n");
255 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
256 actions, &key_found, &error);
258 printf("Line %i: flow_classify_table_entry_add", __LINE__);
259 printf(" should have failed!\n");
263 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
265 printf("Line %i: rte_flow_classify_table_entry_delete",
267 printf(" should have failed!\n");
271 actions[0] = count_action;
272 actions[1] = end_action_bad;
274 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
277 printf("Line %i: rte_flow_classify_validate", __LINE__);
278 printf(" should have failed!\n");
282 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
283 actions, &key_found, &error);
285 printf("Line %i: flow_classify_table_entry_add", __LINE__);
286 printf(" should have failed!\n");
290 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
292 printf("Line %i: rte_flow_classify_table_entry_delete",
294 printf("should have failed!\n");
301 init_ipv4_udp_traffic(struct rte_mempool *mp,
302 struct rte_mbuf **pkts_burst, uint32_t burst_size)
304 struct ether_hdr pkt_eth_hdr;
305 struct ipv4_hdr pkt_ipv4_hdr;
306 struct udp_hdr pkt_udp_hdr;
307 uint32_t src_addr = IPV4_ADDR(2, 2, 2, 3);
308 uint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7);
309 uint16_t src_port = 32;
310 uint16_t dst_port = 33;
313 static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
314 static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
316 printf("Set up IPv4 UDP traffic\n");
317 initialize_eth_header(&pkt_eth_hdr,
318 (struct ether_addr *)src_mac,
319 (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
320 pktlen = (uint16_t)(sizeof(struct ether_hdr));
321 printf("ETH pktlen %u\n", pktlen);
323 pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr,
325 printf("ETH + IPv4 pktlen %u\n", pktlen);
327 pktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port,
329 printf("ETH + IPv4 + UDP pktlen %u\n\n", pktlen);
331 return generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr,
333 &pkt_udp_hdr, burst_size,
334 PACKET_BURST_GEN_PKT_LEN, 1);
338 init_ipv4_tcp_traffic(struct rte_mempool *mp,
339 struct rte_mbuf **pkts_burst, uint32_t burst_size)
341 struct ether_hdr pkt_eth_hdr;
342 struct ipv4_hdr pkt_ipv4_hdr;
343 struct tcp_hdr pkt_tcp_hdr;
344 uint32_t src_addr = IPV4_ADDR(1, 2, 3, 4);
345 uint32_t dst_addr = IPV4_ADDR(5, 6, 7, 8);
346 uint16_t src_port = 16;
347 uint16_t dst_port = 17;
350 static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
351 static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
353 printf("Set up IPv4 TCP traffic\n");
354 initialize_eth_header(&pkt_eth_hdr,
355 (struct ether_addr *)src_mac,
356 (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
357 pktlen = (uint16_t)(sizeof(struct ether_hdr));
358 printf("ETH pktlen %u\n", pktlen);
360 pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr,
361 dst_addr, pktlen, IPPROTO_TCP);
362 printf("ETH + IPv4 pktlen %u\n", pktlen);
364 pktlen = initialize_tcp_header(&pkt_tcp_hdr, src_port, dst_port,
366 printf("ETH + IPv4 + TCP pktlen %u\n\n", pktlen);
368 return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr,
369 0, &pkt_ipv4_hdr, 1, IPPROTO_TCP,
370 &pkt_tcp_hdr, burst_size,
371 PACKET_BURST_GEN_PKT_LEN, 1);
375 init_ipv4_sctp_traffic(struct rte_mempool *mp,
376 struct rte_mbuf **pkts_burst, uint32_t burst_size)
378 struct ether_hdr pkt_eth_hdr;
379 struct ipv4_hdr pkt_ipv4_hdr;
380 struct sctp_hdr pkt_sctp_hdr;
381 uint32_t src_addr = IPV4_ADDR(11, 12, 13, 14);
382 uint32_t dst_addr = IPV4_ADDR(15, 16, 17, 18);
383 uint16_t src_port = 10;
384 uint16_t dst_port = 11;
387 static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
388 static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
390 printf("Set up IPv4 SCTP traffic\n");
391 initialize_eth_header(&pkt_eth_hdr,
392 (struct ether_addr *)src_mac,
393 (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
394 pktlen = (uint16_t)(sizeof(struct ether_hdr));
395 printf("ETH pktlen %u\n", pktlen);
397 pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr,
398 dst_addr, pktlen, IPPROTO_SCTP);
399 printf("ETH + IPv4 pktlen %u\n", pktlen);
401 pktlen = initialize_sctp_header(&pkt_sctp_hdr, src_port, dst_port,
403 printf("ETH + IPv4 + SCTP pktlen %u\n\n", pktlen);
405 return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr,
406 0, &pkt_ipv4_hdr, 1, IPPROTO_SCTP,
407 &pkt_sctp_hdr, burst_size,
408 PACKET_BURST_GEN_PKT_LEN, 1);
416 unsigned int lcore_id;
419 for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
420 if (rte_lcore_is_enabled(lcore_id) == 0)
423 socketid = rte_lcore_to_socket_id(lcore_id);
424 if (socketid >= NB_SOCKETS) {
426 "Socket %d of lcore %u is out of range %d\n",
427 socketid, lcore_id, NB_SOCKETS);
431 if (mbufpool[socketid] == NULL) {
432 snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
434 rte_pktmbuf_pool_create(s, NB_MBUF,
435 MEMPOOL_CACHE_SIZE, 0, MBUF_SIZE,
437 if (mbufpool[socketid]) {
438 printf("Allocated mbuf pool on socket %d\n",
441 printf("Cannot init mbuf pool on socket %d\n",
454 struct rte_flow_error error;
455 struct rte_flow_classify_rule *rule;
460 ret = init_ipv4_udp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
461 if (ret != MAX_PKT_BURST) {
462 printf("Line %i: init_udp_ipv4_traffic has failed!\n",
467 for (i = 0; i < MAX_PKT_BURST; i++)
468 bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
471 * set up parameters for rte_flow_classify_validate,
472 * rte_flow_classify_table_entry_add and
473 * rte_flow_classify_table_entry_delete
478 pattern[0] = eth_item;
479 pattern[1] = ipv4_udp_item_1;
480 pattern[2] = udp_item_1;
481 pattern[3] = end_item;
482 actions[0] = count_action;
483 actions[1] = end_action;
485 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
488 printf("Line %i: rte_flow_classify_validate", __LINE__);
489 printf(" should not have failed!\n");
493 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
494 actions, &key_found, &error);
496 printf("Line %i: flow_classify_table_entry_add", __LINE__);
497 printf(" should not have failed!\n");
501 ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
502 rule, &udp_classify_stats);
504 printf("Line %i: flow_classifier_query", __LINE__);
505 printf(" should not have failed!\n");
509 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
511 printf("Line %i: rte_flow_classify_table_entry_delete",
513 printf(" should not have failed!\n");
522 struct rte_flow_classify_rule *rule;
527 ret = init_ipv4_tcp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
528 if (ret != MAX_PKT_BURST) {
529 printf("Line %i: init_ipv4_tcp_traffic has failed!\n",
534 for (i = 0; i < MAX_PKT_BURST; i++)
535 bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
538 * set up parameters for rte_flow_classify_validate,
539 * rte_flow_classify_table_entry_add and
540 * rte_flow_classify_table_entry_delete
545 pattern[0] = eth_item;
546 pattern[1] = ipv4_tcp_item_1;
547 pattern[2] = tcp_item_1;
548 pattern[3] = end_item;
549 actions[0] = count_action;
550 actions[1] = end_action;
552 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
555 printf("Line %i: flow_classifier_query", __LINE__);
556 printf(" should not have failed!\n");
560 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
561 actions, &key_found, &error);
563 printf("Line %i: flow_classify_table_entry_add", __LINE__);
564 printf(" should not have failed!\n");
568 ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
569 rule, &tcp_classify_stats);
571 printf("Line %i: flow_classifier_query", __LINE__);
572 printf(" should not have failed!\n");
576 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
578 printf("Line %i: rte_flow_classify_table_entry_delete",
580 printf(" should not have failed!\n");
587 test_query_sctp(void)
589 struct rte_flow_classify_rule *rule;
594 ret = init_ipv4_sctp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
595 if (ret != MAX_PKT_BURST) {
596 printf("Line %i: init_ipv4_tcp_traffic has failed!\n",
601 for (i = 0; i < MAX_PKT_BURST; i++)
602 bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
605 * set up parameters rte_flow_classify_validate,
606 * rte_flow_classify_table_entry_add and
607 * rte_flow_classify_table_entry_delete
612 pattern[0] = eth_item;
613 pattern[1] = ipv4_sctp_item_1;
614 pattern[2] = sctp_item_1;
615 pattern[3] = end_item;
616 actions[0] = count_action;
617 actions[1] = end_action;
619 ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
622 printf("Line %i: flow_classifier_query", __LINE__);
623 printf(" should not have failed!\n");
627 rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
628 actions, &key_found, &error);
630 printf("Line %i: flow_classify_table_entry_add", __LINE__);
631 printf(" should not have failed!\n");
635 ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
636 rule, &sctp_classify_stats);
638 printf("Line %i: flow_classifier_query", __LINE__);
639 printf(" should not have failed!\n");
643 ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
645 printf("Line %i: rte_flow_classify_table_entry_delete",
647 printf(" should not have failed!\n");
654 test_flow_classify(void)
656 struct rte_table_acl_params table_acl_params;
657 struct rte_flow_classify_table_params cls_table_params;
658 struct rte_flow_classifier_params cls_params;
663 socket_id = rte_eth_dev_socket_id(0);
665 /* Memory allocation */
666 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl));
667 cls = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
669 cls_params.name = "flow_classifier";
670 cls_params.socket_id = socket_id;
671 cls->cls = rte_flow_classifier_create(&cls_params);
673 /* initialise ACL table params */
674 table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs);
675 table_acl_params.name = "table_acl_ipv4_5tuple";
676 table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM;
677 memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
679 /* initialise table create params */
680 cls_table_params.ops = &rte_table_acl_ops;
681 cls_table_params.arg_create = &table_acl_params;
682 cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE;
684 ret = rte_flow_classify_table_create(cls->cls, &cls_table_params);
686 printf("Line %i: f_create has failed!\n", __LINE__);
687 rte_flow_classifier_free(cls->cls);
691 printf("Created table_acl for for IPv4 five tuple packets\n");
693 ret = init_mbufpool();
695 printf("Line %i: init_mbufpool has failed!\n", __LINE__);
699 if (test_invalid_parameters() < 0)
701 if (test_valid_parameters() < 0)
703 if (test_invalid_patterns() < 0)
705 if (test_invalid_actions() < 0)
707 if (test_query_udp() < 0)
709 if (test_query_tcp() < 0)
711 if (test_query_sctp() < 0)
717 REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify);