1*5074e1d5SCristian Dumitrescu /* SPDX-License-Identifier: BSD-3-Clause 2*5074e1d5SCristian Dumitrescu * Copyright(c) 2020 Intel Corporation 3*5074e1d5SCristian Dumitrescu */ 4*5074e1d5SCristian Dumitrescu 5*5074e1d5SCristian Dumitrescu #include <stdio.h> 6*5074e1d5SCristian Dumitrescu #include <stdint.h> 7*5074e1d5SCristian Dumitrescu #include <stdlib.h> 8*5074e1d5SCristian Dumitrescu #include <string.h> 9*5074e1d5SCristian Dumitrescu 10*5074e1d5SCristian Dumitrescu #include <rte_common.h> 11*5074e1d5SCristian Dumitrescu #include <rte_ethdev.h> 12*5074e1d5SCristian Dumitrescu #include <rte_swx_port_ethdev.h> 13*5074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h> 14*5074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h> 15*5074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h> 16*5074e1d5SCristian Dumitrescu 17*5074e1d5SCristian Dumitrescu #include "cli.h" 18*5074e1d5SCristian Dumitrescu 19*5074e1d5SCristian Dumitrescu #include "obj.h" 20*5074e1d5SCristian Dumitrescu #include "thread.h" 21*5074e1d5SCristian Dumitrescu 22*5074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS 23*5074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS 256 24*5074e1d5SCristian Dumitrescu #endif 25*5074e1d5SCristian Dumitrescu 26*5074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY "Not enough memory.\n" 27*5074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n" 28*5074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n" 29*5074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n" 30*5074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n" 31*5074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n" 32*5074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n" 33*5074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n" 34*5074e1d5SCristian Dumitrescu #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n" 35*5074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n" 36*5074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL "Command \"%s\" failed.\n" 37*5074e1d5SCristian Dumitrescu 38*5074e1d5SCristian Dumitrescu #define skip_white_spaces(pos) \ 39*5074e1d5SCristian Dumitrescu ({ \ 40*5074e1d5SCristian Dumitrescu __typeof__(pos) _p = (pos); \ 41*5074e1d5SCristian Dumitrescu for ( ; isspace(*_p); _p++) \ 42*5074e1d5SCristian Dumitrescu ; \ 43*5074e1d5SCristian Dumitrescu _p; \ 44*5074e1d5SCristian Dumitrescu }) 45*5074e1d5SCristian Dumitrescu 46*5074e1d5SCristian Dumitrescu static int 47*5074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p) 48*5074e1d5SCristian Dumitrescu { 49*5074e1d5SCristian Dumitrescu char *next; 50*5074e1d5SCristian Dumitrescu uint64_t val; 51*5074e1d5SCristian Dumitrescu 52*5074e1d5SCristian Dumitrescu p = skip_white_spaces(p); 53*5074e1d5SCristian Dumitrescu if (!isdigit(*p)) 54*5074e1d5SCristian Dumitrescu return -EINVAL; 55*5074e1d5SCristian Dumitrescu 56*5074e1d5SCristian Dumitrescu val = strtoul(p, &next, 10); 57*5074e1d5SCristian Dumitrescu if (p == next) 58*5074e1d5SCristian Dumitrescu return -EINVAL; 59*5074e1d5SCristian Dumitrescu 60*5074e1d5SCristian Dumitrescu p = next; 61*5074e1d5SCristian Dumitrescu switch (*p) { 62*5074e1d5SCristian Dumitrescu case 'T': 63*5074e1d5SCristian Dumitrescu val *= 1024ULL; 64*5074e1d5SCristian Dumitrescu /* fall through */ 65*5074e1d5SCristian Dumitrescu case 'G': 66*5074e1d5SCristian Dumitrescu val *= 1024ULL; 67*5074e1d5SCristian Dumitrescu /* fall through */ 68*5074e1d5SCristian Dumitrescu case 'M': 69*5074e1d5SCristian Dumitrescu val *= 1024ULL; 70*5074e1d5SCristian Dumitrescu /* fall through */ 71*5074e1d5SCristian Dumitrescu case 'k': 72*5074e1d5SCristian Dumitrescu case 'K': 73*5074e1d5SCristian Dumitrescu val *= 1024ULL; 74*5074e1d5SCristian Dumitrescu p++; 75*5074e1d5SCristian Dumitrescu break; 76*5074e1d5SCristian Dumitrescu } 77*5074e1d5SCristian Dumitrescu 78*5074e1d5SCristian Dumitrescu p = skip_white_spaces(p); 79*5074e1d5SCristian Dumitrescu if (*p != '\0') 80*5074e1d5SCristian Dumitrescu return -EINVAL; 81*5074e1d5SCristian Dumitrescu 82*5074e1d5SCristian Dumitrescu *value = val; 83*5074e1d5SCristian Dumitrescu return 0; 84*5074e1d5SCristian Dumitrescu } 85*5074e1d5SCristian Dumitrescu 86*5074e1d5SCristian Dumitrescu static int 87*5074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p) 88*5074e1d5SCristian Dumitrescu { 89*5074e1d5SCristian Dumitrescu uint64_t val = 0; 90*5074e1d5SCristian Dumitrescu int ret = parser_read_uint64(&val, p); 91*5074e1d5SCristian Dumitrescu 92*5074e1d5SCristian Dumitrescu if (ret < 0) 93*5074e1d5SCristian Dumitrescu return ret; 94*5074e1d5SCristian Dumitrescu 95*5074e1d5SCristian Dumitrescu if (val > UINT32_MAX) 96*5074e1d5SCristian Dumitrescu return -ERANGE; 97*5074e1d5SCristian Dumitrescu 98*5074e1d5SCristian Dumitrescu *value = val; 99*5074e1d5SCristian Dumitrescu return 0; 100*5074e1d5SCristian Dumitrescu } 101*5074e1d5SCristian Dumitrescu 102*5074e1d5SCristian Dumitrescu static int 103*5074e1d5SCristian Dumitrescu parser_read_uint16(uint16_t *value, const char *p) 104*5074e1d5SCristian Dumitrescu { 105*5074e1d5SCristian Dumitrescu uint64_t val = 0; 106*5074e1d5SCristian Dumitrescu int ret = parser_read_uint64(&val, p); 107*5074e1d5SCristian Dumitrescu 108*5074e1d5SCristian Dumitrescu if (ret < 0) 109*5074e1d5SCristian Dumitrescu return ret; 110*5074e1d5SCristian Dumitrescu 111*5074e1d5SCristian Dumitrescu if (val > UINT16_MAX) 112*5074e1d5SCristian Dumitrescu return -ERANGE; 113*5074e1d5SCristian Dumitrescu 114*5074e1d5SCristian Dumitrescu *value = val; 115*5074e1d5SCristian Dumitrescu return 0; 116*5074e1d5SCristian Dumitrescu } 117*5074e1d5SCristian Dumitrescu 118*5074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v" 119*5074e1d5SCristian Dumitrescu 120*5074e1d5SCristian Dumitrescu static int 121*5074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens) 122*5074e1d5SCristian Dumitrescu { 123*5074e1d5SCristian Dumitrescu uint32_t i; 124*5074e1d5SCristian Dumitrescu 125*5074e1d5SCristian Dumitrescu if ((string == NULL) || 126*5074e1d5SCristian Dumitrescu (tokens == NULL) || 127*5074e1d5SCristian Dumitrescu (*n_tokens < 1)) 128*5074e1d5SCristian Dumitrescu return -EINVAL; 129*5074e1d5SCristian Dumitrescu 130*5074e1d5SCristian Dumitrescu for (i = 0; i < *n_tokens; i++) { 131*5074e1d5SCristian Dumitrescu tokens[i] = strtok_r(string, PARSE_DELIMITER, &string); 132*5074e1d5SCristian Dumitrescu if (tokens[i] == NULL) 133*5074e1d5SCristian Dumitrescu break; 134*5074e1d5SCristian Dumitrescu } 135*5074e1d5SCristian Dumitrescu 136*5074e1d5SCristian Dumitrescu if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string)) 137*5074e1d5SCristian Dumitrescu return -E2BIG; 138*5074e1d5SCristian Dumitrescu 139*5074e1d5SCristian Dumitrescu *n_tokens = i; 140*5074e1d5SCristian Dumitrescu return 0; 141*5074e1d5SCristian Dumitrescu } 142*5074e1d5SCristian Dumitrescu 143*5074e1d5SCristian Dumitrescu static int 144*5074e1d5SCristian Dumitrescu is_comment(char *in) 145*5074e1d5SCristian Dumitrescu { 146*5074e1d5SCristian Dumitrescu if ((strlen(in) && index("!#%;", in[0])) || 147*5074e1d5SCristian Dumitrescu (strncmp(in, "//", 2) == 0) || 148*5074e1d5SCristian Dumitrescu (strncmp(in, "--", 2) == 0)) 149*5074e1d5SCristian Dumitrescu return 1; 150*5074e1d5SCristian Dumitrescu 151*5074e1d5SCristian Dumitrescu return 0; 152*5074e1d5SCristian Dumitrescu } 153*5074e1d5SCristian Dumitrescu 154*5074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] = 155*5074e1d5SCristian Dumitrescu "mempool <mempool_name>\n" 156*5074e1d5SCristian Dumitrescu " buffer <buffer_size>\n" 157*5074e1d5SCristian Dumitrescu " pool <pool_size>\n" 158*5074e1d5SCristian Dumitrescu " cache <cache_size>\n" 159*5074e1d5SCristian Dumitrescu " cpu <cpu_id>\n"; 160*5074e1d5SCristian Dumitrescu 161*5074e1d5SCristian Dumitrescu static void 162*5074e1d5SCristian Dumitrescu cmd_mempool(char **tokens, 163*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 164*5074e1d5SCristian Dumitrescu char *out, 165*5074e1d5SCristian Dumitrescu size_t out_size, 166*5074e1d5SCristian Dumitrescu void *obj) 167*5074e1d5SCristian Dumitrescu { 168*5074e1d5SCristian Dumitrescu struct mempool_params p; 169*5074e1d5SCristian Dumitrescu char *name; 170*5074e1d5SCristian Dumitrescu struct mempool *mempool; 171*5074e1d5SCristian Dumitrescu 172*5074e1d5SCristian Dumitrescu if (n_tokens != 10) { 173*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 174*5074e1d5SCristian Dumitrescu return; 175*5074e1d5SCristian Dumitrescu } 176*5074e1d5SCristian Dumitrescu 177*5074e1d5SCristian Dumitrescu name = tokens[1]; 178*5074e1d5SCristian Dumitrescu 179*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "buffer") != 0) { 180*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer"); 181*5074e1d5SCristian Dumitrescu return; 182*5074e1d5SCristian Dumitrescu } 183*5074e1d5SCristian Dumitrescu 184*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) { 185*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size"); 186*5074e1d5SCristian Dumitrescu return; 187*5074e1d5SCristian Dumitrescu } 188*5074e1d5SCristian Dumitrescu 189*5074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "pool") != 0) { 190*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool"); 191*5074e1d5SCristian Dumitrescu return; 192*5074e1d5SCristian Dumitrescu } 193*5074e1d5SCristian Dumitrescu 194*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) { 195*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pool_size"); 196*5074e1d5SCristian Dumitrescu return; 197*5074e1d5SCristian Dumitrescu } 198*5074e1d5SCristian Dumitrescu 199*5074e1d5SCristian Dumitrescu if (strcmp(tokens[6], "cache") != 0) { 200*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache"); 201*5074e1d5SCristian Dumitrescu return; 202*5074e1d5SCristian Dumitrescu } 203*5074e1d5SCristian Dumitrescu 204*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) { 205*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "cache_size"); 206*5074e1d5SCristian Dumitrescu return; 207*5074e1d5SCristian Dumitrescu } 208*5074e1d5SCristian Dumitrescu 209*5074e1d5SCristian Dumitrescu if (strcmp(tokens[8], "cpu") != 0) { 210*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); 211*5074e1d5SCristian Dumitrescu return; 212*5074e1d5SCristian Dumitrescu } 213*5074e1d5SCristian Dumitrescu 214*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) { 215*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); 216*5074e1d5SCristian Dumitrescu return; 217*5074e1d5SCristian Dumitrescu } 218*5074e1d5SCristian Dumitrescu 219*5074e1d5SCristian Dumitrescu mempool = mempool_create(obj, name, &p); 220*5074e1d5SCristian Dumitrescu if (mempool == NULL) { 221*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); 222*5074e1d5SCristian Dumitrescu return; 223*5074e1d5SCristian Dumitrescu } 224*5074e1d5SCristian Dumitrescu } 225*5074e1d5SCristian Dumitrescu 226*5074e1d5SCristian Dumitrescu static const char cmd_link_help[] = 227*5074e1d5SCristian Dumitrescu "link <link_name>\n" 228*5074e1d5SCristian Dumitrescu " dev <device_name> | port <port_id>\n" 229*5074e1d5SCristian Dumitrescu " rxq <n_queues> <queue_size> <mempool_name>\n" 230*5074e1d5SCristian Dumitrescu " txq <n_queues> <queue_size>\n" 231*5074e1d5SCristian Dumitrescu " promiscuous on | off\n" 232*5074e1d5SCristian Dumitrescu " [rss <qid_0> ... <qid_n>]\n"; 233*5074e1d5SCristian Dumitrescu 234*5074e1d5SCristian Dumitrescu static void 235*5074e1d5SCristian Dumitrescu cmd_link(char **tokens, 236*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 237*5074e1d5SCristian Dumitrescu char *out, 238*5074e1d5SCristian Dumitrescu size_t out_size, 239*5074e1d5SCristian Dumitrescu void *obj) 240*5074e1d5SCristian Dumitrescu { 241*5074e1d5SCristian Dumitrescu struct link_params p; 242*5074e1d5SCristian Dumitrescu struct link_params_rss rss; 243*5074e1d5SCristian Dumitrescu struct link *link; 244*5074e1d5SCristian Dumitrescu char *name; 245*5074e1d5SCristian Dumitrescu 246*5074e1d5SCristian Dumitrescu memset(&p, 0, sizeof(p)); 247*5074e1d5SCristian Dumitrescu 248*5074e1d5SCristian Dumitrescu if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) { 249*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 250*5074e1d5SCristian Dumitrescu return; 251*5074e1d5SCristian Dumitrescu } 252*5074e1d5SCristian Dumitrescu name = tokens[1]; 253*5074e1d5SCristian Dumitrescu 254*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "dev") == 0) 255*5074e1d5SCristian Dumitrescu p.dev_name = tokens[3]; 256*5074e1d5SCristian Dumitrescu else if (strcmp(tokens[2], "port") == 0) { 257*5074e1d5SCristian Dumitrescu p.dev_name = NULL; 258*5074e1d5SCristian Dumitrescu 259*5074e1d5SCristian Dumitrescu if (parser_read_uint16(&p.port_id, tokens[3]) != 0) { 260*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); 261*5074e1d5SCristian Dumitrescu return; 262*5074e1d5SCristian Dumitrescu } 263*5074e1d5SCristian Dumitrescu } else { 264*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port"); 265*5074e1d5SCristian Dumitrescu return; 266*5074e1d5SCristian Dumitrescu } 267*5074e1d5SCristian Dumitrescu 268*5074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "rxq") != 0) { 269*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq"); 270*5074e1d5SCristian Dumitrescu return; 271*5074e1d5SCristian Dumitrescu } 272*5074e1d5SCristian Dumitrescu 273*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) { 274*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "n_queues"); 275*5074e1d5SCristian Dumitrescu return; 276*5074e1d5SCristian Dumitrescu } 277*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) { 278*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "queue_size"); 279*5074e1d5SCristian Dumitrescu return; 280*5074e1d5SCristian Dumitrescu } 281*5074e1d5SCristian Dumitrescu 282*5074e1d5SCristian Dumitrescu p.rx.mempool_name = tokens[7]; 283*5074e1d5SCristian Dumitrescu 284*5074e1d5SCristian Dumitrescu if (strcmp(tokens[8], "txq") != 0) { 285*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq"); 286*5074e1d5SCristian Dumitrescu return; 287*5074e1d5SCristian Dumitrescu } 288*5074e1d5SCristian Dumitrescu 289*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) { 290*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "n_queues"); 291*5074e1d5SCristian Dumitrescu return; 292*5074e1d5SCristian Dumitrescu } 293*5074e1d5SCristian Dumitrescu 294*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) { 295*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "queue_size"); 296*5074e1d5SCristian Dumitrescu return; 297*5074e1d5SCristian Dumitrescu } 298*5074e1d5SCristian Dumitrescu 299*5074e1d5SCristian Dumitrescu if (strcmp(tokens[11], "promiscuous") != 0) { 300*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous"); 301*5074e1d5SCristian Dumitrescu return; 302*5074e1d5SCristian Dumitrescu } 303*5074e1d5SCristian Dumitrescu 304*5074e1d5SCristian Dumitrescu if (strcmp(tokens[12], "on") == 0) 305*5074e1d5SCristian Dumitrescu p.promiscuous = 1; 306*5074e1d5SCristian Dumitrescu else if (strcmp(tokens[12], "off") == 0) 307*5074e1d5SCristian Dumitrescu p.promiscuous = 0; 308*5074e1d5SCristian Dumitrescu else { 309*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off"); 310*5074e1d5SCristian Dumitrescu return; 311*5074e1d5SCristian Dumitrescu } 312*5074e1d5SCristian Dumitrescu 313*5074e1d5SCristian Dumitrescu /* RSS */ 314*5074e1d5SCristian Dumitrescu p.rx.rss = NULL; 315*5074e1d5SCristian Dumitrescu if (n_tokens > 13) { 316*5074e1d5SCristian Dumitrescu uint32_t queue_id, i; 317*5074e1d5SCristian Dumitrescu 318*5074e1d5SCristian Dumitrescu if (strcmp(tokens[13], "rss") != 0) { 319*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss"); 320*5074e1d5SCristian Dumitrescu return; 321*5074e1d5SCristian Dumitrescu } 322*5074e1d5SCristian Dumitrescu 323*5074e1d5SCristian Dumitrescu p.rx.rss = &rss; 324*5074e1d5SCristian Dumitrescu 325*5074e1d5SCristian Dumitrescu rss.n_queues = 0; 326*5074e1d5SCristian Dumitrescu for (i = 14; i < n_tokens; i++) { 327*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&queue_id, tokens[i]) != 0) { 328*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 329*5074e1d5SCristian Dumitrescu "queue_id"); 330*5074e1d5SCristian Dumitrescu return; 331*5074e1d5SCristian Dumitrescu } 332*5074e1d5SCristian Dumitrescu 333*5074e1d5SCristian Dumitrescu rss.queue_id[rss.n_queues] = queue_id; 334*5074e1d5SCristian Dumitrescu rss.n_queues++; 335*5074e1d5SCristian Dumitrescu } 336*5074e1d5SCristian Dumitrescu } 337*5074e1d5SCristian Dumitrescu 338*5074e1d5SCristian Dumitrescu link = link_create(obj, name, &p); 339*5074e1d5SCristian Dumitrescu if (link == NULL) { 340*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); 341*5074e1d5SCristian Dumitrescu return; 342*5074e1d5SCristian Dumitrescu } 343*5074e1d5SCristian Dumitrescu } 344*5074e1d5SCristian Dumitrescu 345*5074e1d5SCristian Dumitrescu /* Print the link stats and info */ 346*5074e1d5SCristian Dumitrescu static void 347*5074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size) 348*5074e1d5SCristian Dumitrescu { 349*5074e1d5SCristian Dumitrescu struct rte_eth_stats stats; 350*5074e1d5SCristian Dumitrescu struct rte_ether_addr mac_addr; 351*5074e1d5SCristian Dumitrescu struct rte_eth_link eth_link; 352*5074e1d5SCristian Dumitrescu uint16_t mtu; 353*5074e1d5SCristian Dumitrescu int ret; 354*5074e1d5SCristian Dumitrescu 355*5074e1d5SCristian Dumitrescu memset(&stats, 0, sizeof(stats)); 356*5074e1d5SCristian Dumitrescu rte_eth_stats_get(link->port_id, &stats); 357*5074e1d5SCristian Dumitrescu 358*5074e1d5SCristian Dumitrescu ret = rte_eth_macaddr_get(link->port_id, &mac_addr); 359*5074e1d5SCristian Dumitrescu if (ret != 0) { 360*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s: MAC address get failed: %s", 361*5074e1d5SCristian Dumitrescu link->name, rte_strerror(-ret)); 362*5074e1d5SCristian Dumitrescu return; 363*5074e1d5SCristian Dumitrescu } 364*5074e1d5SCristian Dumitrescu 365*5074e1d5SCristian Dumitrescu ret = rte_eth_link_get(link->port_id, ð_link); 366*5074e1d5SCristian Dumitrescu if (ret < 0) { 367*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s: link get failed: %s", 368*5074e1d5SCristian Dumitrescu link->name, rte_strerror(-ret)); 369*5074e1d5SCristian Dumitrescu return; 370*5074e1d5SCristian Dumitrescu } 371*5074e1d5SCristian Dumitrescu 372*5074e1d5SCristian Dumitrescu rte_eth_dev_get_mtu(link->port_id, &mtu); 373*5074e1d5SCristian Dumitrescu 374*5074e1d5SCristian Dumitrescu snprintf(out, out_size, 375*5074e1d5SCristian Dumitrescu "\n" 376*5074e1d5SCristian Dumitrescu "%s: flags=<%s> mtu %u\n" 377*5074e1d5SCristian Dumitrescu "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n" 378*5074e1d5SCristian Dumitrescu "\tport# %u speed %s\n" 379*5074e1d5SCristian Dumitrescu "\tRX packets %" PRIu64" bytes %" PRIu64"\n" 380*5074e1d5SCristian Dumitrescu "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n" 381*5074e1d5SCristian Dumitrescu "\tTX packets %" PRIu64" bytes %" PRIu64"\n" 382*5074e1d5SCristian Dumitrescu "\tTX errors %" PRIu64"\n", 383*5074e1d5SCristian Dumitrescu link->name, 384*5074e1d5SCristian Dumitrescu eth_link.link_status == 0 ? "DOWN" : "UP", 385*5074e1d5SCristian Dumitrescu mtu, 386*5074e1d5SCristian Dumitrescu mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 387*5074e1d5SCristian Dumitrescu mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 388*5074e1d5SCristian Dumitrescu mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], 389*5074e1d5SCristian Dumitrescu link->n_rxq, 390*5074e1d5SCristian Dumitrescu link->n_txq, 391*5074e1d5SCristian Dumitrescu link->port_id, 392*5074e1d5SCristian Dumitrescu rte_eth_link_speed_to_str(eth_link.link_speed), 393*5074e1d5SCristian Dumitrescu stats.ipackets, 394*5074e1d5SCristian Dumitrescu stats.ibytes, 395*5074e1d5SCristian Dumitrescu stats.ierrors, 396*5074e1d5SCristian Dumitrescu stats.imissed, 397*5074e1d5SCristian Dumitrescu stats.rx_nombuf, 398*5074e1d5SCristian Dumitrescu stats.opackets, 399*5074e1d5SCristian Dumitrescu stats.obytes, 400*5074e1d5SCristian Dumitrescu stats.oerrors); 401*5074e1d5SCristian Dumitrescu } 402*5074e1d5SCristian Dumitrescu 403*5074e1d5SCristian Dumitrescu /* 404*5074e1d5SCristian Dumitrescu * link show [<link_name>] 405*5074e1d5SCristian Dumitrescu */ 406*5074e1d5SCristian Dumitrescu static void 407*5074e1d5SCristian Dumitrescu cmd_link_show(char **tokens, 408*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 409*5074e1d5SCristian Dumitrescu char *out, 410*5074e1d5SCristian Dumitrescu size_t out_size, 411*5074e1d5SCristian Dumitrescu void *obj) 412*5074e1d5SCristian Dumitrescu { 413*5074e1d5SCristian Dumitrescu struct link *link; 414*5074e1d5SCristian Dumitrescu char *link_name; 415*5074e1d5SCristian Dumitrescu 416*5074e1d5SCristian Dumitrescu if (n_tokens != 2 && n_tokens != 3) { 417*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 418*5074e1d5SCristian Dumitrescu return; 419*5074e1d5SCristian Dumitrescu } 420*5074e1d5SCristian Dumitrescu 421*5074e1d5SCristian Dumitrescu if (n_tokens == 2) { 422*5074e1d5SCristian Dumitrescu link = link_next(obj, NULL); 423*5074e1d5SCristian Dumitrescu 424*5074e1d5SCristian Dumitrescu while (link != NULL) { 425*5074e1d5SCristian Dumitrescu out_size = out_size - strlen(out); 426*5074e1d5SCristian Dumitrescu out = &out[strlen(out)]; 427*5074e1d5SCristian Dumitrescu 428*5074e1d5SCristian Dumitrescu print_link_info(link, out, out_size); 429*5074e1d5SCristian Dumitrescu link = link_next(obj, link); 430*5074e1d5SCristian Dumitrescu } 431*5074e1d5SCristian Dumitrescu } else { 432*5074e1d5SCristian Dumitrescu out_size = out_size - strlen(out); 433*5074e1d5SCristian Dumitrescu out = &out[strlen(out)]; 434*5074e1d5SCristian Dumitrescu 435*5074e1d5SCristian Dumitrescu link_name = tokens[2]; 436*5074e1d5SCristian Dumitrescu link = link_find(obj, link_name); 437*5074e1d5SCristian Dumitrescu 438*5074e1d5SCristian Dumitrescu if (link == NULL) { 439*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 440*5074e1d5SCristian Dumitrescu "Link does not exist"); 441*5074e1d5SCristian Dumitrescu return; 442*5074e1d5SCristian Dumitrescu } 443*5074e1d5SCristian Dumitrescu print_link_info(link, out, out_size); 444*5074e1d5SCristian Dumitrescu } 445*5074e1d5SCristian Dumitrescu } 446*5074e1d5SCristian Dumitrescu 447*5074e1d5SCristian Dumitrescu static const char cmd_pipeline_create_help[] = 448*5074e1d5SCristian Dumitrescu "pipeline <pipeline_name> create <numa_node>\n"; 449*5074e1d5SCristian Dumitrescu 450*5074e1d5SCristian Dumitrescu static void 451*5074e1d5SCristian Dumitrescu cmd_pipeline_create(char **tokens, 452*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 453*5074e1d5SCristian Dumitrescu char *out, 454*5074e1d5SCristian Dumitrescu size_t out_size, 455*5074e1d5SCristian Dumitrescu void *obj) 456*5074e1d5SCristian Dumitrescu { 457*5074e1d5SCristian Dumitrescu struct pipeline *p; 458*5074e1d5SCristian Dumitrescu char *name; 459*5074e1d5SCristian Dumitrescu uint32_t numa_node; 460*5074e1d5SCristian Dumitrescu 461*5074e1d5SCristian Dumitrescu if (n_tokens != 4) { 462*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 463*5074e1d5SCristian Dumitrescu return; 464*5074e1d5SCristian Dumitrescu } 465*5074e1d5SCristian Dumitrescu 466*5074e1d5SCristian Dumitrescu name = tokens[1]; 467*5074e1d5SCristian Dumitrescu 468*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&numa_node, tokens[3]) != 0) { 469*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); 470*5074e1d5SCristian Dumitrescu return; 471*5074e1d5SCristian Dumitrescu } 472*5074e1d5SCristian Dumitrescu 473*5074e1d5SCristian Dumitrescu p = pipeline_create(obj, name, (int)numa_node); 474*5074e1d5SCristian Dumitrescu if (!p) { 475*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "pipeline create error."); 476*5074e1d5SCristian Dumitrescu return; 477*5074e1d5SCristian Dumitrescu } 478*5074e1d5SCristian Dumitrescu } 479*5074e1d5SCristian Dumitrescu 480*5074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_in_help[] = 481*5074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port in <port_id>\n" 482*5074e1d5SCristian Dumitrescu " link <link_name> rxq <queue_id> bsz <burst_size>\n" 483*5074e1d5SCristian Dumitrescu " source <mempool_name> <fie_name>\n"; 484*5074e1d5SCristian Dumitrescu 485*5074e1d5SCristian Dumitrescu static void 486*5074e1d5SCristian Dumitrescu cmd_pipeline_port_in(char **tokens, 487*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 488*5074e1d5SCristian Dumitrescu char *out, 489*5074e1d5SCristian Dumitrescu size_t out_size, 490*5074e1d5SCristian Dumitrescu void *obj) 491*5074e1d5SCristian Dumitrescu { 492*5074e1d5SCristian Dumitrescu struct pipeline *p; 493*5074e1d5SCristian Dumitrescu int status; 494*5074e1d5SCristian Dumitrescu uint32_t port_id = 0, t0; 495*5074e1d5SCristian Dumitrescu 496*5074e1d5SCristian Dumitrescu if (n_tokens < 6) { 497*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 498*5074e1d5SCristian Dumitrescu return; 499*5074e1d5SCristian Dumitrescu } 500*5074e1d5SCristian Dumitrescu 501*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 502*5074e1d5SCristian Dumitrescu if (!p || p->ctl) { 503*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 504*5074e1d5SCristian Dumitrescu return; 505*5074e1d5SCristian Dumitrescu } 506*5074e1d5SCristian Dumitrescu 507*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "port") != 0) { 508*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port"); 509*5074e1d5SCristian Dumitrescu return; 510*5074e1d5SCristian Dumitrescu } 511*5074e1d5SCristian Dumitrescu 512*5074e1d5SCristian Dumitrescu if (strcmp(tokens[3], "in") != 0) { 513*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in"); 514*5074e1d5SCristian Dumitrescu return; 515*5074e1d5SCristian Dumitrescu } 516*5074e1d5SCristian Dumitrescu 517*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&port_id, tokens[4]) != 0) { 518*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); 519*5074e1d5SCristian Dumitrescu return; 520*5074e1d5SCristian Dumitrescu } 521*5074e1d5SCristian Dumitrescu 522*5074e1d5SCristian Dumitrescu t0 = 5; 523*5074e1d5SCristian Dumitrescu 524*5074e1d5SCristian Dumitrescu if (strcmp(tokens[t0], "link") == 0) { 525*5074e1d5SCristian Dumitrescu struct rte_swx_port_ethdev_reader_params params; 526*5074e1d5SCristian Dumitrescu struct link *link; 527*5074e1d5SCristian Dumitrescu 528*5074e1d5SCristian Dumitrescu if (n_tokens < t0 + 6) { 529*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, 530*5074e1d5SCristian Dumitrescu "pipeline port in link"); 531*5074e1d5SCristian Dumitrescu return; 532*5074e1d5SCristian Dumitrescu } 533*5074e1d5SCristian Dumitrescu 534*5074e1d5SCristian Dumitrescu link = link_find(obj, tokens[t0 + 1]); 535*5074e1d5SCristian Dumitrescu if (!link) { 536*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 537*5074e1d5SCristian Dumitrescu "link_name"); 538*5074e1d5SCristian Dumitrescu return; 539*5074e1d5SCristian Dumitrescu } 540*5074e1d5SCristian Dumitrescu params.dev_name = link->dev_name; 541*5074e1d5SCristian Dumitrescu 542*5074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 2], "rxq") != 0) { 543*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq"); 544*5074e1d5SCristian Dumitrescu return; 545*5074e1d5SCristian Dumitrescu } 546*5074e1d5SCristian Dumitrescu 547*5074e1d5SCristian Dumitrescu if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) { 548*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 549*5074e1d5SCristian Dumitrescu "queue_id"); 550*5074e1d5SCristian Dumitrescu return; 551*5074e1d5SCristian Dumitrescu } 552*5074e1d5SCristian Dumitrescu 553*5074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 4], "bsz") != 0) { 554*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz"); 555*5074e1d5SCristian Dumitrescu return; 556*5074e1d5SCristian Dumitrescu } 557*5074e1d5SCristian Dumitrescu 558*5074e1d5SCristian Dumitrescu if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) { 559*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 560*5074e1d5SCristian Dumitrescu "burst_size"); 561*5074e1d5SCristian Dumitrescu return; 562*5074e1d5SCristian Dumitrescu } 563*5074e1d5SCristian Dumitrescu 564*5074e1d5SCristian Dumitrescu t0 += 6; 565*5074e1d5SCristian Dumitrescu 566*5074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_in_config(p->p, 567*5074e1d5SCristian Dumitrescu port_id, 568*5074e1d5SCristian Dumitrescu "ethdev", 569*5074e1d5SCristian Dumitrescu ¶ms); 570*5074e1d5SCristian Dumitrescu } else if (strcmp(tokens[t0], "source") == 0) { 571*5074e1d5SCristian Dumitrescu struct rte_swx_port_source_params params; 572*5074e1d5SCristian Dumitrescu struct mempool *mp; 573*5074e1d5SCristian Dumitrescu 574*5074e1d5SCristian Dumitrescu if (n_tokens < t0 + 3) { 575*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, 576*5074e1d5SCristian Dumitrescu "pipeline port in source"); 577*5074e1d5SCristian Dumitrescu return; 578*5074e1d5SCristian Dumitrescu } 579*5074e1d5SCristian Dumitrescu 580*5074e1d5SCristian Dumitrescu mp = mempool_find(obj, tokens[t0 + 1]); 581*5074e1d5SCristian Dumitrescu if (!mp) { 582*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 583*5074e1d5SCristian Dumitrescu "mempool_name"); 584*5074e1d5SCristian Dumitrescu return; 585*5074e1d5SCristian Dumitrescu } 586*5074e1d5SCristian Dumitrescu params.pool = mp->m; 587*5074e1d5SCristian Dumitrescu 588*5074e1d5SCristian Dumitrescu params.file_name = tokens[t0 + 2]; 589*5074e1d5SCristian Dumitrescu 590*5074e1d5SCristian Dumitrescu t0 += 3; 591*5074e1d5SCristian Dumitrescu 592*5074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_in_config(p->p, 593*5074e1d5SCristian Dumitrescu port_id, 594*5074e1d5SCristian Dumitrescu "source", 595*5074e1d5SCristian Dumitrescu ¶ms); 596*5074e1d5SCristian Dumitrescu } else { 597*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 598*5074e1d5SCristian Dumitrescu return; 599*5074e1d5SCristian Dumitrescu } 600*5074e1d5SCristian Dumitrescu 601*5074e1d5SCristian Dumitrescu if (status) { 602*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "port in error."); 603*5074e1d5SCristian Dumitrescu return; 604*5074e1d5SCristian Dumitrescu } 605*5074e1d5SCristian Dumitrescu 606*5074e1d5SCristian Dumitrescu if (n_tokens != t0) { 607*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 608*5074e1d5SCristian Dumitrescu return; 609*5074e1d5SCristian Dumitrescu } 610*5074e1d5SCristian Dumitrescu } 611*5074e1d5SCristian Dumitrescu 612*5074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_out_help[] = 613*5074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port out <port_id>\n" 614*5074e1d5SCristian Dumitrescu " link <link_name> txq <txq_id> bsz <burst_size>\n" 615*5074e1d5SCristian Dumitrescu " | sink <file_name> | none\n"; 616*5074e1d5SCristian Dumitrescu 617*5074e1d5SCristian Dumitrescu static void 618*5074e1d5SCristian Dumitrescu cmd_pipeline_port_out(char **tokens, 619*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 620*5074e1d5SCristian Dumitrescu char *out, 621*5074e1d5SCristian Dumitrescu size_t out_size, 622*5074e1d5SCristian Dumitrescu void *obj) 623*5074e1d5SCristian Dumitrescu { 624*5074e1d5SCristian Dumitrescu struct pipeline *p; 625*5074e1d5SCristian Dumitrescu int status; 626*5074e1d5SCristian Dumitrescu uint32_t port_id = 0, t0; 627*5074e1d5SCristian Dumitrescu 628*5074e1d5SCristian Dumitrescu if (n_tokens < 6) { 629*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 630*5074e1d5SCristian Dumitrescu return; 631*5074e1d5SCristian Dumitrescu } 632*5074e1d5SCristian Dumitrescu 633*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 634*5074e1d5SCristian Dumitrescu if (!p || p->ctl) { 635*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 636*5074e1d5SCristian Dumitrescu return; 637*5074e1d5SCristian Dumitrescu } 638*5074e1d5SCristian Dumitrescu 639*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "port") != 0) { 640*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port"); 641*5074e1d5SCristian Dumitrescu return; 642*5074e1d5SCristian Dumitrescu } 643*5074e1d5SCristian Dumitrescu 644*5074e1d5SCristian Dumitrescu if (strcmp(tokens[3], "out") != 0) { 645*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out"); 646*5074e1d5SCristian Dumitrescu return; 647*5074e1d5SCristian Dumitrescu } 648*5074e1d5SCristian Dumitrescu 649*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&port_id, tokens[4]) != 0) { 650*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); 651*5074e1d5SCristian Dumitrescu return; 652*5074e1d5SCristian Dumitrescu } 653*5074e1d5SCristian Dumitrescu 654*5074e1d5SCristian Dumitrescu t0 = 5; 655*5074e1d5SCristian Dumitrescu 656*5074e1d5SCristian Dumitrescu if (strcmp(tokens[t0], "link") == 0) { 657*5074e1d5SCristian Dumitrescu struct rte_swx_port_ethdev_writer_params params; 658*5074e1d5SCristian Dumitrescu struct link *link; 659*5074e1d5SCristian Dumitrescu 660*5074e1d5SCristian Dumitrescu if (n_tokens < t0 + 6) { 661*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, 662*5074e1d5SCristian Dumitrescu "pipeline port out link"); 663*5074e1d5SCristian Dumitrescu return; 664*5074e1d5SCristian Dumitrescu } 665*5074e1d5SCristian Dumitrescu 666*5074e1d5SCristian Dumitrescu link = link_find(obj, tokens[t0 + 1]); 667*5074e1d5SCristian Dumitrescu if (!link) { 668*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 669*5074e1d5SCristian Dumitrescu "link_name"); 670*5074e1d5SCristian Dumitrescu return; 671*5074e1d5SCristian Dumitrescu } 672*5074e1d5SCristian Dumitrescu params.dev_name = link->dev_name; 673*5074e1d5SCristian Dumitrescu 674*5074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 2], "txq") != 0) { 675*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq"); 676*5074e1d5SCristian Dumitrescu return; 677*5074e1d5SCristian Dumitrescu } 678*5074e1d5SCristian Dumitrescu 679*5074e1d5SCristian Dumitrescu if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) { 680*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 681*5074e1d5SCristian Dumitrescu "queue_id"); 682*5074e1d5SCristian Dumitrescu return; 683*5074e1d5SCristian Dumitrescu } 684*5074e1d5SCristian Dumitrescu 685*5074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 4], "bsz") != 0) { 686*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz"); 687*5074e1d5SCristian Dumitrescu return; 688*5074e1d5SCristian Dumitrescu } 689*5074e1d5SCristian Dumitrescu 690*5074e1d5SCristian Dumitrescu if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) { 691*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 692*5074e1d5SCristian Dumitrescu "burst_size"); 693*5074e1d5SCristian Dumitrescu return; 694*5074e1d5SCristian Dumitrescu } 695*5074e1d5SCristian Dumitrescu 696*5074e1d5SCristian Dumitrescu t0 += 6; 697*5074e1d5SCristian Dumitrescu 698*5074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_out_config(p->p, 699*5074e1d5SCristian Dumitrescu port_id, 700*5074e1d5SCristian Dumitrescu "ethdev", 701*5074e1d5SCristian Dumitrescu ¶ms); 702*5074e1d5SCristian Dumitrescu } else if (strcmp(tokens[t0], "sink") == 0) { 703*5074e1d5SCristian Dumitrescu struct rte_swx_port_sink_params params; 704*5074e1d5SCristian Dumitrescu 705*5074e1d5SCristian Dumitrescu params.file_name = strcmp(tokens[t0 + 1], "none") ? 706*5074e1d5SCristian Dumitrescu tokens[t0 + 1] : NULL; 707*5074e1d5SCristian Dumitrescu 708*5074e1d5SCristian Dumitrescu t0 += 2; 709*5074e1d5SCristian Dumitrescu 710*5074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_out_config(p->p, 711*5074e1d5SCristian Dumitrescu port_id, 712*5074e1d5SCristian Dumitrescu "sink", 713*5074e1d5SCristian Dumitrescu ¶ms); 714*5074e1d5SCristian Dumitrescu } else { 715*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 716*5074e1d5SCristian Dumitrescu return; 717*5074e1d5SCristian Dumitrescu } 718*5074e1d5SCristian Dumitrescu 719*5074e1d5SCristian Dumitrescu if (status) { 720*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "port out error."); 721*5074e1d5SCristian Dumitrescu return; 722*5074e1d5SCristian Dumitrescu } 723*5074e1d5SCristian Dumitrescu 724*5074e1d5SCristian Dumitrescu if (n_tokens != t0) { 725*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 726*5074e1d5SCristian Dumitrescu return; 727*5074e1d5SCristian Dumitrescu } 728*5074e1d5SCristian Dumitrescu } 729*5074e1d5SCristian Dumitrescu 730*5074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] = 731*5074e1d5SCristian Dumitrescu "pipeline <pipeline_name> build <spec_file>\n"; 732*5074e1d5SCristian Dumitrescu 733*5074e1d5SCristian Dumitrescu static void 734*5074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens, 735*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 736*5074e1d5SCristian Dumitrescu char *out, 737*5074e1d5SCristian Dumitrescu size_t out_size, 738*5074e1d5SCristian Dumitrescu void *obj) 739*5074e1d5SCristian Dumitrescu { 740*5074e1d5SCristian Dumitrescu struct pipeline *p = NULL; 741*5074e1d5SCristian Dumitrescu FILE *spec = NULL; 742*5074e1d5SCristian Dumitrescu uint32_t err_line; 743*5074e1d5SCristian Dumitrescu const char *err_msg; 744*5074e1d5SCristian Dumitrescu int status; 745*5074e1d5SCristian Dumitrescu 746*5074e1d5SCristian Dumitrescu if (n_tokens != 4) { 747*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 748*5074e1d5SCristian Dumitrescu return; 749*5074e1d5SCristian Dumitrescu } 750*5074e1d5SCristian Dumitrescu 751*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 752*5074e1d5SCristian Dumitrescu if (!p || p->ctl) { 753*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 754*5074e1d5SCristian Dumitrescu return; 755*5074e1d5SCristian Dumitrescu } 756*5074e1d5SCristian Dumitrescu 757*5074e1d5SCristian Dumitrescu spec = fopen(tokens[3], "r"); 758*5074e1d5SCristian Dumitrescu if (!spec) { 759*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]); 760*5074e1d5SCristian Dumitrescu return; 761*5074e1d5SCristian Dumitrescu } 762*5074e1d5SCristian Dumitrescu 763*5074e1d5SCristian Dumitrescu status = rte_swx_pipeline_build_from_spec(p->p, 764*5074e1d5SCristian Dumitrescu spec, 765*5074e1d5SCristian Dumitrescu &err_line, 766*5074e1d5SCristian Dumitrescu &err_msg); 767*5074e1d5SCristian Dumitrescu fclose(spec); 768*5074e1d5SCristian Dumitrescu if (status) { 769*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Error %d at line %u: %s\n.", 770*5074e1d5SCristian Dumitrescu status, err_line, err_msg); 771*5074e1d5SCristian Dumitrescu return; 772*5074e1d5SCristian Dumitrescu } 773*5074e1d5SCristian Dumitrescu 774*5074e1d5SCristian Dumitrescu p->ctl = rte_swx_ctl_pipeline_create(p->p); 775*5074e1d5SCristian Dumitrescu if (!p->ctl) { 776*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Pipeline control create failed."); 777*5074e1d5SCristian Dumitrescu rte_swx_pipeline_free(p->p); 778*5074e1d5SCristian Dumitrescu return; 779*5074e1d5SCristian Dumitrescu } 780*5074e1d5SCristian Dumitrescu } 781*5074e1d5SCristian Dumitrescu 782*5074e1d5SCristian Dumitrescu static const char cmd_pipeline_table_update_help[] = 783*5074e1d5SCristian Dumitrescu "pipeline <pipeline_name> table <table_name> update <file_name_add> " 784*5074e1d5SCristian Dumitrescu "<file_name_delete> <file_name_default>"; 785*5074e1d5SCristian Dumitrescu 786*5074e1d5SCristian Dumitrescu static void 787*5074e1d5SCristian Dumitrescu cmd_pipeline_table_update(char **tokens, 788*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 789*5074e1d5SCristian Dumitrescu char *out, 790*5074e1d5SCristian Dumitrescu size_t out_size, 791*5074e1d5SCristian Dumitrescu void *obj) 792*5074e1d5SCristian Dumitrescu { 793*5074e1d5SCristian Dumitrescu struct pipeline *p; 794*5074e1d5SCristian Dumitrescu char *pipeline_name, *table_name, *line = NULL; 795*5074e1d5SCristian Dumitrescu char *file_name_add, *file_name_delete, *file_name_default; 796*5074e1d5SCristian Dumitrescu FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL; 797*5074e1d5SCristian Dumitrescu uint32_t line_id; 798*5074e1d5SCristian Dumitrescu int status; 799*5074e1d5SCristian Dumitrescu 800*5074e1d5SCristian Dumitrescu if (n_tokens != 8) { 801*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 802*5074e1d5SCristian Dumitrescu return; 803*5074e1d5SCristian Dumitrescu } 804*5074e1d5SCristian Dumitrescu 805*5074e1d5SCristian Dumitrescu pipeline_name = tokens[1]; 806*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, pipeline_name); 807*5074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 808*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 809*5074e1d5SCristian Dumitrescu return; 810*5074e1d5SCristian Dumitrescu } 811*5074e1d5SCristian Dumitrescu 812*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "table") != 0) { 813*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table"); 814*5074e1d5SCristian Dumitrescu return; 815*5074e1d5SCristian Dumitrescu } 816*5074e1d5SCristian Dumitrescu 817*5074e1d5SCristian Dumitrescu table_name = tokens[3]; 818*5074e1d5SCristian Dumitrescu 819*5074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "update") != 0) { 820*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update"); 821*5074e1d5SCristian Dumitrescu return; 822*5074e1d5SCristian Dumitrescu } 823*5074e1d5SCristian Dumitrescu 824*5074e1d5SCristian Dumitrescu file_name_add = tokens[5]; 825*5074e1d5SCristian Dumitrescu file_name_delete = tokens[6]; 826*5074e1d5SCristian Dumitrescu file_name_default = tokens[7]; 827*5074e1d5SCristian Dumitrescu 828*5074e1d5SCristian Dumitrescu /* File open. */ 829*5074e1d5SCristian Dumitrescu if (strcmp(file_name_add, "none")) { 830*5074e1d5SCristian Dumitrescu file_add = fopen(file_name_add, "r"); 831*5074e1d5SCristian Dumitrescu if (!file_add) { 832*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s", 833*5074e1d5SCristian Dumitrescu file_name_add); 834*5074e1d5SCristian Dumitrescu goto error; 835*5074e1d5SCristian Dumitrescu } 836*5074e1d5SCristian Dumitrescu } 837*5074e1d5SCristian Dumitrescu 838*5074e1d5SCristian Dumitrescu if (strcmp(file_name_delete, "none")) { 839*5074e1d5SCristian Dumitrescu file_add = fopen(file_name_delete, "r"); 840*5074e1d5SCristian Dumitrescu if (!file_add) { 841*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s", 842*5074e1d5SCristian Dumitrescu file_name_delete); 843*5074e1d5SCristian Dumitrescu goto error; 844*5074e1d5SCristian Dumitrescu } 845*5074e1d5SCristian Dumitrescu } 846*5074e1d5SCristian Dumitrescu 847*5074e1d5SCristian Dumitrescu if (strcmp(file_name_default, "none")) { 848*5074e1d5SCristian Dumitrescu file_add = fopen(file_name_default, "r"); 849*5074e1d5SCristian Dumitrescu if (!file_add) { 850*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s", 851*5074e1d5SCristian Dumitrescu file_name_default); 852*5074e1d5SCristian Dumitrescu goto error; 853*5074e1d5SCristian Dumitrescu } 854*5074e1d5SCristian Dumitrescu } 855*5074e1d5SCristian Dumitrescu 856*5074e1d5SCristian Dumitrescu if (!file_add && !file_delete && !file_default) { 857*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Nothing to be done."); 858*5074e1d5SCristian Dumitrescu return; 859*5074e1d5SCristian Dumitrescu } 860*5074e1d5SCristian Dumitrescu 861*5074e1d5SCristian Dumitrescu /* Buffer allocation. */ 862*5074e1d5SCristian Dumitrescu line = malloc(2048); 863*5074e1d5SCristian Dumitrescu if (!line) { 864*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_OUT_OF_MEMORY); 865*5074e1d5SCristian Dumitrescu goto error; 866*5074e1d5SCristian Dumitrescu } 867*5074e1d5SCristian Dumitrescu 868*5074e1d5SCristian Dumitrescu /* Add. */ 869*5074e1d5SCristian Dumitrescu if (file_add) { 870*5074e1d5SCristian Dumitrescu for (line_id = 1; ; line_id++) { 871*5074e1d5SCristian Dumitrescu struct rte_swx_table_entry *entry; 872*5074e1d5SCristian Dumitrescu 873*5074e1d5SCristian Dumitrescu if (fgets(line, 2048, file_add) == NULL) 874*5074e1d5SCristian Dumitrescu break; 875*5074e1d5SCristian Dumitrescu 876*5074e1d5SCristian Dumitrescu entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, 877*5074e1d5SCristian Dumitrescu table_name, 878*5074e1d5SCristian Dumitrescu line); 879*5074e1d5SCristian Dumitrescu if (!entry) { 880*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_FILE_ERR, 881*5074e1d5SCristian Dumitrescu file_name_add, line_id); 882*5074e1d5SCristian Dumitrescu goto error; 883*5074e1d5SCristian Dumitrescu } 884*5074e1d5SCristian Dumitrescu 885*5074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_table_entry_add(p->ctl, 886*5074e1d5SCristian Dumitrescu table_name, 887*5074e1d5SCristian Dumitrescu entry); 888*5074e1d5SCristian Dumitrescu if (status) { 889*5074e1d5SCristian Dumitrescu snprintf(out, out_size, 890*5074e1d5SCristian Dumitrescu "Invalid entry in file %s at line %u", 891*5074e1d5SCristian Dumitrescu file_name_add, line_id); 892*5074e1d5SCristian Dumitrescu goto error; 893*5074e1d5SCristian Dumitrescu } 894*5074e1d5SCristian Dumitrescu } 895*5074e1d5SCristian Dumitrescu 896*5074e1d5SCristian Dumitrescu fclose(file_add); 897*5074e1d5SCristian Dumitrescu } 898*5074e1d5SCristian Dumitrescu 899*5074e1d5SCristian Dumitrescu /* Delete. */ 900*5074e1d5SCristian Dumitrescu if (file_delete) { 901*5074e1d5SCristian Dumitrescu for (line_id = 1; ; line_id++) { 902*5074e1d5SCristian Dumitrescu struct rte_swx_table_entry *entry; 903*5074e1d5SCristian Dumitrescu 904*5074e1d5SCristian Dumitrescu if (fgets(line, 2048, file_delete) == NULL) 905*5074e1d5SCristian Dumitrescu break; 906*5074e1d5SCristian Dumitrescu 907*5074e1d5SCristian Dumitrescu entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, 908*5074e1d5SCristian Dumitrescu table_name, 909*5074e1d5SCristian Dumitrescu line); 910*5074e1d5SCristian Dumitrescu if (!entry) { 911*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_FILE_ERR, 912*5074e1d5SCristian Dumitrescu file_name_delete, line_id); 913*5074e1d5SCristian Dumitrescu goto error; 914*5074e1d5SCristian Dumitrescu } 915*5074e1d5SCristian Dumitrescu 916*5074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl, 917*5074e1d5SCristian Dumitrescu table_name, 918*5074e1d5SCristian Dumitrescu entry); 919*5074e1d5SCristian Dumitrescu if (status) { 920*5074e1d5SCristian Dumitrescu snprintf(out, out_size, 921*5074e1d5SCristian Dumitrescu "Invalid entry in file %s at line %u", 922*5074e1d5SCristian Dumitrescu file_name_delete, line_id); 923*5074e1d5SCristian Dumitrescu goto error; 924*5074e1d5SCristian Dumitrescu } 925*5074e1d5SCristian Dumitrescu } 926*5074e1d5SCristian Dumitrescu 927*5074e1d5SCristian Dumitrescu fclose(file_delete); 928*5074e1d5SCristian Dumitrescu } 929*5074e1d5SCristian Dumitrescu 930*5074e1d5SCristian Dumitrescu /* Default. */ 931*5074e1d5SCristian Dumitrescu if (file_default) { 932*5074e1d5SCristian Dumitrescu for (line_id = 1; ; line_id++) { 933*5074e1d5SCristian Dumitrescu struct rte_swx_table_entry *entry; 934*5074e1d5SCristian Dumitrescu 935*5074e1d5SCristian Dumitrescu if (fgets(line, 2048, file_default) == NULL) 936*5074e1d5SCristian Dumitrescu break; 937*5074e1d5SCristian Dumitrescu 938*5074e1d5SCristian Dumitrescu entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, 939*5074e1d5SCristian Dumitrescu table_name, 940*5074e1d5SCristian Dumitrescu line); 941*5074e1d5SCristian Dumitrescu if (!entry) { 942*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_FILE_ERR, 943*5074e1d5SCristian Dumitrescu file_name_default, line_id); 944*5074e1d5SCristian Dumitrescu goto error; 945*5074e1d5SCristian Dumitrescu } 946*5074e1d5SCristian Dumitrescu 947*5074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl, 948*5074e1d5SCristian Dumitrescu table_name, 949*5074e1d5SCristian Dumitrescu entry); 950*5074e1d5SCristian Dumitrescu if (status) { 951*5074e1d5SCristian Dumitrescu snprintf(out, out_size, 952*5074e1d5SCristian Dumitrescu "Invalid entry in file %s at line %u", 953*5074e1d5SCristian Dumitrescu file_name_default, line_id); 954*5074e1d5SCristian Dumitrescu goto error; 955*5074e1d5SCristian Dumitrescu } 956*5074e1d5SCristian Dumitrescu } 957*5074e1d5SCristian Dumitrescu 958*5074e1d5SCristian Dumitrescu fclose(file_default); 959*5074e1d5SCristian Dumitrescu } 960*5074e1d5SCristian Dumitrescu 961*5074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_commit(p->ctl, 1); 962*5074e1d5SCristian Dumitrescu if (status) { 963*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Commit failed."); 964*5074e1d5SCristian Dumitrescu goto error; 965*5074e1d5SCristian Dumitrescu } 966*5074e1d5SCristian Dumitrescu 967*5074e1d5SCristian Dumitrescu free(line); 968*5074e1d5SCristian Dumitrescu 969*5074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name); 970*5074e1d5SCristian Dumitrescu 971*5074e1d5SCristian Dumitrescu return; 972*5074e1d5SCristian Dumitrescu 973*5074e1d5SCristian Dumitrescu error: 974*5074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_abort(p->ctl); 975*5074e1d5SCristian Dumitrescu free(line); 976*5074e1d5SCristian Dumitrescu if (file_add) 977*5074e1d5SCristian Dumitrescu fclose(file_add); 978*5074e1d5SCristian Dumitrescu if (file_delete) 979*5074e1d5SCristian Dumitrescu fclose(file_delete); 980*5074e1d5SCristian Dumitrescu if (file_default) 981*5074e1d5SCristian Dumitrescu fclose(file_default); 982*5074e1d5SCristian Dumitrescu } 983*5074e1d5SCristian Dumitrescu 984*5074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] = 985*5074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n"; 986*5074e1d5SCristian Dumitrescu 987*5074e1d5SCristian Dumitrescu static void 988*5074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens, 989*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 990*5074e1d5SCristian Dumitrescu char *out, 991*5074e1d5SCristian Dumitrescu size_t out_size, 992*5074e1d5SCristian Dumitrescu void *obj) 993*5074e1d5SCristian Dumitrescu { 994*5074e1d5SCristian Dumitrescu struct rte_swx_ctl_pipeline_info info; 995*5074e1d5SCristian Dumitrescu struct pipeline *p; 996*5074e1d5SCristian Dumitrescu uint32_t i; 997*5074e1d5SCristian Dumitrescu int status; 998*5074e1d5SCristian Dumitrescu 999*5074e1d5SCristian Dumitrescu if (n_tokens != 3) { 1000*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 1001*5074e1d5SCristian Dumitrescu return; 1002*5074e1d5SCristian Dumitrescu } 1003*5074e1d5SCristian Dumitrescu 1004*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 1005*5074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 1006*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 1007*5074e1d5SCristian Dumitrescu return; 1008*5074e1d5SCristian Dumitrescu } 1009*5074e1d5SCristian Dumitrescu 1010*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "stats")) { 1011*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats"); 1012*5074e1d5SCristian Dumitrescu return; 1013*5074e1d5SCristian Dumitrescu } 1014*5074e1d5SCristian Dumitrescu 1015*5074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_info_get(p->p, &info); 1016*5074e1d5SCristian Dumitrescu if (status) { 1017*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Pipeline info get error."); 1018*5074e1d5SCristian Dumitrescu return; 1019*5074e1d5SCristian Dumitrescu } 1020*5074e1d5SCristian Dumitrescu 1021*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Input ports:\n"); 1022*5074e1d5SCristian Dumitrescu out_size -= strlen(out); 1023*5074e1d5SCristian Dumitrescu out += strlen(out); 1024*5074e1d5SCristian Dumitrescu 1025*5074e1d5SCristian Dumitrescu for (i = 0; i < info.n_ports_in; i++) { 1026*5074e1d5SCristian Dumitrescu struct rte_swx_port_in_stats stats; 1027*5074e1d5SCristian Dumitrescu 1028*5074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats); 1029*5074e1d5SCristian Dumitrescu 1030*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\tPort %u:" 1031*5074e1d5SCristian Dumitrescu " packets %" PRIu64 1032*5074e1d5SCristian Dumitrescu " bytes %" PRIu64 1033*5074e1d5SCristian Dumitrescu " empty %" PRIu64 "\n", 1034*5074e1d5SCristian Dumitrescu i, stats.n_pkts, stats.n_bytes, stats.n_empty); 1035*5074e1d5SCristian Dumitrescu out_size -= strlen(out); 1036*5074e1d5SCristian Dumitrescu out += strlen(out); 1037*5074e1d5SCristian Dumitrescu } 1038*5074e1d5SCristian Dumitrescu 1039*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Output ports:\n"); 1040*5074e1d5SCristian Dumitrescu out_size -= strlen(out); 1041*5074e1d5SCristian Dumitrescu out += strlen(out); 1042*5074e1d5SCristian Dumitrescu 1043*5074e1d5SCristian Dumitrescu for (i = 0; i < info.n_ports_out; i++) { 1044*5074e1d5SCristian Dumitrescu struct rte_swx_port_out_stats stats; 1045*5074e1d5SCristian Dumitrescu 1046*5074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats); 1047*5074e1d5SCristian Dumitrescu 1048*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\tPort %u:" 1049*5074e1d5SCristian Dumitrescu " packets %" PRIu64 1050*5074e1d5SCristian Dumitrescu " bytes %" PRIu64 "\n", 1051*5074e1d5SCristian Dumitrescu i, stats.n_pkts, stats.n_bytes); 1052*5074e1d5SCristian Dumitrescu out_size -= strlen(out); 1053*5074e1d5SCristian Dumitrescu out += strlen(out); 1054*5074e1d5SCristian Dumitrescu } 1055*5074e1d5SCristian Dumitrescu } 1056*5074e1d5SCristian Dumitrescu 1057*5074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] = 1058*5074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n"; 1059*5074e1d5SCristian Dumitrescu 1060*5074e1d5SCristian Dumitrescu static void 1061*5074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens, 1062*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 1063*5074e1d5SCristian Dumitrescu char *out, 1064*5074e1d5SCristian Dumitrescu size_t out_size, 1065*5074e1d5SCristian Dumitrescu void *obj) 1066*5074e1d5SCristian Dumitrescu { 1067*5074e1d5SCristian Dumitrescu char *pipeline_name; 1068*5074e1d5SCristian Dumitrescu struct pipeline *p; 1069*5074e1d5SCristian Dumitrescu uint32_t thread_id; 1070*5074e1d5SCristian Dumitrescu int status; 1071*5074e1d5SCristian Dumitrescu 1072*5074e1d5SCristian Dumitrescu if (n_tokens != 5) { 1073*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 1074*5074e1d5SCristian Dumitrescu return; 1075*5074e1d5SCristian Dumitrescu } 1076*5074e1d5SCristian Dumitrescu 1077*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&thread_id, tokens[1]) != 0) { 1078*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); 1079*5074e1d5SCristian Dumitrescu return; 1080*5074e1d5SCristian Dumitrescu } 1081*5074e1d5SCristian Dumitrescu 1082*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "pipeline") != 0) { 1083*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); 1084*5074e1d5SCristian Dumitrescu return; 1085*5074e1d5SCristian Dumitrescu } 1086*5074e1d5SCristian Dumitrescu 1087*5074e1d5SCristian Dumitrescu pipeline_name = tokens[3]; 1088*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, pipeline_name); 1089*5074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 1090*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 1091*5074e1d5SCristian Dumitrescu return; 1092*5074e1d5SCristian Dumitrescu } 1093*5074e1d5SCristian Dumitrescu 1094*5074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "enable") != 0) { 1095*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); 1096*5074e1d5SCristian Dumitrescu return; 1097*5074e1d5SCristian Dumitrescu } 1098*5074e1d5SCristian Dumitrescu 1099*5074e1d5SCristian Dumitrescu status = thread_pipeline_enable(thread_id, obj, pipeline_name); 1100*5074e1d5SCristian Dumitrescu if (status) { 1101*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable"); 1102*5074e1d5SCristian Dumitrescu return; 1103*5074e1d5SCristian Dumitrescu } 1104*5074e1d5SCristian Dumitrescu } 1105*5074e1d5SCristian Dumitrescu 1106*5074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] = 1107*5074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n"; 1108*5074e1d5SCristian Dumitrescu 1109*5074e1d5SCristian Dumitrescu static void 1110*5074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens, 1111*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 1112*5074e1d5SCristian Dumitrescu char *out, 1113*5074e1d5SCristian Dumitrescu size_t out_size, 1114*5074e1d5SCristian Dumitrescu void *obj) 1115*5074e1d5SCristian Dumitrescu { 1116*5074e1d5SCristian Dumitrescu struct pipeline *p; 1117*5074e1d5SCristian Dumitrescu char *pipeline_name; 1118*5074e1d5SCristian Dumitrescu uint32_t thread_id; 1119*5074e1d5SCristian Dumitrescu int status; 1120*5074e1d5SCristian Dumitrescu 1121*5074e1d5SCristian Dumitrescu if (n_tokens != 5) { 1122*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 1123*5074e1d5SCristian Dumitrescu return; 1124*5074e1d5SCristian Dumitrescu } 1125*5074e1d5SCristian Dumitrescu 1126*5074e1d5SCristian Dumitrescu if (parser_read_uint32(&thread_id, tokens[1]) != 0) { 1127*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); 1128*5074e1d5SCristian Dumitrescu return; 1129*5074e1d5SCristian Dumitrescu } 1130*5074e1d5SCristian Dumitrescu 1131*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "pipeline") != 0) { 1132*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); 1133*5074e1d5SCristian Dumitrescu return; 1134*5074e1d5SCristian Dumitrescu } 1135*5074e1d5SCristian Dumitrescu 1136*5074e1d5SCristian Dumitrescu pipeline_name = tokens[3]; 1137*5074e1d5SCristian Dumitrescu p = pipeline_find(obj, pipeline_name); 1138*5074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 1139*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 1140*5074e1d5SCristian Dumitrescu return; 1141*5074e1d5SCristian Dumitrescu } 1142*5074e1d5SCristian Dumitrescu 1143*5074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "disable") != 0) { 1144*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable"); 1145*5074e1d5SCristian Dumitrescu return; 1146*5074e1d5SCristian Dumitrescu } 1147*5074e1d5SCristian Dumitrescu 1148*5074e1d5SCristian Dumitrescu status = thread_pipeline_disable(thread_id, obj, pipeline_name); 1149*5074e1d5SCristian Dumitrescu if (status) { 1150*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, 1151*5074e1d5SCristian Dumitrescu "thread pipeline disable"); 1152*5074e1d5SCristian Dumitrescu return; 1153*5074e1d5SCristian Dumitrescu } 1154*5074e1d5SCristian Dumitrescu } 1155*5074e1d5SCristian Dumitrescu 1156*5074e1d5SCristian Dumitrescu static void 1157*5074e1d5SCristian Dumitrescu cmd_help(char **tokens, 1158*5074e1d5SCristian Dumitrescu uint32_t n_tokens, 1159*5074e1d5SCristian Dumitrescu char *out, 1160*5074e1d5SCristian Dumitrescu size_t out_size, 1161*5074e1d5SCristian Dumitrescu void *arg __rte_unused) 1162*5074e1d5SCristian Dumitrescu { 1163*5074e1d5SCristian Dumitrescu tokens++; 1164*5074e1d5SCristian Dumitrescu n_tokens--; 1165*5074e1d5SCristian Dumitrescu 1166*5074e1d5SCristian Dumitrescu if (n_tokens == 0) { 1167*5074e1d5SCristian Dumitrescu snprintf(out, out_size, 1168*5074e1d5SCristian Dumitrescu "Type 'help <command>' for command details.\n\n"); 1169*5074e1d5SCristian Dumitrescu return; 1170*5074e1d5SCristian Dumitrescu } 1171*5074e1d5SCristian Dumitrescu 1172*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "mempool") == 0) { 1173*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_mempool_help); 1174*5074e1d5SCristian Dumitrescu return; 1175*5074e1d5SCristian Dumitrescu } 1176*5074e1d5SCristian Dumitrescu 1177*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "link") == 0) { 1178*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_link_help); 1179*5074e1d5SCristian Dumitrescu return; 1180*5074e1d5SCristian Dumitrescu } 1181*5074e1d5SCristian Dumitrescu 1182*5074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1183*5074e1d5SCristian Dumitrescu ((n_tokens == 1) && (strcmp(tokens[2], "create")) == 0)) { 1184*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help); 1185*5074e1d5SCristian Dumitrescu return; 1186*5074e1d5SCristian Dumitrescu } 1187*5074e1d5SCristian Dumitrescu 1188*5074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1189*5074e1d5SCristian Dumitrescu (strcmp(tokens[1], "port") == 0)) { 1190*5074e1d5SCristian Dumitrescu if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) { 1191*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 1192*5074e1d5SCristian Dumitrescu cmd_pipeline_port_in_help); 1193*5074e1d5SCristian Dumitrescu return; 1194*5074e1d5SCristian Dumitrescu } 1195*5074e1d5SCristian Dumitrescu 1196*5074e1d5SCristian Dumitrescu if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) { 1197*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 1198*5074e1d5SCristian Dumitrescu cmd_pipeline_port_out_help); 1199*5074e1d5SCristian Dumitrescu return; 1200*5074e1d5SCristian Dumitrescu } 1201*5074e1d5SCristian Dumitrescu } 1202*5074e1d5SCristian Dumitrescu 1203*5074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1204*5074e1d5SCristian Dumitrescu ((n_tokens >= 2) && (strcmp(tokens[2], "build")) == 0)) { 1205*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help); 1206*5074e1d5SCristian Dumitrescu return; 1207*5074e1d5SCristian Dumitrescu } 1208*5074e1d5SCristian Dumitrescu 1209*5074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1210*5074e1d5SCristian Dumitrescu ((n_tokens >= 2) && (strcmp(tokens[2], "table")) == 0)) { 1211*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 1212*5074e1d5SCristian Dumitrescu cmd_pipeline_table_update_help); 1213*5074e1d5SCristian Dumitrescu return; 1214*5074e1d5SCristian Dumitrescu } 1215*5074e1d5SCristian Dumitrescu 1216*5074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1217*5074e1d5SCristian Dumitrescu ((n_tokens >= 2) && (strcmp(tokens[2], "stats")) == 0)) { 1218*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help); 1219*5074e1d5SCristian Dumitrescu return; 1220*5074e1d5SCristian Dumitrescu } 1221*5074e1d5SCristian Dumitrescu 1222*5074e1d5SCristian Dumitrescu if ((n_tokens == 3) && 1223*5074e1d5SCristian Dumitrescu (strcmp(tokens[0], "thread") == 0) && 1224*5074e1d5SCristian Dumitrescu (strcmp(tokens[1], "pipeline") == 0)) { 1225*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "enable") == 0) { 1226*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 1227*5074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable_help); 1228*5074e1d5SCristian Dumitrescu return; 1229*5074e1d5SCristian Dumitrescu } 1230*5074e1d5SCristian Dumitrescu 1231*5074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "disable") == 0) { 1232*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 1233*5074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable_help); 1234*5074e1d5SCristian Dumitrescu return; 1235*5074e1d5SCristian Dumitrescu } 1236*5074e1d5SCristian Dumitrescu } 1237*5074e1d5SCristian Dumitrescu 1238*5074e1d5SCristian Dumitrescu snprintf(out, out_size, "Invalid command\n"); 1239*5074e1d5SCristian Dumitrescu } 1240*5074e1d5SCristian Dumitrescu 1241*5074e1d5SCristian Dumitrescu void 1242*5074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj) 1243*5074e1d5SCristian Dumitrescu { 1244*5074e1d5SCristian Dumitrescu char *tokens[CMD_MAX_TOKENS]; 1245*5074e1d5SCristian Dumitrescu uint32_t n_tokens = RTE_DIM(tokens); 1246*5074e1d5SCristian Dumitrescu int status; 1247*5074e1d5SCristian Dumitrescu 1248*5074e1d5SCristian Dumitrescu if (is_comment(in)) 1249*5074e1d5SCristian Dumitrescu return; 1250*5074e1d5SCristian Dumitrescu 1251*5074e1d5SCristian Dumitrescu status = parse_tokenize_string(in, tokens, &n_tokens); 1252*5074e1d5SCristian Dumitrescu if (status) { 1253*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_TOO_MANY, ""); 1254*5074e1d5SCristian Dumitrescu return; 1255*5074e1d5SCristian Dumitrescu } 1256*5074e1d5SCristian Dumitrescu 1257*5074e1d5SCristian Dumitrescu if (n_tokens == 0) 1258*5074e1d5SCristian Dumitrescu return; 1259*5074e1d5SCristian Dumitrescu 1260*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "help") == 0) { 1261*5074e1d5SCristian Dumitrescu cmd_help(tokens, n_tokens, out, out_size, obj); 1262*5074e1d5SCristian Dumitrescu return; 1263*5074e1d5SCristian Dumitrescu } 1264*5074e1d5SCristian Dumitrescu 1265*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "mempool") == 0) { 1266*5074e1d5SCristian Dumitrescu cmd_mempool(tokens, n_tokens, out, out_size, obj); 1267*5074e1d5SCristian Dumitrescu return; 1268*5074e1d5SCristian Dumitrescu } 1269*5074e1d5SCristian Dumitrescu 1270*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "link") == 0) { 1271*5074e1d5SCristian Dumitrescu if (strcmp(tokens[1], "show") == 0) { 1272*5074e1d5SCristian Dumitrescu cmd_link_show(tokens, n_tokens, out, out_size, obj); 1273*5074e1d5SCristian Dumitrescu return; 1274*5074e1d5SCristian Dumitrescu } 1275*5074e1d5SCristian Dumitrescu 1276*5074e1d5SCristian Dumitrescu cmd_link(tokens, n_tokens, out, out_size, obj); 1277*5074e1d5SCristian Dumitrescu return; 1278*5074e1d5SCristian Dumitrescu } 1279*5074e1d5SCristian Dumitrescu 1280*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "pipeline") == 0) { 1281*5074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 1282*5074e1d5SCristian Dumitrescu (strcmp(tokens[2], "create") == 0)) { 1283*5074e1d5SCristian Dumitrescu cmd_pipeline_create(tokens, n_tokens, out, out_size, 1284*5074e1d5SCristian Dumitrescu obj); 1285*5074e1d5SCristian Dumitrescu return; 1286*5074e1d5SCristian Dumitrescu } 1287*5074e1d5SCristian Dumitrescu 1288*5074e1d5SCristian Dumitrescu if ((n_tokens >= 4) && 1289*5074e1d5SCristian Dumitrescu (strcmp(tokens[2], "port") == 0) && 1290*5074e1d5SCristian Dumitrescu (strcmp(tokens[3], "in") == 0)) { 1291*5074e1d5SCristian Dumitrescu cmd_pipeline_port_in(tokens, n_tokens, out, out_size, 1292*5074e1d5SCristian Dumitrescu obj); 1293*5074e1d5SCristian Dumitrescu return; 1294*5074e1d5SCristian Dumitrescu } 1295*5074e1d5SCristian Dumitrescu 1296*5074e1d5SCristian Dumitrescu if ((n_tokens >= 4) && 1297*5074e1d5SCristian Dumitrescu (strcmp(tokens[2], "port") == 0) && 1298*5074e1d5SCristian Dumitrescu (strcmp(tokens[3], "out") == 0)) { 1299*5074e1d5SCristian Dumitrescu cmd_pipeline_port_out(tokens, n_tokens, out, out_size, 1300*5074e1d5SCristian Dumitrescu obj); 1301*5074e1d5SCristian Dumitrescu return; 1302*5074e1d5SCristian Dumitrescu } 1303*5074e1d5SCristian Dumitrescu 1304*5074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 1305*5074e1d5SCristian Dumitrescu (strcmp(tokens[2], "build") == 0)) { 1306*5074e1d5SCristian Dumitrescu cmd_pipeline_build(tokens, n_tokens, out, out_size, 1307*5074e1d5SCristian Dumitrescu obj); 1308*5074e1d5SCristian Dumitrescu return; 1309*5074e1d5SCristian Dumitrescu } 1310*5074e1d5SCristian Dumitrescu 1311*5074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 1312*5074e1d5SCristian Dumitrescu (strcmp(tokens[2], "table") == 0)) { 1313*5074e1d5SCristian Dumitrescu cmd_pipeline_table_update(tokens, n_tokens, out, 1314*5074e1d5SCristian Dumitrescu out_size, obj); 1315*5074e1d5SCristian Dumitrescu return; 1316*5074e1d5SCristian Dumitrescu } 1317*5074e1d5SCristian Dumitrescu 1318*5074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 1319*5074e1d5SCristian Dumitrescu (strcmp(tokens[2], "stats") == 0)) { 1320*5074e1d5SCristian Dumitrescu cmd_pipeline_stats(tokens, n_tokens, out, out_size, 1321*5074e1d5SCristian Dumitrescu obj); 1322*5074e1d5SCristian Dumitrescu return; 1323*5074e1d5SCristian Dumitrescu } 1324*5074e1d5SCristian Dumitrescu } 1325*5074e1d5SCristian Dumitrescu 1326*5074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "thread") == 0) { 1327*5074e1d5SCristian Dumitrescu if ((n_tokens >= 5) && 1328*5074e1d5SCristian Dumitrescu (strcmp(tokens[4], "enable") == 0)) { 1329*5074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(tokens, n_tokens, 1330*5074e1d5SCristian Dumitrescu out, out_size, obj); 1331*5074e1d5SCristian Dumitrescu return; 1332*5074e1d5SCristian Dumitrescu } 1333*5074e1d5SCristian Dumitrescu 1334*5074e1d5SCristian Dumitrescu if ((n_tokens >= 5) && 1335*5074e1d5SCristian Dumitrescu (strcmp(tokens[4], "disable") == 0)) { 1336*5074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(tokens, n_tokens, 1337*5074e1d5SCristian Dumitrescu out, out_size, obj); 1338*5074e1d5SCristian Dumitrescu return; 1339*5074e1d5SCristian Dumitrescu } 1340*5074e1d5SCristian Dumitrescu } 1341*5074e1d5SCristian Dumitrescu 1342*5074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]); 1343*5074e1d5SCristian Dumitrescu } 1344*5074e1d5SCristian Dumitrescu 1345*5074e1d5SCristian Dumitrescu int 1346*5074e1d5SCristian Dumitrescu cli_script_process(const char *file_name, 1347*5074e1d5SCristian Dumitrescu size_t msg_in_len_max, 1348*5074e1d5SCristian Dumitrescu size_t msg_out_len_max, 1349*5074e1d5SCristian Dumitrescu void *obj) 1350*5074e1d5SCristian Dumitrescu { 1351*5074e1d5SCristian Dumitrescu char *msg_in = NULL, *msg_out = NULL; 1352*5074e1d5SCristian Dumitrescu FILE *f = NULL; 1353*5074e1d5SCristian Dumitrescu 1354*5074e1d5SCristian Dumitrescu /* Check input arguments */ 1355*5074e1d5SCristian Dumitrescu if ((file_name == NULL) || 1356*5074e1d5SCristian Dumitrescu (strlen(file_name) == 0) || 1357*5074e1d5SCristian Dumitrescu (msg_in_len_max == 0) || 1358*5074e1d5SCristian Dumitrescu (msg_out_len_max == 0)) 1359*5074e1d5SCristian Dumitrescu return -EINVAL; 1360*5074e1d5SCristian Dumitrescu 1361*5074e1d5SCristian Dumitrescu msg_in = malloc(msg_in_len_max + 1); 1362*5074e1d5SCristian Dumitrescu msg_out = malloc(msg_out_len_max + 1); 1363*5074e1d5SCristian Dumitrescu if ((msg_in == NULL) || 1364*5074e1d5SCristian Dumitrescu (msg_out == NULL)) { 1365*5074e1d5SCristian Dumitrescu free(msg_out); 1366*5074e1d5SCristian Dumitrescu free(msg_in); 1367*5074e1d5SCristian Dumitrescu return -ENOMEM; 1368*5074e1d5SCristian Dumitrescu } 1369*5074e1d5SCristian Dumitrescu 1370*5074e1d5SCristian Dumitrescu /* Open input file */ 1371*5074e1d5SCristian Dumitrescu f = fopen(file_name, "r"); 1372*5074e1d5SCristian Dumitrescu if (f == NULL) { 1373*5074e1d5SCristian Dumitrescu free(msg_out); 1374*5074e1d5SCristian Dumitrescu free(msg_in); 1375*5074e1d5SCristian Dumitrescu return -EIO; 1376*5074e1d5SCristian Dumitrescu } 1377*5074e1d5SCristian Dumitrescu 1378*5074e1d5SCristian Dumitrescu /* Read file */ 1379*5074e1d5SCristian Dumitrescu for ( ; ; ) { 1380*5074e1d5SCristian Dumitrescu if (fgets(msg_in, msg_in_len_max + 1, f) == NULL) 1381*5074e1d5SCristian Dumitrescu break; 1382*5074e1d5SCristian Dumitrescu 1383*5074e1d5SCristian Dumitrescu printf("%s", msg_in); 1384*5074e1d5SCristian Dumitrescu msg_out[0] = 0; 1385*5074e1d5SCristian Dumitrescu 1386*5074e1d5SCristian Dumitrescu cli_process(msg_in, 1387*5074e1d5SCristian Dumitrescu msg_out, 1388*5074e1d5SCristian Dumitrescu msg_out_len_max, 1389*5074e1d5SCristian Dumitrescu obj); 1390*5074e1d5SCristian Dumitrescu 1391*5074e1d5SCristian Dumitrescu if (strlen(msg_out)) 1392*5074e1d5SCristian Dumitrescu printf("%s", msg_out); 1393*5074e1d5SCristian Dumitrescu } 1394*5074e1d5SCristian Dumitrescu 1395*5074e1d5SCristian Dumitrescu /* Close file */ 1396*5074e1d5SCristian Dumitrescu fclose(f); 1397*5074e1d5SCristian Dumitrescu free(msg_out); 1398*5074e1d5SCristian Dumitrescu free(msg_in); 1399*5074e1d5SCristian Dumitrescu return 0; 1400*5074e1d5SCristian Dumitrescu } 1401