#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <bsd/string.h>
#include <stdint.h>
#include <strings.h>
#include <string.h>
#include "main.h"
static int
{
struct fwd_info *f = arg;
uint32_t cache_sz;
uint32_t total_region_cnt;
char *umem_addr;
size_t nlen;
if (!_obj)
return -1;
nlen = strnlen(obj.
opt->name, MAX_STRLEN_SIZE);
switch (obj.
hdr->cbtype) {
break;
break;
if (!strncmp(obj.
opt->name, PKT_API_TAG, nlen)) {
if (f->pkt_api == UNKNOWN_PKT_API)
f->pkt_api = get_pkt_api(f->opts.pkt_api);
}
}
else if (!strncmp(obj.
opt->name, NO_METRICS_TAG, nlen)) {
}
else if (!strncmp(obj.
opt->name, NO_RESTAPI_TAG, nlen)) {
}
else if (!strncmp(obj.
opt->name, ENABLE_CLI_TAG, nlen)) {
}
else if (!strncmp(obj.
opt->name, MODE_TAG, nlen)) {
if (f->test == UNKNOWN_TEST)
f->test = get_app_mode(f->opts.mode);
}
}
else if (!strncmp(obj.
opt->name, UDS_PATH_TAG, nlen)) {
f->xdp_uds = udsc_handshake(obj.
opt->
val.
str);
if (f->xdp_uds == NULL)
}
}
break;
if (f->pkt_api == UNKNOWN_PKT_API) {
f->pkt_api = XSKDEV_PKT_API;
"[yellow]**** [magenta]API type defaulting to use [cyan]%s [magenta]APIs[]\n",
XSKDEV_API_NAME);
}
total_region_cnt = 0;
total_region_cnt += ri->bufcnt;
}
CNE_ERR_RET(
"Total region bufcnt %d does not match UMEM bufcnt %d\n",
total_region_cnt / 1024, obj.
umem->
bufcnt / 1024);
CNE_ERR_RET(
"**** Failed to allocate mmap memory %ld\n",
cache_sz = MEMPOOL_CACHE_MAX_SIZE;
ri->addr = umem_addr;
if (!pi) {
CNE_ERR_RET(
"pktmbuf_pool_init() failed for region %d\n", i);
}
snprintf(name,
sizeof(name),
"%s-%d", obj.
umem->name, i);
ri->pool = pi;
}
break;
do {
struct fwd_port *pd;
struct lport_cfg pcfg = {0};
pd = calloc(1, sizeof(struct fwd_port));
if (!pd)
CNE_ERR_RET(
"Unable to allocate fwd_port structure\n");
lport->priv_ = pd;
cne_printf(
"[yellow]**** [green]SKB_MODE is [red]enabled[]\n");
cne_printf(
"[yellow]**** [green]BUSY_POLLING is [red]enabled[]\n");
pcfg.bufsz = umem->
bufsz;
pcfg.rx_nb_desc = umem->
rxdesc;
pcfg.tx_nb_desc = umem->
txdesc;
pcfg.flags = lport->
flags;
if (!pcfg.addr) {
free(pd);
CNE_ERR_RET(
"lport %s region index %d >= %d or not configured correctly\n",
}
if (f->xdp_uds)
pcfg.xsk_uds = f->xdp_uds;
else
}
strlcpy(pcfg.pmd_name, lport->
pmd_name,
sizeof(pcfg.pmd_name));
strlcpy(pcfg.ifname, lport->
netdev,
sizeof(pcfg.ifname));
strlcpy(pcfg.name, lport->name, sizeof(pcfg.name));
switch (f->pkt_api) {
case XSKDEV_PKT_API:
if (pd->xsk == NULL) {
free(pd);
CNE_ERR_RET(
"xskdev_port_setup(%s) failed\n", lport->name);
}
break;
case PKTDEV_PKT_API:
if (pd->lport < 0) {
free(pd);
CNE_ERR_RET(
"pktdev_port_setup(%s) failed\n", lport->name);
}
break;
default:
CNE_ERR_RET(
"lport %s API not supported %d\n", lport->name, f->pkt_api);
}
} while ((0));
break;
break;
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
if (f->test != UNKNOWN_TEST) {
struct thread_func_arg_t *func_arg;
func_arg = calloc(1, sizeof(struct thread_func_arg_t));
if (!func_arg)
CNE_ERR_RET(
"Allocation of struct thread_func_arg_t failed\n");
func_arg->fwd = f;
free(func_arg);
CNE_ERR_RET(
"Unable to create thread %d (%s) or type %s\n", idx, obj.
thd->name,
}
} else
} else
break;
break;
break;
default:
return -1;
}
return 0;
}
#define OPT_NO_COLOR "no-color"
#define OPT_NO_COLOR_NUM 256
static void
print_usage(char *prog_name)
{
cne_printf(
"Usage: %s [-h] [-c json_file] [-b burst] <mode>\n"
" <mode> Mode types [drop | rx-only], tx-only, [lb | loopback], fwd, "
"acl-strict or acl-permissive\n"
" -a <api> The API type to use xskdev or pktdev APIs, default is xskdev.\n"
" The -a option overrides JSON file.\n"
" -b <burst> Burst size. If not present default burst size %d max %d.\n"
" -c <json-file> The JSON configuration file\n"
" -C Wait on unix domain socket for JSON or JSON-C file\n"
" -d More debug stats are displayed\n"
" -D JCFG debug decoding\n"
" -V JCFG information verbose\n"
" -P JCFG debug parsing\n"
" -L [level] Enable a logging level\n"
" -h Display the help information\n"
" --%-12s Disable color output\n",
prog_name, BURST_SIZE, MAX_BURST_SIZE, OPT_NO_COLOR);
}
int
parse_args(int argc, char **argv, struct fwd_info *fwd)
{
struct option lgopts[] = {
{OPT_NO_COLOR, no_argument, NULL, OPT_NO_COLOR_NUM},
{NULL, 0, 0, 0}
};
int opt, option_index, flags = 0;
char json_file[1024] = {0};
char log_level[16] = {0};
fwd->pkt_api = UNKNOWN_PKT_API;
fwd->burst = BURST_SIZE;
for (;;) {
opt = getopt_long(argc, argv, "ha:b:c:dCDPVL:", lgopts, &option_index);
if (opt == EOF)
break;
switch (opt) {
case 'h':
print_usage(argv[0]);
return -1;
case 'a':
fwd->pkt_api = get_pkt_api(optarg);
break;
case 'b':
fwd->burst = atoi(optarg);
if (fwd->burst <= 0 || fwd->burst > MAX_BURST_SIZE)
fwd->burst = BURST_SIZE;
break;
case 'c':
strlcpy(json_file, optarg, sizeof(json_file));
break;
case 'd':
fwd->flags |= FWD_DEBUG_STATS;
break;
case 'C':
break;
case 'D':
break;
case 'P':
break;
case 'V':
break;
case 'L':
strlcpy(log_level, optarg, sizeof(log_level));
CNE_ERR("Invalid command option\n");
print_usage(argv[0]);
return -1;
}
break;
case OPT_NO_COLOR_NUM:
break;
default:
CNE_ERR("Invalid command option\n");
print_usage(argv[0]);
return -1;
}
}
if (optind < argc)
fwd->test = get_app_mode(argv[optind]);
fwd->jinfo =
jcfg_parser(flags, (
const char *)json_file);
if (fwd->jinfo == NULL)
CNE_ERR_RET(
"*** Did not find any configuration to use ***\n");
if (pthread_barrier_init(&fwd->barrier, NULL, jcfg_num_threads(fwd->jinfo)))
CNE_ERR_RET(
"*** Failed to initialize pthread barrier ***\n");
fwd->barrier_inited = true;
if (!fwd->opts.no_metrics && (enable_metrics(fwd) || enable_uds_info(fwd)))
CNE_ERR_RET(
"*** Failed to start metrics support ***\n");
if (fwd->test == ACL_STRICT_TEST || fwd->test == ACL_PERMISSIVE_TEST)
fwd->flags |= FWD_ACL_STATS;
if (fwd->test == UNKNOWN_TEST) {
fwd->test = DROP_TEST;
CNE_INFO("*** Mode type was not set in json file or command line, use drop mode ***\n");
}
return 0;
}
CNDP_API int cne_log_set_level_str(char *log_level)
#define LPORT_UNPRIVILEGED
#define LPORT_BUSY_POLLING
#define LPORT_SHARED_UMEM
CNDP_API void * mmap_addr(mmap_t *mm)
CNDP_API int mmap_free(mmap_t *mmap)
CNDP_API mmap_t * mmap_alloc(uint32_t bufcnt, uint32_t bufsz, mmap_type_t hugepage)
CNDP_API size_t mmap_size(mmap_t *mm, uint32_t *bufcnt, uint32_t *bufsz)
CNDP_API int cne_printf(const char *fmt,...)
CNDP_API int thread_create(const char *name, thd_func_t func, void *arg)
CNDP_API void tty_disable_color(void)
CNDP_API jcfg_info_t * jcfg_parser(int flags, const char *s)
static int jcfg_default_get_u32(jcfg_info_t *jinfo, const char *name, uint32_t *v)
CNDP_API char * jcfg_lport_region(jcfg_lport_t *lport, uint32_t *objcnt)
CNDP_API int jcfg_process(jcfg_info_t *jinfo, int flags, jcfg_parse_cb_t *cb, void *cb_arg)
CNDP_API int pktdev_port_setup(lport_cfg_t *c)
static void pktmbuf_info_name_set(pktmbuf_info_t *pi, const char *str)
CNDP_API pktmbuf_info_t * pktmbuf_pool_create(char *addr, uint32_t bufcnt, uint32_t bufsz, uint32_t cache_sz, mbuf_ops_t *ops)
CNDP_API xskdev_info_t * xskdev_socket_create(struct lport_cfg *c)