mirror of https://github.com/F-Stack/f-stack.git
Add kni type argument in config.ini and FF_KNI_KNI in lib/Makefile to set exception path type.
FF_KNI_KNI disabled by default and then: type 0 and 1 both use virtio_user. If enabled FF_KNI_KNI(and you must set meson -Ddisable_libs=flow_classif to re-enable kni driver in DPDK first): type:0 means use historical kni. type:1 means use virtio_user(linux only), see https://doc.dpdk.org/guides/howto/virtio_user_as_exception_path.html#virtio-user-as-exception-path.
This commit is contained in:
parent
a4834761df
commit
ba2a7fe957
|
@ -151,7 +151,9 @@ gateway=192.168.1.1
|
|||
# all packets that do not belong to the following tcp_port and udp_port
|
||||
# will transmit to kernel; if method=accept, all packets that belong to
|
||||
# the following tcp_port and udp_port will transmit to kernel.
|
||||
# type: exception path type, 0 means kni(must set meson -Ddisable_libs=flow_classif to re-enable kni in DPDK first), 1 means virtio_user(linux only)
|
||||
#[kni]
|
||||
#type=1
|
||||
#enable=1
|
||||
#method=reject
|
||||
# The format is same as port_list
|
||||
|
|
|
@ -33,6 +33,7 @@ HOST_OS:=$(shell uname -s)
|
|||
# No DPDK KNI support on FreeBSD
|
||||
ifneq ($(TGT_OS),FreeBSD)
|
||||
FF_KNI=1
|
||||
#FF_KNI_KNI=1
|
||||
endif
|
||||
|
||||
#FF_FLOW_ISOLATE=1
|
||||
|
@ -82,6 +83,10 @@ ifdef FF_KNI
|
|||
HOST_CFLAGS+= -DFF_KNI
|
||||
endif
|
||||
|
||||
ifdef FF_KNI_KNI
|
||||
HOST_CFLAGS+= -DFF_KNI_KNI
|
||||
endif
|
||||
|
||||
HOST_CFLAGS+= ${DPDK_CFLAGS}
|
||||
HOST_CFLAGS+= ${CONF_CFLAGS}
|
||||
|
||||
|
|
|
@ -697,6 +697,8 @@ ini_parse_handler(void* user, const char* section, const char* name,
|
|||
pconfig->dpdk.symmetric_rss = atoi(value);
|
||||
} else if (MATCH("kni", "enable")) {
|
||||
pconfig->kni.enable= atoi(value);
|
||||
} else if (MATCH("kni", "type")) {
|
||||
pconfig->kni.type= atoi(value);
|
||||
} else if (MATCH("kni", "kni_action")) {
|
||||
pconfig->kni.kni_action= strdup(value);
|
||||
} else if (MATCH("kni", "method")) {
|
||||
|
@ -1009,6 +1011,12 @@ ff_check_config(struct ff_config *cfg)
|
|||
lcore_id, pc->port_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cfg->kni.type != KNI_TYPE_KNI && cfg->kni.type != KNI_TYPE_VIRTIO) {
|
||||
fprintf(stderr,
|
||||
"kni type value must be 0 or 1, now is:%d\n", cfg->kni.type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ extern char *dpdk_argv[DPDK_CONFIG_NUM + 1];
|
|||
|
||||
#define VIP_MAX_NUM 64
|
||||
|
||||
/* exception path(KNI) type */
|
||||
#define KNI_TYPE_KNI 0
|
||||
#define KNI_TYPE_VIRTIO 1
|
||||
|
||||
struct ff_hw_features {
|
||||
uint8_t rx_csum;
|
||||
uint8_t rx_lro;
|
||||
|
@ -175,6 +179,7 @@ struct ff_config {
|
|||
|
||||
struct {
|
||||
int enable;
|
||||
int type;
|
||||
char *kni_action;
|
||||
char *method;
|
||||
char *tcp_port;
|
||||
|
|
262
lib/ff_dpdk_if.c
262
lib/ff_dpdk_if.c
|
@ -67,12 +67,13 @@
|
|||
|
||||
#ifdef FF_KNI
|
||||
#define KNI_MBUF_MAX 2048
|
||||
#define KNI_QUEUE_SIZE 2048
|
||||
#define KNI_QUEUE_SIZE KNI_MBUF_MAX
|
||||
|
||||
int enable_kni;
|
||||
int enable_kni = 0;
|
||||
static int kni_accept;
|
||||
static int knictl_action = FF_KNICTL_ACTION_DEFAULT;
|
||||
#endif
|
||||
int nb_dev_ports = 0; /* primary is correct, secondary is not correct, but no impact now*/
|
||||
|
||||
static int numa_on;
|
||||
|
||||
|
@ -237,7 +238,9 @@ check_all_ports_link_status(void)
|
|||
static int
|
||||
init_lcore_conf(void)
|
||||
{
|
||||
uint8_t nb_dev_ports = rte_eth_dev_count_avail();
|
||||
if (nb_dev_ports == 0) {
|
||||
nb_dev_ports = rte_eth_dev_count_avail();
|
||||
}
|
||||
if (nb_dev_ports == 0) {
|
||||
rte_exit(EXIT_FAILURE, "No probed ethernet devices\n");
|
||||
}
|
||||
|
@ -513,14 +516,16 @@ static enum FF_KNICTL_CMD get_kni_action(const char *c){
|
|||
static int
|
||||
init_kni(void)
|
||||
{
|
||||
int nb_ports = rte_eth_dev_count_avail();
|
||||
int nb_ports = nb_dev_ports;
|
||||
|
||||
kni_accept = 0;
|
||||
|
||||
if(strcasecmp(ff_global_cfg.kni.method, "accept") == 0)
|
||||
kni_accept = 1;
|
||||
|
||||
knictl_action = get_kni_action(ff_global_cfg.kni.kni_action);
|
||||
|
||||
ff_kni_init(nb_ports, ff_global_cfg.kni.tcp_port,
|
||||
ff_kni_init(nb_ports, ff_global_cfg.kni.type, ff_global_cfg.kni.tcp_port,
|
||||
ff_global_cfg.kni.udp_port);
|
||||
|
||||
unsigned socket_id = lcore_conf.socket_id;
|
||||
|
@ -530,7 +535,7 @@ init_kni(void)
|
|||
int i, ret;
|
||||
for (i = 0; i < nb_ports; i++) {
|
||||
uint16_t port_id = ff_global_cfg.dpdk.portid_list[i];
|
||||
ff_kni_alloc(port_id, socket_id, mbuf_pool, KNI_QUEUE_SIZE);
|
||||
ff_kni_alloc(port_id, socket_id, ff_global_cfg.kni.type, i, mbuf_pool, KNI_QUEUE_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -568,21 +573,47 @@ set_rss_table(uint16_t port_id, uint16_t reta_size, uint16_t nb_queues)
|
|||
static int
|
||||
init_port_start(void)
|
||||
{
|
||||
int nb_ports = ff_global_cfg.dpdk.nb_ports;
|
||||
int nb_ports = ff_global_cfg.dpdk.nb_ports, total_nb_ports;
|
||||
unsigned socketid = 0;
|
||||
struct rte_mempool *mbuf_pool;
|
||||
uint16_t i, j;
|
||||
|
||||
for (i = 0; i < nb_ports; i++) {
|
||||
uint16_t port_id, u_port_id = ff_global_cfg.dpdk.portid_list[i];
|
||||
struct ff_port_cfg *pconf = &ff_global_cfg.dpdk.port_cfgs[u_port_id];
|
||||
uint16_t nb_queues = pconf->nb_lcores;
|
||||
|
||||
if (pconf->nb_slaves > 0) {
|
||||
rte_eth_bond_8023ad_dedicated_queues_enable(u_port_id);
|
||||
total_nb_ports = nb_ports;
|
||||
#ifdef FF_KNI
|
||||
if (enable_kni && rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
#ifdef FF_KNI_KNI
|
||||
if (ff_global_cfg.kni.type == 1)
|
||||
#endif
|
||||
{
|
||||
total_nb_ports *= 2; /* one more virtio_user port for kernel per port */
|
||||
}
|
||||
for (j=0; j<=pconf->nb_slaves; j++) {
|
||||
if (j < pconf->nb_slaves) {
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < total_nb_ports; i++) {
|
||||
uint16_t port_id, u_port_id;
|
||||
struct ff_port_cfg *pconf = NULL;
|
||||
uint16_t nb_queues;
|
||||
int nb_slaves;
|
||||
|
||||
if (i < nb_ports) {
|
||||
u_port_id = ff_global_cfg.dpdk.portid_list[i];
|
||||
pconf = &ff_global_cfg.dpdk.port_cfgs[u_port_id];
|
||||
nb_queues = pconf->nb_lcores;
|
||||
nb_slaves = pconf->nb_slaves;
|
||||
|
||||
if (nb_slaves > 0) {
|
||||
rte_eth_bond_8023ad_dedicated_queues_enable(u_port_id);
|
||||
}
|
||||
} else {
|
||||
/* kernel virtio user, port id start from `nb_dev_ports` */
|
||||
u_port_id = i - nb_ports + nb_dev_ports;
|
||||
nb_queues = 1; /* see ff_kni_alloc in ff_dpdk_kni.c */
|
||||
nb_slaves = 0;
|
||||
}
|
||||
|
||||
|
||||
for (j = 0; j <= nb_slaves; j++) {
|
||||
if (j < nb_slaves) {
|
||||
port_id = pconf->slave_portid_list[j];
|
||||
printf("To init %s's %d'st slave port[%d]\n",
|
||||
ff_global_cfg.dpdk.bond_cfgs->name,
|
||||
|
@ -616,109 +647,108 @@ init_port_start(void)
|
|||
|
||||
struct rte_ether_addr addr;
|
||||
rte_eth_macaddr_get(port_id, &addr);
|
||||
printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
|
||||
" %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
|
||||
(unsigned)port_id,
|
||||
addr.addr_bytes[0], addr.addr_bytes[1],
|
||||
addr.addr_bytes[2], addr.addr_bytes[3],
|
||||
addr.addr_bytes[4], addr.addr_bytes[5]);
|
||||
printf("Port %u MAC:"RTE_ETHER_ADDR_PRT_FMT"\n",
|
||||
(unsigned)port_id, RTE_ETHER_ADDR_BYTES(&addr));
|
||||
|
||||
rte_memcpy(pconf->mac,
|
||||
addr.addr_bytes, RTE_ETHER_ADDR_LEN);
|
||||
/* Only config dev port, but not kernel virtio user port */
|
||||
if (pconf) {
|
||||
rte_memcpy(pconf->mac,
|
||||
addr.addr_bytes, RTE_ETHER_ADDR_LEN);
|
||||
|
||||
/* Set RSS mode */
|
||||
uint64_t default_rss_hf = RTE_ETH_RSS_PROTO_MASK;
|
||||
port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf = default_rss_hf;
|
||||
if (dev_info.hash_key_size == 52) {
|
||||
rsskey = default_rsskey_52bytes;
|
||||
rsskey_len = 52;
|
||||
}
|
||||
if (ff_global_cfg.dpdk.symmetric_rss) {
|
||||
printf("Use symmetric Receive-side Scaling(RSS) key\n");
|
||||
rsskey = symmetric_rsskey;
|
||||
}
|
||||
port_conf.rx_adv_conf.rss_conf.rss_key = rsskey;
|
||||
port_conf.rx_adv_conf.rss_conf.rss_key_len = rsskey_len;
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
|
||||
if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
|
||||
RTE_ETH_RSS_PROTO_MASK) {
|
||||
printf("Port %u modified RSS hash function based on hardware support,"
|
||||
"requested:%#"PRIx64" configured:%#"PRIx64"\n",
|
||||
port_id, default_rss_hf,
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf);
|
||||
}
|
||||
|
||||
if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
|
||||
port_conf.txmode.offloads |=
|
||||
RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
|
||||
}
|
||||
|
||||
/* Set Rx VLAN stripping */
|
||||
if (ff_global_cfg.dpdk.vlan_strip) {
|
||||
if (dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
|
||||
port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
|
||||
/* Set RSS mode */
|
||||
uint64_t default_rss_hf = RTE_ETH_RSS_PROTO_MASK;
|
||||
port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf = default_rss_hf;
|
||||
if (dev_info.hash_key_size == 52) {
|
||||
rsskey = default_rsskey_52bytes;
|
||||
rsskey_len = 52;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable HW CRC stripping */
|
||||
port_conf.rxmode.offloads &= ~RTE_ETH_RX_OFFLOAD_KEEP_CRC;
|
||||
|
||||
/* FIXME: Enable TCP LRO ?*/
|
||||
#if 0
|
||||
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
|
||||
printf("LRO is supported\n");
|
||||
port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_LRO;
|
||||
pconf->hw_features.rx_lro = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set Rx checksum checking */
|
||||
if ((dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) &&
|
||||
(dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_UDP_CKSUM) &&
|
||||
(dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_TCP_CKSUM)) {
|
||||
printf("RX checksum offload supported\n");
|
||||
port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM;
|
||||
pconf->hw_features.rx_csum = 1;
|
||||
}
|
||||
|
||||
if (ff_global_cfg.dpdk.tx_csum_offoad_skip == 0) {
|
||||
if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM)) {
|
||||
printf("TX ip checksum offload supported\n");
|
||||
port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM;
|
||||
pconf->hw_features.tx_csum_ip = 1;
|
||||
if (ff_global_cfg.dpdk.symmetric_rss) {
|
||||
printf("Use symmetric Receive-side Scaling(RSS) key\n");
|
||||
rsskey = symmetric_rsskey;
|
||||
}
|
||||
port_conf.rx_adv_conf.rss_conf.rss_key = rsskey;
|
||||
port_conf.rx_adv_conf.rss_conf.rss_key_len = rsskey_len;
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads;
|
||||
if (port_conf.rx_adv_conf.rss_conf.rss_hf !=
|
||||
RTE_ETH_RSS_PROTO_MASK) {
|
||||
printf("Port %u modified RSS hash function based on hardware support,"
|
||||
"requested:%#"PRIx64" configured:%#"PRIx64"\n",
|
||||
port_id, default_rss_hf,
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf);
|
||||
}
|
||||
|
||||
if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) &&
|
||||
(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_CKSUM)) {
|
||||
printf("TX TCP&UDP checksum offload supported\n");
|
||||
port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_UDP_CKSUM | RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
|
||||
pconf->hw_features.tx_csum_l4 = 1;
|
||||
if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
|
||||
port_conf.txmode.offloads |=
|
||||
RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
|
||||
}
|
||||
} else {
|
||||
printf("TX checksum offoad is disabled\n");
|
||||
}
|
||||
|
||||
if (ff_global_cfg.dpdk.tso) {
|
||||
if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_TSO) {
|
||||
printf("TSO is supported\n");
|
||||
port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
|
||||
pconf->hw_features.tx_tso = 1;
|
||||
/* Set Rx VLAN stripping */
|
||||
if (ff_global_cfg.dpdk.vlan_strip) {
|
||||
if (dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
|
||||
port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("TSO is not supported\n");
|
||||
|
||||
/* Enable HW CRC stripping */
|
||||
port_conf.rxmode.offloads &= ~RTE_ETH_RX_OFFLOAD_KEEP_CRC;
|
||||
|
||||
/* FIXME: Enable TCP LRO ?*/
|
||||
#if 0
|
||||
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
|
||||
printf("LRO is supported\n");
|
||||
port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_LRO;
|
||||
pconf->hw_features.rx_lro = 1;
|
||||
}
|
||||
} else {
|
||||
printf("TSO is disabled\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dev_info.reta_size) {
|
||||
/* reta size must be power of 2 */
|
||||
assert((dev_info.reta_size & (dev_info.reta_size - 1)) == 0);
|
||||
/* Set Rx checksum checking */
|
||||
if ((dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) &&
|
||||
(dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_UDP_CKSUM) &&
|
||||
(dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_TCP_CKSUM)) {
|
||||
printf("RX checksum offload supported\n");
|
||||
port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM;
|
||||
pconf->hw_features.rx_csum = 1;
|
||||
}
|
||||
|
||||
rss_reta_size[port_id] = dev_info.reta_size;
|
||||
printf("port[%d]: rss table size: %d\n", port_id,
|
||||
dev_info.reta_size);
|
||||
if (ff_global_cfg.dpdk.tx_csum_offoad_skip == 0) {
|
||||
if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM)) {
|
||||
printf("TX ip checksum offload supported\n");
|
||||
port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM;
|
||||
pconf->hw_features.tx_csum_ip = 1;
|
||||
}
|
||||
|
||||
if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) &&
|
||||
(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_CKSUM)) {
|
||||
printf("TX TCP&UDP checksum offload supported\n");
|
||||
port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_UDP_CKSUM | RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
|
||||
pconf->hw_features.tx_csum_l4 = 1;
|
||||
}
|
||||
} else {
|
||||
printf("TX checksum offoad is disabled\n");
|
||||
}
|
||||
|
||||
if (ff_global_cfg.dpdk.tso) {
|
||||
if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_TSO) {
|
||||
printf("TSO is supported\n");
|
||||
port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
|
||||
pconf->hw_features.tx_tso = 1;
|
||||
}
|
||||
else {
|
||||
printf("TSO is not supported\n");
|
||||
}
|
||||
} else {
|
||||
printf("TSO is disabled\n");
|
||||
}
|
||||
|
||||
if (dev_info.reta_size) {
|
||||
/* reta size must be power of 2 */
|
||||
assert((dev_info.reta_size & (dev_info.reta_size - 1)) == 0);
|
||||
|
||||
rss_reta_size[port_id] = dev_info.reta_size;
|
||||
printf("port[%d]: rss table size: %d\n", port_id,
|
||||
dev_info.reta_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
|
||||
|
@ -762,17 +792,12 @@ init_port_start(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (strncmp(dev_info.driver_name, BOND_DRIVER_NAME,
|
||||
strlen(dev_info.driver_name)) == 0) {
|
||||
|
||||
rte_eth_macaddr_get(port_id, &addr);
|
||||
printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
|
||||
" %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
|
||||
(unsigned)port_id,
|
||||
addr.addr_bytes[0], addr.addr_bytes[1],
|
||||
addr.addr_bytes[2], addr.addr_bytes[3],
|
||||
addr.addr_bytes[4], addr.addr_bytes[5]);
|
||||
printf("Port %u MAC:"RTE_ETHER_ADDR_PRT_FMT"\n",
|
||||
(unsigned)port_id, RTE_ETHER_ADDR_BYTES(&addr));
|
||||
|
||||
rte_memcpy(pconf->mac,
|
||||
addr.addr_bytes, RTE_ETHER_ADDR_LEN);
|
||||
|
@ -796,15 +821,16 @@ init_port_start(void)
|
|||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
//RSS reta update will failed when enable flow isolate
|
||||
#ifndef FF_FLOW_ISOLATE
|
||||
|
||||
//RSS reta update will failed when enable flow isolate
|
||||
#ifndef FF_FLOW_ISOLATE
|
||||
if (nb_queues > 1) {
|
||||
/*
|
||||
* FIXME: modify RSS set to FDIR
|
||||
*/
|
||||
set_rss_table(port_id, dev_info.reta_size, nb_queues);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Enable RX in promiscuous mode for the Ethernet device. */
|
||||
if (ff_global_cfg.dpdk.promiscuous) {
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
#include <rte_ether.h>
|
||||
#include <rte_bus_pci.h>
|
||||
#include <rte_ethdev.h>
|
||||
#ifdef FF_KNI_KNI
|
||||
#include <rte_kni.h>
|
||||
#endif
|
||||
#include <rte_malloc.h>
|
||||
#include <rte_ring.h>
|
||||
#include <rte_ip.h>
|
||||
|
@ -49,6 +51,10 @@
|
|||
/* Total octets in the FCS */
|
||||
#define KNI_ENET_FCS_SIZE 4
|
||||
|
||||
#ifndef RTE_KNI_NAMESIZE
|
||||
#define RTE_KNI_NAMESIZE 16
|
||||
#endif
|
||||
|
||||
#define set_bit(n, m) (n | magic_bits[m])
|
||||
#define clear_bit(n, m) (n & (~magic_bits[m]))
|
||||
#define get_bit(n, m) (n & magic_bits[m])
|
||||
|
@ -63,7 +69,12 @@ static unsigned char *tcp_port_bitmap = NULL;
|
|||
|
||||
/* Structure type for recording kni interface specific stats */
|
||||
struct kni_interface_stats {
|
||||
#ifdef FF_KNI_KNI
|
||||
struct rte_kni *kni;
|
||||
#endif
|
||||
|
||||
/* port id of dev or virtio_user */
|
||||
uint16_t port_id;
|
||||
|
||||
/* number of pkts received from NIC, and sent to KNI */
|
||||
uint64_t rx_packets;
|
||||
|
@ -123,6 +134,7 @@ kni_set_bitmap(const char *p, unsigned char *port_bitmap)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef FF_KNI_KNI
|
||||
/* Currently we don't support change mtu. */
|
||||
static int
|
||||
kni_change_mtu(uint16_t port_id, unsigned new_mtu)
|
||||
|
@ -200,6 +212,7 @@ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
kni_process_tx(uint16_t port_id, uint16_t queue_id,
|
||||
|
@ -209,13 +222,21 @@ kni_process_tx(uint16_t port_id, uint16_t queue_id,
|
|||
uint16_t nb_tx, nb_kni_tx;
|
||||
nb_tx = rte_ring_dequeue_burst(kni_rp[port_id], (void **)pkts_burst, count, NULL);
|
||||
|
||||
/* NB.
|
||||
* if nb_tx is 0,it must call rte_kni_tx_burst
|
||||
* must Call regularly rte_kni_tx_burst(kni, NULL, 0).
|
||||
* detail https://embedded.communities.intel.com/thread/6668
|
||||
*/
|
||||
nb_kni_tx = rte_kni_tx_burst(kni_stat[port_id]->kni, pkts_burst, nb_tx);
|
||||
rte_kni_handle_request(kni_stat[port_id]->kni);
|
||||
#ifdef FF_KNI_KNI
|
||||
if (ff_global_cfg.kni.type == KNI_TYPE_KNI) {
|
||||
/* NB.
|
||||
* if nb_tx is 0,it must call rte_kni_tx_burst
|
||||
* must Call regularly rte_kni_tx_burst(kni, NULL, 0).
|
||||
* detail https://embedded.communities.intel.com/thread/6668
|
||||
*/
|
||||
nb_kni_tx = rte_kni_tx_burst(kni_stat[port_id]->kni, pkts_burst, nb_tx);
|
||||
rte_kni_handle_request(kni_stat[port_id]->kni);
|
||||
} else if (ff_global_cfg.kni.type == KNI_TYPE_VIRTIO)
|
||||
#endif
|
||||
{
|
||||
nb_kni_tx = rte_eth_tx_burst(kni_stat[port_id]->port_id, 0, pkts_burst, nb_tx);
|
||||
}
|
||||
|
||||
if(nb_kni_tx < nb_tx) {
|
||||
uint16_t i;
|
||||
for(i = nb_kni_tx; i < nb_tx; ++i)
|
||||
|
@ -234,8 +255,16 @@ kni_process_rx(uint16_t port_id, uint16_t queue_id,
|
|||
{
|
||||
uint16_t nb_kni_rx, nb_rx;
|
||||
|
||||
/* read packet from kni, and transmit to phy port */
|
||||
nb_kni_rx = rte_kni_rx_burst(kni_stat[port_id]->kni, pkts_burst, count);
|
||||
#ifdef FF_KNI_KNI
|
||||
if (ff_global_cfg.kni.type == KNI_TYPE_KNI) {
|
||||
/* read packet from kni, and transmit to phy port */
|
||||
nb_kni_rx = rte_kni_rx_burst(kni_stat[port_id]->kni, pkts_burst, count);
|
||||
} else if (ff_global_cfg.kni.type == KNI_TYPE_VIRTIO)
|
||||
#endif
|
||||
{
|
||||
nb_kni_rx = rte_eth_rx_burst(kni_stat[port_id]->port_id, 0, pkts_burst, count);
|
||||
}
|
||||
|
||||
if (nb_kni_rx > 0) {
|
||||
nb_rx = rte_eth_tx_burst(port_id, queue_id, pkts_burst, nb_kni_rx);
|
||||
if (nb_rx < nb_kni_rx) {
|
||||
|
@ -426,7 +455,7 @@ ff_kni_proto_filter(const void *data, uint16_t len, uint16_t eth_frame_type)
|
|||
}
|
||||
|
||||
void
|
||||
ff_kni_init(uint16_t nb_ports, const char *tcp_ports, const char *udp_ports)
|
||||
ff_kni_init(uint16_t nb_ports, int type, const char *tcp_ports, const char *udp_ports)
|
||||
{
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
kni_stat = rte_zmalloc("kni:stat",
|
||||
|
@ -436,7 +465,11 @@ ff_kni_init(uint16_t nb_ports, const char *tcp_ports, const char *udp_ports)
|
|||
rte_exit(EXIT_FAILURE, "rte_zmalloc(1 (struct netio_kni_stat *)) "
|
||||
"failed\n");
|
||||
|
||||
rte_kni_init(nb_ports);
|
||||
if (type == KNI_TYPE_KNI) {
|
||||
#ifdef FF_KNI_KNI
|
||||
rte_kni_init(nb_ports);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t lcoreid = rte_lcore_id();
|
||||
|
@ -474,14 +507,12 @@ ff_kni_init(uint16_t nb_ports, const char *tcp_ports, const char *udp_ports)
|
|||
}
|
||||
|
||||
void
|
||||
ff_kni_alloc(uint16_t port_id, unsigned socket_id,
|
||||
ff_kni_alloc(uint16_t port_id, unsigned socket_id, int type, int port_idx,
|
||||
struct rte_mempool *mbuf_pool, unsigned ring_queue_size)
|
||||
{
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
struct rte_kni_conf conf;
|
||||
struct rte_kni_ops ops;
|
||||
struct rte_eth_dev_info dev_info;
|
||||
const struct rte_pci_device *pci_dev;
|
||||
struct rte_ether_addr addr = {0};
|
||||
int ret;
|
||||
|
||||
kni_stat[port_id] = (struct kni_interface_stats*)rte_zmalloc(
|
||||
|
@ -489,18 +520,14 @@ ff_kni_alloc(uint16_t port_id, unsigned socket_id,
|
|||
sizeof(struct kni_interface_stats),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
|
||||
if (kni_stat[port_id] == NULL)
|
||||
if (kni_stat[port_id] == NULL) {
|
||||
rte_panic("rte_zmalloc kni_interface_stats failed\n");
|
||||
}
|
||||
|
||||
/* only support one kni */
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
snprintf(conf.name, RTE_KNI_NAMESIZE, "veth%u", port_id);
|
||||
conf.core_id = rte_lcore_id();
|
||||
conf.force_bind = 1;
|
||||
conf.group_id = port_id;
|
||||
uint16_t mtu;
|
||||
rte_eth_dev_get_mtu(port_id, &mtu);
|
||||
conf.mbuf_size = mtu + KNI_ENET_HEADER_SIZE + KNI_ENET_FCS_SIZE;
|
||||
kni_stat[port_id]->rx_packets = 0;
|
||||
kni_stat[port_id]->rx_dropped = 0;
|
||||
kni_stat[port_id]->tx_packets = 0;
|
||||
kni_stat[port_id]->tx_dropped = 0;
|
||||
|
||||
memset(&dev_info, 0, sizeof(dev_info));
|
||||
ret = rte_eth_dev_info_get(port_id, &dev_info);
|
||||
|
@ -510,24 +537,65 @@ ff_kni_alloc(uint16_t port_id, unsigned socket_id,
|
|||
|
||||
/* Get the interface default mac address */
|
||||
rte_eth_macaddr_get(port_id,
|
||||
(struct rte_ether_addr *)&conf.mac_addr);
|
||||
(struct rte_ether_addr *)&addr);
|
||||
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.port_id = port_id;
|
||||
ops.change_mtu = kni_change_mtu;
|
||||
ops.config_network_if = kni_config_network_interface;
|
||||
ops.config_mac_address = kni_config_mac_address;
|
||||
printf("ff_kni_alloc get Port %u MAC:"RTE_ETHER_ADDR_PRT_FMT"\n",
|
||||
(unsigned)port_id, RTE_ETHER_ADDR_BYTES(&addr));
|
||||
|
||||
kni_stat[port_id]->kni = rte_kni_alloc(mbuf_pool, &conf, &ops);
|
||||
if (kni_stat[port_id]->kni == NULL)
|
||||
rte_panic("create kni on port %u failed!\n", port_id);
|
||||
else
|
||||
printf("create kni on port %u success!\n", port_id);
|
||||
#ifdef FF_KNI_KNI
|
||||
if (type == KNI_TYPE_KNI) {
|
||||
struct rte_kni_conf conf;
|
||||
struct rte_kni_ops ops;
|
||||
|
||||
kni_stat[port_id]->rx_packets = 0;
|
||||
kni_stat[port_id]->rx_dropped = 0;
|
||||
kni_stat[port_id]->tx_packets = 0;
|
||||
kni_stat[port_id]->tx_dropped = 0;
|
||||
/* only support one kni */
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
snprintf(conf.name, RTE_KNI_NAMESIZE, "veth%u", port_id);
|
||||
conf.core_id = rte_lcore_id();
|
||||
conf.force_bind = 1;
|
||||
conf.group_id = port_id;
|
||||
uint16_t mtu;
|
||||
rte_eth_dev_get_mtu(port_id, &mtu);
|
||||
conf.mbuf_size = mtu + KNI_ENET_HEADER_SIZE + KNI_ENET_FCS_SIZE;
|
||||
rte_memcpy(&conf.addr, addr.addr_bytes, RTE_ETHER_ADDR_LEN);
|
||||
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.port_id = port_id;
|
||||
ops.change_mtu = kni_change_mtu;
|
||||
ops.config_network_if = kni_config_network_interface;
|
||||
ops.config_mac_address = kni_config_mac_address;
|
||||
|
||||
kni_stat[port_id]->kni = rte_kni_alloc(mbuf_pool, &conf, &ops);
|
||||
if (kni_stat[port_id]->kni == NULL)
|
||||
rte_panic("create kni on port %u failed!\n", port_id);
|
||||
else
|
||||
printf("create kni on port %u success!\n", port_id);
|
||||
|
||||
kni_stat[port_id]->port_id = port_id;
|
||||
}else if (type == KNI_TYPE_VIRTIO)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* to add virtio port for exception path(KNI),
|
||||
* see https://doc.dpdk.org/guides/howto/virtio_user_as_exception_path.html#virtio-user-as-exception-path
|
||||
*/
|
||||
char port_name[32];
|
||||
char port_args[256];
|
||||
|
||||
/* set the name and arguments */
|
||||
snprintf(port_name, sizeof(port_name), "virtio_user%u", port_id);
|
||||
snprintf(port_args, sizeof(port_args),
|
||||
"path=/dev/vhost-net,queues=1,queue_size=%u,iface=veth%d,mac=" RTE_ETHER_ADDR_PRT_FMT,
|
||||
ring_queue_size, port_id, RTE_ETHER_ADDR_BYTES(&addr));
|
||||
printf("ff_kni_alloc to rte_eal_hotplug_add virtio user port, portname:%s, portargs:%s\n",
|
||||
port_name, port_args);
|
||||
|
||||
/* add the vdev for virtio_user */
|
||||
if (rte_eal_hotplug_add("vdev", port_name, port_args) < 0) {
|
||||
rte_exit(EXIT_FAILURE, "ff_kni_alloc cannot create virtio user paired port for port %u\n", port_id);
|
||||
}
|
||||
|
||||
kni_stat[port_id]->port_id = port_idx + nb_dev_ports;
|
||||
}
|
||||
}
|
||||
|
||||
char ring_name[RTE_KNI_NAMESIZE];
|
||||
|
@ -555,7 +623,7 @@ ff_kni_process(uint16_t port_id, uint16_t queue_id,
|
|||
struct rte_mbuf **pkts_burst, unsigned count)
|
||||
{
|
||||
kni_process_tx(port_id, queue_id, pkts_burst, count);
|
||||
kni_process_rx(port_id, queue_id, pkts_burst, count);
|
||||
kni_process_rx(port_id, queue_id,pkts_burst, count);
|
||||
}
|
||||
|
||||
/* enqueue the packet, and own it */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <rte_mempool.h>
|
||||
|
||||
extern int enable_kni;
|
||||
extern int nb_dev_ports;
|
||||
|
||||
enum FilterReturn {
|
||||
FILTER_UNKNOWN = -1,
|
||||
|
@ -42,10 +43,10 @@ enum FilterReturn {
|
|||
#endif
|
||||
};
|
||||
|
||||
void ff_kni_init(uint16_t nb_ports, const char *tcp_ports,
|
||||
void ff_kni_init(uint16_t nb_ports, int type, const char *tcp_ports,
|
||||
const char *udp_ports);
|
||||
|
||||
void ff_kni_alloc(uint16_t port_id, unsigned socket_id,
|
||||
void ff_kni_alloc(uint16_t port_id, unsigned socket_id, int type, int port_idx,
|
||||
struct rte_mempool *mbuf_pool, unsigned ring_queue_size);
|
||||
|
||||
void ff_kni_process(uint16_t port_id, uint16_t queue_id,
|
||||
|
|
Loading…
Reference in New Issue