下面是一个DPDK KNI(Kernel NIC Interface)的使用例子,该代码会创建一个KNI设备,并通过KNI设备发送和接收数据包。
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/queue.h>
#include "rte_common.h"
#include "rte_ethdev.h"
#include "rte_ether.h"
#include "rte_ip.h"
#include "rte_kni.h"
#define MAX_PACKET_SZ 1024
static volatile bool force_quit;
static struct rte_kni *kni;
static void signal_handler(int signum)
{
if (signum == SIGINT || signum == SIGTERM)
force_quit = true;
}
/* display usage */
static void kni_usage(const char *prgname)
{
printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
" -p PORTMASK: hexadecimal bitmask of ports to configure\n",
prgname);
}
/* create a new KNI device */
static int kni_create(uint8_t port_id, struct rte_mempool *mbuf_pool,
uint16_t mbuf_sz, const char *if_name)
{
struct rte_kni_conf conf;
struct rte_eth_dev_info dev_info;
struct rte_pci_device *pci_dev = NULL;
int ret;
/* allocate the PCI device for the given port ID */
pci_dev = RTE_ETH_DEV_TO_PCI(rte_eth_devices[port_id]);
/* set up the KNI configuration structure */
memset(&conf, 0, sizeof(conf));
snprintf(conf.name, RTE_KNI_NAMESIZE, "%s", if_name);
conf.group_id = (uint16_t)port_id;
conf.mbuf_size = (uint16_t)mbuf_sz;
conf.addr = pci_dev->mem_resource[0].addr;
conf.id = pci_dev->id;
/* create the KNI device */
kni = rte_kni_alloc(mbuf_pool, &conf);
if (!kni) {
printf("Failed to create KNI device for port %u\n", port_id);
return -ENOMEM;
}
/* set the promiscuous mode for the associated Ethernet device */
ret = rte_eth_promiscuous_enable(port_id);
if (ret != 0) {
printf("Failed to enable promiscuous mode for port %u\n", port_id);
return ret;
}
/* get information about the associated Ethernet device */
memset(&dev_info, 0, sizeof(dev_info));
rte_eth_dev_info_get(port_id, &dev_info);
/* enable RX and TX for the associated Ethernet device */
ret = rte_eth_dev_start(port_id);
if (ret != 0) {
printf("Failed to start port %u\n", port_id);
return ret;
}
return 0;
}
/* send a packet through the KNI device */
static int kni_send(struct rte_mbuf *pkt)
{
uint16_t nb_tx;
nb_tx = rte_kni_tx_burst(kni, &pkt, 1);
if (nb_tx == 0)
rte_pktmbuf_free(pkt);
return nb_tx ? 0 : -ENOSPC;
}
/* receive packets from the KNI interface */
static void kni_receive(void)
{
struct rte_mbuf *pkts[MAX_PACKET_SZ];
uint16_t nb_rx;
while (!force_quit) {
nb_rx = rte_kni_rx_burst(kni, pkts, MAX_PACKET_SZ);
if (nb_rx == 0)
continue;
for (uint16_t i = 0; i < nb_rx; i++)
rte_pktmbuf_free(pkts[i]);
}
}
int main(int argc, char **argv)
{
int ret;
uint8_t port_id;
uint32_t port_mask = 0;
const char *prgname = argv[0];
struct rte_mempool *mbuf_pool = NULL;
/* initialize the EAL */
ret = rte_eal_init(argc, argv);
if (ret < 0) {
printf("Failed to initialize EAL: %s\n", strerror(errno));
return -1;
}
argc -= ret;
argv += ret;
/* parse application arguments */
ret = 0;
for (; argc > 0; argc--, argv++) {
if (strcmp(*argv, "-p") == 0) {
/* parse hexadecimal bitmask of ports to configure */
ret = sscanf(*(++argv), "%" SCNx32, &port_mask);
if (ret != 1)
kni_usage(prgname);
else if (!port_mask)
kni_usage(prgname);
} else {
kni_usage(prgname);
}
}
/* create a memory pool for packet buffers */
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
MBUF_CACHE_SIZE, 0,
RTE_MBUF_DEFAULT_BUF_SIZE,
rte_socket_id());
if (!mbuf_pool) {
printf("Failed to create packet buffer memory pool\n");
return -ENOMEM;
}
/* iterate over all enabled ports and create KNI devices */
RTE_ETH_FOREACH_DEV(port_id) {
if (!(port_mask & (1 << port_id)))
continue;
ret = kni_create(port_id, mbuf_pool, RTE_MBUF_DEFAULT_BUF_SIZE,
"eth%d");
if (ret != 0) {
printf("Failed to create KNI device for port %u\n", port_id);
return ret;
}
}
/* set up signal handlers */
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
/* start receiving packets from the KNI interface */
kni_receive();
/* free the KNI device and exit */
rte_kni_release(kni);
return 0;
}
注释如下:
kni_create()
:创建KNI设备并设置相关配置,其中包括名称、group ID、MBUF大小等;kni_send()
:通过KNI设备发送数据包;kni_receive()
:接收从KNI设备上发来的数据包,并释放这些数据包。
内容由零声教学AI助手提供,问题来源于学员提问