当前位置:网站首页>Dpdk - tcp/udp protocol stack server implementation (I)
Dpdk - tcp/udp protocol stack server implementation (I)
2022-06-26 06:25:00 【Ah Jie's small fish pond】
One 、 Introduce
In order to know more about the protocol stack , With the help of dpdk-19.11 Implement a simple protocol stack .
About dpdk Students can read this article :https://blog.csdn.net/hjlogzw/article/details/124561294?spm=1001.2014.3001.5502
Let's start with a frame composition :
The work to be completed in this project is as follows :
- dpdk Related configuration
- Implementation protocol stack , Mainly aimed at TCP And UDP, Contains three handshakes 、 Four waves
- Implement the server socket system call api:socket、bind、listen、accept、recv、send、recvfrom、sendto、recv、send、close
- Realization epoll Multithreading
Two 、DPDK To configure
dpdk, Mainly for network card devices to send and receive data packets , It is also responsible for assembling and parsing data packets , Send to applications such as TCP or UDP To deal with .
2.1 dpdk Environment initialization
if(rte_eal_init(argc, argv) < 0)
rte_exit(EXIT_FAILURE, "Error with EAL init\n");
pstMbufPoolPub = rte_pktmbuf_pool_create("MBUF_POOL_PUB", D_NUM_MBUFS, 0, 0,
RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
if(pstMbufPoolPub == NULL)
{
printf("rte_errno = %x, errmsg = %s\n", rte_errno, rte_strerror(rte_errno));
return -1;
}
2.2 Port and transceiver queue configuration
It mainly sets the sending and receiving queues of the network card .
struct rte_eth_conf stPortConf = // Port configuration information
{
.rxmode = {
.max_rx_pkt_len = 1518 } // RTE_ETHER_MAX_LEN = 1518
};
uiPortsNum = rte_eth_dev_count_avail();
if (uiPortsNum == 0)
rte_exit(EXIT_FAILURE, "No Supported eth found\n");
rte_eth_dev_info_get(D_PORT_ID, &stDevInfo);
// Configure Ethernet devices
rte_eth_dev_configure(D_PORT_ID, iRxQueueNum, iTxQueueNum, &stPortConf);
iRet = rte_eth_rx_queue_setup(D_PORT_ID, 0 , 1024, rte_eth_dev_socket_id(D_PORT_ID), NULL, pstMbufPoolPub);
if(iRet < 0)
rte_exit(EXIT_FAILURE, "Could not setup RX queue!\n");
stTxConf = stDevInfo.default_txconf;
stTxConf.offloads = stPortConf.txmode.offloads;
iRet = rte_eth_tx_queue_setup(D_PORT_ID, 0 , 1024, rte_eth_dev_socket_id(D_PORT_ID), &stTxConf);
if (iRet < 0)
rte_exit(EXIT_FAILURE, "Could not setup TX queue\n");
if (rte_eth_dev_start(D_PORT_ID) < 0 )
rte_exit(EXIT_FAILURE, "Could not start\n");
rte_eth_promiscuous_enable(D_PORT_ID);
// Set up IN、OUT queue , Store the received and sent packets of the network card in the queue
pstRing->pstInRing = rte_ring_create("in ring", D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);
pstRing->pstOutRing = rte_ring_create("out ring", D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);
2.3 Thread settings
dpdk have cpu Characteristics of affinity , You can bind separate for each thread cpu The core , This project sets up three worker threads : Network card packet distribution 、TCP Applications 、UDP Applications , Finish separately : Distribute and filter packets from the network card 、TCP Application layer business services 、UDP Application layer business services .
uiCoreId = rte_lcore_id();
uiCoreId = rte_get_next_lcore(uiCoreId, 1, 0);
rte_eal_remote_launch(pkt_process, pstMbufPoolPub, uiCoreId);
uiCoreId = rte_get_next_lcore(uiCoreId, 1, 0);
rte_eal_remote_launch(udp_server_entry, pstMbufPoolPub, uiCoreId);
uiCoreId = rte_get_next_lcore(uiCoreId, 1, 0);
rte_eal_remote_launch(tcp_server_entry, pstMbufPoolPub, uiCoreId);
The main thread is only responsible for putting the data from the network card into IN ring, Put the data to be sent to the network card into OUT ring, Realize decoupling .
while (1)
{
// rx
iRxNum = rte_eth_rx_burst(D_PORT_ID, 0, pstRecvMbuf, D_BURST_SIZE);
if(iRxNum > 0)
rte_ring_sp_enqueue_burst(pstRing->pstInRing, (void**)pstRecvMbuf, iRxNum, NULL);
// tx
iTotalNum = rte_ring_sc_dequeue_burst(pstRing->pstOutRing, (void**)pstSendMbuf, D_BURST_SIZE, NULL);
if(iTotalNum > 0)
{
iOffset = 0;
while(iOffset < iTotalNum)
{
iTxNum = rte_eth_tx_burst(D_PORT_ID, 0, &pstSendMbuf[iOffset], iTotalNum - iOffset);
if(iTxNum > 0)
iOffset += iTxNum;
}
}
}
3、 ... and 、 Summary
This article mainly introduces the architecture of the project , as well as DPDK Related configuration of .
Project links are as follows :
https://github.com/hjlogzw/DPDK-TCP-UDP_Protocol_Stack/tree/master
边栏推荐
猜你喜欢
随机推荐
Laravel 实现 groupBy 查询分组数量
Handwritten background management framework template (I)
获取当前月份的第一天和最后一天,上个月的第一天和最后一天
Self attention and multi head self attention (MSA) in transformer
Library management system
成水最多的容器
Comparison between Prometheus and ZABBIX
How to select and build a real-time data warehouse scheme
vs code 使用 prettier 格式化 js 的时候, 函数定义的名称和括号之间有一个空格, 而 eslit 又不允许这个空格.
SparseArray
去哪儿网BI平台建设演进史
[alluxio & Dachang] the original boss direct employment was applied in this way
C# Nuget离线缓存包安装
Efk Upgrade to clickhouse log Storage Reality
A new paradigm for large model application: unified feature representation optimization (UFO)
Number of connections server database message: error number 2003can't connect to MySQL server on 'server address' (10061)
EFK昇級到ClickHouse的日志存儲實戰
Zotero文献管理工具之Jasminum(茉莉花)插件
Implement the runnable interface
Market trend report, technical innovation and market forecast of China's valeryl chloride








