当前位置:网站首页>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 :
 Insert picture description here
The work to be completed in this project is as follows :

  1. dpdk Related configuration
  2. Implementation protocol stack , Mainly aimed at TCP And UDP, Contains three handshakes 、 Four waves
  3. Implement the server socket system call api:socket、bind、listen、accept、recv、send、recvfrom、sendto、recv、send、close
  4. 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

原网站

版权声明
本文为[Ah Jie's small fish pond]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206260603367185.html