aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorKiran Kumar K <kirankumark@marvell.com>2020-12-01 13:47:37 +0530
committerPetri Savolainen <petri.savolainen@nokia.com>2020-12-03 11:21:54 +0200
commitf00f240ccb7f3aa4c499c162b3b6d64055bbd86e (patch)
treeeea0183f3069d9f54c144336088a41d43f1ba1c4 /example
parent5fdb0f2fe83430efa4c1bd4a39ef1efebe45b0d7 (diff)
example: cls: add ci pass option
Added an option to check the number of received packets per CoS. Using -C option, the minimum number of expected packets can be specified for each CoS. On application close, the number of received packets on each CoS will be compared to the expected values. If received packet count is less than the expected value, the application will exit with an error. Signed-off-by: Kiran Kumar K <kirankumark@marvell.com> Reviewed-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'example')
-rw-r--r--example/classifier/odp_classifier.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c
index 3cdd116fc..859802358 100644
--- a/example/classifier/odp_classifier.c
+++ b/example/classifier/odp_classifier.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2015-2018, Linaro Limited
* Copyright (c) 2019-2020, Nokia
+ * Copyright (C) 2020, Marvell
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -74,8 +75,15 @@ typedef struct {
} global_statistics;
typedef struct {
+ char cos_name[ODP_COS_NAME_LEN];
+ uint64_t count;
+} ci_pass_counters;
+
+typedef struct {
global_statistics stats[MAX_PMR_COUNT];
+ ci_pass_counters ci_pass_rules[MAX_PMR_COUNT];
int policy_count; /**< global policy count */
+ int num_ci_pass_rules; /**< ci pass count */
int appl_mode; /**< application mode */
odp_atomic_u64_t total_packets; /**< total received packets */
unsigned int cpu_count; /**< Number of CPUs to use */
@@ -100,6 +108,38 @@ 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(void);
+static inline int check_ci_pass_count(appl_args_t *args)
+{
+ int i, j;
+ uint64_t count;
+
+ if (args->num_ci_pass_rules == 0)
+ return 0;
+
+ for (i = 0; i < args->num_ci_pass_rules; i++) {
+ for (j = 0; j < args->policy_count; j++) {
+ if (!strcmp(args->stats[j].cos_name,
+ args->ci_pass_rules[i].cos_name)) {
+ count = odp_atomic_load_u64(&args->stats[i].queue_pkt_count);
+ if (args->ci_pass_rules[i].count > count) {
+ ODPH_ERR("Error: Cos = %s, expected packets = %" PRIu64 ","
+ "received packet = %" PRIu64 "\n",
+ args->stats[j].cos_name,
+ args->ci_pass_rules[i].count, count);
+ return -1;
+ }
+ break;
+ }
+ }
+ if (j == args->policy_count) {
+ ODPH_ERR("Error: invalid Cos:%s specified for CI pass count\n",
+ args->ci_pass_rules[i].cos_name);
+ return -1;
+ }
+ }
+ return 0;
+}
+
static inline void print_cls_statistics(appl_args_t *args)
{
int i;
@@ -670,6 +710,11 @@ int main(int argc, char *argv[])
args->shutdown = 1;
odph_thread_join(thread_tbl, num_workers);
+ if (check_ci_pass_count(args)) {
+ ODPH_ERR("Error: Packet count verification failed\n");
+ exit(EXIT_FAILURE);
+ }
+
for (i = 0; i < args->policy_count; i++) {
if ((i != args->policy_count - 1) &&
odp_cls_pmr_destroy(args->stats[i].pmr))
@@ -1006,6 +1051,42 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
return 0;
}
+static int parse_policy_ci_pass_count(appl_args_t *appl_args, char *optarg)
+{
+ int num_ci_pass_rules;
+ char *token, *value;
+ size_t len;
+ ci_pass_counters *ci_pass_rules;
+ char *count_str;
+
+ num_ci_pass_rules = appl_args->num_ci_pass_rules;
+ ci_pass_rules = appl_args->ci_pass_rules;
+
+ /* last array index is needed for default queue */
+ if (num_ci_pass_rules >= MAX_PMR_COUNT) {
+ ODPH_ERR("Too many ci pass counters. Max count is %i.\n",
+ MAX_PMR_COUNT);
+ return -1;
+ }
+
+ len = strlen(optarg);
+ len++;
+ count_str = malloc(len);
+ strcpy(count_str, optarg);
+
+ token = strtok(count_str, ":");
+ value = strtok(NULL, ":");
+ if (!token || !value) {
+ free(count_str);
+ return -1;
+ }
+ strcpy(ci_pass_rules[num_ci_pass_rules].cos_name, token);
+ ci_pass_rules[num_ci_pass_rules].count = atoll(value);
+ appl_args->num_ci_pass_rules++;
+ free(count_str);
+ return 0;
+}
+
/**
* Parse and store the command line arguments
*
@@ -1029,13 +1110,14 @@ static int parse_args(int argc, char *argv[], appl_args_t *appl_args)
{"policy", required_argument, NULL, 'p'},
{"mode", required_argument, NULL, 'm'},
{"time", required_argument, NULL, 't'},
+ {"ci_pass", required_argument, NULL, 'C'},
{"promisc_mode", no_argument, NULL, 'P'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
- static const char *shortopts = "+c:t:i:p:m:t:Pvh";
+ static const char *shortopts = "+c:t:i:p:m:t:C:Pvh";
appl_args->cpu_count = 1; /* Use one worker by default */
appl_args->verbose = 0;
@@ -1086,6 +1168,12 @@ static int parse_args(int argc, char *argv[], appl_args_t *appl_args)
else
appl_args->appl_mode = APPL_MODE_REPLY;
break;
+ case 'C':
+ if (parse_policy_ci_pass_count(appl_args, optarg)) {
+ ret = -1;
+ break;
+ }
+ break;
case 'P':
appl_args->promisc_mode = 1;
break;
@@ -1176,6 +1264,11 @@ static void usage(void)
" 0: Runs in infinite loop\n"
" default: Runs in infinite loop\n"
"\n"
+ " -C, --ci_pass <dst queue:count>\n"
+ " Minimum acceptable packet count for a CoS destination queue.\n"
+ " If the received packet count is smaller than this value,\n"
+ " the application will exit with an error.\n"
+ " E.g: -C \"queue1:100\" -C \"queue2:200\" -C \"DefaultQueue:100\"\n"
" -P, --promisc_mode Enable promiscuous mode.\n"
" -v, --verbose Verbose output.\n"
" -h, --help Display help and exit.\n"