使用DPDK实现UDP用户态协议栈,实现流程中包括:

三类线程

1、收发包线程

2、用户态协议栈线程

3、udp服务端线程

两类缓冲区:

1、协议栈收包缓冲区和协议栈发包缓冲区

2、udp收包缓冲区和udp发包缓冲区

协议栈缓冲区中存储的数据是struct rte_mbuf *指针

udp缓冲区中存储的数据是struct offload*指针

struct offload {
     uint32_t sip;
     uint32_t dip;
     
     uint16_t sport;
     uint16_t dport;
     
     int protocol;    unsigned char *data;
     uint16_t length;
 };
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

dpdk实现udp协议栈_数据

线程1:收发包线程

dpdk实现udp协议栈_数据_02

线程2:用户态协议栈线程

udp服务端线程会有多个,这里会根据报文的目的ip和目的端口,判断写入到哪个udp收包缓冲区

dpdk实现udp协议栈_网络协议_03

线程3:udp服务端线程

dpdk实现udp协议栈_数据_04


需要重写,socket,bind,recvfrom和sendto函数

1、socket函数

创建如下类型变量,并加入到链表中:

struct localhost {
     int fd;    uint32_t localip;    //网络字节序
     uint8_t localmac[RTE_ETHER_ADDR_LEN];
     uint16_t localport;    //网络字节序
     uint8_t protocol;    struct rte_ring *sndbuffer;
     struct rte_ring *rcvbuffer;    struct localhost *prev;
     struct localhost *next;    pthread_cond_t cond;
     pthread_mutex_t mutex;
 };
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

2、bind

将ip和端口赋值到struct localhos变量中,并分配sndbuffer和rcvbuffer缓冲区,初始化条件变量和互斥锁

3、recvfrom

从rcvbuffer缓冲区中读取数据,如果rcvbuffer没数据,则通过条件变量进行等待。(udp协议栈往rcvbuffer写入数据时,需要发送条件变量唤醒信号)

4、sendto

将需要发送的数据写入sendbuffer中