14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang * Copyright(c) 2017 Intel Corporation
34418919fSjohnjiang */
44418919fSjohnjiang
54418919fSjohnjiang #include <string.h>
64418919fSjohnjiang #include <errno.h>
74418919fSjohnjiang
84418919fSjohnjiang #include "test.h"
94418919fSjohnjiang
104418919fSjohnjiang #include <rte_string_fns.h>
114418919fSjohnjiang #include <rte_mbuf.h>
124418919fSjohnjiang #include <rte_byteorder.h>
134418919fSjohnjiang #include <rte_ip.h>
144418919fSjohnjiang #include <rte_acl.h>
154418919fSjohnjiang #include <rte_common.h>
164418919fSjohnjiang #include <rte_table_acl.h>
174418919fSjohnjiang #include <rte_flow.h>
184418919fSjohnjiang #include <rte_flow_classify.h>
194418919fSjohnjiang
204418919fSjohnjiang #include "packet_burst_generator.h"
214418919fSjohnjiang #include "test_flow_classify.h"
224418919fSjohnjiang
234418919fSjohnjiang
244418919fSjohnjiang #define FLOW_CLASSIFY_MAX_RULE_NUM 100
254418919fSjohnjiang #define MAX_PKT_BURST 32
26*0c6bd470Sfengbojiang #define NB_SOCKETS 4
274418919fSjohnjiang #define MEMPOOL_CACHE_SIZE 256
284418919fSjohnjiang #define MBUF_SIZE 512
294418919fSjohnjiang #define NB_MBUF 512
304418919fSjohnjiang
314418919fSjohnjiang /* test UDP, TCP and SCTP packets */
324418919fSjohnjiang static struct rte_mempool *mbufpool[NB_SOCKETS];
334418919fSjohnjiang static struct rte_mbuf *bufs[MAX_PKT_BURST];
344418919fSjohnjiang
354418919fSjohnjiang static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
364418919fSjohnjiang /* first input field - always one byte long. */
374418919fSjohnjiang {
384418919fSjohnjiang .type = RTE_ACL_FIELD_TYPE_BITMASK,
394418919fSjohnjiang .size = sizeof(uint8_t),
404418919fSjohnjiang .field_index = PROTO_FIELD_IPV4,
414418919fSjohnjiang .input_index = PROTO_INPUT_IPV4,
424418919fSjohnjiang .offset = sizeof(struct rte_ether_hdr) +
434418919fSjohnjiang offsetof(struct rte_ipv4_hdr, next_proto_id),
444418919fSjohnjiang },
454418919fSjohnjiang /* next input field (IPv4 source address) - 4 consecutive bytes. */
464418919fSjohnjiang {
474418919fSjohnjiang /* rte_flow uses a bit mask for IPv4 addresses */
484418919fSjohnjiang .type = RTE_ACL_FIELD_TYPE_BITMASK,
494418919fSjohnjiang .size = sizeof(uint32_t),
504418919fSjohnjiang .field_index = SRC_FIELD_IPV4,
514418919fSjohnjiang .input_index = SRC_INPUT_IPV4,
524418919fSjohnjiang .offset = sizeof(struct rte_ether_hdr) +
534418919fSjohnjiang offsetof(struct rte_ipv4_hdr, src_addr),
544418919fSjohnjiang },
554418919fSjohnjiang /* next input field (IPv4 destination address) - 4 consecutive bytes. */
564418919fSjohnjiang {
574418919fSjohnjiang /* rte_flow uses a bit mask for IPv4 addresses */
584418919fSjohnjiang .type = RTE_ACL_FIELD_TYPE_BITMASK,
594418919fSjohnjiang .size = sizeof(uint32_t),
604418919fSjohnjiang .field_index = DST_FIELD_IPV4,
614418919fSjohnjiang .input_index = DST_INPUT_IPV4,
624418919fSjohnjiang .offset = sizeof(struct rte_ether_hdr) +
634418919fSjohnjiang offsetof(struct rte_ipv4_hdr, dst_addr),
644418919fSjohnjiang },
654418919fSjohnjiang /*
664418919fSjohnjiang * Next 2 fields (src & dst ports) form 4 consecutive bytes.
674418919fSjohnjiang * They share the same input index.
684418919fSjohnjiang */
694418919fSjohnjiang {
704418919fSjohnjiang /* rte_flow uses a bit mask for protocol ports */
714418919fSjohnjiang .type = RTE_ACL_FIELD_TYPE_BITMASK,
724418919fSjohnjiang .size = sizeof(uint16_t),
734418919fSjohnjiang .field_index = SRCP_FIELD_IPV4,
744418919fSjohnjiang .input_index = SRCP_DESTP_INPUT_IPV4,
754418919fSjohnjiang .offset = sizeof(struct rte_ether_hdr) +
764418919fSjohnjiang sizeof(struct rte_ipv4_hdr) +
774418919fSjohnjiang offsetof(struct rte_tcp_hdr, src_port),
784418919fSjohnjiang },
794418919fSjohnjiang {
804418919fSjohnjiang /* rte_flow uses a bit mask for protocol ports */
814418919fSjohnjiang .type = RTE_ACL_FIELD_TYPE_BITMASK,
824418919fSjohnjiang .size = sizeof(uint16_t),
834418919fSjohnjiang .field_index = DSTP_FIELD_IPV4,
844418919fSjohnjiang .input_index = SRCP_DESTP_INPUT_IPV4,
854418919fSjohnjiang .offset = sizeof(struct rte_ether_hdr) +
864418919fSjohnjiang sizeof(struct rte_ipv4_hdr) +
874418919fSjohnjiang offsetof(struct rte_tcp_hdr, dst_port),
884418919fSjohnjiang },
894418919fSjohnjiang };
904418919fSjohnjiang
914418919fSjohnjiang /* parameters for rte_flow_classify_validate and rte_flow_classify_create */
924418919fSjohnjiang
934418919fSjohnjiang /* test UDP pattern:
944418919fSjohnjiang * "eth / ipv4 src spec 2.2.2.3 src mask 255.255.255.00 dst spec 2.2.2.7
954418919fSjohnjiang * dst mask 255.255.255.00 / udp src is 32 dst is 33 / end"
964418919fSjohnjiang */
974418919fSjohnjiang static struct rte_flow_item_ipv4 ipv4_udp_spec_1 = {
984418919fSjohnjiang { 0, 0, 0, 0, 0, 0, IPPROTO_UDP, 0,
994418919fSjohnjiang RTE_IPV4(2, 2, 2, 3), RTE_IPV4(2, 2, 2, 7)}
1004418919fSjohnjiang };
1014418919fSjohnjiang static const struct rte_flow_item_ipv4 ipv4_mask_24 = {
1024418919fSjohnjiang .hdr = {
1034418919fSjohnjiang .next_proto_id = 0xff,
1044418919fSjohnjiang .src_addr = 0xffffff00,
1054418919fSjohnjiang .dst_addr = 0xffffff00,
1064418919fSjohnjiang },
1074418919fSjohnjiang };
1084418919fSjohnjiang static struct rte_flow_item_udp udp_spec_1 = {
1094418919fSjohnjiang { 32, 33, 0, 0 }
1104418919fSjohnjiang };
1114418919fSjohnjiang
1124418919fSjohnjiang static struct rte_flow_item eth_item = { RTE_FLOW_ITEM_TYPE_ETH,
1134418919fSjohnjiang 0, 0, 0 };
1144418919fSjohnjiang static struct rte_flow_item eth_item_bad = { -1, 0, 0, 0 };
1154418919fSjohnjiang
1164418919fSjohnjiang static struct rte_flow_item ipv4_udp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4,
1174418919fSjohnjiang &ipv4_udp_spec_1, 0, &ipv4_mask_24};
1184418919fSjohnjiang static struct rte_flow_item ipv4_udp_item_bad = { RTE_FLOW_ITEM_TYPE_IPV4,
1194418919fSjohnjiang NULL, 0, NULL};
1204418919fSjohnjiang
1214418919fSjohnjiang static struct rte_flow_item udp_item_1 = { RTE_FLOW_ITEM_TYPE_UDP,
1224418919fSjohnjiang &udp_spec_1, 0, &rte_flow_item_udp_mask};
1234418919fSjohnjiang static struct rte_flow_item udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP,
1244418919fSjohnjiang NULL, 0, NULL};
1254418919fSjohnjiang
1264418919fSjohnjiang static struct rte_flow_item end_item = { RTE_FLOW_ITEM_TYPE_END,
1274418919fSjohnjiang 0, 0, 0 };
1284418919fSjohnjiang
1294418919fSjohnjiang /* test TCP pattern:
1304418919fSjohnjiang * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8
1314418919fSjohnjiang * dst mask 255.255.255.00 / tcp src is 16 dst is 17 / end"
1324418919fSjohnjiang */
1334418919fSjohnjiang static struct rte_flow_item_ipv4 ipv4_tcp_spec_1 = {
1344418919fSjohnjiang { 0, 0, 0, 0, 0, 0, IPPROTO_TCP, 0,
1354418919fSjohnjiang RTE_IPV4(1, 2, 3, 4), RTE_IPV4(5, 6, 7, 8)}
1364418919fSjohnjiang };
1374418919fSjohnjiang
1384418919fSjohnjiang static struct rte_flow_item_tcp tcp_spec_1 = {
1394418919fSjohnjiang { 16, 17, 0, 0, 0, 0, 0, 0, 0}
1404418919fSjohnjiang };
1414418919fSjohnjiang
1424418919fSjohnjiang static struct rte_flow_item ipv4_tcp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4,
1434418919fSjohnjiang &ipv4_tcp_spec_1, 0, &ipv4_mask_24};
1444418919fSjohnjiang
1454418919fSjohnjiang static struct rte_flow_item tcp_item_1 = { RTE_FLOW_ITEM_TYPE_TCP,
1464418919fSjohnjiang &tcp_spec_1, 0, &rte_flow_item_tcp_mask};
1474418919fSjohnjiang
1484418919fSjohnjiang /* test SCTP pattern:
1494418919fSjohnjiang * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8
1504418919fSjohnjiang * dst mask 255.255.255.00 / sctp src is 16 dst is 17/ end"
1514418919fSjohnjiang */
1524418919fSjohnjiang static struct rte_flow_item_ipv4 ipv4_sctp_spec_1 = {
1534418919fSjohnjiang { 0, 0, 0, 0, 0, 0, IPPROTO_SCTP, 0, RTE_IPV4(11, 12, 13, 14),
1544418919fSjohnjiang RTE_IPV4(15, 16, 17, 18)}
1554418919fSjohnjiang };
1564418919fSjohnjiang
1574418919fSjohnjiang static struct rte_flow_item_sctp sctp_spec_1 = {
1584418919fSjohnjiang { 10, 11, 0, 0}
1594418919fSjohnjiang };
1604418919fSjohnjiang
1614418919fSjohnjiang static struct rte_flow_item ipv4_sctp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4,
1624418919fSjohnjiang &ipv4_sctp_spec_1, 0, &ipv4_mask_24};
1634418919fSjohnjiang
1644418919fSjohnjiang static struct rte_flow_item sctp_item_1 = { RTE_FLOW_ITEM_TYPE_SCTP,
1654418919fSjohnjiang &sctp_spec_1, 0, &rte_flow_item_sctp_mask};
1664418919fSjohnjiang
1674418919fSjohnjiang
1684418919fSjohnjiang /* test actions:
1694418919fSjohnjiang * "actions count / end"
1704418919fSjohnjiang */
1714418919fSjohnjiang static struct rte_flow_query_count count = {
1724418919fSjohnjiang .reset = 1,
1734418919fSjohnjiang .hits_set = 1,
1744418919fSjohnjiang .bytes_set = 1,
1754418919fSjohnjiang .hits = 0,
1764418919fSjohnjiang .bytes = 0,
1774418919fSjohnjiang };
1784418919fSjohnjiang static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
1794418919fSjohnjiang &count};
1804418919fSjohnjiang static struct rte_flow_action count_action_bad = { -1, 0};
1814418919fSjohnjiang
1824418919fSjohnjiang static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};
1834418919fSjohnjiang
1844418919fSjohnjiang static struct rte_flow_action actions[2];
1854418919fSjohnjiang
1864418919fSjohnjiang /* test attributes */
1874418919fSjohnjiang static struct rte_flow_attr attr;
1884418919fSjohnjiang
1894418919fSjohnjiang /* test error */
1904418919fSjohnjiang static struct rte_flow_error error;
1914418919fSjohnjiang
1924418919fSjohnjiang /* test pattern */
1934418919fSjohnjiang static struct rte_flow_item pattern[4];
1944418919fSjohnjiang
1954418919fSjohnjiang /* flow classify data for UDP burst */
1964418919fSjohnjiang static struct rte_flow_classify_ipv4_5tuple_stats udp_ntuple_stats;
1974418919fSjohnjiang static struct rte_flow_classify_stats udp_classify_stats = {
1984418919fSjohnjiang .stats = (void *)&udp_ntuple_stats
1994418919fSjohnjiang };
2004418919fSjohnjiang
2014418919fSjohnjiang /* flow classify data for TCP burst */
2024418919fSjohnjiang static struct rte_flow_classify_ipv4_5tuple_stats tcp_ntuple_stats;
2034418919fSjohnjiang static struct rte_flow_classify_stats tcp_classify_stats = {
2044418919fSjohnjiang .stats = (void *)&tcp_ntuple_stats
2054418919fSjohnjiang };
2064418919fSjohnjiang
2074418919fSjohnjiang /* flow classify data for SCTP burst */
2084418919fSjohnjiang static struct rte_flow_classify_ipv4_5tuple_stats sctp_ntuple_stats;
2094418919fSjohnjiang static struct rte_flow_classify_stats sctp_classify_stats = {
2104418919fSjohnjiang .stats = (void *)&sctp_ntuple_stats
2114418919fSjohnjiang };
2124418919fSjohnjiang
2134418919fSjohnjiang struct flow_classifier_acl *cls;
2144418919fSjohnjiang
2154418919fSjohnjiang struct flow_classifier_acl {
2164418919fSjohnjiang struct rte_flow_classifier *cls;
2174418919fSjohnjiang } __rte_cache_aligned;
2184418919fSjohnjiang
2194418919fSjohnjiang /*
2204418919fSjohnjiang * test functions by passing invalid or
2214418919fSjohnjiang * non-workable parameters.
2224418919fSjohnjiang */
2234418919fSjohnjiang static int
test_invalid_parameters(void)2244418919fSjohnjiang test_invalid_parameters(void)
2254418919fSjohnjiang {
2264418919fSjohnjiang struct rte_flow_classify_rule *rule;
2274418919fSjohnjiang int ret;
2284418919fSjohnjiang
2294418919fSjohnjiang ret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL);
2304418919fSjohnjiang if (!ret) {
2314418919fSjohnjiang printf("Line %i: rte_flow_classify_validate",
2324418919fSjohnjiang __LINE__);
2334418919fSjohnjiang printf(" with NULL param should have failed!\n");
2344418919fSjohnjiang return -1;
2354418919fSjohnjiang }
2364418919fSjohnjiang
2374418919fSjohnjiang rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL,
2384418919fSjohnjiang NULL, NULL);
2394418919fSjohnjiang if (rule) {
2404418919fSjohnjiang printf("Line %i: flow_classifier_table_entry_add", __LINE__);
2414418919fSjohnjiang printf(" with NULL param should have failed!\n");
2424418919fSjohnjiang return -1;
2434418919fSjohnjiang }
2444418919fSjohnjiang
2454418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(NULL, NULL);
2464418919fSjohnjiang if (!ret) {
2474418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
2484418919fSjohnjiang __LINE__);
2494418919fSjohnjiang printf(" with NULL param should have failed!\n");
2504418919fSjohnjiang return -1;
2514418919fSjohnjiang }
2524418919fSjohnjiang
2534418919fSjohnjiang ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL);
2544418919fSjohnjiang if (!ret) {
2554418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
2564418919fSjohnjiang printf(" with NULL param should have failed!\n");
2574418919fSjohnjiang return -1;
2584418919fSjohnjiang }
2594418919fSjohnjiang
2604418919fSjohnjiang rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL,
2614418919fSjohnjiang NULL, &error);
2624418919fSjohnjiang if (rule) {
2634418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add ", __LINE__);
2644418919fSjohnjiang printf("with NULL param should have failed!\n");
2654418919fSjohnjiang return -1;
2664418919fSjohnjiang }
2674418919fSjohnjiang
2684418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(NULL, NULL);
2694418919fSjohnjiang if (!ret) {
2704418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
2714418919fSjohnjiang __LINE__);
2724418919fSjohnjiang printf("with NULL param should have failed!\n");
2734418919fSjohnjiang return -1;
2744418919fSjohnjiang }
2754418919fSjohnjiang
2764418919fSjohnjiang ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL);
2774418919fSjohnjiang if (!ret) {
2784418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
2794418919fSjohnjiang printf(" with NULL param should have failed!\n");
2804418919fSjohnjiang return -1;
2814418919fSjohnjiang }
2824418919fSjohnjiang return 0;
2834418919fSjohnjiang }
2844418919fSjohnjiang
2854418919fSjohnjiang static int
test_valid_parameters(void)2864418919fSjohnjiang test_valid_parameters(void)
2874418919fSjohnjiang {
2884418919fSjohnjiang struct rte_flow_classify_rule *rule;
2894418919fSjohnjiang int ret;
2904418919fSjohnjiang int key_found;
2914418919fSjohnjiang
2924418919fSjohnjiang /*
2934418919fSjohnjiang * set up parameters for rte_flow_classify_validate,
2944418919fSjohnjiang * rte_flow_classify_table_entry_add and
2954418919fSjohnjiang * rte_flow_classify_table_entry_delete
2964418919fSjohnjiang */
2974418919fSjohnjiang
2984418919fSjohnjiang attr.ingress = 1;
2994418919fSjohnjiang attr.priority = 1;
3004418919fSjohnjiang pattern[0] = eth_item;
3014418919fSjohnjiang pattern[1] = ipv4_udp_item_1;
3024418919fSjohnjiang pattern[2] = udp_item_1;
3034418919fSjohnjiang pattern[3] = end_item;
3044418919fSjohnjiang actions[0] = count_action;
3054418919fSjohnjiang actions[1] = end_action;
3064418919fSjohnjiang
3074418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
3084418919fSjohnjiang actions, &error);
3094418919fSjohnjiang if (ret) {
3104418919fSjohnjiang printf("Line %i: rte_flow_classify_validate",
3114418919fSjohnjiang __LINE__);
3124418919fSjohnjiang printf(" should not have failed!\n");
3134418919fSjohnjiang return -1;
3144418919fSjohnjiang }
3154418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
3164418919fSjohnjiang actions, &key_found, &error);
3174418919fSjohnjiang
3184418919fSjohnjiang if (!rule) {
3194418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
3204418919fSjohnjiang printf(" should not have failed!\n");
3214418919fSjohnjiang return -1;
3224418919fSjohnjiang }
3234418919fSjohnjiang
3244418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
3254418919fSjohnjiang if (ret) {
3264418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
3274418919fSjohnjiang __LINE__);
3284418919fSjohnjiang printf(" should not have failed!\n");
3294418919fSjohnjiang return -1;
3304418919fSjohnjiang }
3314418919fSjohnjiang return 0;
3324418919fSjohnjiang }
3334418919fSjohnjiang
3344418919fSjohnjiang static int
test_invalid_patterns(void)3354418919fSjohnjiang test_invalid_patterns(void)
3364418919fSjohnjiang {
3374418919fSjohnjiang struct rte_flow_classify_rule *rule;
3384418919fSjohnjiang int ret;
3394418919fSjohnjiang int key_found;
3404418919fSjohnjiang
3414418919fSjohnjiang /*
3424418919fSjohnjiang * set up parameters for rte_flow_classify_validate,
3434418919fSjohnjiang * rte_flow_classify_table_entry_add and
3444418919fSjohnjiang * rte_flow_classify_table_entry_delete
3454418919fSjohnjiang */
3464418919fSjohnjiang
3474418919fSjohnjiang attr.ingress = 1;
3484418919fSjohnjiang attr.priority = 1;
3494418919fSjohnjiang pattern[0] = eth_item_bad;
3504418919fSjohnjiang pattern[1] = ipv4_udp_item_1;
3514418919fSjohnjiang pattern[2] = udp_item_1;
3524418919fSjohnjiang pattern[3] = end_item;
3534418919fSjohnjiang actions[0] = count_action;
3544418919fSjohnjiang actions[1] = end_action;
3554418919fSjohnjiang
3564418919fSjohnjiang pattern[0] = eth_item;
3574418919fSjohnjiang pattern[1] = ipv4_udp_item_bad;
3584418919fSjohnjiang
3594418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
3604418919fSjohnjiang actions, &error);
3614418919fSjohnjiang if (!ret) {
3624418919fSjohnjiang printf("Line %i: rte_flow_classify_validate", __LINE__);
3634418919fSjohnjiang printf(" should have failed!\n");
3644418919fSjohnjiang return -1;
3654418919fSjohnjiang }
3664418919fSjohnjiang
3674418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
3684418919fSjohnjiang actions, &key_found, &error);
3694418919fSjohnjiang if (rule) {
3704418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
3714418919fSjohnjiang printf(" should have failed!\n");
3724418919fSjohnjiang return -1;
3734418919fSjohnjiang }
3744418919fSjohnjiang
3754418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
3764418919fSjohnjiang if (!ret) {
3774418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
3784418919fSjohnjiang __LINE__);
3794418919fSjohnjiang printf(" should have failed!\n");
3804418919fSjohnjiang return -1;
3814418919fSjohnjiang }
3824418919fSjohnjiang
3834418919fSjohnjiang pattern[1] = ipv4_udp_item_1;
3844418919fSjohnjiang pattern[2] = udp_item_bad;
3854418919fSjohnjiang pattern[3] = end_item;
3864418919fSjohnjiang
3874418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
3884418919fSjohnjiang actions, &error);
3894418919fSjohnjiang if (!ret) {
3904418919fSjohnjiang printf("Line %i: rte_flow_classify_validate", __LINE__);
3914418919fSjohnjiang printf(" should have failed!\n");
3924418919fSjohnjiang return -1;
3934418919fSjohnjiang }
3944418919fSjohnjiang
3954418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
3964418919fSjohnjiang actions, &key_found, &error);
3974418919fSjohnjiang if (rule) {
3984418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
3994418919fSjohnjiang printf(" should have failed!\n");
4004418919fSjohnjiang return -1;
4014418919fSjohnjiang }
4024418919fSjohnjiang
4034418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
4044418919fSjohnjiang if (!ret) {
4054418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
4064418919fSjohnjiang __LINE__);
4074418919fSjohnjiang printf(" should have failed!\n");
4084418919fSjohnjiang return -1;
4094418919fSjohnjiang }
4104418919fSjohnjiang return 0;
4114418919fSjohnjiang }
4124418919fSjohnjiang
4134418919fSjohnjiang static int
test_invalid_actions(void)4144418919fSjohnjiang test_invalid_actions(void)
4154418919fSjohnjiang {
4164418919fSjohnjiang struct rte_flow_classify_rule *rule;
4174418919fSjohnjiang int ret;
4184418919fSjohnjiang int key_found;
4194418919fSjohnjiang
4204418919fSjohnjiang /*
4214418919fSjohnjiang * set up parameters for rte_flow_classify_validate,
4224418919fSjohnjiang * rte_flow_classify_table_entry_add and
4234418919fSjohnjiang * rte_flow_classify_table_entry_delete
4244418919fSjohnjiang */
4254418919fSjohnjiang
4264418919fSjohnjiang attr.ingress = 1;
4274418919fSjohnjiang attr.priority = 1;
4284418919fSjohnjiang pattern[0] = eth_item;
4294418919fSjohnjiang pattern[1] = ipv4_udp_item_1;
4304418919fSjohnjiang pattern[2] = udp_item_1;
4314418919fSjohnjiang pattern[3] = end_item;
4324418919fSjohnjiang actions[0] = count_action_bad;
4334418919fSjohnjiang actions[1] = end_action;
4344418919fSjohnjiang
4354418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
4364418919fSjohnjiang actions, &error);
4374418919fSjohnjiang if (!ret) {
4384418919fSjohnjiang printf("Line %i: rte_flow_classify_validate", __LINE__);
4394418919fSjohnjiang printf(" should have failed!\n");
4404418919fSjohnjiang return -1;
4414418919fSjohnjiang }
4424418919fSjohnjiang
4434418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
4444418919fSjohnjiang actions, &key_found, &error);
4454418919fSjohnjiang if (rule) {
4464418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
4474418919fSjohnjiang printf(" should have failed!\n");
4484418919fSjohnjiang return -1;
4494418919fSjohnjiang }
4504418919fSjohnjiang
4514418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
4524418919fSjohnjiang if (!ret) {
4534418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
4544418919fSjohnjiang __LINE__);
4554418919fSjohnjiang printf(" should have failed!\n");
4564418919fSjohnjiang return -1;
4574418919fSjohnjiang }
4584418919fSjohnjiang
4594418919fSjohnjiang return 0;
4604418919fSjohnjiang }
4614418919fSjohnjiang
4624418919fSjohnjiang static int
init_ipv4_udp_traffic(struct rte_mempool * mp,struct rte_mbuf ** pkts_burst,uint32_t burst_size)4634418919fSjohnjiang init_ipv4_udp_traffic(struct rte_mempool *mp,
4644418919fSjohnjiang struct rte_mbuf **pkts_burst, uint32_t burst_size)
4654418919fSjohnjiang {
4664418919fSjohnjiang struct rte_ether_hdr pkt_eth_hdr;
4674418919fSjohnjiang struct rte_ipv4_hdr pkt_ipv4_hdr;
4684418919fSjohnjiang struct rte_udp_hdr pkt_udp_hdr;
4694418919fSjohnjiang uint32_t src_addr = IPV4_ADDR(2, 2, 2, 3);
4704418919fSjohnjiang uint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7);
4714418919fSjohnjiang uint16_t src_port = 32;
4724418919fSjohnjiang uint16_t dst_port = 33;
4734418919fSjohnjiang uint16_t pktlen;
4744418919fSjohnjiang
4754418919fSjohnjiang static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
4764418919fSjohnjiang static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
4774418919fSjohnjiang
4784418919fSjohnjiang printf("Set up IPv4 UDP traffic\n");
4794418919fSjohnjiang initialize_eth_header(&pkt_eth_hdr,
4804418919fSjohnjiang (struct rte_ether_addr *)src_mac,
4814418919fSjohnjiang (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0);
4824418919fSjohnjiang pktlen = (uint16_t)(sizeof(struct rte_ether_hdr));
4834418919fSjohnjiang printf("ETH pktlen %u\n", pktlen);
4844418919fSjohnjiang
4854418919fSjohnjiang pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr,
4864418919fSjohnjiang pktlen);
4874418919fSjohnjiang printf("ETH + IPv4 pktlen %u\n", pktlen);
4884418919fSjohnjiang
4894418919fSjohnjiang pktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port,
4904418919fSjohnjiang pktlen);
4914418919fSjohnjiang printf("ETH + IPv4 + UDP pktlen %u\n\n", pktlen);
4924418919fSjohnjiang
4934418919fSjohnjiang return generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr,
4944418919fSjohnjiang 0, &pkt_ipv4_hdr, 1,
4954418919fSjohnjiang &pkt_udp_hdr, burst_size,
4964418919fSjohnjiang PACKET_BURST_GEN_PKT_LEN, 1);
4974418919fSjohnjiang }
4984418919fSjohnjiang
4994418919fSjohnjiang static int
init_ipv4_tcp_traffic(struct rte_mempool * mp,struct rte_mbuf ** pkts_burst,uint32_t burst_size)5004418919fSjohnjiang init_ipv4_tcp_traffic(struct rte_mempool *mp,
5014418919fSjohnjiang struct rte_mbuf **pkts_burst, uint32_t burst_size)
5024418919fSjohnjiang {
5034418919fSjohnjiang struct rte_ether_hdr pkt_eth_hdr;
5044418919fSjohnjiang struct rte_ipv4_hdr pkt_ipv4_hdr;
5054418919fSjohnjiang struct rte_tcp_hdr pkt_tcp_hdr;
5064418919fSjohnjiang uint32_t src_addr = IPV4_ADDR(1, 2, 3, 4);
5074418919fSjohnjiang uint32_t dst_addr = IPV4_ADDR(5, 6, 7, 8);
5084418919fSjohnjiang uint16_t src_port = 16;
5094418919fSjohnjiang uint16_t dst_port = 17;
5104418919fSjohnjiang uint16_t pktlen;
5114418919fSjohnjiang
5124418919fSjohnjiang static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
5134418919fSjohnjiang static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
5144418919fSjohnjiang
5154418919fSjohnjiang printf("Set up IPv4 TCP traffic\n");
5164418919fSjohnjiang initialize_eth_header(&pkt_eth_hdr,
5174418919fSjohnjiang (struct rte_ether_addr *)src_mac,
5184418919fSjohnjiang (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0);
5194418919fSjohnjiang pktlen = (uint16_t)(sizeof(struct rte_ether_hdr));
5204418919fSjohnjiang printf("ETH pktlen %u\n", pktlen);
5214418919fSjohnjiang
5224418919fSjohnjiang pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr,
5234418919fSjohnjiang dst_addr, pktlen, IPPROTO_TCP);
5244418919fSjohnjiang printf("ETH + IPv4 pktlen %u\n", pktlen);
5254418919fSjohnjiang
5264418919fSjohnjiang pktlen = initialize_tcp_header(&pkt_tcp_hdr, src_port, dst_port,
5274418919fSjohnjiang pktlen);
5284418919fSjohnjiang printf("ETH + IPv4 + TCP pktlen %u\n\n", pktlen);
5294418919fSjohnjiang
5304418919fSjohnjiang return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr,
5314418919fSjohnjiang 0, &pkt_ipv4_hdr, 1, IPPROTO_TCP,
5324418919fSjohnjiang &pkt_tcp_hdr, burst_size,
5334418919fSjohnjiang PACKET_BURST_GEN_PKT_LEN, 1);
5344418919fSjohnjiang }
5354418919fSjohnjiang
5364418919fSjohnjiang static int
init_ipv4_sctp_traffic(struct rte_mempool * mp,struct rte_mbuf ** pkts_burst,uint32_t burst_size)5374418919fSjohnjiang init_ipv4_sctp_traffic(struct rte_mempool *mp,
5384418919fSjohnjiang struct rte_mbuf **pkts_burst, uint32_t burst_size)
5394418919fSjohnjiang {
5404418919fSjohnjiang struct rte_ether_hdr pkt_eth_hdr;
5414418919fSjohnjiang struct rte_ipv4_hdr pkt_ipv4_hdr;
5424418919fSjohnjiang struct rte_sctp_hdr pkt_sctp_hdr;
5434418919fSjohnjiang uint32_t src_addr = IPV4_ADDR(11, 12, 13, 14);
5444418919fSjohnjiang uint32_t dst_addr = IPV4_ADDR(15, 16, 17, 18);
5454418919fSjohnjiang uint16_t src_port = 10;
5464418919fSjohnjiang uint16_t dst_port = 11;
5474418919fSjohnjiang uint16_t pktlen;
5484418919fSjohnjiang
5494418919fSjohnjiang static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
5504418919fSjohnjiang static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
5514418919fSjohnjiang
5524418919fSjohnjiang printf("Set up IPv4 SCTP traffic\n");
5534418919fSjohnjiang initialize_eth_header(&pkt_eth_hdr,
5544418919fSjohnjiang (struct rte_ether_addr *)src_mac,
5554418919fSjohnjiang (struct rte_ether_addr *)dst_mac, RTE_ETHER_TYPE_IPV4, 0, 0);
5564418919fSjohnjiang pktlen = (uint16_t)(sizeof(struct rte_ether_hdr));
5574418919fSjohnjiang printf("ETH pktlen %u\n", pktlen);
5584418919fSjohnjiang
5594418919fSjohnjiang pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr,
5604418919fSjohnjiang dst_addr, pktlen, IPPROTO_SCTP);
5614418919fSjohnjiang printf("ETH + IPv4 pktlen %u\n", pktlen);
5624418919fSjohnjiang
5634418919fSjohnjiang pktlen = initialize_sctp_header(&pkt_sctp_hdr, src_port, dst_port,
5644418919fSjohnjiang pktlen);
5654418919fSjohnjiang printf("ETH + IPv4 + SCTP pktlen %u\n\n", pktlen);
5664418919fSjohnjiang
5674418919fSjohnjiang return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr,
5684418919fSjohnjiang 0, &pkt_ipv4_hdr, 1, IPPROTO_SCTP,
5694418919fSjohnjiang &pkt_sctp_hdr, burst_size,
5704418919fSjohnjiang PACKET_BURST_GEN_PKT_LEN, 1);
5714418919fSjohnjiang }
5724418919fSjohnjiang
5734418919fSjohnjiang static int
init_mbufpool(void)5744418919fSjohnjiang init_mbufpool(void)
5754418919fSjohnjiang {
5764418919fSjohnjiang int socketid;
5774418919fSjohnjiang int ret = 0;
5784418919fSjohnjiang unsigned int lcore_id;
5794418919fSjohnjiang char s[64];
5804418919fSjohnjiang
5814418919fSjohnjiang for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
5824418919fSjohnjiang if (rte_lcore_is_enabled(lcore_id) == 0)
5834418919fSjohnjiang continue;
5844418919fSjohnjiang
5854418919fSjohnjiang socketid = rte_lcore_to_socket_id(lcore_id);
5864418919fSjohnjiang if (socketid >= NB_SOCKETS) {
5874418919fSjohnjiang printf(
5884418919fSjohnjiang "Socket %d of lcore %u is out of range %d\n",
5894418919fSjohnjiang socketid, lcore_id, NB_SOCKETS);
5904418919fSjohnjiang ret = -1;
5914418919fSjohnjiang break;
5924418919fSjohnjiang }
5934418919fSjohnjiang if (mbufpool[socketid] == NULL) {
5944418919fSjohnjiang snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
5954418919fSjohnjiang mbufpool[socketid] =
5964418919fSjohnjiang rte_pktmbuf_pool_create(s, NB_MBUF,
5974418919fSjohnjiang MEMPOOL_CACHE_SIZE, 0, MBUF_SIZE,
5984418919fSjohnjiang socketid);
5994418919fSjohnjiang if (mbufpool[socketid]) {
6004418919fSjohnjiang printf("Allocated mbuf pool on socket %d\n",
6014418919fSjohnjiang socketid);
6024418919fSjohnjiang } else {
6034418919fSjohnjiang printf("Cannot init mbuf pool on socket %d\n",
6044418919fSjohnjiang socketid);
6054418919fSjohnjiang ret = -ENOMEM;
6064418919fSjohnjiang break;
6074418919fSjohnjiang }
6084418919fSjohnjiang }
6094418919fSjohnjiang }
6104418919fSjohnjiang return ret;
6114418919fSjohnjiang }
6124418919fSjohnjiang
6134418919fSjohnjiang static int
test_query_udp(void)6144418919fSjohnjiang test_query_udp(void)
6154418919fSjohnjiang {
6164418919fSjohnjiang struct rte_flow_error error;
6174418919fSjohnjiang struct rte_flow_classify_rule *rule;
6184418919fSjohnjiang int ret;
6194418919fSjohnjiang int i;
6204418919fSjohnjiang int key_found;
6214418919fSjohnjiang
6224418919fSjohnjiang ret = init_ipv4_udp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
6234418919fSjohnjiang if (ret != MAX_PKT_BURST) {
6244418919fSjohnjiang printf("Line %i: init_udp_ipv4_traffic has failed!\n",
6254418919fSjohnjiang __LINE__);
6264418919fSjohnjiang return -1;
6274418919fSjohnjiang }
6284418919fSjohnjiang
6294418919fSjohnjiang for (i = 0; i < MAX_PKT_BURST; i++)
6304418919fSjohnjiang bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
6314418919fSjohnjiang
6324418919fSjohnjiang /*
6334418919fSjohnjiang * set up parameters for rte_flow_classify_validate,
6344418919fSjohnjiang * rte_flow_classify_table_entry_add and
6354418919fSjohnjiang * rte_flow_classify_table_entry_delete
6364418919fSjohnjiang */
6374418919fSjohnjiang
6384418919fSjohnjiang attr.ingress = 1;
6394418919fSjohnjiang attr.priority = 1;
6404418919fSjohnjiang pattern[0] = eth_item;
6414418919fSjohnjiang pattern[1] = ipv4_udp_item_1;
6424418919fSjohnjiang pattern[2] = udp_item_1;
6434418919fSjohnjiang pattern[3] = end_item;
6444418919fSjohnjiang actions[0] = count_action;
6454418919fSjohnjiang actions[1] = end_action;
6464418919fSjohnjiang
6474418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
6484418919fSjohnjiang actions, &error);
6494418919fSjohnjiang if (ret) {
6504418919fSjohnjiang printf("Line %i: rte_flow_classify_validate", __LINE__);
6514418919fSjohnjiang printf(" should not have failed!\n");
6524418919fSjohnjiang return -1;
6534418919fSjohnjiang }
6544418919fSjohnjiang
6554418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
6564418919fSjohnjiang actions, &key_found, &error);
6574418919fSjohnjiang if (!rule) {
6584418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
6594418919fSjohnjiang printf(" should not have failed!\n");
6604418919fSjohnjiang return -1;
6614418919fSjohnjiang }
6624418919fSjohnjiang
6634418919fSjohnjiang ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
6644418919fSjohnjiang rule, &udp_classify_stats);
6654418919fSjohnjiang if (ret) {
6664418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
6674418919fSjohnjiang printf(" should not have failed!\n");
6684418919fSjohnjiang return -1;
6694418919fSjohnjiang }
6704418919fSjohnjiang
6714418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
6724418919fSjohnjiang if (ret) {
6734418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
6744418919fSjohnjiang __LINE__);
6754418919fSjohnjiang printf(" should not have failed!\n");
6764418919fSjohnjiang return -1;
6774418919fSjohnjiang }
6784418919fSjohnjiang return 0;
6794418919fSjohnjiang }
6804418919fSjohnjiang
6814418919fSjohnjiang static int
test_query_tcp(void)6824418919fSjohnjiang test_query_tcp(void)
6834418919fSjohnjiang {
6844418919fSjohnjiang struct rte_flow_classify_rule *rule;
6854418919fSjohnjiang int ret;
6864418919fSjohnjiang int i;
6874418919fSjohnjiang int key_found;
6884418919fSjohnjiang
6894418919fSjohnjiang ret = init_ipv4_tcp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
6904418919fSjohnjiang if (ret != MAX_PKT_BURST) {
6914418919fSjohnjiang printf("Line %i: init_ipv4_tcp_traffic has failed!\n",
6924418919fSjohnjiang __LINE__);
6934418919fSjohnjiang return -1;
6944418919fSjohnjiang }
6954418919fSjohnjiang
6964418919fSjohnjiang for (i = 0; i < MAX_PKT_BURST; i++)
6974418919fSjohnjiang bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
6984418919fSjohnjiang
6994418919fSjohnjiang /*
7004418919fSjohnjiang * set up parameters for rte_flow_classify_validate,
7014418919fSjohnjiang * rte_flow_classify_table_entry_add and
7024418919fSjohnjiang * rte_flow_classify_table_entry_delete
7034418919fSjohnjiang */
7044418919fSjohnjiang
7054418919fSjohnjiang attr.ingress = 1;
7064418919fSjohnjiang attr.priority = 1;
7074418919fSjohnjiang pattern[0] = eth_item;
7084418919fSjohnjiang pattern[1] = ipv4_tcp_item_1;
7094418919fSjohnjiang pattern[2] = tcp_item_1;
7104418919fSjohnjiang pattern[3] = end_item;
7114418919fSjohnjiang actions[0] = count_action;
7124418919fSjohnjiang actions[1] = end_action;
7134418919fSjohnjiang
7144418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
7154418919fSjohnjiang actions, &error);
7164418919fSjohnjiang if (ret) {
7174418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
7184418919fSjohnjiang printf(" should not have failed!\n");
7194418919fSjohnjiang return -1;
7204418919fSjohnjiang }
7214418919fSjohnjiang
7224418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
7234418919fSjohnjiang actions, &key_found, &error);
7244418919fSjohnjiang if (!rule) {
7254418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
7264418919fSjohnjiang printf(" should not have failed!\n");
7274418919fSjohnjiang return -1;
7284418919fSjohnjiang }
7294418919fSjohnjiang
7304418919fSjohnjiang ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
7314418919fSjohnjiang rule, &tcp_classify_stats);
7324418919fSjohnjiang if (ret) {
7334418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
7344418919fSjohnjiang printf(" should not have failed!\n");
7354418919fSjohnjiang return -1;
7364418919fSjohnjiang }
7374418919fSjohnjiang
7384418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
7394418919fSjohnjiang if (ret) {
7404418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
7414418919fSjohnjiang __LINE__);
7424418919fSjohnjiang printf(" should not have failed!\n");
7434418919fSjohnjiang return -1;
7444418919fSjohnjiang }
7454418919fSjohnjiang return 0;
7464418919fSjohnjiang }
7474418919fSjohnjiang
7484418919fSjohnjiang static int
test_query_sctp(void)7494418919fSjohnjiang test_query_sctp(void)
7504418919fSjohnjiang {
7514418919fSjohnjiang struct rte_flow_classify_rule *rule;
7524418919fSjohnjiang int ret;
7534418919fSjohnjiang int i;
7544418919fSjohnjiang int key_found;
7554418919fSjohnjiang
7564418919fSjohnjiang ret = init_ipv4_sctp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
7574418919fSjohnjiang if (ret != MAX_PKT_BURST) {
7584418919fSjohnjiang printf("Line %i: init_ipv4_tcp_traffic has failed!\n",
7594418919fSjohnjiang __LINE__);
7604418919fSjohnjiang return -1;
7614418919fSjohnjiang }
7624418919fSjohnjiang
7634418919fSjohnjiang for (i = 0; i < MAX_PKT_BURST; i++)
7644418919fSjohnjiang bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
7654418919fSjohnjiang
7664418919fSjohnjiang /*
7674418919fSjohnjiang * set up parameters rte_flow_classify_validate,
7684418919fSjohnjiang * rte_flow_classify_table_entry_add and
7694418919fSjohnjiang * rte_flow_classify_table_entry_delete
7704418919fSjohnjiang */
7714418919fSjohnjiang
7724418919fSjohnjiang attr.ingress = 1;
7734418919fSjohnjiang attr.priority = 1;
7744418919fSjohnjiang pattern[0] = eth_item;
7754418919fSjohnjiang pattern[1] = ipv4_sctp_item_1;
7764418919fSjohnjiang pattern[2] = sctp_item_1;
7774418919fSjohnjiang pattern[3] = end_item;
7784418919fSjohnjiang actions[0] = count_action;
7794418919fSjohnjiang actions[1] = end_action;
7804418919fSjohnjiang
7814418919fSjohnjiang ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
7824418919fSjohnjiang actions, &error);
7834418919fSjohnjiang if (ret) {
7844418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
7854418919fSjohnjiang printf(" should not have failed!\n");
7864418919fSjohnjiang return -1;
7874418919fSjohnjiang }
7884418919fSjohnjiang
7894418919fSjohnjiang rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
7904418919fSjohnjiang actions, &key_found, &error);
7914418919fSjohnjiang if (!rule) {
7924418919fSjohnjiang printf("Line %i: flow_classify_table_entry_add", __LINE__);
7934418919fSjohnjiang printf(" should not have failed!\n");
7944418919fSjohnjiang return -1;
7954418919fSjohnjiang }
7964418919fSjohnjiang
7974418919fSjohnjiang ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
7984418919fSjohnjiang rule, &sctp_classify_stats);
7994418919fSjohnjiang if (ret) {
8004418919fSjohnjiang printf("Line %i: flow_classifier_query", __LINE__);
8014418919fSjohnjiang printf(" should not have failed!\n");
8024418919fSjohnjiang return -1;
8034418919fSjohnjiang }
8044418919fSjohnjiang
8054418919fSjohnjiang ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
8064418919fSjohnjiang if (ret) {
8074418919fSjohnjiang printf("Line %i: rte_flow_classify_table_entry_delete",
8084418919fSjohnjiang __LINE__);
8094418919fSjohnjiang printf(" should not have failed!\n");
8104418919fSjohnjiang return -1;
8114418919fSjohnjiang }
8124418919fSjohnjiang return 0;
8134418919fSjohnjiang }
8144418919fSjohnjiang
8154418919fSjohnjiang static int
test_flow_classify(void)8164418919fSjohnjiang test_flow_classify(void)
8174418919fSjohnjiang {
8184418919fSjohnjiang struct rte_table_acl_params table_acl_params;
8194418919fSjohnjiang struct rte_flow_classify_table_params cls_table_params;
8204418919fSjohnjiang struct rte_flow_classifier_params cls_params;
8214418919fSjohnjiang int ret;
8224418919fSjohnjiang uint32_t size;
8234418919fSjohnjiang
8244418919fSjohnjiang /* Memory allocation */
8254418919fSjohnjiang size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl));
8264418919fSjohnjiang cls = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
8274418919fSjohnjiang
8284418919fSjohnjiang cls_params.name = "flow_classifier";
8294418919fSjohnjiang cls_params.socket_id = 0;
8304418919fSjohnjiang cls->cls = rte_flow_classifier_create(&cls_params);
8314418919fSjohnjiang
8324418919fSjohnjiang /* initialise ACL table params */
8334418919fSjohnjiang table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs);
8344418919fSjohnjiang table_acl_params.name = "table_acl_ipv4_5tuple";
8354418919fSjohnjiang table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM;
8364418919fSjohnjiang memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
8374418919fSjohnjiang
8384418919fSjohnjiang /* initialise table create params */
8394418919fSjohnjiang cls_table_params.ops = &rte_table_acl_ops;
8404418919fSjohnjiang cls_table_params.arg_create = &table_acl_params;
8414418919fSjohnjiang cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE;
8424418919fSjohnjiang
8434418919fSjohnjiang ret = rte_flow_classify_table_create(cls->cls, &cls_table_params);
8444418919fSjohnjiang if (ret) {
8454418919fSjohnjiang printf("Line %i: f_create has failed!\n", __LINE__);
8464418919fSjohnjiang rte_flow_classifier_free(cls->cls);
8474418919fSjohnjiang rte_free(cls);
8484418919fSjohnjiang return TEST_FAILED;
8494418919fSjohnjiang }
8504418919fSjohnjiang printf("Created table_acl for for IPv4 five tuple packets\n");
8514418919fSjohnjiang
8524418919fSjohnjiang ret = init_mbufpool();
8534418919fSjohnjiang if (ret) {
8544418919fSjohnjiang printf("Line %i: init_mbufpool has failed!\n", __LINE__);
8554418919fSjohnjiang return TEST_FAILED;
8564418919fSjohnjiang }
8574418919fSjohnjiang
8584418919fSjohnjiang if (test_invalid_parameters() < 0)
8594418919fSjohnjiang return TEST_FAILED;
8604418919fSjohnjiang if (test_valid_parameters() < 0)
8614418919fSjohnjiang return TEST_FAILED;
8624418919fSjohnjiang if (test_invalid_patterns() < 0)
8634418919fSjohnjiang return TEST_FAILED;
8644418919fSjohnjiang if (test_invalid_actions() < 0)
8654418919fSjohnjiang return TEST_FAILED;
8664418919fSjohnjiang if (test_query_udp() < 0)
8674418919fSjohnjiang return TEST_FAILED;
8684418919fSjohnjiang if (test_query_tcp() < 0)
8694418919fSjohnjiang return TEST_FAILED;
8704418919fSjohnjiang if (test_query_sctp() < 0)
8714418919fSjohnjiang return TEST_FAILED;
8724418919fSjohnjiang
8734418919fSjohnjiang return TEST_SUCCESS;
8744418919fSjohnjiang }
8754418919fSjohnjiang
8764418919fSjohnjiang REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify);
877