net/softnic: add connection agent
Add connection agent to enable connectivity with external agent (e.g. telnet, netcat, Python script, etc). Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
This commit is contained in:
parent
31ce8d8886
commit
7709a63bf1
@ -424,7 +424,7 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
|
||||
#
|
||||
# Compile SOFTNIC PMD
|
||||
#
|
||||
CONFIG_RTE_LIBRTE_PMD_SOFTNIC=y
|
||||
CONFIG_RTE_LIBRTE_PMD_SOFTNIC=n
|
||||
|
||||
#
|
||||
# Compile the TAP PMD
|
||||
|
@ -17,6 +17,7 @@ CONFIG_RTE_LIBRTE_VHOST_NUMA=y
|
||||
CONFIG_RTE_LIBRTE_PMD_VHOST=y
|
||||
CONFIG_RTE_LIBRTE_IFC_PMD=y
|
||||
CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
|
||||
CONFIG_RTE_LIBRTE_PMD_SOFTNIC=y
|
||||
CONFIG_RTE_LIBRTE_PMD_TAP=y
|
||||
CONFIG_RTE_LIBRTE_AVP_PMD=y
|
||||
CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD=y
|
||||
|
@ -34,10 +34,20 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_cli.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += parser.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += conn.c
|
||||
|
||||
#
|
||||
# Export include files
|
||||
#
|
||||
SYMLINK-y-include += rte_eth_softnic.h
|
||||
|
||||
ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
|
||||
$(info Softnic PMD can only operate in a linuxapp environment, \
|
||||
please change the definition of the RTE_TARGET environment variable)
|
||||
all:
|
||||
clean:
|
||||
else
|
||||
|
||||
include $(RTE_SDK)/mk/rte.lib.mk
|
||||
|
||||
endif
|
||||
|
332
drivers/net/softnic/conn.c
Normal file
332
drivers/net/softnic/conn.c
Normal file
@ -0,0 +1,332 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2010-2018 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define __USE_GNU
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "conn.h"
|
||||
|
||||
#define MSG_CMD_TOO_LONG "Command too long."
|
||||
|
||||
struct softnic_conn {
|
||||
char *welcome;
|
||||
char *prompt;
|
||||
char *buf;
|
||||
char *msg_in;
|
||||
char *msg_out;
|
||||
size_t buf_size;
|
||||
size_t msg_in_len_max;
|
||||
size_t msg_out_len_max;
|
||||
size_t msg_in_len;
|
||||
int fd_server;
|
||||
int fd_client_group;
|
||||
softnic_conn_msg_handle_t msg_handle;
|
||||
void *msg_handle_arg;
|
||||
};
|
||||
|
||||
struct softnic_conn *
|
||||
softnic_conn_init(struct softnic_conn_params *p)
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
struct softnic_conn *conn;
|
||||
int fd_server, fd_client_group, status;
|
||||
|
||||
memset(&server_address, 0, sizeof(server_address));
|
||||
|
||||
/* Check input arguments */
|
||||
if (p == NULL ||
|
||||
p->welcome == NULL ||
|
||||
p->prompt == NULL ||
|
||||
p->addr == NULL ||
|
||||
p->buf_size == 0 ||
|
||||
p->msg_in_len_max == 0 ||
|
||||
p->msg_out_len_max == 0 ||
|
||||
p->msg_handle == NULL)
|
||||
return NULL;
|
||||
|
||||
status = inet_aton(p->addr, &server_address.sin_addr);
|
||||
if (status == 0)
|
||||
return NULL;
|
||||
|
||||
/* Memory allocation */
|
||||
conn = calloc(1, sizeof(struct softnic_conn));
|
||||
if (conn == NULL)
|
||||
return NULL;
|
||||
|
||||
conn->welcome = calloc(1, CONN_WELCOME_LEN_MAX + 1);
|
||||
conn->prompt = calloc(1, CONN_PROMPT_LEN_MAX + 1);
|
||||
conn->buf = calloc(1, p->buf_size);
|
||||
conn->msg_in = calloc(1, p->msg_in_len_max + 1);
|
||||
conn->msg_out = calloc(1, p->msg_out_len_max + 1);
|
||||
|
||||
if (conn->welcome == NULL ||
|
||||
conn->prompt == NULL ||
|
||||
conn->buf == NULL ||
|
||||
conn->msg_in == NULL ||
|
||||
conn->msg_out == NULL) {
|
||||
softnic_conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Server socket */
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_port = htons(p->port);
|
||||
|
||||
fd_server = socket(AF_INET,
|
||||
SOCK_STREAM | SOCK_NONBLOCK,
|
||||
0);
|
||||
if (fd_server == -1) {
|
||||
softnic_conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = bind(fd_server,
|
||||
(struct sockaddr *)&server_address,
|
||||
sizeof(server_address));
|
||||
if (status == -1) {
|
||||
softnic_conn_free(conn);
|
||||
close(fd_server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = listen(fd_server, 16);
|
||||
if (status == -1) {
|
||||
softnic_conn_free(conn);
|
||||
close(fd_server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Client group */
|
||||
fd_client_group = epoll_create(1);
|
||||
if (fd_client_group == -1) {
|
||||
softnic_conn_free(conn);
|
||||
close(fd_server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fill in */
|
||||
strncpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX);
|
||||
strncpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX);
|
||||
conn->buf_size = p->buf_size;
|
||||
conn->msg_in_len_max = p->msg_in_len_max;
|
||||
conn->msg_out_len_max = p->msg_out_len_max;
|
||||
conn->msg_in_len = 0;
|
||||
conn->fd_server = fd_server;
|
||||
conn->fd_client_group = fd_client_group;
|
||||
conn->msg_handle = p->msg_handle;
|
||||
conn->msg_handle_arg = p->msg_handle_arg;
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
void
|
||||
softnic_conn_free(struct softnic_conn *conn)
|
||||
{
|
||||
if (conn == NULL)
|
||||
return;
|
||||
|
||||
if (conn->fd_client_group)
|
||||
close(conn->fd_client_group);
|
||||
|
||||
if (conn->fd_server)
|
||||
close(conn->fd_server);
|
||||
|
||||
free(conn->msg_out);
|
||||
free(conn->msg_in);
|
||||
free(conn->prompt);
|
||||
free(conn->welcome);
|
||||
free(conn);
|
||||
}
|
||||
|
||||
int
|
||||
softnic_conn_poll_for_conn(struct softnic_conn *conn)
|
||||
{
|
||||
struct sockaddr_in client_address;
|
||||
struct epoll_event event;
|
||||
socklen_t client_address_length;
|
||||
int fd_client, status;
|
||||
|
||||
/* Check input arguments */
|
||||
if (conn == NULL)
|
||||
return -1;
|
||||
|
||||
/* Server socket */
|
||||
client_address_length = sizeof(client_address);
|
||||
fd_client = accept4(conn->fd_server,
|
||||
(struct sockaddr *)&client_address,
|
||||
&client_address_length,
|
||||
SOCK_NONBLOCK);
|
||||
if (fd_client == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Client group */
|
||||
event.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;
|
||||
event.data.fd = fd_client;
|
||||
|
||||
status = epoll_ctl(conn->fd_client_group,
|
||||
EPOLL_CTL_ADD,
|
||||
fd_client,
|
||||
&event);
|
||||
if (status == -1) {
|
||||
close(fd_client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Client */
|
||||
status = write(fd_client,
|
||||
conn->welcome,
|
||||
strlen(conn->welcome));
|
||||
if (status == -1) {
|
||||
close(fd_client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = write(fd_client,
|
||||
conn->prompt,
|
||||
strlen(conn->prompt));
|
||||
if (status == -1) {
|
||||
close(fd_client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
data_event_handle(struct softnic_conn *conn,
|
||||
int fd_client)
|
||||
{
|
||||
ssize_t len, i, status;
|
||||
|
||||
/* Read input message */
|
||||
|
||||
len = read(fd_client,
|
||||
conn->buf,
|
||||
conn->buf_size);
|
||||
if (len == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
/* Handle input messages */
|
||||
for (i = 0; i < len; i++) {
|
||||
if (conn->buf[i] == '\n') {
|
||||
size_t n;
|
||||
|
||||
conn->msg_in[conn->msg_in_len] = 0;
|
||||
conn->msg_out[0] = 0;
|
||||
|
||||
conn->msg_handle(conn->msg_in,
|
||||
conn->msg_out,
|
||||
conn->msg_out_len_max,
|
||||
conn->msg_handle_arg);
|
||||
|
||||
n = strlen(conn->msg_out);
|
||||
if (n) {
|
||||
status = write(fd_client,
|
||||
conn->msg_out,
|
||||
n);
|
||||
if (status == -1)
|
||||
return status;
|
||||
}
|
||||
|
||||
conn->msg_in_len = 0;
|
||||
} else if (conn->msg_in_len < conn->msg_in_len_max) {
|
||||
conn->msg_in[conn->msg_in_len] = conn->buf[i];
|
||||
conn->msg_in_len++;
|
||||
} else {
|
||||
status = write(fd_client,
|
||||
MSG_CMD_TOO_LONG,
|
||||
strlen(MSG_CMD_TOO_LONG));
|
||||
if (status == -1)
|
||||
return status;
|
||||
|
||||
conn->msg_in_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write prompt */
|
||||
status = write(fd_client,
|
||||
conn->prompt,
|
||||
strlen(conn->prompt));
|
||||
if (status == -1)
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
control_event_handle(struct softnic_conn *conn,
|
||||
int fd_client)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = epoll_ctl(conn->fd_client_group,
|
||||
EPOLL_CTL_DEL,
|
||||
fd_client,
|
||||
NULL);
|
||||
if (status == -1)
|
||||
return -1;
|
||||
|
||||
status = close(fd_client);
|
||||
if (status == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
softnic_conn_poll_for_msg(struct softnic_conn *conn)
|
||||
{
|
||||
struct epoll_event event;
|
||||
int fd_client, status, status_data = 0, status_control = 0;
|
||||
|
||||
/* Check input arguments */
|
||||
if (conn == NULL)
|
||||
return -1;
|
||||
|
||||
/* Client group */
|
||||
status = epoll_wait(conn->fd_client_group,
|
||||
&event,
|
||||
1,
|
||||
0);
|
||||
if (status == -1)
|
||||
return -1;
|
||||
if (status == 0)
|
||||
return 0;
|
||||
|
||||
fd_client = event.data.fd;
|
||||
|
||||
/* Data available */
|
||||
if (event.events & EPOLLIN)
|
||||
status_data = data_event_handle(conn, fd_client);
|
||||
|
||||
/* Control events */
|
||||
if (event.events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP))
|
||||
status_control = control_event_handle(conn, fd_client);
|
||||
|
||||
if (status_data || status_control)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
49
drivers/net/softnic/conn.h
Normal file
49
drivers/net/softnic/conn.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2010-2018 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_CONN_H__
|
||||
#define __INCLUDE_CONN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct softnic_conn;
|
||||
|
||||
#ifndef CONN_WELCOME_LEN_MAX
|
||||
#define CONN_WELCOME_LEN_MAX 1024
|
||||
#endif
|
||||
|
||||
#ifndef CONN_PROMPT_LEN_MAX
|
||||
#define CONN_PROMPT_LEN_MAX 16
|
||||
#endif
|
||||
|
||||
typedef void (*softnic_conn_msg_handle_t)(char *msg_in,
|
||||
char *msg_out,
|
||||
size_t msg_out_len_max,
|
||||
void *arg);
|
||||
|
||||
struct softnic_conn_params {
|
||||
const char *welcome;
|
||||
const char *prompt;
|
||||
const char *addr;
|
||||
uint16_t port;
|
||||
size_t buf_size;
|
||||
size_t msg_in_len_max;
|
||||
size_t msg_out_len_max;
|
||||
softnic_conn_msg_handle_t msg_handle;
|
||||
void *msg_handle_arg;
|
||||
};
|
||||
|
||||
struct softnic_conn *
|
||||
softnic_conn_init(struct softnic_conn_params *p);
|
||||
|
||||
void
|
||||
softnic_conn_free(struct softnic_conn *conn);
|
||||
|
||||
int
|
||||
softnic_conn_poll_for_conn(struct softnic_conn *conn);
|
||||
|
||||
int
|
||||
softnic_conn_poll_for_msg(struct softnic_conn *conn);
|
||||
|
||||
#endif
|
@ -13,5 +13,6 @@ sources = files('rte_eth_softnic_tm.c',
|
||||
'rte_eth_softnic_pipeline.c',
|
||||
'rte_eth_softnic_thread.c',
|
||||
'rte_eth_softnic_cli.c',
|
||||
'parser.c')
|
||||
'parser.c',
|
||||
'conn.c')
|
||||
deps += ['pipeline', 'port', 'table', 'sched']
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include "rte_eth_softnic_internals.h"
|
||||
|
||||
#define PMD_PARAM_FIRMWARE "firmware"
|
||||
#define PMD_PARAM_CPU_ID "cpu_id"
|
||||
#define PMD_PARAM_SCRIPT "script"
|
||||
#define PMD_PARAM_CONN_PORT "conn_port"
|
||||
#define PMD_PARAM_CPU_ID "cpu_id"
|
||||
#define PMD_PARAM_TM_N_QUEUES "tm_n_queues"
|
||||
@ -31,6 +29,7 @@
|
||||
|
||||
static const char *pmd_valid_args[] = {
|
||||
PMD_PARAM_FIRMWARE,
|
||||
PMD_PARAM_CONN_PORT,
|
||||
PMD_PARAM_CPU_ID,
|
||||
PMD_PARAM_TM_N_QUEUES,
|
||||
PMD_PARAM_TM_QSIZE0,
|
||||
@ -40,6 +39,25 @@ static const char *pmd_valid_args[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char welcome[] =
|
||||
"\n"
|
||||
"Welcome to Soft NIC!\n"
|
||||
"\n";
|
||||
|
||||
static const char prompt[] = "softnic> ";
|
||||
|
||||
struct softnic_conn_params conn_params_default = {
|
||||
.welcome = welcome,
|
||||
.prompt = prompt,
|
||||
.addr = "0.0.0.0",
|
||||
.port = 0,
|
||||
.buf_size = 1024 * 1024,
|
||||
.msg_in_len_max = 1024,
|
||||
.msg_out_len_max = 1024 * 1024,
|
||||
.msg_handle = softnic_cli_process,
|
||||
.msg_handle_arg = NULL,
|
||||
};
|
||||
|
||||
static const struct rte_eth_dev_info pmd_dev_info = {
|
||||
.min_rx_bufsize = 0,
|
||||
.max_rx_pktlen = UINT32_MAX,
|
||||
@ -240,6 +258,21 @@ pmd_init(struct pmd_params *params)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (params->conn_port) {
|
||||
struct softnic_conn_params conn_params;
|
||||
|
||||
memcpy(&conn_params, &conn_params_default, sizeof(conn_params));
|
||||
conn_params.port = p->params.conn_port;
|
||||
conn_params.msg_handle_arg = p;
|
||||
|
||||
p->conn = softnic_conn_init(&conn_params);
|
||||
if (p->conn == NULL) {
|
||||
softnic_thread_free(p);
|
||||
rte_free(p);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -249,6 +282,9 @@ pmd_free(struct pmd_internals *p)
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
if (p->params.conn_port)
|
||||
softnic_conn_free(p->conn);
|
||||
|
||||
softnic_thread_free(p);
|
||||
softnic_pipeline_free(p);
|
||||
softnic_table_action_profile_free(p);
|
||||
@ -327,6 +363,17 @@ get_uint32(const char *key __rte_unused, const char *value, void *extra_args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_uint16(const char *key __rte_unused, const char *value, void *extra_args)
|
||||
{
|
||||
if (!value || !extra_args)
|
||||
return -EINVAL;
|
||||
|
||||
*(uint16_t *)extra_args = strtoull(value, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pmd_parse_args(struct pmd_params *p, const char *params)
|
||||
{
|
||||
@ -355,6 +402,14 @@ pmd_parse_args(struct pmd_params *p, const char *params)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Connection listening port (optional) */
|
||||
if (rte_kvargs_count(kvlist, PMD_PARAM_CONN_PORT) == 1) {
|
||||
ret = rte_kvargs_process(kvlist, PMD_PARAM_CONN_PORT,
|
||||
&get_uint16, &p->conn_port);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* CPU ID (optional) */
|
||||
if (rte_kvargs_count(kvlist, PMD_PARAM_CPU_ID) == 1) {
|
||||
ret = rte_kvargs_process(kvlist, PMD_PARAM_CPU_ID,
|
||||
@ -478,6 +533,7 @@ static struct rte_vdev_driver pmd_softnic_drv = {
|
||||
RTE_PMD_REGISTER_VDEV(net_softnic, pmd_softnic_drv);
|
||||
RTE_PMD_REGISTER_PARAM_STRING(net_softnic,
|
||||
PMD_PARAM_FIRMWARE "=<string> "
|
||||
PMD_PARAM_CONN_PORT "=<uint16> "
|
||||
PMD_PARAM_CPU_ID "=<uint32> "
|
||||
PMD_PARAM_TM_N_QUEUES "=<uint32> "
|
||||
PMD_PARAM_TM_QSIZE0 "=<uint32> "
|
||||
@ -493,3 +549,22 @@ RTE_INIT(pmd_softnic_init_log)
|
||||
if (pmd_softnic_logtype >= 0)
|
||||
rte_log_set_level(pmd_softnic_logtype, RTE_LOG_NOTICE);
|
||||
}
|
||||
|
||||
int
|
||||
rte_pmd_softnic_manage(uint16_t port_id)
|
||||
{
|
||||
struct rte_eth_dev *dev = &rte_eth_devices[port_id];
|
||||
struct pmd_internals *softnic;
|
||||
|
||||
#ifdef RTE_LIBRTE_ETHDEV_DEBUG
|
||||
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
|
||||
#endif
|
||||
|
||||
softnic = dev->data->dev_private;
|
||||
|
||||
softnic_conn_poll_for_conn(softnic->conn);
|
||||
|
||||
softnic_conn_poll_for_msg(softnic->conn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,6 +16,11 @@ extern "C" {
|
||||
#define SOFTNIC_FIRMWARE "firmware.cli"
|
||||
#endif
|
||||
|
||||
/** TCP connection port (0 = no connectivity). */
|
||||
#ifndef SOFTNIC_CONN_PORT
|
||||
#define SOFTNIC_CONN_PORT 0
|
||||
#endif
|
||||
|
||||
/** NUMA node ID. */
|
||||
#ifndef SOFTNIC_CPU_ID
|
||||
#define SOFTNIC_CPU_ID 0
|
||||
@ -42,6 +47,17 @@ extern "C" {
|
||||
int
|
||||
rte_pmd_softnic_run(uint16_t port_id);
|
||||
|
||||
/**
|
||||
* Soft NIC manage.
|
||||
*
|
||||
* @param port_id
|
||||
* Port ID of the Soft NIC device.
|
||||
* @return
|
||||
* Zero on success, error code otherwise.
|
||||
*/
|
||||
int __rte_experimental
|
||||
rte_pmd_softnic_manage(uint16_t port_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <rte_tm_driver.h>
|
||||
|
||||
#include "rte_eth_softnic.h"
|
||||
#include "conn.h"
|
||||
|
||||
#define NAME_SIZE 64
|
||||
|
||||
@ -32,6 +33,7 @@
|
||||
struct pmd_params {
|
||||
const char *name;
|
||||
const char *firmware;
|
||||
uint16_t conn_port;
|
||||
uint32_t cpu_id;
|
||||
|
||||
/** Traffic Management (TM) */
|
||||
@ -488,6 +490,7 @@ struct pmd_internals {
|
||||
struct tm_internals tm; /**< Traffic Management */
|
||||
} soft;
|
||||
|
||||
struct softnic_conn *conn;
|
||||
struct softnic_mempool_list mempool_list;
|
||||
struct softnic_swq_list swq_list;
|
||||
struct softnic_link_list link_list;
|
||||
|
@ -5,3 +5,9 @@ DPDK_17.11 {
|
||||
|
||||
local: *;
|
||||
};
|
||||
|
||||
EXPERIMENTAL {
|
||||
global:
|
||||
|
||||
rte_pmd_softnic_manage;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user