/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2016 Intel Corporation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
static volatile bool force_quit;
/* MAC updating enabled by default */
static int mac_updating = 1;
/* MAC updating,默认开启。若不开启,则是和basicfw一样的模式。开启后,会有如下影响:
The source MAC address is replaced by the TX_PORT MAC address
源MAC地址会改写成发送端口的MAC地址
The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID
改写目的MAC地址,改写为 02:00:00:00:00:<发送端口的port id>
*/
#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
#define MEMPOOL_CACHE_SIZE 256
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
/* ethernet addresses of ports */
static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS];
/* mask of enabled ports */
static uint32_t l2fwd_enabled_port_mask = 0;
/* list of enabled ports */
static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS];
static unsigned int l2fwd_rx_queue_per_lcore = 1; // 每个逻辑核最多可以用来处理几个端口/队列(L2fwd 一个端口分配各一个收发队列)
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct lcore_queue_conf { // 逻辑核上的队列配置
unsigned n_rx_port; // 该 lcore 上绑定多少个端口,也作为下一个数组的下标(0 ~ n-1)。
unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; // 存放一系列端口号,绑定哪些端口。
} __rte_cache_aligned;
// 这也就是 poll module driver 思想。绑定 lcore 和 port,特定的 lcore 轮询对应的一个或多个 port
struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; // 数组下标是 lcore id
static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; // 用于缓冲未来要发送的数据包的结构,API rte_eth_tx_buffer 和 rte_eth_tx_buffer_flush使用的结构
static struct rte_eth_conf port_conf = {
.rxmode = { // RX feature 见 flow_filtering
.split_hdr_size = 0,
.ignore_offload_bitfield = 1,
.offloads = DEV_RX_OFFLOAD_CRC_STRIP,
},
.txmode = { // TX feature
.mq_mode = ETH_MQ_TX_NONE, // mq_多队列选项,有一些宏来定义用多队列发包的方法
},
};
struct rte_mempool * l2fwd_pktmbuf_pool = NULL;
/* Per-port statistics struct */
struct l2fwd_port_statistics {
uint64_t tx; // 发包的数量
uint64_t rx; // 收包的数量
uint64_t dropped; // 丢包的数量
} __rte_cache_aligned;
struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS];
#define MAX_TIMER_PERIOD 86400 /* 1 day max */
/* A tsc-based timer responsible for triggering statistics printout */
// timer 负责每隔一段时间触发打印数据
static uint64_t timer_period = 10; /* default period is 10 seconds */
/* Print out statistics on packets dropped */
static void
print_stats(void)
{
uint64_t total_packets_dropped, total_packets_tx, total_packets_rx;
unsigned portid;
total_packets_dropped = 0;
total_packets_tx = 0;
total_packets_rx = 0;
const char clr[] = { 27, '[', '2', 'J', '\0' };
const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' };
/* Clear screen and move to top left */
printf("%s%s", clr, topLeft);
printf("\nPort statistics ====================================");
for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
/* skip disabled ports */
if ((l2fwd_enabled_port_mask & (1 << portid)) == 0)
continue;
printf("\nStatistics for port %u ------------------------------"
"\nPackets sent: %24"PRIu64
"\nPackets received: %20"PRIu64
"\nPackets dropped: %21"PRIu64,
portid,
port_statistics[portid].tx,
port_statistics[portid].rx,
port_statistics[portid].dropped);
total_packets_dropped += port_statistics[portid].dropped;
total_packets_tx += port_statistics[portid].tx;
total_packets_rx += port_statistics[portid].rx;
}
printf("\nAggregate statistics ==============================="
"\nTotal packets sent: %18"PRIu64
"\nTotal packets received: %14"PRIu64
"\nTotal packets dropped: %15"PRIu64,
total_packets_tx,
total_packets_rx,
total_packets_dropped);
printf("\n====================================================\n");
}
static void
l2fwd_mac_updating(struct rte_mbuf *m, unsigned dest_portid) // 改写包的 MAC 层信息
{
struct ether_hdr *eth;
void *tmp;
eth = rte_pktmbuf_mtod(m, struct ether_hdr *);
/* 02:00:00:
DPDK L2fwd 源码阅读
最新推荐文章于 2024-08-25 23:28:25 发布