15074e1d5SCristian Dumitrescu /* SPDX-License-Identifier: BSD-3-Clause 25074e1d5SCristian Dumitrescu * Copyright(c) 2020 Intel Corporation 35074e1d5SCristian Dumitrescu */ 45074e1d5SCristian Dumitrescu 55074e1d5SCristian Dumitrescu #include <stdio.h> 65074e1d5SCristian Dumitrescu #include <stdint.h> 75074e1d5SCristian Dumitrescu #include <stdlib.h> 85074e1d5SCristian Dumitrescu #include <string.h> 95074e1d5SCristian Dumitrescu 105074e1d5SCristian Dumitrescu #include <rte_common.h> 115074e1d5SCristian Dumitrescu #include <rte_ethdev.h> 125074e1d5SCristian Dumitrescu #include <rte_swx_port_ethdev.h> 135074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h> 145074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h> 155074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h> 165074e1d5SCristian Dumitrescu 175074e1d5SCristian Dumitrescu #include "cli.h" 185074e1d5SCristian Dumitrescu 195074e1d5SCristian Dumitrescu #include "obj.h" 205074e1d5SCristian Dumitrescu #include "thread.h" 215074e1d5SCristian Dumitrescu 225074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS 235074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS 256 245074e1d5SCristian Dumitrescu #endif 255074e1d5SCristian Dumitrescu 265074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY "Not enough memory.\n" 275074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n" 285074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n" 295074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n" 305074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n" 315074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n" 325074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n" 335074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n" 345074e1d5SCristian Dumitrescu #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n" 355074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n" 365074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL "Command \"%s\" failed.\n" 375074e1d5SCristian Dumitrescu 385074e1d5SCristian Dumitrescu #define skip_white_spaces(pos) \ 395074e1d5SCristian Dumitrescu ({ \ 405074e1d5SCristian Dumitrescu __typeof__(pos) _p = (pos); \ 415074e1d5SCristian Dumitrescu for ( ; isspace(*_p); _p++) \ 425074e1d5SCristian Dumitrescu ; \ 435074e1d5SCristian Dumitrescu _p; \ 445074e1d5SCristian Dumitrescu }) 455074e1d5SCristian Dumitrescu 465074e1d5SCristian Dumitrescu static int 475074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p) 485074e1d5SCristian Dumitrescu { 495074e1d5SCristian Dumitrescu char *next; 505074e1d5SCristian Dumitrescu uint64_t val; 515074e1d5SCristian Dumitrescu 525074e1d5SCristian Dumitrescu p = skip_white_spaces(p); 535074e1d5SCristian Dumitrescu if (!isdigit(*p)) 545074e1d5SCristian Dumitrescu return -EINVAL; 555074e1d5SCristian Dumitrescu 565074e1d5SCristian Dumitrescu val = strtoul(p, &next, 10); 575074e1d5SCristian Dumitrescu if (p == next) 585074e1d5SCristian Dumitrescu return -EINVAL; 595074e1d5SCristian Dumitrescu 605074e1d5SCristian Dumitrescu p = next; 615074e1d5SCristian Dumitrescu switch (*p) { 625074e1d5SCristian Dumitrescu case 'T': 635074e1d5SCristian Dumitrescu val *= 1024ULL; 645074e1d5SCristian Dumitrescu /* fall through */ 655074e1d5SCristian Dumitrescu case 'G': 665074e1d5SCristian Dumitrescu val *= 1024ULL; 675074e1d5SCristian Dumitrescu /* fall through */ 685074e1d5SCristian Dumitrescu case 'M': 695074e1d5SCristian Dumitrescu val *= 1024ULL; 705074e1d5SCristian Dumitrescu /* fall through */ 715074e1d5SCristian Dumitrescu case 'k': 725074e1d5SCristian Dumitrescu case 'K': 735074e1d5SCristian Dumitrescu val *= 1024ULL; 745074e1d5SCristian Dumitrescu p++; 755074e1d5SCristian Dumitrescu break; 765074e1d5SCristian Dumitrescu } 775074e1d5SCristian Dumitrescu 785074e1d5SCristian Dumitrescu p = skip_white_spaces(p); 795074e1d5SCristian Dumitrescu if (*p != '\0') 805074e1d5SCristian Dumitrescu return -EINVAL; 815074e1d5SCristian Dumitrescu 825074e1d5SCristian Dumitrescu *value = val; 835074e1d5SCristian Dumitrescu return 0; 845074e1d5SCristian Dumitrescu } 855074e1d5SCristian Dumitrescu 865074e1d5SCristian Dumitrescu static int 875074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p) 885074e1d5SCristian Dumitrescu { 895074e1d5SCristian Dumitrescu uint64_t val = 0; 905074e1d5SCristian Dumitrescu int ret = parser_read_uint64(&val, p); 915074e1d5SCristian Dumitrescu 925074e1d5SCristian Dumitrescu if (ret < 0) 935074e1d5SCristian Dumitrescu return ret; 945074e1d5SCristian Dumitrescu 955074e1d5SCristian Dumitrescu if (val > UINT32_MAX) 965074e1d5SCristian Dumitrescu return -ERANGE; 975074e1d5SCristian Dumitrescu 985074e1d5SCristian Dumitrescu *value = val; 995074e1d5SCristian Dumitrescu return 0; 1005074e1d5SCristian Dumitrescu } 1015074e1d5SCristian Dumitrescu 1025074e1d5SCristian Dumitrescu static int 1035074e1d5SCristian Dumitrescu parser_read_uint16(uint16_t *value, const char *p) 1045074e1d5SCristian Dumitrescu { 1055074e1d5SCristian Dumitrescu uint64_t val = 0; 1065074e1d5SCristian Dumitrescu int ret = parser_read_uint64(&val, p); 1075074e1d5SCristian Dumitrescu 1085074e1d5SCristian Dumitrescu if (ret < 0) 1095074e1d5SCristian Dumitrescu return ret; 1105074e1d5SCristian Dumitrescu 1115074e1d5SCristian Dumitrescu if (val > UINT16_MAX) 1125074e1d5SCristian Dumitrescu return -ERANGE; 1135074e1d5SCristian Dumitrescu 1145074e1d5SCristian Dumitrescu *value = val; 1155074e1d5SCristian Dumitrescu return 0; 1165074e1d5SCristian Dumitrescu } 1175074e1d5SCristian Dumitrescu 1185074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v" 1195074e1d5SCristian Dumitrescu 1205074e1d5SCristian Dumitrescu static int 1215074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens) 1225074e1d5SCristian Dumitrescu { 1235074e1d5SCristian Dumitrescu uint32_t i; 1245074e1d5SCristian Dumitrescu 1255074e1d5SCristian Dumitrescu if ((string == NULL) || 1265074e1d5SCristian Dumitrescu (tokens == NULL) || 1275074e1d5SCristian Dumitrescu (*n_tokens < 1)) 1285074e1d5SCristian Dumitrescu return -EINVAL; 1295074e1d5SCristian Dumitrescu 1305074e1d5SCristian Dumitrescu for (i = 0; i < *n_tokens; i++) { 1315074e1d5SCristian Dumitrescu tokens[i] = strtok_r(string, PARSE_DELIMITER, &string); 1325074e1d5SCristian Dumitrescu if (tokens[i] == NULL) 1335074e1d5SCristian Dumitrescu break; 1345074e1d5SCristian Dumitrescu } 1355074e1d5SCristian Dumitrescu 1365074e1d5SCristian Dumitrescu if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string)) 1375074e1d5SCristian Dumitrescu return -E2BIG; 1385074e1d5SCristian Dumitrescu 1395074e1d5SCristian Dumitrescu *n_tokens = i; 1405074e1d5SCristian Dumitrescu return 0; 1415074e1d5SCristian Dumitrescu } 1425074e1d5SCristian Dumitrescu 1435074e1d5SCristian Dumitrescu static int 1445074e1d5SCristian Dumitrescu is_comment(char *in) 1455074e1d5SCristian Dumitrescu { 1465074e1d5SCristian Dumitrescu if ((strlen(in) && index("!#%;", in[0])) || 1475074e1d5SCristian Dumitrescu (strncmp(in, "//", 2) == 0) || 1485074e1d5SCristian Dumitrescu (strncmp(in, "--", 2) == 0)) 1495074e1d5SCristian Dumitrescu return 1; 1505074e1d5SCristian Dumitrescu 1515074e1d5SCristian Dumitrescu return 0; 1525074e1d5SCristian Dumitrescu } 1535074e1d5SCristian Dumitrescu 1545074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] = 1555074e1d5SCristian Dumitrescu "mempool <mempool_name>\n" 1565074e1d5SCristian Dumitrescu " buffer <buffer_size>\n" 1575074e1d5SCristian Dumitrescu " pool <pool_size>\n" 1585074e1d5SCristian Dumitrescu " cache <cache_size>\n" 1595074e1d5SCristian Dumitrescu " cpu <cpu_id>\n"; 1605074e1d5SCristian Dumitrescu 1615074e1d5SCristian Dumitrescu static void 1625074e1d5SCristian Dumitrescu cmd_mempool(char **tokens, 1635074e1d5SCristian Dumitrescu uint32_t n_tokens, 1645074e1d5SCristian Dumitrescu char *out, 1655074e1d5SCristian Dumitrescu size_t out_size, 1665074e1d5SCristian Dumitrescu void *obj) 1675074e1d5SCristian Dumitrescu { 1685074e1d5SCristian Dumitrescu struct mempool_params p; 1695074e1d5SCristian Dumitrescu char *name; 1705074e1d5SCristian Dumitrescu struct mempool *mempool; 1715074e1d5SCristian Dumitrescu 1725074e1d5SCristian Dumitrescu if (n_tokens != 10) { 1735074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 1745074e1d5SCristian Dumitrescu return; 1755074e1d5SCristian Dumitrescu } 1765074e1d5SCristian Dumitrescu 1775074e1d5SCristian Dumitrescu name = tokens[1]; 1785074e1d5SCristian Dumitrescu 1795074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "buffer") != 0) { 1805074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer"); 1815074e1d5SCristian Dumitrescu return; 1825074e1d5SCristian Dumitrescu } 1835074e1d5SCristian Dumitrescu 1845074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) { 1855074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size"); 1865074e1d5SCristian Dumitrescu return; 1875074e1d5SCristian Dumitrescu } 1885074e1d5SCristian Dumitrescu 1895074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "pool") != 0) { 1905074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool"); 1915074e1d5SCristian Dumitrescu return; 1925074e1d5SCristian Dumitrescu } 1935074e1d5SCristian Dumitrescu 1945074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) { 1955074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pool_size"); 1965074e1d5SCristian Dumitrescu return; 1975074e1d5SCristian Dumitrescu } 1985074e1d5SCristian Dumitrescu 1995074e1d5SCristian Dumitrescu if (strcmp(tokens[6], "cache") != 0) { 2005074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache"); 2015074e1d5SCristian Dumitrescu return; 2025074e1d5SCristian Dumitrescu } 2035074e1d5SCristian Dumitrescu 2045074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) { 2055074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "cache_size"); 2065074e1d5SCristian Dumitrescu return; 2075074e1d5SCristian Dumitrescu } 2085074e1d5SCristian Dumitrescu 2095074e1d5SCristian Dumitrescu if (strcmp(tokens[8], "cpu") != 0) { 2105074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); 2115074e1d5SCristian Dumitrescu return; 2125074e1d5SCristian Dumitrescu } 2135074e1d5SCristian Dumitrescu 2145074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) { 2155074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); 2165074e1d5SCristian Dumitrescu return; 2175074e1d5SCristian Dumitrescu } 2185074e1d5SCristian Dumitrescu 2195074e1d5SCristian Dumitrescu mempool = mempool_create(obj, name, &p); 2205074e1d5SCristian Dumitrescu if (mempool == NULL) { 2215074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); 2225074e1d5SCristian Dumitrescu return; 2235074e1d5SCristian Dumitrescu } 2245074e1d5SCristian Dumitrescu } 2255074e1d5SCristian Dumitrescu 2265074e1d5SCristian Dumitrescu static const char cmd_link_help[] = 2275074e1d5SCristian Dumitrescu "link <link_name>\n" 2285074e1d5SCristian Dumitrescu " dev <device_name> | port <port_id>\n" 2295074e1d5SCristian Dumitrescu " rxq <n_queues> <queue_size> <mempool_name>\n" 2305074e1d5SCristian Dumitrescu " txq <n_queues> <queue_size>\n" 2315074e1d5SCristian Dumitrescu " promiscuous on | off\n" 2325074e1d5SCristian Dumitrescu " [rss <qid_0> ... <qid_n>]\n"; 2335074e1d5SCristian Dumitrescu 2345074e1d5SCristian Dumitrescu static void 2355074e1d5SCristian Dumitrescu cmd_link(char **tokens, 2365074e1d5SCristian Dumitrescu uint32_t n_tokens, 2375074e1d5SCristian Dumitrescu char *out, 2385074e1d5SCristian Dumitrescu size_t out_size, 2395074e1d5SCristian Dumitrescu void *obj) 2405074e1d5SCristian Dumitrescu { 2415074e1d5SCristian Dumitrescu struct link_params p; 2425074e1d5SCristian Dumitrescu struct link_params_rss rss; 2435074e1d5SCristian Dumitrescu struct link *link; 2445074e1d5SCristian Dumitrescu char *name; 2455074e1d5SCristian Dumitrescu 2465074e1d5SCristian Dumitrescu memset(&p, 0, sizeof(p)); 2475074e1d5SCristian Dumitrescu 2485074e1d5SCristian Dumitrescu if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) { 2495074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 2505074e1d5SCristian Dumitrescu return; 2515074e1d5SCristian Dumitrescu } 2525074e1d5SCristian Dumitrescu name = tokens[1]; 2535074e1d5SCristian Dumitrescu 2545074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "dev") == 0) 2555074e1d5SCristian Dumitrescu p.dev_name = tokens[3]; 2565074e1d5SCristian Dumitrescu else if (strcmp(tokens[2], "port") == 0) { 2575074e1d5SCristian Dumitrescu p.dev_name = NULL; 2585074e1d5SCristian Dumitrescu 2595074e1d5SCristian Dumitrescu if (parser_read_uint16(&p.port_id, tokens[3]) != 0) { 2605074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); 2615074e1d5SCristian Dumitrescu return; 2625074e1d5SCristian Dumitrescu } 2635074e1d5SCristian Dumitrescu } else { 2645074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port"); 2655074e1d5SCristian Dumitrescu return; 2665074e1d5SCristian Dumitrescu } 2675074e1d5SCristian Dumitrescu 2685074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "rxq") != 0) { 2695074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq"); 2705074e1d5SCristian Dumitrescu return; 2715074e1d5SCristian Dumitrescu } 2725074e1d5SCristian Dumitrescu 2735074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) { 2745074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "n_queues"); 2755074e1d5SCristian Dumitrescu return; 2765074e1d5SCristian Dumitrescu } 2775074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) { 2785074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "queue_size"); 2795074e1d5SCristian Dumitrescu return; 2805074e1d5SCristian Dumitrescu } 2815074e1d5SCristian Dumitrescu 2825074e1d5SCristian Dumitrescu p.rx.mempool_name = tokens[7]; 2835074e1d5SCristian Dumitrescu 2845074e1d5SCristian Dumitrescu if (strcmp(tokens[8], "txq") != 0) { 2855074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq"); 2865074e1d5SCristian Dumitrescu return; 2875074e1d5SCristian Dumitrescu } 2885074e1d5SCristian Dumitrescu 2895074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) { 2905074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "n_queues"); 2915074e1d5SCristian Dumitrescu return; 2925074e1d5SCristian Dumitrescu } 2935074e1d5SCristian Dumitrescu 2945074e1d5SCristian Dumitrescu if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) { 2955074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "queue_size"); 2965074e1d5SCristian Dumitrescu return; 2975074e1d5SCristian Dumitrescu } 2985074e1d5SCristian Dumitrescu 2995074e1d5SCristian Dumitrescu if (strcmp(tokens[11], "promiscuous") != 0) { 3005074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous"); 3015074e1d5SCristian Dumitrescu return; 3025074e1d5SCristian Dumitrescu } 3035074e1d5SCristian Dumitrescu 3045074e1d5SCristian Dumitrescu if (strcmp(tokens[12], "on") == 0) 3055074e1d5SCristian Dumitrescu p.promiscuous = 1; 3065074e1d5SCristian Dumitrescu else if (strcmp(tokens[12], "off") == 0) 3075074e1d5SCristian Dumitrescu p.promiscuous = 0; 3085074e1d5SCristian Dumitrescu else { 3095074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off"); 3105074e1d5SCristian Dumitrescu return; 3115074e1d5SCristian Dumitrescu } 3125074e1d5SCristian Dumitrescu 3135074e1d5SCristian Dumitrescu /* RSS */ 3145074e1d5SCristian Dumitrescu p.rx.rss = NULL; 3155074e1d5SCristian Dumitrescu if (n_tokens > 13) { 3165074e1d5SCristian Dumitrescu uint32_t queue_id, i; 3175074e1d5SCristian Dumitrescu 3185074e1d5SCristian Dumitrescu if (strcmp(tokens[13], "rss") != 0) { 3195074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss"); 3205074e1d5SCristian Dumitrescu return; 3215074e1d5SCristian Dumitrescu } 3225074e1d5SCristian Dumitrescu 3235074e1d5SCristian Dumitrescu p.rx.rss = &rss; 3245074e1d5SCristian Dumitrescu 3255074e1d5SCristian Dumitrescu rss.n_queues = 0; 3265074e1d5SCristian Dumitrescu for (i = 14; i < n_tokens; i++) { 3275074e1d5SCristian Dumitrescu if (parser_read_uint32(&queue_id, tokens[i]) != 0) { 3285074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 3295074e1d5SCristian Dumitrescu "queue_id"); 3305074e1d5SCristian Dumitrescu return; 3315074e1d5SCristian Dumitrescu } 3325074e1d5SCristian Dumitrescu 3335074e1d5SCristian Dumitrescu rss.queue_id[rss.n_queues] = queue_id; 3345074e1d5SCristian Dumitrescu rss.n_queues++; 3355074e1d5SCristian Dumitrescu } 3365074e1d5SCristian Dumitrescu } 3375074e1d5SCristian Dumitrescu 3385074e1d5SCristian Dumitrescu link = link_create(obj, name, &p); 3395074e1d5SCristian Dumitrescu if (link == NULL) { 3405074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); 3415074e1d5SCristian Dumitrescu return; 3425074e1d5SCristian Dumitrescu } 3435074e1d5SCristian Dumitrescu } 3445074e1d5SCristian Dumitrescu 3455074e1d5SCristian Dumitrescu /* Print the link stats and info */ 3465074e1d5SCristian Dumitrescu static void 3475074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size) 3485074e1d5SCristian Dumitrescu { 3495074e1d5SCristian Dumitrescu struct rte_eth_stats stats; 3505074e1d5SCristian Dumitrescu struct rte_ether_addr mac_addr; 3515074e1d5SCristian Dumitrescu struct rte_eth_link eth_link; 3525074e1d5SCristian Dumitrescu uint16_t mtu; 3535074e1d5SCristian Dumitrescu int ret; 3545074e1d5SCristian Dumitrescu 3555074e1d5SCristian Dumitrescu memset(&stats, 0, sizeof(stats)); 3565074e1d5SCristian Dumitrescu rte_eth_stats_get(link->port_id, &stats); 3575074e1d5SCristian Dumitrescu 3585074e1d5SCristian Dumitrescu ret = rte_eth_macaddr_get(link->port_id, &mac_addr); 3595074e1d5SCristian Dumitrescu if (ret != 0) { 3605074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s: MAC address get failed: %s", 3615074e1d5SCristian Dumitrescu link->name, rte_strerror(-ret)); 3625074e1d5SCristian Dumitrescu return; 3635074e1d5SCristian Dumitrescu } 3645074e1d5SCristian Dumitrescu 3655074e1d5SCristian Dumitrescu ret = rte_eth_link_get(link->port_id, ð_link); 3665074e1d5SCristian Dumitrescu if (ret < 0) { 3675074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s: link get failed: %s", 3685074e1d5SCristian Dumitrescu link->name, rte_strerror(-ret)); 3695074e1d5SCristian Dumitrescu return; 3705074e1d5SCristian Dumitrescu } 3715074e1d5SCristian Dumitrescu 3725074e1d5SCristian Dumitrescu rte_eth_dev_get_mtu(link->port_id, &mtu); 3735074e1d5SCristian Dumitrescu 3745074e1d5SCristian Dumitrescu snprintf(out, out_size, 3755074e1d5SCristian Dumitrescu "\n" 3765074e1d5SCristian Dumitrescu "%s: flags=<%s> mtu %u\n" 3775074e1d5SCristian Dumitrescu "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n" 3785074e1d5SCristian Dumitrescu "\tport# %u speed %s\n" 3795074e1d5SCristian Dumitrescu "\tRX packets %" PRIu64" bytes %" PRIu64"\n" 3805074e1d5SCristian Dumitrescu "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n" 3815074e1d5SCristian Dumitrescu "\tTX packets %" PRIu64" bytes %" PRIu64"\n" 3825074e1d5SCristian Dumitrescu "\tTX errors %" PRIu64"\n", 3835074e1d5SCristian Dumitrescu link->name, 3845074e1d5SCristian Dumitrescu eth_link.link_status == 0 ? "DOWN" : "UP", 3855074e1d5SCristian Dumitrescu mtu, 3865074e1d5SCristian Dumitrescu mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 3875074e1d5SCristian Dumitrescu mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 3885074e1d5SCristian Dumitrescu mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], 3895074e1d5SCristian Dumitrescu link->n_rxq, 3905074e1d5SCristian Dumitrescu link->n_txq, 3915074e1d5SCristian Dumitrescu link->port_id, 3925074e1d5SCristian Dumitrescu rte_eth_link_speed_to_str(eth_link.link_speed), 3935074e1d5SCristian Dumitrescu stats.ipackets, 3945074e1d5SCristian Dumitrescu stats.ibytes, 3955074e1d5SCristian Dumitrescu stats.ierrors, 3965074e1d5SCristian Dumitrescu stats.imissed, 3975074e1d5SCristian Dumitrescu stats.rx_nombuf, 3985074e1d5SCristian Dumitrescu stats.opackets, 3995074e1d5SCristian Dumitrescu stats.obytes, 4005074e1d5SCristian Dumitrescu stats.oerrors); 4015074e1d5SCristian Dumitrescu } 4025074e1d5SCristian Dumitrescu 4035074e1d5SCristian Dumitrescu /* 4045074e1d5SCristian Dumitrescu * link show [<link_name>] 4055074e1d5SCristian Dumitrescu */ 4065074e1d5SCristian Dumitrescu static void 4075074e1d5SCristian Dumitrescu cmd_link_show(char **tokens, 4085074e1d5SCristian Dumitrescu uint32_t n_tokens, 4095074e1d5SCristian Dumitrescu char *out, 4105074e1d5SCristian Dumitrescu size_t out_size, 4115074e1d5SCristian Dumitrescu void *obj) 4125074e1d5SCristian Dumitrescu { 4135074e1d5SCristian Dumitrescu struct link *link; 4145074e1d5SCristian Dumitrescu char *link_name; 4155074e1d5SCristian Dumitrescu 4165074e1d5SCristian Dumitrescu if (n_tokens != 2 && n_tokens != 3) { 4175074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 4185074e1d5SCristian Dumitrescu return; 4195074e1d5SCristian Dumitrescu } 4205074e1d5SCristian Dumitrescu 4215074e1d5SCristian Dumitrescu if (n_tokens == 2) { 4225074e1d5SCristian Dumitrescu link = link_next(obj, NULL); 4235074e1d5SCristian Dumitrescu 4245074e1d5SCristian Dumitrescu while (link != NULL) { 4255074e1d5SCristian Dumitrescu out_size = out_size - strlen(out); 4265074e1d5SCristian Dumitrescu out = &out[strlen(out)]; 4275074e1d5SCristian Dumitrescu 4285074e1d5SCristian Dumitrescu print_link_info(link, out, out_size); 4295074e1d5SCristian Dumitrescu link = link_next(obj, link); 4305074e1d5SCristian Dumitrescu } 4315074e1d5SCristian Dumitrescu } else { 4325074e1d5SCristian Dumitrescu out_size = out_size - strlen(out); 4335074e1d5SCristian Dumitrescu out = &out[strlen(out)]; 4345074e1d5SCristian Dumitrescu 4355074e1d5SCristian Dumitrescu link_name = tokens[2]; 4365074e1d5SCristian Dumitrescu link = link_find(obj, link_name); 4375074e1d5SCristian Dumitrescu 4385074e1d5SCristian Dumitrescu if (link == NULL) { 4395074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 4405074e1d5SCristian Dumitrescu "Link does not exist"); 4415074e1d5SCristian Dumitrescu return; 4425074e1d5SCristian Dumitrescu } 4435074e1d5SCristian Dumitrescu print_link_info(link, out, out_size); 4445074e1d5SCristian Dumitrescu } 4455074e1d5SCristian Dumitrescu } 4465074e1d5SCristian Dumitrescu 4475074e1d5SCristian Dumitrescu static const char cmd_pipeline_create_help[] = 4485074e1d5SCristian Dumitrescu "pipeline <pipeline_name> create <numa_node>\n"; 4495074e1d5SCristian Dumitrescu 4505074e1d5SCristian Dumitrescu static void 4515074e1d5SCristian Dumitrescu cmd_pipeline_create(char **tokens, 4525074e1d5SCristian Dumitrescu uint32_t n_tokens, 4535074e1d5SCristian Dumitrescu char *out, 4545074e1d5SCristian Dumitrescu size_t out_size, 4555074e1d5SCristian Dumitrescu void *obj) 4565074e1d5SCristian Dumitrescu { 4575074e1d5SCristian Dumitrescu struct pipeline *p; 4585074e1d5SCristian Dumitrescu char *name; 4595074e1d5SCristian Dumitrescu uint32_t numa_node; 4605074e1d5SCristian Dumitrescu 4615074e1d5SCristian Dumitrescu if (n_tokens != 4) { 4625074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 4635074e1d5SCristian Dumitrescu return; 4645074e1d5SCristian Dumitrescu } 4655074e1d5SCristian Dumitrescu 4665074e1d5SCristian Dumitrescu name = tokens[1]; 4675074e1d5SCristian Dumitrescu 4685074e1d5SCristian Dumitrescu if (parser_read_uint32(&numa_node, tokens[3]) != 0) { 4695074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); 4705074e1d5SCristian Dumitrescu return; 4715074e1d5SCristian Dumitrescu } 4725074e1d5SCristian Dumitrescu 4735074e1d5SCristian Dumitrescu p = pipeline_create(obj, name, (int)numa_node); 4745074e1d5SCristian Dumitrescu if (!p) { 4755074e1d5SCristian Dumitrescu snprintf(out, out_size, "pipeline create error."); 4765074e1d5SCristian Dumitrescu return; 4775074e1d5SCristian Dumitrescu } 4785074e1d5SCristian Dumitrescu } 4795074e1d5SCristian Dumitrescu 4805074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_in_help[] = 4815074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port in <port_id>\n" 4825074e1d5SCristian Dumitrescu " link <link_name> rxq <queue_id> bsz <burst_size>\n" 483*7fef9ef1SYogesh Jangra " | source <mempool_name> <file_name>\n"; 4845074e1d5SCristian Dumitrescu 4855074e1d5SCristian Dumitrescu static void 4865074e1d5SCristian Dumitrescu cmd_pipeline_port_in(char **tokens, 4875074e1d5SCristian Dumitrescu uint32_t n_tokens, 4885074e1d5SCristian Dumitrescu char *out, 4895074e1d5SCristian Dumitrescu size_t out_size, 4905074e1d5SCristian Dumitrescu void *obj) 4915074e1d5SCristian Dumitrescu { 4925074e1d5SCristian Dumitrescu struct pipeline *p; 4935074e1d5SCristian Dumitrescu int status; 4945074e1d5SCristian Dumitrescu uint32_t port_id = 0, t0; 4955074e1d5SCristian Dumitrescu 4965074e1d5SCristian Dumitrescu if (n_tokens < 6) { 4975074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 4985074e1d5SCristian Dumitrescu return; 4995074e1d5SCristian Dumitrescu } 5005074e1d5SCristian Dumitrescu 5015074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 5025074e1d5SCristian Dumitrescu if (!p || p->ctl) { 5035074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 5045074e1d5SCristian Dumitrescu return; 5055074e1d5SCristian Dumitrescu } 5065074e1d5SCristian Dumitrescu 5075074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "port") != 0) { 5085074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port"); 5095074e1d5SCristian Dumitrescu return; 5105074e1d5SCristian Dumitrescu } 5115074e1d5SCristian Dumitrescu 5125074e1d5SCristian Dumitrescu if (strcmp(tokens[3], "in") != 0) { 5135074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in"); 5145074e1d5SCristian Dumitrescu return; 5155074e1d5SCristian Dumitrescu } 5165074e1d5SCristian Dumitrescu 5175074e1d5SCristian Dumitrescu if (parser_read_uint32(&port_id, tokens[4]) != 0) { 5185074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); 5195074e1d5SCristian Dumitrescu return; 5205074e1d5SCristian Dumitrescu } 5215074e1d5SCristian Dumitrescu 5225074e1d5SCristian Dumitrescu t0 = 5; 5235074e1d5SCristian Dumitrescu 5245074e1d5SCristian Dumitrescu if (strcmp(tokens[t0], "link") == 0) { 5255074e1d5SCristian Dumitrescu struct rte_swx_port_ethdev_reader_params params; 5265074e1d5SCristian Dumitrescu struct link *link; 5275074e1d5SCristian Dumitrescu 5285074e1d5SCristian Dumitrescu if (n_tokens < t0 + 6) { 5295074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, 5305074e1d5SCristian Dumitrescu "pipeline port in link"); 5315074e1d5SCristian Dumitrescu return; 5325074e1d5SCristian Dumitrescu } 5335074e1d5SCristian Dumitrescu 5345074e1d5SCristian Dumitrescu link = link_find(obj, tokens[t0 + 1]); 5355074e1d5SCristian Dumitrescu if (!link) { 5365074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 5375074e1d5SCristian Dumitrescu "link_name"); 5385074e1d5SCristian Dumitrescu return; 5395074e1d5SCristian Dumitrescu } 5405074e1d5SCristian Dumitrescu params.dev_name = link->dev_name; 5415074e1d5SCristian Dumitrescu 5425074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 2], "rxq") != 0) { 5435074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq"); 5445074e1d5SCristian Dumitrescu return; 5455074e1d5SCristian Dumitrescu } 5465074e1d5SCristian Dumitrescu 5475074e1d5SCristian Dumitrescu if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) { 5485074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 5495074e1d5SCristian Dumitrescu "queue_id"); 5505074e1d5SCristian Dumitrescu return; 5515074e1d5SCristian Dumitrescu } 5525074e1d5SCristian Dumitrescu 5535074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 4], "bsz") != 0) { 5545074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz"); 5555074e1d5SCristian Dumitrescu return; 5565074e1d5SCristian Dumitrescu } 5575074e1d5SCristian Dumitrescu 5585074e1d5SCristian Dumitrescu if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) { 5595074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 5605074e1d5SCristian Dumitrescu "burst_size"); 5615074e1d5SCristian Dumitrescu return; 5625074e1d5SCristian Dumitrescu } 5635074e1d5SCristian Dumitrescu 5645074e1d5SCristian Dumitrescu t0 += 6; 5655074e1d5SCristian Dumitrescu 5665074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_in_config(p->p, 5675074e1d5SCristian Dumitrescu port_id, 5685074e1d5SCristian Dumitrescu "ethdev", 5695074e1d5SCristian Dumitrescu ¶ms); 5705074e1d5SCristian Dumitrescu } else if (strcmp(tokens[t0], "source") == 0) { 5715074e1d5SCristian Dumitrescu struct rte_swx_port_source_params params; 5725074e1d5SCristian Dumitrescu struct mempool *mp; 5735074e1d5SCristian Dumitrescu 5745074e1d5SCristian Dumitrescu if (n_tokens < t0 + 3) { 5755074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, 5765074e1d5SCristian Dumitrescu "pipeline port in source"); 5775074e1d5SCristian Dumitrescu return; 5785074e1d5SCristian Dumitrescu } 5795074e1d5SCristian Dumitrescu 5805074e1d5SCristian Dumitrescu mp = mempool_find(obj, tokens[t0 + 1]); 5815074e1d5SCristian Dumitrescu if (!mp) { 5825074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 5835074e1d5SCristian Dumitrescu "mempool_name"); 5845074e1d5SCristian Dumitrescu return; 5855074e1d5SCristian Dumitrescu } 5865074e1d5SCristian Dumitrescu params.pool = mp->m; 5875074e1d5SCristian Dumitrescu 5885074e1d5SCristian Dumitrescu params.file_name = tokens[t0 + 2]; 5895074e1d5SCristian Dumitrescu 5905074e1d5SCristian Dumitrescu t0 += 3; 5915074e1d5SCristian Dumitrescu 5925074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_in_config(p->p, 5935074e1d5SCristian Dumitrescu port_id, 5945074e1d5SCristian Dumitrescu "source", 5955074e1d5SCristian Dumitrescu ¶ms); 5965074e1d5SCristian Dumitrescu } else { 5975074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 5985074e1d5SCristian Dumitrescu return; 5995074e1d5SCristian Dumitrescu } 6005074e1d5SCristian Dumitrescu 6015074e1d5SCristian Dumitrescu if (status) { 6025074e1d5SCristian Dumitrescu snprintf(out, out_size, "port in error."); 6035074e1d5SCristian Dumitrescu return; 6045074e1d5SCristian Dumitrescu } 6055074e1d5SCristian Dumitrescu 6065074e1d5SCristian Dumitrescu if (n_tokens != t0) { 6075074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 6085074e1d5SCristian Dumitrescu return; 6095074e1d5SCristian Dumitrescu } 6105074e1d5SCristian Dumitrescu } 6115074e1d5SCristian Dumitrescu 6125074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_out_help[] = 6135074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port out <port_id>\n" 6145074e1d5SCristian Dumitrescu " link <link_name> txq <txq_id> bsz <burst_size>\n" 6155074e1d5SCristian Dumitrescu " | sink <file_name> | none\n"; 6165074e1d5SCristian Dumitrescu 6175074e1d5SCristian Dumitrescu static void 6185074e1d5SCristian Dumitrescu cmd_pipeline_port_out(char **tokens, 6195074e1d5SCristian Dumitrescu uint32_t n_tokens, 6205074e1d5SCristian Dumitrescu char *out, 6215074e1d5SCristian Dumitrescu size_t out_size, 6225074e1d5SCristian Dumitrescu void *obj) 6235074e1d5SCristian Dumitrescu { 6245074e1d5SCristian Dumitrescu struct pipeline *p; 6255074e1d5SCristian Dumitrescu int status; 6265074e1d5SCristian Dumitrescu uint32_t port_id = 0, t0; 6275074e1d5SCristian Dumitrescu 6285074e1d5SCristian Dumitrescu if (n_tokens < 6) { 6295074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 6305074e1d5SCristian Dumitrescu return; 6315074e1d5SCristian Dumitrescu } 6325074e1d5SCristian Dumitrescu 6335074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 6345074e1d5SCristian Dumitrescu if (!p || p->ctl) { 6355074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 6365074e1d5SCristian Dumitrescu return; 6375074e1d5SCristian Dumitrescu } 6385074e1d5SCristian Dumitrescu 6395074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "port") != 0) { 6405074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port"); 6415074e1d5SCristian Dumitrescu return; 6425074e1d5SCristian Dumitrescu } 6435074e1d5SCristian Dumitrescu 6445074e1d5SCristian Dumitrescu if (strcmp(tokens[3], "out") != 0) { 6455074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out"); 6465074e1d5SCristian Dumitrescu return; 6475074e1d5SCristian Dumitrescu } 6485074e1d5SCristian Dumitrescu 6495074e1d5SCristian Dumitrescu if (parser_read_uint32(&port_id, tokens[4]) != 0) { 6505074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "port_id"); 6515074e1d5SCristian Dumitrescu return; 6525074e1d5SCristian Dumitrescu } 6535074e1d5SCristian Dumitrescu 6545074e1d5SCristian Dumitrescu t0 = 5; 6555074e1d5SCristian Dumitrescu 6565074e1d5SCristian Dumitrescu if (strcmp(tokens[t0], "link") == 0) { 6575074e1d5SCristian Dumitrescu struct rte_swx_port_ethdev_writer_params params; 6585074e1d5SCristian Dumitrescu struct link *link; 6595074e1d5SCristian Dumitrescu 6605074e1d5SCristian Dumitrescu if (n_tokens < t0 + 6) { 6615074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, 6625074e1d5SCristian Dumitrescu "pipeline port out link"); 6635074e1d5SCristian Dumitrescu return; 6645074e1d5SCristian Dumitrescu } 6655074e1d5SCristian Dumitrescu 6665074e1d5SCristian Dumitrescu link = link_find(obj, tokens[t0 + 1]); 6675074e1d5SCristian Dumitrescu if (!link) { 6685074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 6695074e1d5SCristian Dumitrescu "link_name"); 6705074e1d5SCristian Dumitrescu return; 6715074e1d5SCristian Dumitrescu } 6725074e1d5SCristian Dumitrescu params.dev_name = link->dev_name; 6735074e1d5SCristian Dumitrescu 6745074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 2], "txq") != 0) { 6755074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq"); 6765074e1d5SCristian Dumitrescu return; 6775074e1d5SCristian Dumitrescu } 6785074e1d5SCristian Dumitrescu 6795074e1d5SCristian Dumitrescu if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) { 6805074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 6815074e1d5SCristian Dumitrescu "queue_id"); 6825074e1d5SCristian Dumitrescu return; 6835074e1d5SCristian Dumitrescu } 6845074e1d5SCristian Dumitrescu 6855074e1d5SCristian Dumitrescu if (strcmp(tokens[t0 + 4], "bsz") != 0) { 6865074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz"); 6875074e1d5SCristian Dumitrescu return; 6885074e1d5SCristian Dumitrescu } 6895074e1d5SCristian Dumitrescu 6905074e1d5SCristian Dumitrescu if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) { 6915074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, 6925074e1d5SCristian Dumitrescu "burst_size"); 6935074e1d5SCristian Dumitrescu return; 6945074e1d5SCristian Dumitrescu } 6955074e1d5SCristian Dumitrescu 6965074e1d5SCristian Dumitrescu t0 += 6; 6975074e1d5SCristian Dumitrescu 6985074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_out_config(p->p, 6995074e1d5SCristian Dumitrescu port_id, 7005074e1d5SCristian Dumitrescu "ethdev", 7015074e1d5SCristian Dumitrescu ¶ms); 7025074e1d5SCristian Dumitrescu } else if (strcmp(tokens[t0], "sink") == 0) { 7035074e1d5SCristian Dumitrescu struct rte_swx_port_sink_params params; 7045074e1d5SCristian Dumitrescu 7055074e1d5SCristian Dumitrescu params.file_name = strcmp(tokens[t0 + 1], "none") ? 7065074e1d5SCristian Dumitrescu tokens[t0 + 1] : NULL; 7075074e1d5SCristian Dumitrescu 7085074e1d5SCristian Dumitrescu t0 += 2; 7095074e1d5SCristian Dumitrescu 7105074e1d5SCristian Dumitrescu status = rte_swx_pipeline_port_out_config(p->p, 7115074e1d5SCristian Dumitrescu port_id, 7125074e1d5SCristian Dumitrescu "sink", 7135074e1d5SCristian Dumitrescu ¶ms); 7145074e1d5SCristian Dumitrescu } else { 7155074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 7165074e1d5SCristian Dumitrescu return; 7175074e1d5SCristian Dumitrescu } 7185074e1d5SCristian Dumitrescu 7195074e1d5SCristian Dumitrescu if (status) { 7205074e1d5SCristian Dumitrescu snprintf(out, out_size, "port out error."); 7215074e1d5SCristian Dumitrescu return; 7225074e1d5SCristian Dumitrescu } 7235074e1d5SCristian Dumitrescu 7245074e1d5SCristian Dumitrescu if (n_tokens != t0) { 7255074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 7265074e1d5SCristian Dumitrescu return; 7275074e1d5SCristian Dumitrescu } 7285074e1d5SCristian Dumitrescu } 7295074e1d5SCristian Dumitrescu 7305074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] = 7315074e1d5SCristian Dumitrescu "pipeline <pipeline_name> build <spec_file>\n"; 7325074e1d5SCristian Dumitrescu 7335074e1d5SCristian Dumitrescu static void 7345074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens, 7355074e1d5SCristian Dumitrescu uint32_t n_tokens, 7365074e1d5SCristian Dumitrescu char *out, 7375074e1d5SCristian Dumitrescu size_t out_size, 7385074e1d5SCristian Dumitrescu void *obj) 7395074e1d5SCristian Dumitrescu { 7405074e1d5SCristian Dumitrescu struct pipeline *p = NULL; 7415074e1d5SCristian Dumitrescu FILE *spec = NULL; 7425074e1d5SCristian Dumitrescu uint32_t err_line; 7435074e1d5SCristian Dumitrescu const char *err_msg; 7445074e1d5SCristian Dumitrescu int status; 7455074e1d5SCristian Dumitrescu 7465074e1d5SCristian Dumitrescu if (n_tokens != 4) { 7475074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 7485074e1d5SCristian Dumitrescu return; 7495074e1d5SCristian Dumitrescu } 7505074e1d5SCristian Dumitrescu 7515074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 7525074e1d5SCristian Dumitrescu if (!p || p->ctl) { 7535074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]); 7545074e1d5SCristian Dumitrescu return; 7555074e1d5SCristian Dumitrescu } 7565074e1d5SCristian Dumitrescu 7575074e1d5SCristian Dumitrescu spec = fopen(tokens[3], "r"); 7585074e1d5SCristian Dumitrescu if (!spec) { 7595074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]); 7605074e1d5SCristian Dumitrescu return; 7615074e1d5SCristian Dumitrescu } 7625074e1d5SCristian Dumitrescu 7635074e1d5SCristian Dumitrescu status = rte_swx_pipeline_build_from_spec(p->p, 7645074e1d5SCristian Dumitrescu spec, 7655074e1d5SCristian Dumitrescu &err_line, 7665074e1d5SCristian Dumitrescu &err_msg); 7675074e1d5SCristian Dumitrescu fclose(spec); 7685074e1d5SCristian Dumitrescu if (status) { 7695074e1d5SCristian Dumitrescu snprintf(out, out_size, "Error %d at line %u: %s\n.", 7705074e1d5SCristian Dumitrescu status, err_line, err_msg); 7715074e1d5SCristian Dumitrescu return; 7725074e1d5SCristian Dumitrescu } 7735074e1d5SCristian Dumitrescu 7745074e1d5SCristian Dumitrescu p->ctl = rte_swx_ctl_pipeline_create(p->p); 7755074e1d5SCristian Dumitrescu if (!p->ctl) { 7765074e1d5SCristian Dumitrescu snprintf(out, out_size, "Pipeline control create failed."); 7775074e1d5SCristian Dumitrescu rte_swx_pipeline_free(p->p); 7785074e1d5SCristian Dumitrescu return; 7795074e1d5SCristian Dumitrescu } 7805074e1d5SCristian Dumitrescu } 7815074e1d5SCristian Dumitrescu 7825074e1d5SCristian Dumitrescu static const char cmd_pipeline_table_update_help[] = 7835074e1d5SCristian Dumitrescu "pipeline <pipeline_name> table <table_name> update <file_name_add> " 7845074e1d5SCristian Dumitrescu "<file_name_delete> <file_name_default>"; 7855074e1d5SCristian Dumitrescu 7865074e1d5SCristian Dumitrescu static void 7875074e1d5SCristian Dumitrescu cmd_pipeline_table_update(char **tokens, 7885074e1d5SCristian Dumitrescu uint32_t n_tokens, 7895074e1d5SCristian Dumitrescu char *out, 7905074e1d5SCristian Dumitrescu size_t out_size, 7915074e1d5SCristian Dumitrescu void *obj) 7925074e1d5SCristian Dumitrescu { 7935074e1d5SCristian Dumitrescu struct pipeline *p; 7945074e1d5SCristian Dumitrescu char *pipeline_name, *table_name, *line = NULL; 7955074e1d5SCristian Dumitrescu char *file_name_add, *file_name_delete, *file_name_default; 7965074e1d5SCristian Dumitrescu FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL; 7975074e1d5SCristian Dumitrescu uint32_t line_id; 7985074e1d5SCristian Dumitrescu int status; 7995074e1d5SCristian Dumitrescu 8005074e1d5SCristian Dumitrescu if (n_tokens != 8) { 8015074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 8025074e1d5SCristian Dumitrescu return; 8035074e1d5SCristian Dumitrescu } 8045074e1d5SCristian Dumitrescu 8055074e1d5SCristian Dumitrescu pipeline_name = tokens[1]; 8065074e1d5SCristian Dumitrescu p = pipeline_find(obj, pipeline_name); 8075074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 8085074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 8095074e1d5SCristian Dumitrescu return; 8105074e1d5SCristian Dumitrescu } 8115074e1d5SCristian Dumitrescu 8125074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "table") != 0) { 8135074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table"); 8145074e1d5SCristian Dumitrescu return; 8155074e1d5SCristian Dumitrescu } 8165074e1d5SCristian Dumitrescu 8175074e1d5SCristian Dumitrescu table_name = tokens[3]; 8185074e1d5SCristian Dumitrescu 8195074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "update") != 0) { 8205074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update"); 8215074e1d5SCristian Dumitrescu return; 8225074e1d5SCristian Dumitrescu } 8235074e1d5SCristian Dumitrescu 8245074e1d5SCristian Dumitrescu file_name_add = tokens[5]; 8255074e1d5SCristian Dumitrescu file_name_delete = tokens[6]; 8265074e1d5SCristian Dumitrescu file_name_default = tokens[7]; 8275074e1d5SCristian Dumitrescu 8285074e1d5SCristian Dumitrescu /* File open. */ 8295074e1d5SCristian Dumitrescu if (strcmp(file_name_add, "none")) { 8305074e1d5SCristian Dumitrescu file_add = fopen(file_name_add, "r"); 8315074e1d5SCristian Dumitrescu if (!file_add) { 8325074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s", 8335074e1d5SCristian Dumitrescu file_name_add); 8345074e1d5SCristian Dumitrescu goto error; 8355074e1d5SCristian Dumitrescu } 8365074e1d5SCristian Dumitrescu } 8375074e1d5SCristian Dumitrescu 8385074e1d5SCristian Dumitrescu if (strcmp(file_name_delete, "none")) { 83964eaee23SCristian Dumitrescu file_delete = fopen(file_name_delete, "r"); 84064eaee23SCristian Dumitrescu if (!file_delete) { 8415074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s", 8425074e1d5SCristian Dumitrescu file_name_delete); 8435074e1d5SCristian Dumitrescu goto error; 8445074e1d5SCristian Dumitrescu } 8455074e1d5SCristian Dumitrescu } 8465074e1d5SCristian Dumitrescu 8475074e1d5SCristian Dumitrescu if (strcmp(file_name_default, "none")) { 84864eaee23SCristian Dumitrescu file_default = fopen(file_name_default, "r"); 84964eaee23SCristian Dumitrescu if (!file_default) { 8505074e1d5SCristian Dumitrescu snprintf(out, out_size, "Cannot open file %s", 8515074e1d5SCristian Dumitrescu file_name_default); 8525074e1d5SCristian Dumitrescu goto error; 8535074e1d5SCristian Dumitrescu } 8545074e1d5SCristian Dumitrescu } 8555074e1d5SCristian Dumitrescu 8565074e1d5SCristian Dumitrescu if (!file_add && !file_delete && !file_default) { 8575074e1d5SCristian Dumitrescu snprintf(out, out_size, "Nothing to be done."); 8585074e1d5SCristian Dumitrescu return; 8595074e1d5SCristian Dumitrescu } 8605074e1d5SCristian Dumitrescu 8615074e1d5SCristian Dumitrescu /* Buffer allocation. */ 8625074e1d5SCristian Dumitrescu line = malloc(2048); 8635074e1d5SCristian Dumitrescu if (!line) { 8645074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_OUT_OF_MEMORY); 8655074e1d5SCristian Dumitrescu goto error; 8665074e1d5SCristian Dumitrescu } 8675074e1d5SCristian Dumitrescu 8685074e1d5SCristian Dumitrescu /* Add. */ 86903665a48SCristian Dumitrescu if (file_add) 8705074e1d5SCristian Dumitrescu for (line_id = 1; ; line_id++) { 8715074e1d5SCristian Dumitrescu struct rte_swx_table_entry *entry; 8725074e1d5SCristian Dumitrescu 8735074e1d5SCristian Dumitrescu if (fgets(line, 2048, file_add) == NULL) 8745074e1d5SCristian Dumitrescu break; 8755074e1d5SCristian Dumitrescu 8765074e1d5SCristian Dumitrescu entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, 8775074e1d5SCristian Dumitrescu table_name, 8785074e1d5SCristian Dumitrescu line); 8795074e1d5SCristian Dumitrescu if (!entry) { 8805074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_FILE_ERR, 8815074e1d5SCristian Dumitrescu file_name_add, line_id); 8825074e1d5SCristian Dumitrescu goto error; 8835074e1d5SCristian Dumitrescu } 8845074e1d5SCristian Dumitrescu 8855074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_table_entry_add(p->ctl, 8865074e1d5SCristian Dumitrescu table_name, 8875074e1d5SCristian Dumitrescu entry); 8885074e1d5SCristian Dumitrescu if (status) { 8895074e1d5SCristian Dumitrescu snprintf(out, out_size, 8905074e1d5SCristian Dumitrescu "Invalid entry in file %s at line %u", 8915074e1d5SCristian Dumitrescu file_name_add, line_id); 8925074e1d5SCristian Dumitrescu goto error; 8935074e1d5SCristian Dumitrescu } 8945074e1d5SCristian Dumitrescu } 8955074e1d5SCristian Dumitrescu 8965074e1d5SCristian Dumitrescu 8975074e1d5SCristian Dumitrescu /* Delete. */ 89803665a48SCristian Dumitrescu if (file_delete) 8995074e1d5SCristian Dumitrescu for (line_id = 1; ; line_id++) { 9005074e1d5SCristian Dumitrescu struct rte_swx_table_entry *entry; 9015074e1d5SCristian Dumitrescu 9025074e1d5SCristian Dumitrescu if (fgets(line, 2048, file_delete) == NULL) 9035074e1d5SCristian Dumitrescu break; 9045074e1d5SCristian Dumitrescu 9055074e1d5SCristian Dumitrescu entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, 9065074e1d5SCristian Dumitrescu table_name, 9075074e1d5SCristian Dumitrescu line); 9085074e1d5SCristian Dumitrescu if (!entry) { 9095074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_FILE_ERR, 9105074e1d5SCristian Dumitrescu file_name_delete, line_id); 9115074e1d5SCristian Dumitrescu goto error; 9125074e1d5SCristian Dumitrescu } 9135074e1d5SCristian Dumitrescu 9145074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl, 9155074e1d5SCristian Dumitrescu table_name, 9165074e1d5SCristian Dumitrescu entry); 9175074e1d5SCristian Dumitrescu if (status) { 9185074e1d5SCristian Dumitrescu snprintf(out, out_size, 9195074e1d5SCristian Dumitrescu "Invalid entry in file %s at line %u", 9205074e1d5SCristian Dumitrescu file_name_delete, line_id); 9215074e1d5SCristian Dumitrescu goto error; 9225074e1d5SCristian Dumitrescu } 9235074e1d5SCristian Dumitrescu } 9245074e1d5SCristian Dumitrescu 9255074e1d5SCristian Dumitrescu /* Default. */ 92603665a48SCristian Dumitrescu if (file_default) 9275074e1d5SCristian Dumitrescu for (line_id = 1; ; line_id++) { 9285074e1d5SCristian Dumitrescu struct rte_swx_table_entry *entry; 9295074e1d5SCristian Dumitrescu 9305074e1d5SCristian Dumitrescu if (fgets(line, 2048, file_default) == NULL) 9315074e1d5SCristian Dumitrescu break; 9325074e1d5SCristian Dumitrescu 9335074e1d5SCristian Dumitrescu entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, 9345074e1d5SCristian Dumitrescu table_name, 9355074e1d5SCristian Dumitrescu line); 9365074e1d5SCristian Dumitrescu if (!entry) { 9375074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_FILE_ERR, 9385074e1d5SCristian Dumitrescu file_name_default, line_id); 9395074e1d5SCristian Dumitrescu goto error; 9405074e1d5SCristian Dumitrescu } 9415074e1d5SCristian Dumitrescu 9425074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl, 9435074e1d5SCristian Dumitrescu table_name, 9445074e1d5SCristian Dumitrescu entry); 9455074e1d5SCristian Dumitrescu if (status) { 9465074e1d5SCristian Dumitrescu snprintf(out, out_size, 9475074e1d5SCristian Dumitrescu "Invalid entry in file %s at line %u", 9485074e1d5SCristian Dumitrescu file_name_default, line_id); 9495074e1d5SCristian Dumitrescu goto error; 9505074e1d5SCristian Dumitrescu } 9515074e1d5SCristian Dumitrescu } 9525074e1d5SCristian Dumitrescu 9535074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_commit(p->ctl, 1); 9545074e1d5SCristian Dumitrescu if (status) { 9555074e1d5SCristian Dumitrescu snprintf(out, out_size, "Commit failed."); 9565074e1d5SCristian Dumitrescu goto error; 9575074e1d5SCristian Dumitrescu } 9585074e1d5SCristian Dumitrescu 9595074e1d5SCristian Dumitrescu 9605074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name); 9615074e1d5SCristian Dumitrescu 96203665a48SCristian Dumitrescu free(line); 96303665a48SCristian Dumitrescu if (file_add) 96403665a48SCristian Dumitrescu fclose(file_add); 96503665a48SCristian Dumitrescu if (file_delete) 96603665a48SCristian Dumitrescu fclose(file_delete); 96703665a48SCristian Dumitrescu if (file_default) 96803665a48SCristian Dumitrescu fclose(file_default); 9695074e1d5SCristian Dumitrescu return; 9705074e1d5SCristian Dumitrescu 9715074e1d5SCristian Dumitrescu error: 9725074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_abort(p->ctl); 9735074e1d5SCristian Dumitrescu free(line); 9745074e1d5SCristian Dumitrescu if (file_add) 9755074e1d5SCristian Dumitrescu fclose(file_add); 9765074e1d5SCristian Dumitrescu if (file_delete) 9775074e1d5SCristian Dumitrescu fclose(file_delete); 9785074e1d5SCristian Dumitrescu if (file_default) 9795074e1d5SCristian Dumitrescu fclose(file_default); 9805074e1d5SCristian Dumitrescu } 9815074e1d5SCristian Dumitrescu 9825074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] = 9835074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n"; 9845074e1d5SCristian Dumitrescu 9855074e1d5SCristian Dumitrescu static void 9865074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens, 9875074e1d5SCristian Dumitrescu uint32_t n_tokens, 9885074e1d5SCristian Dumitrescu char *out, 9895074e1d5SCristian Dumitrescu size_t out_size, 9905074e1d5SCristian Dumitrescu void *obj) 9915074e1d5SCristian Dumitrescu { 9925074e1d5SCristian Dumitrescu struct rte_swx_ctl_pipeline_info info; 9935074e1d5SCristian Dumitrescu struct pipeline *p; 9945074e1d5SCristian Dumitrescu uint32_t i; 9955074e1d5SCristian Dumitrescu int status; 9965074e1d5SCristian Dumitrescu 9975074e1d5SCristian Dumitrescu if (n_tokens != 3) { 9985074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 9995074e1d5SCristian Dumitrescu return; 10005074e1d5SCristian Dumitrescu } 10015074e1d5SCristian Dumitrescu 10025074e1d5SCristian Dumitrescu p = pipeline_find(obj, tokens[1]); 10035074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 10045074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 10055074e1d5SCristian Dumitrescu return; 10065074e1d5SCristian Dumitrescu } 10075074e1d5SCristian Dumitrescu 10085074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "stats")) { 10095074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats"); 10105074e1d5SCristian Dumitrescu return; 10115074e1d5SCristian Dumitrescu } 10125074e1d5SCristian Dumitrescu 10135074e1d5SCristian Dumitrescu status = rte_swx_ctl_pipeline_info_get(p->p, &info); 10145074e1d5SCristian Dumitrescu if (status) { 10155074e1d5SCristian Dumitrescu snprintf(out, out_size, "Pipeline info get error."); 10165074e1d5SCristian Dumitrescu return; 10175074e1d5SCristian Dumitrescu } 10185074e1d5SCristian Dumitrescu 10195074e1d5SCristian Dumitrescu snprintf(out, out_size, "Input ports:\n"); 10205074e1d5SCristian Dumitrescu out_size -= strlen(out); 10215074e1d5SCristian Dumitrescu out += strlen(out); 10225074e1d5SCristian Dumitrescu 10235074e1d5SCristian Dumitrescu for (i = 0; i < info.n_ports_in; i++) { 10245074e1d5SCristian Dumitrescu struct rte_swx_port_in_stats stats; 10255074e1d5SCristian Dumitrescu 10265074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats); 10275074e1d5SCristian Dumitrescu 10285074e1d5SCristian Dumitrescu snprintf(out, out_size, "\tPort %u:" 10295074e1d5SCristian Dumitrescu " packets %" PRIu64 10305074e1d5SCristian Dumitrescu " bytes %" PRIu64 10315074e1d5SCristian Dumitrescu " empty %" PRIu64 "\n", 10325074e1d5SCristian Dumitrescu i, stats.n_pkts, stats.n_bytes, stats.n_empty); 10335074e1d5SCristian Dumitrescu out_size -= strlen(out); 10345074e1d5SCristian Dumitrescu out += strlen(out); 10355074e1d5SCristian Dumitrescu } 10365074e1d5SCristian Dumitrescu 10375074e1d5SCristian Dumitrescu snprintf(out, out_size, "Output ports:\n"); 10385074e1d5SCristian Dumitrescu out_size -= strlen(out); 10395074e1d5SCristian Dumitrescu out += strlen(out); 10405074e1d5SCristian Dumitrescu 10415074e1d5SCristian Dumitrescu for (i = 0; i < info.n_ports_out; i++) { 10425074e1d5SCristian Dumitrescu struct rte_swx_port_out_stats stats; 10435074e1d5SCristian Dumitrescu 10445074e1d5SCristian Dumitrescu rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats); 10455074e1d5SCristian Dumitrescu 10465074e1d5SCristian Dumitrescu snprintf(out, out_size, "\tPort %u:" 10475074e1d5SCristian Dumitrescu " packets %" PRIu64 10485074e1d5SCristian Dumitrescu " bytes %" PRIu64 "\n", 10495074e1d5SCristian Dumitrescu i, stats.n_pkts, stats.n_bytes); 10505074e1d5SCristian Dumitrescu out_size -= strlen(out); 10515074e1d5SCristian Dumitrescu out += strlen(out); 10525074e1d5SCristian Dumitrescu } 10535074e1d5SCristian Dumitrescu } 10545074e1d5SCristian Dumitrescu 10555074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] = 10565074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n"; 10575074e1d5SCristian Dumitrescu 10585074e1d5SCristian Dumitrescu static void 10595074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens, 10605074e1d5SCristian Dumitrescu uint32_t n_tokens, 10615074e1d5SCristian Dumitrescu char *out, 10625074e1d5SCristian Dumitrescu size_t out_size, 10635074e1d5SCristian Dumitrescu void *obj) 10645074e1d5SCristian Dumitrescu { 10655074e1d5SCristian Dumitrescu char *pipeline_name; 10665074e1d5SCristian Dumitrescu struct pipeline *p; 10675074e1d5SCristian Dumitrescu uint32_t thread_id; 10685074e1d5SCristian Dumitrescu int status; 10695074e1d5SCristian Dumitrescu 10705074e1d5SCristian Dumitrescu if (n_tokens != 5) { 10715074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 10725074e1d5SCristian Dumitrescu return; 10735074e1d5SCristian Dumitrescu } 10745074e1d5SCristian Dumitrescu 10755074e1d5SCristian Dumitrescu if (parser_read_uint32(&thread_id, tokens[1]) != 0) { 10765074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); 10775074e1d5SCristian Dumitrescu return; 10785074e1d5SCristian Dumitrescu } 10795074e1d5SCristian Dumitrescu 10805074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "pipeline") != 0) { 10815074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); 10825074e1d5SCristian Dumitrescu return; 10835074e1d5SCristian Dumitrescu } 10845074e1d5SCristian Dumitrescu 10855074e1d5SCristian Dumitrescu pipeline_name = tokens[3]; 10865074e1d5SCristian Dumitrescu p = pipeline_find(obj, pipeline_name); 10875074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 10885074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 10895074e1d5SCristian Dumitrescu return; 10905074e1d5SCristian Dumitrescu } 10915074e1d5SCristian Dumitrescu 10925074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "enable") != 0) { 10935074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); 10945074e1d5SCristian Dumitrescu return; 10955074e1d5SCristian Dumitrescu } 10965074e1d5SCristian Dumitrescu 10975074e1d5SCristian Dumitrescu status = thread_pipeline_enable(thread_id, obj, pipeline_name); 10985074e1d5SCristian Dumitrescu if (status) { 10995074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable"); 11005074e1d5SCristian Dumitrescu return; 11015074e1d5SCristian Dumitrescu } 11025074e1d5SCristian Dumitrescu } 11035074e1d5SCristian Dumitrescu 11045074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] = 11055074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n"; 11065074e1d5SCristian Dumitrescu 11075074e1d5SCristian Dumitrescu static void 11085074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens, 11095074e1d5SCristian Dumitrescu uint32_t n_tokens, 11105074e1d5SCristian Dumitrescu char *out, 11115074e1d5SCristian Dumitrescu size_t out_size, 11125074e1d5SCristian Dumitrescu void *obj) 11135074e1d5SCristian Dumitrescu { 11145074e1d5SCristian Dumitrescu struct pipeline *p; 11155074e1d5SCristian Dumitrescu char *pipeline_name; 11165074e1d5SCristian Dumitrescu uint32_t thread_id; 11175074e1d5SCristian Dumitrescu int status; 11185074e1d5SCristian Dumitrescu 11195074e1d5SCristian Dumitrescu if (n_tokens != 5) { 11205074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); 11215074e1d5SCristian Dumitrescu return; 11225074e1d5SCristian Dumitrescu } 11235074e1d5SCristian Dumitrescu 11245074e1d5SCristian Dumitrescu if (parser_read_uint32(&thread_id, tokens[1]) != 0) { 11255074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); 11265074e1d5SCristian Dumitrescu return; 11275074e1d5SCristian Dumitrescu } 11285074e1d5SCristian Dumitrescu 11295074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "pipeline") != 0) { 11305074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); 11315074e1d5SCristian Dumitrescu return; 11325074e1d5SCristian Dumitrescu } 11335074e1d5SCristian Dumitrescu 11345074e1d5SCristian Dumitrescu pipeline_name = tokens[3]; 11355074e1d5SCristian Dumitrescu p = pipeline_find(obj, pipeline_name); 11365074e1d5SCristian Dumitrescu if (!p || !p->ctl) { 11375074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); 11385074e1d5SCristian Dumitrescu return; 11395074e1d5SCristian Dumitrescu } 11405074e1d5SCristian Dumitrescu 11415074e1d5SCristian Dumitrescu if (strcmp(tokens[4], "disable") != 0) { 11425074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable"); 11435074e1d5SCristian Dumitrescu return; 11445074e1d5SCristian Dumitrescu } 11455074e1d5SCristian Dumitrescu 11465074e1d5SCristian Dumitrescu status = thread_pipeline_disable(thread_id, obj, pipeline_name); 11475074e1d5SCristian Dumitrescu if (status) { 11485074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_FAIL, 11495074e1d5SCristian Dumitrescu "thread pipeline disable"); 11505074e1d5SCristian Dumitrescu return; 11515074e1d5SCristian Dumitrescu } 11525074e1d5SCristian Dumitrescu } 11535074e1d5SCristian Dumitrescu 11545074e1d5SCristian Dumitrescu static void 11555074e1d5SCristian Dumitrescu cmd_help(char **tokens, 11565074e1d5SCristian Dumitrescu uint32_t n_tokens, 11575074e1d5SCristian Dumitrescu char *out, 11585074e1d5SCristian Dumitrescu size_t out_size, 11595074e1d5SCristian Dumitrescu void *arg __rte_unused) 11605074e1d5SCristian Dumitrescu { 11615074e1d5SCristian Dumitrescu tokens++; 11625074e1d5SCristian Dumitrescu n_tokens--; 11635074e1d5SCristian Dumitrescu 11645074e1d5SCristian Dumitrescu if (n_tokens == 0) { 11655074e1d5SCristian Dumitrescu snprintf(out, out_size, 1166*7fef9ef1SYogesh Jangra "Type 'help <command>' for command details.\n\n" 1167*7fef9ef1SYogesh Jangra "List of commands:\n" 1168*7fef9ef1SYogesh Jangra "\tmempool\n" 1169*7fef9ef1SYogesh Jangra "\tlink\n" 1170*7fef9ef1SYogesh Jangra "\tpipeline create\n" 1171*7fef9ef1SYogesh Jangra "\tpipeline port in\n" 1172*7fef9ef1SYogesh Jangra "\tpipeline port out\n" 1173*7fef9ef1SYogesh Jangra "\tpipeline build\n" 1174*7fef9ef1SYogesh Jangra "\tpipeline table update\n" 1175*7fef9ef1SYogesh Jangra "\tpipeline stats\n" 1176*7fef9ef1SYogesh Jangra "\tthread pipeline enable\n" 1177*7fef9ef1SYogesh Jangra "\tthread pipeline disable\n\n"); 11785074e1d5SCristian Dumitrescu return; 11795074e1d5SCristian Dumitrescu } 11805074e1d5SCristian Dumitrescu 11815074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "mempool") == 0) { 11825074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_mempool_help); 11835074e1d5SCristian Dumitrescu return; 11845074e1d5SCristian Dumitrescu } 11855074e1d5SCristian Dumitrescu 11865074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "link") == 0) { 11875074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_link_help); 11885074e1d5SCristian Dumitrescu return; 11895074e1d5SCristian Dumitrescu } 11905074e1d5SCristian Dumitrescu 11915074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1192*7fef9ef1SYogesh Jangra (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) { 11935074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help); 11945074e1d5SCristian Dumitrescu return; 11955074e1d5SCristian Dumitrescu } 11965074e1d5SCristian Dumitrescu 11975074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1198*7fef9ef1SYogesh Jangra (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) { 1199*7fef9ef1SYogesh Jangra if (strcmp(tokens[2], "in") == 0) { 12005074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 12015074e1d5SCristian Dumitrescu cmd_pipeline_port_in_help); 12025074e1d5SCristian Dumitrescu return; 12035074e1d5SCristian Dumitrescu } 12045074e1d5SCristian Dumitrescu 1205*7fef9ef1SYogesh Jangra if (strcmp(tokens[2], "out") == 0) { 12065074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 12075074e1d5SCristian Dumitrescu cmd_pipeline_port_out_help); 12085074e1d5SCristian Dumitrescu return; 12095074e1d5SCristian Dumitrescu } 12105074e1d5SCristian Dumitrescu } 12115074e1d5SCristian Dumitrescu 12125074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1213*7fef9ef1SYogesh Jangra (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) { 12145074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help); 12155074e1d5SCristian Dumitrescu return; 12165074e1d5SCristian Dumitrescu } 12175074e1d5SCristian Dumitrescu 12185074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1219*7fef9ef1SYogesh Jangra (n_tokens == 3) && 1220*7fef9ef1SYogesh Jangra (strcmp(tokens[1], "table") == 0) && 1221*7fef9ef1SYogesh Jangra (strcmp(tokens[2], "update") == 0)) { 12225074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 12235074e1d5SCristian Dumitrescu cmd_pipeline_table_update_help); 12245074e1d5SCristian Dumitrescu return; 12255074e1d5SCristian Dumitrescu } 12265074e1d5SCristian Dumitrescu 12275074e1d5SCristian Dumitrescu if ((strcmp(tokens[0], "pipeline") == 0) && 1228*7fef9ef1SYogesh Jangra (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) { 12295074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help); 12305074e1d5SCristian Dumitrescu return; 12315074e1d5SCristian Dumitrescu } 12325074e1d5SCristian Dumitrescu 12335074e1d5SCristian Dumitrescu if ((n_tokens == 3) && 12345074e1d5SCristian Dumitrescu (strcmp(tokens[0], "thread") == 0) && 12355074e1d5SCristian Dumitrescu (strcmp(tokens[1], "pipeline") == 0)) { 12365074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "enable") == 0) { 12375074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 12385074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable_help); 12395074e1d5SCristian Dumitrescu return; 12405074e1d5SCristian Dumitrescu } 12415074e1d5SCristian Dumitrescu 12425074e1d5SCristian Dumitrescu if (strcmp(tokens[2], "disable") == 0) { 12435074e1d5SCristian Dumitrescu snprintf(out, out_size, "\n%s\n", 12445074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable_help); 12455074e1d5SCristian Dumitrescu return; 12465074e1d5SCristian Dumitrescu } 12475074e1d5SCristian Dumitrescu } 12485074e1d5SCristian Dumitrescu 12495074e1d5SCristian Dumitrescu snprintf(out, out_size, "Invalid command\n"); 12505074e1d5SCristian Dumitrescu } 12515074e1d5SCristian Dumitrescu 12525074e1d5SCristian Dumitrescu void 12535074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj) 12545074e1d5SCristian Dumitrescu { 12555074e1d5SCristian Dumitrescu char *tokens[CMD_MAX_TOKENS]; 12565074e1d5SCristian Dumitrescu uint32_t n_tokens = RTE_DIM(tokens); 12575074e1d5SCristian Dumitrescu int status; 12585074e1d5SCristian Dumitrescu 12595074e1d5SCristian Dumitrescu if (is_comment(in)) 12605074e1d5SCristian Dumitrescu return; 12615074e1d5SCristian Dumitrescu 12625074e1d5SCristian Dumitrescu status = parse_tokenize_string(in, tokens, &n_tokens); 12635074e1d5SCristian Dumitrescu if (status) { 12645074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_ARG_TOO_MANY, ""); 12655074e1d5SCristian Dumitrescu return; 12665074e1d5SCristian Dumitrescu } 12675074e1d5SCristian Dumitrescu 12685074e1d5SCristian Dumitrescu if (n_tokens == 0) 12695074e1d5SCristian Dumitrescu return; 12705074e1d5SCristian Dumitrescu 12715074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "help") == 0) { 12725074e1d5SCristian Dumitrescu cmd_help(tokens, n_tokens, out, out_size, obj); 12735074e1d5SCristian Dumitrescu return; 12745074e1d5SCristian Dumitrescu } 12755074e1d5SCristian Dumitrescu 12765074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "mempool") == 0) { 12775074e1d5SCristian Dumitrescu cmd_mempool(tokens, n_tokens, out, out_size, obj); 12785074e1d5SCristian Dumitrescu return; 12795074e1d5SCristian Dumitrescu } 12805074e1d5SCristian Dumitrescu 12815074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "link") == 0) { 12825074e1d5SCristian Dumitrescu if (strcmp(tokens[1], "show") == 0) { 12835074e1d5SCristian Dumitrescu cmd_link_show(tokens, n_tokens, out, out_size, obj); 12845074e1d5SCristian Dumitrescu return; 12855074e1d5SCristian Dumitrescu } 12865074e1d5SCristian Dumitrescu 12875074e1d5SCristian Dumitrescu cmd_link(tokens, n_tokens, out, out_size, obj); 12885074e1d5SCristian Dumitrescu return; 12895074e1d5SCristian Dumitrescu } 12905074e1d5SCristian Dumitrescu 12915074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "pipeline") == 0) { 12925074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 12935074e1d5SCristian Dumitrescu (strcmp(tokens[2], "create") == 0)) { 12945074e1d5SCristian Dumitrescu cmd_pipeline_create(tokens, n_tokens, out, out_size, 12955074e1d5SCristian Dumitrescu obj); 12965074e1d5SCristian Dumitrescu return; 12975074e1d5SCristian Dumitrescu } 12985074e1d5SCristian Dumitrescu 12995074e1d5SCristian Dumitrescu if ((n_tokens >= 4) && 13005074e1d5SCristian Dumitrescu (strcmp(tokens[2], "port") == 0) && 13015074e1d5SCristian Dumitrescu (strcmp(tokens[3], "in") == 0)) { 13025074e1d5SCristian Dumitrescu cmd_pipeline_port_in(tokens, n_tokens, out, out_size, 13035074e1d5SCristian Dumitrescu obj); 13045074e1d5SCristian Dumitrescu return; 13055074e1d5SCristian Dumitrescu } 13065074e1d5SCristian Dumitrescu 13075074e1d5SCristian Dumitrescu if ((n_tokens >= 4) && 13085074e1d5SCristian Dumitrescu (strcmp(tokens[2], "port") == 0) && 13095074e1d5SCristian Dumitrescu (strcmp(tokens[3], "out") == 0)) { 13105074e1d5SCristian Dumitrescu cmd_pipeline_port_out(tokens, n_tokens, out, out_size, 13115074e1d5SCristian Dumitrescu obj); 13125074e1d5SCristian Dumitrescu return; 13135074e1d5SCristian Dumitrescu } 13145074e1d5SCristian Dumitrescu 13155074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 13165074e1d5SCristian Dumitrescu (strcmp(tokens[2], "build") == 0)) { 13175074e1d5SCristian Dumitrescu cmd_pipeline_build(tokens, n_tokens, out, out_size, 13185074e1d5SCristian Dumitrescu obj); 13195074e1d5SCristian Dumitrescu return; 13205074e1d5SCristian Dumitrescu } 13215074e1d5SCristian Dumitrescu 13225074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 13235074e1d5SCristian Dumitrescu (strcmp(tokens[2], "table") == 0)) { 13245074e1d5SCristian Dumitrescu cmd_pipeline_table_update(tokens, n_tokens, out, 13255074e1d5SCristian Dumitrescu out_size, obj); 13265074e1d5SCristian Dumitrescu return; 13275074e1d5SCristian Dumitrescu } 13285074e1d5SCristian Dumitrescu 13295074e1d5SCristian Dumitrescu if ((n_tokens >= 3) && 13305074e1d5SCristian Dumitrescu (strcmp(tokens[2], "stats") == 0)) { 13315074e1d5SCristian Dumitrescu cmd_pipeline_stats(tokens, n_tokens, out, out_size, 13325074e1d5SCristian Dumitrescu obj); 13335074e1d5SCristian Dumitrescu return; 13345074e1d5SCristian Dumitrescu } 13355074e1d5SCristian Dumitrescu } 13365074e1d5SCristian Dumitrescu 13375074e1d5SCristian Dumitrescu if (strcmp(tokens[0], "thread") == 0) { 13385074e1d5SCristian Dumitrescu if ((n_tokens >= 5) && 13395074e1d5SCristian Dumitrescu (strcmp(tokens[4], "enable") == 0)) { 13405074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(tokens, n_tokens, 13415074e1d5SCristian Dumitrescu out, out_size, obj); 13425074e1d5SCristian Dumitrescu return; 13435074e1d5SCristian Dumitrescu } 13445074e1d5SCristian Dumitrescu 13455074e1d5SCristian Dumitrescu if ((n_tokens >= 5) && 13465074e1d5SCristian Dumitrescu (strcmp(tokens[4], "disable") == 0)) { 13475074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(tokens, n_tokens, 13485074e1d5SCristian Dumitrescu out, out_size, obj); 13495074e1d5SCristian Dumitrescu return; 13505074e1d5SCristian Dumitrescu } 13515074e1d5SCristian Dumitrescu } 13525074e1d5SCristian Dumitrescu 13535074e1d5SCristian Dumitrescu snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]); 13545074e1d5SCristian Dumitrescu } 13555074e1d5SCristian Dumitrescu 13565074e1d5SCristian Dumitrescu int 13575074e1d5SCristian Dumitrescu cli_script_process(const char *file_name, 13585074e1d5SCristian Dumitrescu size_t msg_in_len_max, 13595074e1d5SCristian Dumitrescu size_t msg_out_len_max, 13605074e1d5SCristian Dumitrescu void *obj) 13615074e1d5SCristian Dumitrescu { 13625074e1d5SCristian Dumitrescu char *msg_in = NULL, *msg_out = NULL; 13635074e1d5SCristian Dumitrescu FILE *f = NULL; 13645074e1d5SCristian Dumitrescu 13655074e1d5SCristian Dumitrescu /* Check input arguments */ 13665074e1d5SCristian Dumitrescu if ((file_name == NULL) || 13675074e1d5SCristian Dumitrescu (strlen(file_name) == 0) || 13685074e1d5SCristian Dumitrescu (msg_in_len_max == 0) || 13695074e1d5SCristian Dumitrescu (msg_out_len_max == 0)) 13705074e1d5SCristian Dumitrescu return -EINVAL; 13715074e1d5SCristian Dumitrescu 13725074e1d5SCristian Dumitrescu msg_in = malloc(msg_in_len_max + 1); 13735074e1d5SCristian Dumitrescu msg_out = malloc(msg_out_len_max + 1); 13745074e1d5SCristian Dumitrescu if ((msg_in == NULL) || 13755074e1d5SCristian Dumitrescu (msg_out == NULL)) { 13765074e1d5SCristian Dumitrescu free(msg_out); 13775074e1d5SCristian Dumitrescu free(msg_in); 13785074e1d5SCristian Dumitrescu return -ENOMEM; 13795074e1d5SCristian Dumitrescu } 13805074e1d5SCristian Dumitrescu 13815074e1d5SCristian Dumitrescu /* Open input file */ 13825074e1d5SCristian Dumitrescu f = fopen(file_name, "r"); 13835074e1d5SCristian Dumitrescu if (f == NULL) { 13845074e1d5SCristian Dumitrescu free(msg_out); 13855074e1d5SCristian Dumitrescu free(msg_in); 13865074e1d5SCristian Dumitrescu return -EIO; 13875074e1d5SCristian Dumitrescu } 13885074e1d5SCristian Dumitrescu 13895074e1d5SCristian Dumitrescu /* Read file */ 13905074e1d5SCristian Dumitrescu for ( ; ; ) { 13915074e1d5SCristian Dumitrescu if (fgets(msg_in, msg_in_len_max + 1, f) == NULL) 13925074e1d5SCristian Dumitrescu break; 13935074e1d5SCristian Dumitrescu 13945074e1d5SCristian Dumitrescu printf("%s", msg_in); 13955074e1d5SCristian Dumitrescu msg_out[0] = 0; 13965074e1d5SCristian Dumitrescu 13975074e1d5SCristian Dumitrescu cli_process(msg_in, 13985074e1d5SCristian Dumitrescu msg_out, 13995074e1d5SCristian Dumitrescu msg_out_len_max, 14005074e1d5SCristian Dumitrescu obj); 14015074e1d5SCristian Dumitrescu 14025074e1d5SCristian Dumitrescu if (strlen(msg_out)) 14035074e1d5SCristian Dumitrescu printf("%s", msg_out); 14045074e1d5SCristian Dumitrescu } 14055074e1d5SCristian Dumitrescu 14065074e1d5SCristian Dumitrescu /* Close file */ 14075074e1d5SCristian Dumitrescu fclose(f); 14085074e1d5SCristian Dumitrescu free(msg_out); 14095074e1d5SCristian Dumitrescu free(msg_in); 14105074e1d5SCristian Dumitrescu return 0; 14115074e1d5SCristian Dumitrescu } 1412