This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via 810bc2ee9b5285e1692a6b0c7457ca503f381e1e (commit) via bd2aea3186fd4e2d3ba6ec91f2a6ba72f0443941 (commit) via b904314ec95e4e680a739a5f98b6fd814b9a6fef (commit) via 2376fa5b4b5f5b7b9d2c11cb08438f11883bfe50 (commit) via 55ea0298a7cf917b466d2154d79d00fd86f3c936 (commit) via d688a269562ff9efc2ff03411c385a2bd1228d2c (commit) via 13b478eaa76ee8461341b114d447835e3906748d (commit) via 4c4145f8c9c73665c9f834f8ca639b9f0525e30f (commit) via 4c58ce0cd530c59907164f2fa7ae78800c494151 (commit) via 65891255eec4884e941aece9808ad684155feac8 (commit) via d4eb0481e1dd40a0d0b70486cdf8f9b676862b2f (commit) via f15da1c0ee13dd0e342944dccdd9014c16d4d5be (commit) via 6f855d843b1d87013908998a050e16c435b89e07 (commit) via 35a6b2e5c369e81196f6c288085990eaaf83f360 (commit) via 0e2ee113fcc0e7383d9e465c11a8495a65f7a171 (commit) via 0cfdb2c5a6b3afe0e4b0eee2b3749a0cfca3917d (commit) via b7a8fd47362a3853db8cc3ea56fe1d268defa574 (commit) via 0df7a38e2b9be4ad72528d43551e56ac4d152b96 (commit) via 139b28399d3bd1f53624908c9fd99c1f14283cdd (commit) from 86745e999aa2bf644fd72775df55042289e07b2b (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 810bc2ee9b5285e1692a6b0c7457ca503f381e1e Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 28 14:49:26 2019 +0200
api: increment version to 1.23
Increment API version number to reflect API changes: * cls: PMR values for protocol fields are defined in big endian * cls: ODP_PMR_CUSTOM_L3 term has been added * coding style: use 'unsigned int' instead of 'unsigned'
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/configure.ac b/configure.ac index 81123cbc6..4cff42913 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.5]) # ODP API version ########################################################################## m4_define([odpapi_generation_version], [1]) -m4_define([odpapi_major_version], [22]) +m4_define([odpapi_major_version], [23]) m4_define([odpapi_minor_version], [0]) m4_define([odpapi_point_version], [0]) m4_define([odpapi_version],
commit bd2aea3186fd4e2d3ba6ec91f2a6ba72f0443941 Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 28 15:33:05 2019 +0200
api: clean up coding style warnings
Clean checkpatch warnings on include/odp/api/spec files. Current checkpatch version warns about 'unsigned' type name usage.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index eadcaa2d8..1db85e8b7 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -175,17 +175,17 @@ typedef struct odp_cls_capability_t { odp_cls_pmr_terms_t supported_terms;
/** Maximum number of PMR terms */ - unsigned max_pmr_terms; + unsigned int max_pmr_terms;
/** Number of PMR terms available for use now */ - unsigned available_pmr_terms; + unsigned int available_pmr_terms;
/** Maximum number of CoS supported */ - unsigned max_cos; + unsigned int max_cos;
/** Maximun number of queue supported per CoS * if the value is 1, then hashing is not supported*/ - unsigned max_hash_queues; + unsigned int max_hash_queues;
/** Protocol header combination supported for Hashing */ odp_pktin_hash_proto_t hash_protocols; diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index 5d5ca2bc4..cddacecc5 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -201,7 +201,7 @@ typedef struct odp_pktin_queue_param_t { * More than one input queues require flow hashing configured. * The maximum value is defined by pktio capability 'max_input_queues'. * Queue type is defined by the input mode. The default value is 1. */ - unsigned num_queues; + unsigned int num_queues;
/** Queue parameters * @@ -243,7 +243,7 @@ typedef struct odp_pktout_queue_param_t {
/** Number of output queues to be created. The value must be between * 1 and interface capability. The default value is 1. */ - unsigned num_queues; + unsigned int num_queues;
} odp_pktout_queue_param_t;
@@ -551,10 +551,10 @@ typedef union odp_pktio_set_op_t { */ typedef struct odp_pktio_capability_t { /** Maximum number of input queues */ - unsigned max_input_queues; + unsigned int max_input_queues;
/** Maximum number of output queues */ - unsigned max_output_queues; + unsigned int max_output_queues;
/** Supported pktio configuration options */ odp_pktio_config_t config; @@ -650,7 +650,7 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa); * * @return Maximum packet IO interface index */ -unsigned odp_pktio_max_index(void); +unsigned int odp_pktio_max_index(void);
/** * Configure packet IO interface options @@ -947,8 +947,8 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], * @return Number of packets received * @retval <0 on failure */ -int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], unsigned num_q, - unsigned *from, odp_packet_t packets[], int num, +int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], unsigned int num_q, + unsigned int *from, odp_packet_t packets[], int num, uint64_t wait);
/** diff --git a/include/odp/api/spec/pool.h b/include/odp/api/spec/pool.h index d4cf088f1..69e99605c 100644 --- a/include/odp/api/spec/pool.h +++ b/include/odp/api/spec/pool.h @@ -48,12 +48,12 @@ extern "C" { */ typedef struct odp_pool_capability_t { /** Maximum number of pools of any type */ - unsigned max_pools; + unsigned int max_pools;
/** Buffer pool capabilities */ struct { /** Maximum number of buffer pools */ - unsigned max_pools; + unsigned int max_pools;
/** Maximum buffer data alignment in bytes */ uint32_t max_align; @@ -74,7 +74,7 @@ typedef struct odp_pool_capability_t { /** Packet pool capabilities */ struct { /** Maximum number of packet pools */ - unsigned max_pools; + unsigned int max_pools;
/** Maximum packet data length in bytes * @@ -147,7 +147,7 @@ typedef struct odp_pool_capability_t { /** Timeout pool capabilities */ struct { /** Maximum number of timeout pools */ - unsigned max_pools; + unsigned int max_pools;
/** Maximum number of timeout events in a pool * diff --git a/include/odp/api/spec/shared_memory.h b/include/odp/api/spec/shared_memory.h index 0882c4a1c..425e6c77a 100644 --- a/include/odp/api/spec/shared_memory.h +++ b/include/odp/api/spec/shared_memory.h @@ -106,7 +106,7 @@ typedef struct odp_shm_capability_t { * * This number of separate shared memory blocks can be * reserved concurrently. */ - unsigned max_blocks; + unsigned int max_blocks;
/** Maximum memory block size in bytes * diff --git a/include/odp/api/spec/version.h.in b/include/odp/api/spec/version.h.in index 35df9ba26..4c3cbfee8 100644 --- a/include/odp/api/spec/version.h.in +++ b/include/odp/api/spec/version.h.in @@ -4,7 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */
- /** * @file *
commit b904314ec95e4e680a739a5f98b6fd814b9a6fef Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 28 14:36:13 2019 +0200
example: cls: update help text
Updated help text with changes to application options. Also, avoid shm memory leak when command line options have errors, or when --help option is used.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index ecfa732a9..3af418704 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -95,9 +95,9 @@ static appl_args_t *appl_args_gbl;
static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len); static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len); -static void parse_args(int argc, char *argv[], appl_args_t *appl_args); +static int parse_args(int argc, char *argv[], appl_args_t *appl_args); static void print_info(char *progname, appl_args_t *appl_args); -static void usage(char *progname); +static void usage(void);
static inline void print_cls_statistics(appl_args_t *args) { @@ -568,7 +568,8 @@ int main(int argc, char *argv[]) appl_args_gbl = args; memset(args, 0, sizeof(*args)); /* Parse and store the application arguments */ - parse_args(argc, argv, args); + if (parse_args(argc, argv, args)) + goto args_error;
/* Print both system and application information */ print_info(NO_PATH(argv[0]), args); @@ -662,13 +663,14 @@ int main(int argc, char *argv[]) ODPH_ERR("err: odp_pool_destroy for %d\n", i); }
- free(args->if_name); - odp_shm_free(shm); if (odp_pktio_close(pktio)) ODPH_ERR("err: close pktio error\n"); if (odp_pool_destroy(pool)) ODPH_ERR("err: odp_pool_destroy error\n");
+args_error: + odp_shm_free(shm); + ret = odp_term_local(); if (ret) ODPH_ERR("odp_term_local error %d\n", ret); @@ -772,7 +774,7 @@ static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term) return -1; }
-static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) +static int parse_pmr_policy(appl_args_t *appl_args, char *optarg) { int policy_count; char *token, *cos0, *cos1; @@ -889,7 +891,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) return -1; break; default: - usage(argv[0]); + usage(); exit(EXIT_FAILURE); }
@@ -923,7 +925,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) * @param argv[] argument vector * @param appl_args Store application arguments here */ -static void parse_args(int argc, char *argv[], appl_args_t *appl_args) +static int parse_args(int argc, char *argv[], appl_args_t *appl_args) { int opt; int long_index; @@ -931,6 +933,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) int i; int interface = 0; int policy = 0; + int ret = 0;
static const struct option longopts[] = { {"count", required_argument, NULL, 'c'}, @@ -960,7 +963,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->cpu_count = atoi(optarg); break; case 'p': - if (0 > parse_pmr_policy(appl_args, argv, optarg)) + if (0 > parse_pmr_policy(appl_args, optarg)) continue; policy = 1; break; @@ -970,15 +973,15 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) case 'i': len = strlen(optarg); if (len == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); + ret = -1; + break; } len += 1; /* add room for '\0' */
appl_args->if_name = malloc(len); if (appl_args->if_name == NULL) { - usage(argv[0]); - exit(EXIT_FAILURE); + ret = -1; + break; }
strcpy(appl_args->if_name, optarg); @@ -995,24 +998,30 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->verbose = 1; break; case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); + ret = -1; break; default: break; } }
- if (!interface || !policy) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - if (appl_args->if_name == NULL) { - usage(argv[0]); - exit(EXIT_FAILURE); + if (!interface || !policy) + ret = -1; + + if (appl_args->if_name == NULL) + ret = -1; + + if (ret) { + usage(); + + if (appl_args->if_name) + free(appl_args->if_name); }
- optind = 1; /* reset 'extern optind' from the getopt lib */ + /* reset optind from the getopt lib */ + optind = 1; + + return ret; }
/** @@ -1033,45 +1042,44 @@ static void print_info(char *progname, appl_args_t *appl_args) /** * Prinf usage information */ -static void usage(char *progname) +static void usage(void) { printf("\n" - "OpenDataPlane Classifier example.\n" - "Usage: %s OPTIONS\n" - " E.g. %s -i eth1 -m 0 -p "ODP_PMR_SIP_ADDR:10.10.10.5:FFFFFFFF:queue1" \\n" - "\t\t\t-p "ODP_PMR_SIP_ADDR:10.10.10.7:000000FF:queue2" \\n" - "\t\t\t-p "ODP_PMR_SIP_ADDR:10.5.5.10:FFFFFF00:queue3"\n" - "\n" - "For the above example configuration the following will be the packet distribution\n" - "queue1\t\tPackets with source ip address 10.10.10.5\n" - "queue2\t\tPackets with source ip address whose last 8 bits match 7\n" - "queue3\t\tPackets with source ip address in the subnet 10.5.5.0\n" - "\n" - "Mandatory OPTIONS:\n" - " -i, --interface Eth interface\n" - " -p, --policy [<odp_cls_pmr_term_t>|<offset>]:<value>:<mask bits>:<queue name>\n" - "\n" - "<odp_cls_pmr_term_t> Packet Matching Rule defined with odp_cls_pmr_term_t " - "for the policy\n" - "<offset> Absolute offset in bytes from frame start to define a " - "ODP_PMR_CUSTOM_FRAME Packet Matching Rule for the policy\n" - "\n" - "<value> PMR value to be matched.\n" - "\n" - "<mask bits> PMR mask bits to be applied on the PMR term value\n" - "\n" - "Optional OPTIONS\n" - " -c, --count <number> CPU count, 0=all available, default=1\n" - "\n" - " -m, --mode 0: Packet Drop mode. Received packets will be dropped\n" - " !0: Packet ICMP mode. Received packets will be sent back\n" - " default: Packet Drop mode\n" - "\n" - " -t, --timeout !0: Time for which the classifier will be run in seconds\n" - " 0: Runs in infinite loop\n" - " default: Runs in infinite loop\n" - "\n" - " -h, --help Display help and exit.\n" - "\n", NO_PATH(progname), NO_PATH(progname) - ); + "ODP Classifier example.\n" + "Usage: odp_classifier OPTIONS\n" + " E.g. odp_classifier -i eth1 -m 0 -p "ODP_PMR_SIP_ADDR:10.10.10.0:0xFFFFFF00:queue1" \\n" + " -p "ODP_PMR_SIP_ADDR:10.10.10.10:0xFFFFFFFF:queue1:queue2"\n" + "\n" + "The above example would classify:\n" + " 1) Packets from source IP address 10.10.10.0/24 to queue1, except ...\n" + " 2) Packets from source IP address 10.10.10.10 to queue2\n" + " 3) All other packets to DefaultCos\n" + "\n" + "Mandatory OPTIONS:\n" + " -i, --interface <interface name>\n" + " -p, --policy <PMR term>:<offset>:<value>:<mask>:<src queue>:<dst queue>\n" + "\n" + " <PMR term> PMR term name defined in odp_cls_pmr_term_t\n" + " <offset> If term is ODP_PMR_CUSTOM_FRAME or _CUSTOM_L3, offset in bytes is used\n" + " <value> PMR value to be matched\n" + " <mask> PMR mask bits to be applied on the PMR value.\n" + " CUSTOM PMR terms accept plain hex string, other PMR terms require\n" + " hex string with '0x' prefix.\n" + " <src queue> Optional name of the source queue (CoS). The default CoS is used when\n" + " this is not defined.\n" + " <dst queue> Name of the destination queue (CoS).\n" + "\n" + "Optional OPTIONS\n" + " -c, --count <num> CPU count, 0=all available, default=1\n" + "\n" + " -m, --mode <mode> 0: Packet Drop mode. Received packets will be dropped\n" + " !0: Packet ICMP mode. Received packets will be sent back\n" + " default: Packet Drop mode\n" + "\n" + " -t, --timeout <sec> !0: Time for which the classifier will be run in seconds\n" + " 0: Runs in infinite loop\n" + " default: Runs in infinite loop\n" + "\n" + " -h, --help Display help and exit.\n" + "\n"); }
commit 2376fa5b4b5f5b7b9d2c11cb08438f11883bfe50 Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 28 11:04:59 2019 +0200
example: cls: add ODP_PMR_CUSTOM_L3 support
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 47c689f6e..ecfa732a9 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -764,6 +764,9 @@ static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term) } else if (strcasecmp(token, "ODP_PMR_CUSTOM_FRAME") == 0) { *term = ODP_PMR_CUSTOM_FRAME; return 0; + } else if (strcasecmp(token, "ODP_PMR_CUSTOM_L3") == 0) { + *term = ODP_PMR_CUSTOM_L3; + return 0; }
return -1; @@ -856,6 +859,8 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) stats[policy_count].rule.val_sz = 4; break; case ODP_PMR_CUSTOM_FRAME: + /* Fall through */ + case ODP_PMR_CUSTOM_L3: /* :<offset>:<value>:<mask> */ token = strtok(NULL, ":"); errno = 0;
commit 55ea0298a7cf917b466d2154d79d00fd86f3c936 Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 28 10:20:43 2019 +0200
linux-gen: cls: add ODP_PMR_CUSTOM_L3 support
Added support for ODP_PMR_CUSTOM_L3 PMR term.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 60171cc5e..1b5337ff6 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -174,6 +174,7 @@ int odp_cls_capability(odp_cls_capability_t *capability) capability->supported_terms.bit.sip6_addr = 1; capability->supported_terms.bit.dip6_addr = 1; capability->supported_terms.bit.custom_frame = 1; + capability->supported_terms.bit.custom_l3 = 1; capability->random_early_detection = ODP_SUPPORT_NO; capability->back_pressure = ODP_SUPPORT_NO; capability->threshold_red.all_bits = 0; @@ -631,6 +632,8 @@ static int pmr_create_term(pmr_term_value_t *value, break;
case ODP_PMR_CUSTOM_FRAME: + /* Fall through */ + case ODP_PMR_CUSTOM_L3: custom = 1; size = MAX_PMR_TERM_SIZE; break; @@ -1050,7 +1053,8 @@ static inline int verify_pmr_custom_frame(const uint8_t *pkt_addr, odp_packet_hdr_t *pkt_hdr, pmr_term_value_t *term_value) { - uint64_t val = 0; + uint32_t i; + uint8_t val; uint32_t offset = term_value->offset; uint32_t val_sz = term_value->val_sz;
@@ -1059,11 +1063,46 @@ static inline int verify_pmr_custom_frame(const uint8_t *pkt_addr, if (packet_len(pkt_hdr) <= offset + val_sz) return 0;
- memcpy(&val, pkt_addr + offset, val_sz); - if (term_value->match.value == (val & term_value->match.mask)) - return 1; + pkt_addr += offset;
- return 0; + for (i = 0; i < val_sz; i++) { + val = pkt_addr[i] & term_value->match.mask_u8[i]; + + if (val != term_value->match.value_u8[i]) + return 0; + } + + return 1; +} + +static inline int verify_pmr_custom_l3(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint32_t i; + uint8_t val; + uint32_t l3_offset = pkt_hdr->p.l3_offset; + uint32_t offset = l3_offset + term_value->offset; + uint32_t val_sz = term_value->val_sz; + + ODP_ASSERT(val_sz <= MAX_PMR_TERM_SIZE); + + if (!pkt_hdr->p.input_flags.l3) + return 0; + + if (packet_len(pkt_hdr) <= offset + val_sz) + return 0; + + pkt_addr += offset; + + for (i = 0; i < val_sz; i++) { + val = pkt_addr[i] & term_value->match.mask_u8[i]; + + if (val != term_value->match.value_u8[i]) + return 0; + } + + return 1; }
static inline int verify_pmr_eth_type_0(const uint8_t *pkt_addr, @@ -1222,6 +1261,11 @@ static int verify_pmr(pmr_t *pmr, const uint8_t *pkt_addr, term_value)) pmr_failure = 1; break; + case ODP_PMR_CUSTOM_L3: + if (!verify_pmr_custom_l3(pkt_addr, pkt_hdr, + term_value)) + pmr_failure = 1; + break; case ODP_PMR_INNER_HDR_OFF: break; default:
commit d688a269562ff9efc2ff03411c385a2bd1228d2c Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 14 14:13:33 2019 +0300
linux-gen: cls: add custom frame PMR capability
Mark custom frame as a supported PMR.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 164daf3fc..60171cc5e 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -173,6 +173,7 @@ int odp_cls_capability(odp_cls_capability_t *capability) capability->supported_terms.bit.dip_addr = 1; capability->supported_terms.bit.sip6_addr = 1; capability->supported_terms.bit.dip6_addr = 1; + capability->supported_terms.bit.custom_frame = 1; capability->random_early_detection = ODP_SUPPORT_NO; capability->back_pressure = ODP_SUPPORT_NO; capability->threshold_red.all_bits = 0;
commit 13b478eaa76ee8461341b114d447835e3906748d Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 14 14:12:42 2019 +0300
validation: cls: add custom PMR test cases
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 46bbdf4b1..d4a3110e3 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -2037,6 +2037,147 @@ static void classification_test_pmr_term_tcp_dport_multi(void) _classification_test_pmr_term_tcp_dport(SHM_PKT_NUM_BUFS / 4); }
+static void test_pmr_term_custom(int custom_l3) +{ + odp_packet_t pkt; + uint32_t seqno; + int retval; + odp_pktio_t pktio; + odp_queue_t queue; + odp_queue_t retqueue; + odp_queue_t default_queue; + odp_pool_t pool; + odp_pool_t default_pool; + odp_pmr_t pmr; + odp_cos_t cos; + odp_cos_t default_cos; + uint32_t dst_addr, src_addr; + uint32_t addr_be, mask_be; + uint32_t dst_mask, src_mask; + char cosname[ODP_QUEUE_NAME_LEN]; + odp_pmr_param_t pmr_param; + odp_cls_cos_param_t cls_param; + odph_ipv4hdr_t *ip; + odph_ethhdr_t *eth; + const char *pmr_src_str = "10.0.8.0/24"; + const char *pmr_dst_str = "10.0.9.0/24"; + const char *pkt_src_str = "10.0.8.88/32"; + const char *pkt_dst_str = "10.0.9.99/32"; + + pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); + retval = start_pktio(pktio); + CU_ASSERT(retval == 0); + + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + + queue = queue_create("ipv4 addr", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + pool = pool_create("ipv4 addr"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + sprintf(cosname, "ipv4 addr"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + + /* Match values for custom PRM rules are passed in network endian */ + parse_ipv4_string(pmr_src_str, &src_addr, &src_mask); + parse_ipv4_string(pmr_dst_str, &dst_addr, &dst_mask); + + odp_cls_pmr_param_init(&pmr_param); + + if (custom_l3) { + addr_be = odp_cpu_to_be_32(dst_addr); + mask_be = odp_cpu_to_be_32(dst_mask); + pmr_param.term = ODP_PMR_CUSTOM_L3; + pmr_param.match.value = &addr_be; + pmr_param.match.mask = &mask_be; + pmr_param.val_sz = sizeof(addr_be); + /* Offset from start of L3 to IPv4 dst address */ + pmr_param.offset = 16; + } else { + addr_be = odp_cpu_to_be_32(src_addr); + mask_be = odp_cpu_to_be_32(src_mask); + pmr_param.term = ODP_PMR_CUSTOM_FRAME; + pmr_param.match.value = &addr_be; + pmr_param.match.mask = &mask_be; + pmr_param.val_sz = sizeof(addr_be); + /* Offset from start of ethernet/IPv4 frame to IPv4 + * src address */ + pmr_param.offset = 26; + } + + pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); + CU_ASSERT_FATAL(pmr != ODP_PMR_INVALID); + + /* IPv4 packet with matching addresses */ + parse_ipv4_string(pkt_src_str, &src_addr, NULL); + parse_ipv4_string(pkt_dst_str, &dst_addr, NULL); + pkt = create_packet(default_pkt_info); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); + ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); + ip->src_addr = odp_cpu_to_be_32(src_addr); + ip->dst_addr = odp_cpu_to_be_32(dst_addr); + odph_ipv4_csum_update(pkt); + + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + CU_ASSERT(retqueue == queue); + odp_packet_free(pkt); + + /* Other packets delivered to default queue */ + pkt = create_packet(default_pkt_info); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + CU_ASSERT(retqueue == default_queue); + + odp_cos_destroy(cos); + odp_cos_destroy(default_cos); + odp_cls_pmr_destroy(pmr); + odp_packet_free(pkt); + stop_pktio(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); + odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pktio_close(pktio); +} + +static void classification_test_pmr_term_custom_frame(void) +{ + test_pmr_term_custom(0); +} + +static void classification_test_pmr_term_custom_l3(void) +{ + test_pmr_term_custom(1); +} + static int check_capa_tcp_dport(void) { return cls_capa.supported_terms.bit.tcp_dport; @@ -2112,6 +2253,16 @@ static int check_capa_ethtype_x(void) return cls_capa.supported_terms.bit.ethtype_x; }
+static int check_capa_custom_frame(void) +{ + return cls_capa.supported_terms.bit.custom_frame; +} + +static int check_capa_custom_l3(void) +{ + return cls_capa.supported_terms.bit.custom_l3; +} + odp_testinfo_t classification_suite_pmr[] = { ODP_TEST_INFO_CONDITIONAL(classification_test_pmr_term_tcp_dport, check_capa_tcp_dport), @@ -2145,6 +2296,10 @@ odp_testinfo_t classification_suite_pmr[] = { check_capa_ethtype_0), ODP_TEST_INFO_CONDITIONAL(classification_test_pmr_term_eth_type_x, check_capa_ethtype_x), + ODP_TEST_INFO_CONDITIONAL(classification_test_pmr_term_custom_frame, + check_capa_custom_frame), + ODP_TEST_INFO_CONDITIONAL(classification_test_pmr_term_custom_l3, + check_capa_custom_l3), ODP_TEST_INFO(classification_test_pktin_classifier_flag), ODP_TEST_INFO(classification_test_pmr_term_tcp_dport_multi), ODP_TEST_INFO_NULL,
commit 4c4145f8c9c73665c9f834f8ca639b9f0525e30f Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Oct 25 15:07:25 2019 +0300
api: cls: add ODP_PMR_CUSTOM_L3 term
Added new term to match custom layer 3 protocol fields. PMR offset refers to the start of layer 3 in the packet. Other PMR rules (e.g. L2 classification rules) may precede custom L3 rules.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 67fdd20aa..eadcaa2d8 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -97,11 +97,12 @@ typedef union odp_cls_pmr_terms_t { uint64_t ipsec_spi:1; /** NVGRE/VXLAN network identifier */ uint64_t ld_vni:1; - /** Custom match rule, offset from start of - * frame. The match is defined by the offset, the - * expected value, and its size. - */ - uint64_t custom_frame:1; + /** Custom frame match rule. PMR offset is counted from + * the start of the packet. */ + uint64_t custom_frame:1; + /** Custom layer 3 match rule. PMR offset is counted from + * the start of layer 3 in the packet. */ + uint64_t custom_l3:1;
} bit; /** All bits of the bit field structure */ @@ -535,6 +536,15 @@ typedef enum { */ ODP_PMR_CUSTOM_FRAME,
+ /** + * Custom layer 3 match rule + * + * PMR offset is counted from the start of layer 3 in the packet. + * The match is defined by the offset, the expected value, and its size. + * Custom L3 rules may be combined with other PMRs. + */ + ODP_PMR_CUSTOM_L3, + /** Inner header may repeat above values with this offset */ ODP_PMR_INNER_HDR_OFF = 32
@@ -578,11 +588,18 @@ typedef struct odp_pmr_param_t { const void *val_end; } range; }; - uint32_t val_sz; /**< Size of the term value */
- uint32_t offset; /**< User-defined offset in packet - Used if term == ODP_PMR_CUSTOM_FRAME only, - ignored otherwise */ + /** Size of the value to be matched */ + uint32_t val_sz; + + /** Offset to the value + * + * Byte offset to the value to be matched in a packet. PMR term defines + * starting point for the offset. Used only with custom PMR terms, + * ignored with other terms. + */ + uint32_t offset; + } odp_pmr_param_t;
/**
commit 4c58ce0cd530c59907164f2fa7ae78800c494151 Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Oct 25 14:36:08 2019 +0300
example: cls: change PMR values and masks to big endian
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 691fec297..47c689f6e 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -44,6 +44,9 @@ */ #define DISPLAY_STRING_LEN 32
+/** Maximum PMR value size */ +#define MAX_VAL_SIZE 16 + /** Get rid of path in filename - only for unix-type paths using '/' */ #define NO_PATH(file_name) (strrchr((file_name), '/') ? \ strrchr((file_name), '/') + 1 : (file_name)) @@ -59,8 +62,8 @@ typedef struct { char src_cos_name[ODP_COS_NAME_LEN]; /**< source cos name */ struct { odp_cls_pmr_term_t term; /**< odp pmr term value */ - uint64_t val; /**< pmr term value */ - uint64_t mask; /**< pmr term mask */ + uint8_t value_be[MAX_VAL_SIZE]; /**< value in big endian */ + uint8_t mask_be[MAX_VAL_SIZE]; /**< mask in big endian */ uint32_t val_sz; /**< size of the pmr term */ uint32_t offset; /**< pmr term offset */ } rule; @@ -166,39 +169,20 @@ static inline void print_cls_statistics(appl_args_t *args) printf("\n"); }
-static inline int parse_mask(const char *str, uint64_t *mask) -{ - uint64_t b; - int ret; - - ret = sscanf(str, "%" SCNx64, &b); - *mask = b; - return ret != 1; -} - -static int parse_value(const char *str, uint64_t *val, uint32_t *val_sz) +static int parse_custom(const char *str, uint8_t *buf_be, int max_size) { - size_t len; - size_t i; - int converted; - union { - uint64_t u64; - uint8_t u8[8]; - } buf = {.u64 = 0}; + int i, len;
+ /* hex string without 0x prefix */ len = strlen(str); - if (len > 2 * sizeof(buf)) + if (len > 2 * max_size) return -1;
- for (i = 0; i < len; i += 2) { - converted = sscanf(&str[i], "%2" SCNx8, &buf.u8[i / 2]); - if (1 != converted) + for (i = 0; i < len; i += 2) + if (sscanf(&str[i], "%2" SCNx8, &buf_be[i / 2]) != 1) return -1; - }
- *val = buf.u64; - *val_sz = len / 2; - return 0; + return len / 2; }
/** @@ -494,8 +478,8 @@ static void configure_cos(odp_cos_t default_cos, appl_args_t *args)
odp_cls_pmr_param_init(&pmr_param); pmr_param.term = stats->rule.term; - pmr_param.match.value = &stats->rule.val; - pmr_param.match.mask = &stats->rule.mask; + pmr_param.match.value = stats->rule.value_be; + pmr_param.match.mask = stats->rule.mask_be; pmr_param.val_sz = stats->rule.val_sz; pmr_param.offset = stats->rule.offset;
@@ -793,9 +777,10 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) odp_cls_pmr_term_t term; global_statistics *stats; char *pmr_str; - uint32_t offset; - uint32_t ip_addr; - unsigned long int value; + uint32_t offset, ip_addr, u32; + unsigned long int value, mask; + uint16_t u16; + int val_sz, mask_sz;
policy_count = appl_args->policy_count; stats = appl_args->stats; @@ -832,12 +817,18 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) strncpy(stats[policy_count].value, token, DISPLAY_STRING_LEN - 1); value = strtoul(token, NULL, 0); - stats[policy_count].rule.val = value; + u16 = value; + u16 = odp_cpu_to_be_16(u16); + memcpy(stats[policy_count].rule.value_be, &u16, sizeof(u16));
token = strtok(NULL, ":"); strncpy(stats[policy_count].mask, token, DISPLAY_STRING_LEN - 1); - parse_mask(token, &stats[policy_count].rule.mask); + mask = strtoul(token, NULL, 0); + u16 = mask; + u16 = odp_cpu_to_be_16(u16); + memcpy(stats[policy_count].rule.mask_be, &u16, sizeof(u16)); + stats[policy_count].rule.val_sz = 2; break; case ODP_PMR_SIP_ADDR: @@ -851,12 +842,17 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) exit(EXIT_FAILURE); }
- stats[policy_count].rule.val = ip_addr; + u32 = odp_cpu_to_be_32(ip_addr); + memcpy(stats[policy_count].rule.value_be, &u32, sizeof(u32));
token = strtok(NULL, ":"); strncpy(stats[policy_count].mask, token, DISPLAY_STRING_LEN - 1); - parse_mask(token, &stats[policy_count].rule.mask); + mask = strtoul(token, NULL, 0); + u32 = mask; + u32 = odp_cpu_to_be_32(u32); + memcpy(stats[policy_count].rule.mask_be, &u32, sizeof(u32)); + stats[policy_count].rule.val_sz = 4; break; case ODP_PMR_CUSTOM_FRAME: @@ -864,19 +860,28 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) token = strtok(NULL, ":"); errno = 0; offset = strtoul(token, NULL, 0); + stats[policy_count].rule.offset = offset; if (errno) return -1;
token = strtok(NULL, ":"); strncpy(stats[policy_count].value, token, DISPLAY_STRING_LEN - 1); - parse_value(token, &stats[policy_count].rule.val, - &stats[policy_count].rule.val_sz); + val_sz = parse_custom(token, + stats[policy_count].rule.value_be, + MAX_VAL_SIZE); + stats[policy_count].rule.val_sz = val_sz; + if (val_sz <= 0) + return -1; + token = strtok(NULL, ":"); strncpy(stats[policy_count].mask, token, DISPLAY_STRING_LEN - 1); - parse_mask(token, &stats[policy_count].rule.mask); - stats[policy_count].rule.offset = offset; + mask_sz = parse_custom(token, + stats[policy_count].rule.mask_be, + MAX_VAL_SIZE); + if (mask_sz != val_sz) + return -1; break; default: usage(argv[0]);
commit 65891255eec4884e941aece9808ad684155feac8 Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Oct 25 11:08:03 2019 +0300
linux-gen: cls: clean up IPv6 match implementation
Use the same range data structure for all terms (removed IPv6 specific fields).
Range terms are not currently supported. Return failure on PMR create if range is used. Removed other range related code as has not been tested and is not needed currently.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h index 1032a1c0b..9ebb2a509 100644 --- a/platform/linux-generic/include/odp_classification_datamodel.h +++ b/platform/linux-generic/include/odp_classification_datamodel.h @@ -42,8 +42,8 @@ extern "C" { #define CLS_COS_L3_QOS_BITS 6 /* Max L3 QoS Value */ #define CLS_COS_MAX_L3_QOS (1 << CLS_COS_L3_QOS_BITS) -/* Max PMR Term bits */ -#define CLS_PMR_TERM_BYTES_MAX 16 +/* Max PMR Term size */ +#define MAX_PMR_TERM_SIZE 16 /* Max queue per Class of service */ #define CLS_COS_QUEUE_MAX 32 /* Max number of implementation created queues */ @@ -61,39 +61,62 @@ typedef union { }; } odp_cls_hash_proto_t;
-/** -Packet Matching Rule Term Value - -Stores the Term and Value mapping for a PMR. -The maximum size of value currently supported in 64 bits -**/ +/* + * Term and value mapping for a PMR + */ typedef struct pmr_term_value { - odp_cls_pmr_term_t term; /* PMR Term */ - odp_bool_t range_term; /* True if range, false if match */ + /* PMR Term */ + odp_cls_pmr_term_t term; + + /* True if range, false if match */ + odp_bool_t range_term; + union { + /* Match value and mask */ struct { - /** Value to be matched */ - uint64_t value; - /** Masked set of bits to be matched */ - uint64_t mask; + /* Value to be matched. Arrays are used with custom and + * IPv6 address terms. */ + union { + uint64_t value; + uint8_t value_u8[MAX_PMR_TERM_SIZE]; + uint64_t value_u64[2]; + }; + + /* Mask for the data to be matched */ + union { + uint64_t mask; + uint8_t mask_u8[MAX_PMR_TERM_SIZE]; + uint64_t mask_u64[2]; + }; + } match; + + /* Range values */ struct { - /** Start value of the range */ - uint64_t val_start; - /** End value of the range */ - uint64_t val_end; + /* Start value of the range */ + union { + uint64_t start; + uint8_t start_u8[MAX_PMR_TERM_SIZE]; + uint64_t start_u64[2]; + }; + + /* End value of the range */ + union { + uint64_t end; + uint8_t end_u8[MAX_PMR_TERM_SIZE]; + uint64_t end_u64[2]; + }; + } range; - struct { - _odp_ipv6_addr_t addr; - _odp_ipv6_addr_t mask; - } match_ipv6; - struct { - _odp_ipv6_addr_t addr_start; - _odp_ipv6_addr_t addr_end; - } range_ipv6; + }; - uint32_t offset; /**< Offset if term == ODP_PMR_CUSTOM_FRAME */ - uint32_t val_sz; /**< Size of the value to be matched */ + + /* Offset used with custom PMR */ + uint32_t offset; + + /* Size of the value to be matched */ + uint32_t val_sz; + } pmr_term_value_t;
/* diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index e85e8d00c..164daf3fc 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -576,6 +576,11 @@ static int pmr_create_term(pmr_term_value_t *value, int custom = 0; odp_cls_pmr_term_t term = param->term;
+ if (param->range_term) { + ODP_ERR("PRM value range not supported\n"); + return -1; + } + value->term = term; value->range_term = param->range_term;
@@ -626,7 +631,7 @@ static int pmr_create_term(pmr_term_value_t *value,
case ODP_PMR_CUSTOM_FRAME: custom = 1; - size = CLS_PMR_TERM_BYTES_MAX; + size = MAX_PMR_TERM_SIZE; break;
default: @@ -640,45 +645,14 @@ static int pmr_create_term(pmr_term_value_t *value, return -1; }
- switch (value->term) { - case ODP_PMR_SIP6_ADDR: - case ODP_PMR_DIP6_ADDR: - if (!value->range_term) { - memset(value->match_ipv6.addr.u8, 0, 16); - memset(value->match_ipv6.mask.u8, 0, 16); - memcpy(&value->match_ipv6.addr.u8, param->match.value, - param->val_sz); - memcpy(&value->match_ipv6.mask.u8, param->match.mask, - param->val_sz); - for (i = 0; i < 2; i++) - value->match_ipv6.addr.u64[i] &= - value->match_ipv6.mask.u64[i]; - } else { - memset(value->range_ipv6.addr_start.u8, 0, 16); - memset(value->range_ipv6.addr_end.u8, 0, 16); - memcpy(&value->range_ipv6.addr_start.u8, param->range.val_start, - param->val_sz); - memcpy(&value->range_ipv6.addr_end.u8, param->range.val_end, - param->val_sz); - } + memset(&value->match.value, 0, MAX_PMR_TERM_SIZE); + memset(&value->match.mask, 0, MAX_PMR_TERM_SIZE); + memcpy(&value->match.value, param->match.value, param->val_sz); + memcpy(&value->match.mask, param->match.mask, param->val_sz); + + for (i = 0; i < param->val_sz; i++) + value->match.value_u8[i] &= value->match.mask_u8[i];
- break; - default: - if (!value->range_term) { - value->match.value = 0; - value->match.mask = 0; - memcpy(&value->match.value, param->match.value, param->val_sz); - memcpy(&value->match.mask, param->match.mask, param->val_sz); - value->match.value &= value->match.mask; - } else { - value->range.val_start = 0; - value->range.val_end = 0; - memcpy(&value->range.val_start, param->range.val_start, - param->val_sz); - memcpy(&value->range.val_end, param->range.val_end, - param->val_sz); - } - } value->offset = param->offset; value->val_sz = param->val_sz; return 0; @@ -952,16 +926,13 @@ static inline int verify_pmr_ipv6_saddr(const uint8_t *pkt_addr, return 0;
ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + memcpy(addr, ipv6->src_addr.u64, _ODP_IPV6ADDR_LEN);
- addr[0] = ipv6->src_addr.u64[0]; - addr[1] = ipv6->src_addr.u64[1]; - - /* 128 bit address is processed as two 64 bit value - * for bitwise AND operation */ - addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; - addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; + addr[0] = addr[0] & term_value->match.mask_u64[0]; + addr[1] = addr[1] & term_value->match.mask_u64[1];
- if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) + if (addr[0] == term_value->match.value_u64[0] && + addr[1] == term_value->match.value_u64[1]) return 1;
return 0; @@ -976,16 +947,15 @@ static inline int verify_pmr_ipv6_daddr(const uint8_t *pkt_addr,
if (!packet_hdr_has_ipv6(pkt_hdr)) return 0; + ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - addr[0] = ipv6->dst_addr.u64[0]; - addr[1] = ipv6->dst_addr.u64[1]; + memcpy(addr, ipv6->dst_addr.u64, _ODP_IPV6ADDR_LEN);
- /* 128 bit address is processed as two 64 bit value - * for bitwise AND operation */ - addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; - addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; + addr[0] = addr[0] & term_value->match.mask_u64[0]; + addr[1] = addr[1] & term_value->match.mask_u64[1];
- if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) + if (addr[0] == term_value->match.value_u64[0] && + addr[1] == term_value->match.value_u64[1]) return 1;
return 0; @@ -1083,7 +1053,7 @@ static inline int verify_pmr_custom_frame(const uint8_t *pkt_addr, uint32_t offset = term_value->offset; uint32_t val_sz = term_value->val_sz;
- ODP_ASSERT(val_sz <= CLS_PMR_TERM_BYTES_MAX); + ODP_ASSERT(val_sz <= MAX_PMR_TERM_SIZE);
if (packet_len(pkt_hdr) <= offset + val_sz) return 0;
commit d4eb0481e1dd40a0d0b70486cdf8f9b676862b2f Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 16:16:12 2019 +0300
linux-gen: cls: change ODP_PMR_ IPv4 addresses to big endian
Change ODP_PMR_SIP_ADDR and ODP_PMR_DIP_ADDR to big endian. Both are changed simultaneously as some tests use both terms.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index ae90ee82a..e85e8d00c 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -825,7 +825,7 @@ static inline int verify_pmr_ipv4_saddr(const uint8_t *pkt_addr, if (!pkt_hdr->p.input_flags.ipv4) return 0; ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - ipaddr = odp_be_to_cpu_32(ip->src_addr); + ipaddr = ip->src_addr; if (term_value->match.value == (ipaddr & term_value->match.mask)) return 1;
@@ -842,7 +842,7 @@ static inline int verify_pmr_ipv4_daddr(const uint8_t *pkt_addr, if (!pkt_hdr->p.input_flags.ipv4) return 0; ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - ipaddr = odp_be_to_cpu_32(ip->dst_addr); + ipaddr = ip->dst_addr; if (term_value->match.value == (ipaddr & term_value->match.mask)) return 1;
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index a939bdbee..46bbdf4b1 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1722,6 +1722,10 @@ static void test_pmr_term_ipv4_addr(int dst)
parse_ipv4_string(src_str, &src_addr, &src_mask); parse_ipv4_string(dst_str, &dst_addr, &dst_mask); + src_addr = odp_cpu_to_be_32(src_addr); + src_mask = odp_cpu_to_be_32(src_mask); + dst_addr = odp_cpu_to_be_32(dst_addr); + dst_mask = odp_cpu_to_be_32(dst_mask);
odp_cls_pmr_param_init(&pmr_param);
@@ -1748,8 +1752,8 @@ static void test_pmr_term_ipv4_addr(int dst) odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); - ip->src_addr = odp_cpu_to_be_32(src_addr); - ip->dst_addr = odp_cpu_to_be_32(dst_addr); + ip->src_addr = src_addr; + ip->dst_addr = dst_addr; odph_ipv4_csum_update(pkt);
seqno = cls_pkt_get_seq(pkt); diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c index 3a97023cf..b86bfe272 100644 --- a/test/validation/api/classification/odp_classification_tests.c +++ b/test/validation/api/classification/odp_classification_tests.c @@ -213,6 +213,9 @@ void configure_cls_pmr_chain(void) CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_DST] != ODP_COS_INVALID);
parse_ipv4_string(CLS_PMR_CHAIN_SADDR, &addr, &mask); + addr = odp_cpu_to_be_32(addr); + mask = odp_cpu_to_be_32(mask); + odp_cls_pmr_param_init(&pmr_param); pmr_param.term = ODP_PMR_SIP_ADDR; pmr_param.match.value = &addr; @@ -649,6 +652,9 @@ void configure_pktio_pmr_composite(void) CU_ASSERT_FATAL(cos_list[CLS_PMR_SET] != ODP_COS_INVALID);
parse_ipv4_string(CLS_PMR_SET_SADDR, &addr, &mask); + addr = odp_cpu_to_be_32(addr); + mask = odp_cpu_to_be_32(mask); + odp_cls_pmr_param_init(&pmr_params[0]); pmr_params[0].term = ODP_PMR_SIP_ADDR; pmr_params[0].match.value = &addr;
commit f15da1c0ee13dd0e342944dccdd9014c16d4d5be Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 15:22:38 2019 +0300
linux-gen: cls: change ODP_PMR_UDP/TCP ports to big endian
Change ODP_PMR_UDP_DPORT, ODP_PMR_TCP_DPORT, ODP_PMR_UDP_SPORT and ODP_PMR_TCP_SPORT terms to big endian. All four needs to be changed simultaneously in order not to break some validation tests.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 9ad3380e5..ae90ee82a 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -859,7 +859,7 @@ static inline int verify_pmr_tcp_sport(const uint8_t *pkt_addr, if (!pkt_hdr->p.input_flags.tcp) return 0; tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - sport = odp_be_to_cpu_16(tcp->src_port); + sport = tcp->src_port; if (term_value->match.value == (sport & term_value->match.mask)) return 1;
@@ -876,7 +876,7 @@ static inline int verify_pmr_tcp_dport(const uint8_t *pkt_addr, if (!pkt_hdr->p.input_flags.tcp) return 0; tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - dport = odp_be_to_cpu_16(tcp->dst_port); + dport = tcp->dst_port; if (term_value->match.value == (dport & term_value->match.mask)) return 1;
@@ -893,7 +893,7 @@ static inline int verify_pmr_udp_dport(const uint8_t *pkt_addr, if (!pkt_hdr->p.input_flags.udp) return 0; udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - dport = odp_be_to_cpu_16(udp->dst_port); + dport = udp->dst_port; if (term_value->match.value == (dport & term_value->match.mask)) return 1;
@@ -910,7 +910,7 @@ static inline int verify_pmr_udp_sport(const uint8_t *pkt_addr, if (!pkt_hdr->p.input_flags.udp) return 0; udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - sport = odp_be_to_cpu_16(udp->src_port); + sport = udp->src_port; if (term_value->match.value == (sport & term_value->match.mask)) return 1;
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 9ac735020..a939bdbee 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -121,8 +121,8 @@ static void classification_test_pktin_classifier_flag(void) odp_pmr_param_t pmr_param; odph_ethhdr_t *eth;
- val = CLS_DEFAULT_DPORT; - mask = 0xffff; + val = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + mask = odp_cpu_to_be_16(0xffff); seqno = 0;
/* classifier is disabled in pktin queue configuration */ @@ -167,7 +167,7 @@ static void classification_test_pktin_classifier_flag(void) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); - tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + tcp->dst_port = val;
enqueue_pktio_interface(pkt, pktio);
@@ -217,8 +217,8 @@ static void _classification_test_pmr_term_tcp_dport(int num_pkt) odp_pool_t pool_recv; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; - val = CLS_DEFAULT_DPORT; - mask = 0xffff; + val = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + mask = odp_cpu_to_be_16(0xffff);
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); @@ -262,7 +262,7 @@ static void _classification_test_pmr_term_tcp_dport(int num_pkt) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); - tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + tcp->dst_port = val;
enqueue_pktio_interface(pkt, pktio); } @@ -320,7 +320,7 @@ static void _classification_test_pmr_term_tcp_dport(int num_pkt)
if ((i % 5) < 2) { sent_queue++; - tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + tcp->dst_port = val; } else { sent_default++; tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1); @@ -341,8 +341,7 @@ static void _classification_test_pmr_term_tcp_dport(int num_pkt)
if (retqueue == queue) { recv_queue++; - CU_ASSERT(tcp->dst_port == - odp_cpu_to_be_16(CLS_DEFAULT_DPORT)); + CU_ASSERT(tcp->dst_port == val); } else if (retqueue == default_queue) { recv_default++; CU_ASSERT(tcp->dst_port == @@ -388,8 +387,8 @@ static void classification_test_pmr_term_tcp_sport(void) odp_pmr_param_t pmr_param; odph_ethhdr_t *eth;
- val = CLS_DEFAULT_SPORT; - mask = 0xffff; + val = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); + mask = odp_cpu_to_be_16(0xffff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -433,7 +432,7 @@ static void classification_test_pmr_term_tcp_sport(void) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); - tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); + tcp->src_port = val;
enqueue_pktio_interface(pkt, pktio);
@@ -501,8 +500,8 @@ static void classification_test_pmr_term_udp_dport(void) odph_ethhdr_t *eth; cls_packet_info_t pkt_info;
- val = CLS_DEFAULT_DPORT; - mask = 0xffff; + val = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + mask = odp_cpu_to_be_16(0xffff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -548,7 +547,7 @@ static void classification_test_pmr_term_udp_dport(void) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); - udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); + udp->dst_port = val;
enqueue_pktio_interface(pkt, pktio);
@@ -617,8 +616,8 @@ static void classification_test_pmr_term_udp_sport(void) odph_ethhdr_t *eth; cls_packet_info_t pkt_info;
- val = CLS_DEFAULT_SPORT; - mask = 0xffff; + val = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); + mask = odp_cpu_to_be_16(0xffff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -664,7 +663,7 @@ static void classification_test_pmr_term_udp_sport(void) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); - udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); + udp->src_port = val;
enqueue_pktio_interface(pkt, pktio);
diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c index 9df869ece..3a97023cf 100644 --- a/test/validation/api/classification/odp_classification_tests.c +++ b/test/validation/api/classification/odp_classification_tests.c @@ -223,8 +223,8 @@ void configure_cls_pmr_chain(void) cos_list[CLS_PMR_CHAIN_SRC]); CU_ASSERT_FATAL(pmr_list[CLS_PMR_CHAIN_SRC] != ODP_PMR_INVALID);
- val = CLS_PMR_CHAIN_PORT; - maskport = 0xffff; + val = odp_cpu_to_be_16(CLS_PMR_CHAIN_PORT); + maskport = odp_cpu_to_be_16(0xffff); odp_cls_pmr_param_init(&pmr_param); pmr_param.term = find_first_supported_l3_pmr(); pmr_param.match.value = &val; @@ -573,8 +573,8 @@ void configure_pmr_cos(void) cos_list[CLS_PMR] = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos_list[CLS_PMR] != ODP_COS_INVALID);
- val = CLS_PMR_PORT; - mask = 0xffff; + val = odp_cpu_to_be_16(CLS_PMR_PORT); + mask = odp_cpu_to_be_16(0xffff); odp_cls_pmr_param_init(&pmr_param); pmr_param.term = find_first_supported_l3_pmr(); pmr_param.match.value = &val; @@ -655,8 +655,8 @@ void configure_pktio_pmr_composite(void) pmr_params[0].match.mask = &mask; pmr_params[0].val_sz = sizeof(addr);
- val = CLS_PMR_SET_PORT; - maskport = 0xffff; + val = odp_cpu_to_be_16(CLS_PMR_SET_PORT); + maskport = odp_cpu_to_be_16(0xffff); odp_cls_pmr_param_init(&pmr_params[1]); pmr_params[1].term = find_first_supported_l3_pmr(); pmr_params[1].match.value = &val;
commit 6f855d843b1d87013908998a050e16c435b89e07 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 15:10:01 2019 +0300
linux-gen: cls: change ODP_PMR_DMAC to big endian
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 1d717f413..9ad3380e5 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -921,24 +921,23 @@ static inline int verify_pmr_dmac(const uint8_t *pkt_addr, odp_packet_hdr_t *pkt_hdr, pmr_term_value_t *term_value) { - uint64_t dmac = 0; - uint64_t dmac_be = 0; const _odp_ethhdr_t *eth; + uint16_t dmac[3]; + uint16_t *mask = (uint16_t *)&term_value->match.mask; + uint16_t *value = (uint16_t *)&term_value->match.value;
if (!packet_hdr_has_eth(pkt_hdr)) return 0;
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - memcpy(&dmac_be, eth->dst.addr, _ODP_ETHADDR_LEN); - dmac = odp_be_to_cpu_64(dmac_be); - /* since we are converting a 48 bit ethernet address from BE to cpu - format using odp_be_to_cpu_64() the last 16 bits needs to be right - shifted */ - if (dmac_be != dmac) - dmac = dmac >> (64 - (_ODP_ETHADDR_LEN * 8)); - - if (term_value->match.value == (dmac & term_value->match.mask)) + memcpy(dmac, eth->dst.addr, _ODP_ETHADDR_LEN); + dmac[0] &= mask[0]; + dmac[1] &= mask[1]; + dmac[2] &= mask[2]; + + if (value[0] == dmac[0] && value[1] == dmac[1] && value[2] == dmac[2]) return 1; + return 0; }
diff --git a/test/validation/api/classification/classification.h b/test/validation/api/classification/classification.h index ae8d57221..c16b340c9 100644 --- a/test/validation/api/classification/classification.h +++ b/test/validation/api/classification/classification.h @@ -19,8 +19,8 @@ #define CLS_DEFAULT_DADDR "10.0.0.100/32" #define CLS_DEFAULT_SPORT 1024 #define CLS_DEFAULT_DPORT 2048 -#define CLS_DEFAULT_DMAC 0x010203040506 -#define CLS_DEFAULT_SMAC 0x060504030201 +#define CLS_DEFAULT_DMAC {0x01, 0x02, 0x03, 0x04, 0x05, 0x06} +#define CLS_DEFAULT_SMAC {0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c}
/* Config values for Error CoS */ #define TEST_ERROR 1 diff --git a/test/validation/api/classification/odp_classification_common.c b/test/validation/api/classification/odp_classification_common.c index ad64b9d4a..851f949cc 100644 --- a/test/validation/api/classification/odp_classification_common.c +++ b/test/validation/api/classification/odp_classification_common.c @@ -240,9 +240,6 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info) odph_ipv4hdr_t *ip; odph_ipv6hdr_t *ipv6; uint16_t payload_len; - uint64_t src_mac = CLS_DEFAULT_SMAC; - uint64_t dst_mac = CLS_DEFAULT_DMAC; - uint64_t dst_mac_be; uint32_t addr = 0; uint32_t mask; odp_packet_t pkt; @@ -257,12 +254,8 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info) uint16_t eth_type; odp_u16be_t *vlan_type; odph_vlanhdr_t *vlan_hdr; - - /* 48 bit ethernet address needs to be left shifted for proper - value after changing to be*/ - dst_mac_be = odp_cpu_to_be_64(dst_mac); - if (dst_mac != dst_mac_be) - dst_mac_be = dst_mac_be >> (64 - 8 * ODPH_ETHADDR_LEN); + uint8_t src_mac[] = CLS_DEFAULT_SMAC; + uint8_t dst_mac[] = CLS_DEFAULT_DMAC;
payload_len = sizeof(cls_test_packet_t) + pkt_info.len; seqno = odp_atomic_fetch_inc_u32(pkt_info.seq); @@ -287,7 +280,7 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info) odp_packet_l2_offset_set(pkt, 0); ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN); - memcpy(ethhdr->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN); + memcpy(ethhdr->dst.addr, &dst_mac, ODPH_ETHADDR_LEN); vlan_type = (odp_u16be_t *)(void *)ðhdr->type; vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index abb1a743b..9ac735020 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -821,8 +821,6 @@ static void classification_test_pmr_term_dmac(void) { odp_packet_t pkt; uint32_t seqno; - uint64_t val; - uint64_t mask; int retval; odp_pktio_t pktio; odp_queue_t queue; @@ -839,9 +837,8 @@ static void classification_test_pmr_term_dmac(void) odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; cls_packet_info_t pkt_info; - - val = CLS_DEFAULT_DMAC; /* 48 bit Ethernet Mac address */ - mask = 0xffffffffffff; + uint8_t val[] = {0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee}; + uint8_t mask[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -880,6 +877,8 @@ static void classification_test_pmr_term_dmac(void) pkt_info.udp = true; pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + memcpy(eth->dst.addr, val, ODPH_ETHADDR_LEN); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -896,9 +895,6 @@ static void classification_test_pmr_term_dmac(void) /* Other packets delivered to default queue */ pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); - memset(eth->dst.addr, 0, ODPH_ETHADDR_LEN); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID);
commit 35a6b2e5c369e81196f6c288085990eaaf83f360 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 14:41:59 2019 +0300
linux-gen: cls: change ODP_PMR_VLAN_ID_X to big endian
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 308f060b1..1d717f413 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -1033,8 +1033,8 @@ static inline int verify_pmr_vlan_id_x(const uint8_t *pkt_addr, if (pkt_hdr->p.input_flags.vlan_qinq) vlan++;
- tci = odp_be_to_cpu_16(vlan->tci); - vlan_id = tci & 0x0fff; + tci = vlan->tci; + vlan_id = tci & odp_cpu_to_be_16(0x0fff);
if (term_value->match.value == (vlan_id & term_value->match.mask)) return 1; diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 7111595c5..abb1a743b 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1170,8 +1170,8 @@ static void classification_test_pmr_term_vlan_id_x(void) odph_vlanhdr_t *vlan_x; cls_packet_info_t pkt_info;
- val = 0x345; - mask = 0xfff; + val = odp_cpu_to_be_16(0x345); + mask = odp_cpu_to_be_16(0xfff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -1218,7 +1218,7 @@ static void classification_test_pmr_term_vlan_id_x(void) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); vlan_x = (odph_vlanhdr_t *)(eth + 1); vlan_x++; - vlan_x->tci = odp_cpu_to_be_16(val); + vlan_x->tci = val; enqueue_pktio_interface(pkt, pktio);
pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
commit 0e2ee113fcc0e7383d9e465c11a8495a65f7a171 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 14:38:47 2019 +0300
linux-gen: cls: change ODP_PMR_VLAN_ID_0 to big endian
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 91d04640f..308f060b1 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -1006,8 +1006,8 @@ static inline int verify_pmr_vlan_id_0(const uint8_t *pkt_addr,
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); vlan = (const _odp_vlanhdr_t *)(eth + 1); - tci = odp_be_to_cpu_16(vlan->tci); - vlan_id = tci & 0x0fff; + tci = vlan->tci; + vlan_id = tci & odp_cpu_to_be_16(0x0fff);
if (term_value->match.value == (vlan_id & term_value->match.mask)) return 1; diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 5dd16c321..7111595c5 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1059,8 +1059,8 @@ static void classification_test_pmr_term_vlan_id_0(void) odph_vlanhdr_t *vlan_0; cls_packet_info_t pkt_info;
- val = 0x123; - mask = 0xfff; + val = odp_cpu_to_be_16(0x123); + mask = odp_cpu_to_be_16(0xfff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -1105,7 +1105,7 @@ static void classification_test_pmr_term_vlan_id_0(void) odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); vlan_0 = (odph_vlanhdr_t *)(eth + 1); - vlan_0->tci = odp_cpu_to_be_16(val); + vlan_0->tci = val; enqueue_pktio_interface(pkt, pktio);
pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
commit 0cfdb2c5a6b3afe0e4b0eee2b3749a0cfca3917d Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 14:27:09 2019 +0300
linux-gen: cls: change ODP_PMR_ETHTYPE_X to big endian
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index e640ede2e..91d04640f 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -1132,7 +1132,7 @@ static inline int verify_pmr_eth_type_x(const uint8_t *pkt_addr, if (pkt_hdr->p.input_flags.vlan_qinq) vlan++;
- ethtype = odp_be_to_cpu_16(vlan->type); + ethtype = vlan->type;
if (term_value->match.value == (ethtype & term_value->match.mask)) return 1; diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index abcc73e07..5dd16c321 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1391,8 +1391,8 @@ static void classification_test_pmr_term_eth_type_x(void) odph_vlanhdr_t *vlan_x; cls_packet_info_t pkt_info;
- val = 0x0800; - mask = 0xffff; + val = odp_cpu_to_be_16(0x0800); + mask = odp_cpu_to_be_16(0xffff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -1440,7 +1440,7 @@ static void classification_test_pmr_term_eth_type_x(void) vlan_x = (odph_vlanhdr_t *)(eth + 1); vlan_x++; vlan_x->tci = odp_cpu_to_be_16(0x123); - vlan_x->type = odp_cpu_to_be_16(val); + vlan_x->type = val;
enqueue_pktio_interface(pkt, pktio);
commit b7a8fd47362a3853db8cc3ea56fe1d268defa574 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 24 13:55:29 2019 +0300
linux-gen: cls: change ODP_PMR_ETHTYPE_0 to big endian
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 0119f7537..e640ede2e 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -1107,7 +1107,7 @@ static inline int verify_pmr_eth_type_0(const uint8_t *pkt_addr, return 0;
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - ethtype = odp_be_to_cpu_16(eth->type); + ethtype = eth->type;
if (term_value->match.value == (ethtype & term_value->match.mask)) return 1; diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 44942de98..abcc73e07 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1282,8 +1282,8 @@ static void classification_test_pmr_term_eth_type_0(void) odph_ethhdr_t *eth; cls_packet_info_t pkt_info;
- val = ODPH_ETHTYPE_IPV6; - mask = 0xffff; + val = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV6); + mask = odp_cpu_to_be_16(0xffff); seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true);
commit 0df7a38e2b9be4ad72528d43551e56ac4d152b96 Author: Petri Savolainen petri.savolainen@nokia.com Date: Wed Oct 23 17:21:13 2019 +0300
linux-gen: cls: check PMR value size
Check that PMR value size matches API specification.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 907d68481..0119f7537 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -568,12 +568,77 @@ int odp_cos_with_l3_qos(odp_pktio_t pktio_in, return 0; }
-static int odp_pmr_create_term(pmr_term_value_t *value, - const odp_pmr_param_t *param) +static int pmr_create_term(pmr_term_value_t *value, + const odp_pmr_param_t *param) { - value->term = param->term; - value->range_term = param->range_term; + uint32_t size; uint8_t i; + int custom = 0; + odp_cls_pmr_term_t term = param->term; + + value->term = term; + value->range_term = param->range_term; + + switch (term) { + case ODP_PMR_IPPROTO: + size = 1; + break; + + case ODP_PMR_ETHTYPE_0: + /* Fall through */ + case ODP_PMR_ETHTYPE_X: + /* Fall through */ + case ODP_PMR_VLAN_ID_0: + /* Fall through */ + case ODP_PMR_VLAN_ID_X: + /* Fall through */ + case ODP_PMR_UDP_DPORT: + /* Fall through */ + case ODP_PMR_TCP_DPORT: + /* Fall through */ + case ODP_PMR_UDP_SPORT: + /* Fall through */ + case ODP_PMR_TCP_SPORT: + size = 2; + break; + + case ODP_PMR_LEN: + /* Fall through */ + case ODP_PMR_SIP_ADDR: + /* Fall through */ + case ODP_PMR_DIP_ADDR: + /* Fall through */ + case ODP_PMR_IPSEC_SPI: + /* Fall through */ + case ODP_PMR_LD_VNI: + size = 4; + break; + + case ODP_PMR_DMAC: + size = 6; + break; + + case ODP_PMR_SIP6_ADDR: + /* Fall through */ + case ODP_PMR_DIP6_ADDR: + size = 16; + break; + + case ODP_PMR_CUSTOM_FRAME: + custom = 1; + size = CLS_PMR_TERM_BYTES_MAX; + break; + + default: + ODP_ERR("Bad PRM term\n"); + return -1; + } + + if ((!custom && param->val_sz != size) || + (custom && param->val_sz > size)) { + ODP_ERR("Bad PMR value size: %u\n", param->val_sz); + return -1; + }
switch (value->term) { case ODP_PMR_SIP6_ADDR: @@ -655,7 +720,6 @@ odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms, pmr_t *pmr; int i; odp_pmr_t id; - int val_sz; uint32_t loc; cos_t *cos_src = get_cos_entry(src_cos); cos_t *cos_dst = get_cos_entry(dst_cos); @@ -680,13 +744,8 @@ odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
pmr->s.num_pmr = num_terms; for (i = 0; i < num_terms; i++) { - val_sz = terms[i].val_sz; - if (val_sz > CLS_PMR_TERM_BYTES_MAX) { + if (pmr_create_term(&pmr->s.pmr_term_value[i], &terms[i])) { pmr->s.valid = 0; - return ODP_PMR_INVALID; - } - if (0 > odp_pmr_create_term(&pmr->s.pmr_term_value[i], - &terms[i])) { UNLOCK(&pmr->s.lock); return ODP_PMR_INVALID; } diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index a01c0a403..44942de98 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -927,8 +927,8 @@ static void classification_test_pmr_term_packet_len(void) { odp_packet_t pkt; uint32_t seqno; - uint16_t val; - uint16_t mask; + uint32_t val; + uint32_t mask; int retval; odp_pktio_t pktio; odp_queue_t queue;
commit 139b28399d3bd1f53624908c9fd99c1f14283cdd Author: Petri Savolainen petri.savolainen@nokia.com Date: Wed Oct 23 16:36:40 2019 +0300
api: cls: PMR value in big endian format
PMR term documentation was not explicit about endianness of value and mask fields. Most terms assumed CPU endian, but terms with larger data sizes assumed big endian (MAC, IPv6 address and custom).
Harmonize term specification so that all terms expect value/mask data to be in big endian format, have fixed size and allow free memory alignment. Packet length term is an exception to this as it does not represent a field in a packet.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com Reviewed-by: Stanislaw Kardach skardach@marvell.com
diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 043059fa1..67fdd20aa 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -461,44 +461,92 @@ int odp_cos_with_l3_qos(odp_pktio_t pktio_in, */
/** - * Packet Matching Rule field enumeration - * for fields that may be used to calculate - * the PMR, if present in a packet. + * Packet Matching Rule terms + * + * This enumeration selects the protocol field that is matched against PMR + * value/mask or value range. Protocol field values and masks are passed in big + * endian (network endian) format. However, ODP_PMR_LEN value and range are + * passed in CPU native endian (uint32_t words), as the term does not represent + * a protocol field. + * + * PMR value/mask data size is term specific. This size must be set into val_sz + * field of odp_pmr_param_t. There is no alignment requirement for PMR + * value/mask data. */ typedef enum { - ODP_PMR_LEN, /**< Total length of received packet*/ - ODP_PMR_ETHTYPE_0, /**< Initial (outer) - Ethertype only (*val=uint16_t)*/ - ODP_PMR_ETHTYPE_X, /**< Ethertype of most inner VLAN tag - (*val=uint16_t)*/ - ODP_PMR_VLAN_ID_0, /**< First VLAN ID (outer) (*val=uint16_t) */ - ODP_PMR_VLAN_ID_X, /**< Last VLAN ID (inner) (*val=uint16_t) */ - ODP_PMR_DMAC, /**< destination MAC address (*val=uint64_t)*/ - ODP_PMR_IPPROTO, /**< IP Protocol or IPv6 Next Header - (*val=uint8_t) */ - ODP_PMR_UDP_DPORT, /**< Destination UDP port, implies IPPROTO=17*/ - ODP_PMR_TCP_DPORT, /**< Destination TCP port implies IPPROTO=6*/ - ODP_PMR_UDP_SPORT, /**< Source UDP Port (*val=uint16_t)*/ - ODP_PMR_TCP_SPORT, /**< Source TCP port (*val=uint16_t)*/ - ODP_PMR_SIP_ADDR, /**< Source IP address (uint32_t)*/ - ODP_PMR_DIP_ADDR, /**< Destination IP address (uint32_t)*/ - ODP_PMR_SIP6_ADDR, /**< Source IP address (uint8_t[16])*/ - ODP_PMR_DIP6_ADDR, /**< Destination IP address (uint8_t[16])*/ - ODP_PMR_IPSEC_SPI, /**< IPsec session identifier(*val=uint32_t)*/ - ODP_PMR_LD_VNI, /**< NVGRE/VXLAN network identifier - (*val=uint32_t)*/ - ODP_PMR_CUSTOM_FRAME, /**< Custom match rule, offset from start of - frame. The match is defined by the offset, the - expected value, and its size. They must be - applied before any other PMR. - (*val=uint8_t[val_sz])*/ + /** Total length of received packet. Exceptionally, value and mask are + * uint32_t (val_sz = 4) in CPU endian. */ + ODP_PMR_LEN, + + /** Initial (outer) Ethertype only (val_sz = 2) */ + ODP_PMR_ETHTYPE_0, + + /** Ethertype of most inner VLAN tag (val_sz = 2) */ + ODP_PMR_ETHTYPE_X, + + /** First (outer) VLAN ID (val_sz = 2) */ + ODP_PMR_VLAN_ID_0, + + /** Last (most inner) VLAN ID (val_sz = 2) */ + ODP_PMR_VLAN_ID_X, + + /** Destination MAC address (val_sz = 6) */ + ODP_PMR_DMAC, + + /** IPv4 Protocol or IPv6 Next Header (val_sz = 1) */ + ODP_PMR_IPPROTO, + + /** Destination UDP port (val_sz = 2) */ + ODP_PMR_UDP_DPORT, + + /** Destination TCP port (val_sz = 2) */ + ODP_PMR_TCP_DPORT, + + /** Source UDP port (val_sz = 2) */ + ODP_PMR_UDP_SPORT, + + /** Source TCP port (val_sz = 2) */ + ODP_PMR_TCP_SPORT, + + /** Source IPv4 address (val_sz = 4) */ + ODP_PMR_SIP_ADDR, + + /** Destination IPv4 address (val_sz = 4) */ + ODP_PMR_DIP_ADDR, + + /** Source IPv6 address (val_sz = 16) */ + ODP_PMR_SIP6_ADDR, + + /** Destination IPv6 address (val_sz = 16) */ + ODP_PMR_DIP6_ADDR, + + /** IPsec session identifier (val_sz = 4)*/ + ODP_PMR_IPSEC_SPI, + + /** NVGRE/VXLAN network identifier (val_sz = 4) */ + ODP_PMR_LD_VNI, + + /** + * Custom frame match rule + * + * PMR offset is counted from the start of the packet. The match is + * defined by the offset, the expected value, and its size. Custom frame + * rules must be applied before any other PMR. + */ + ODP_PMR_CUSTOM_FRAME,
/** Inner header may repeat above values with this offset */ ODP_PMR_INNER_HDR_OFF = 32 + } odp_cls_pmr_term_t;
/** * Packet Matching Rule parameter structure + * + * Match value/mask size and endianness are defined in PMR term documentation + * (@see odp_cls_pmr_term_t). Most values and masks are passed in big + * endian format without data alignment requirement. ODP_PMR_LEN is + * an exception to this (uint32_t in CPU endian). */ typedef struct odp_pmr_param_t { odp_cls_pmr_term_t term; /**< Packet Matching Rule term */ @@ -510,21 +558,24 @@ typedef struct odp_pmr_param_t { union { /** Parameters for single-valued matches */ struct { - /** Value to be matched */ - const void *value; - - /** Masked set of bits to be matched */ - const void *mask; + /** Points to the value to be matched. Value size and + * endianness are defined by the term used. Values of + * protocol fields are defined in big endian format. + */ + const void *value; + + /** Mask of the bits to be matched. The same size and + * endianness is used than with the value. */ + const void *mask; } match;
/** Parameter for range value matches */ struct { - /** Start and End values are included in the range */ - /** start value of range */ - const void *val_start; + /** Start value of the range */ + const void *val_start;
- /** End value of range */ - const void *val_end; + /** End value of the range */ + const void *val_end; } range; }; uint32_t val_sz; /**< Size of the term value */
-----------------------------------------------------------------------
Summary of changes: configure.ac | 2 +- example/classifier/odp_classifier.c | 224 +++++++++--------- include/odp/api/spec/classification.h | 172 +++++++++----- include/odp/api/spec/packet_io.h | 14 +- include/odp/api/spec/pool.h | 8 +- include/odp/api/spec/shared_memory.h | 2 +- include/odp/api/spec/version.h.in | 1 - .../include/odp_classification_datamodel.h | 79 ++++--- platform/linux-generic/odp_classification.c | 249 +++++++++++++-------- .../validation/api/classification/classification.h | 4 +- .../api/classification/odp_classification_common.c | 13 +- .../classification/odp_classification_test_pmr.c | 236 +++++++++++++++---- .../api/classification/odp_classification_tests.c | 18 +- 13 files changed, 678 insertions(+), 344 deletions(-)
hooks/post-receive