DPDK学习(基础知识)

名词解释

简称 全称 备注
DPDK Data Plane Development Kit 数据平面开发套件
RTE RunTime Environment 运行时环境
EAL Environment Abstraction Layer 环境抽象层
lcore logical core EAL pthread
TLS Thread Local Storage 线程本地存储

lcore

一个lcore就是一个基于pthread实现的线程,不同的lcore可以亲和到不同的logical CPU,它们之间是多对多的关系。在当前线程中调用rte_eal_init()后,当前线程会被设置成MASTER lcore,MASTER lcore会根据lcore的个数创建SLAVE lcore

对于多个线程运行在一个logical CPU上的情形,有两种处理办法:

  • 使用–lcores参数指定lcore及亲和到的logical CPU,全部使用EAL pthread(个人推荐的方法)
  • 第一个线程直接使用EAL pthread,其它线程使用通过pthread_create()创建的用户线程并绑核

rte_mbuf

http://dpdk.org/doc/guides/prog_guide/mbuf_lib.html
https://www.cnblogs.com/MerlinJ/p/4284706.html

一般在MASTER lcore中调用rte_pktmbuf_pool_create()创建一个rte_mempool,在创建rte_mempool时需要指定包含多少个rte_mbuf以及每个rte_mbuf的大小

一个rte_mbuf通常存储一个L2报文,比较大的L2报文可能需要多个rte_mbuf存储

调用rte_eth_rx_burst()收包后,网卡读上来的L2报文存储在rte_mbuf后面,通过宏rte_pktmbuf_mtod(m, struct ether_hdr*)可以得到L2报文的以太网头指针

rte_ring

http://dpdk-docs.readthedocs.io/en/latest/prog_guide/ring_lib.html

1、修改r->prod.head指向本地变量prod_next(CAS操作)

  • 如果r->prod.head等于本地变量prod_head,修改ring->prod.head指向本地变量prod_next,CAS操作成功
  • 如果r->prod.head不等于本地变量prod_head,CAS操作失败

2、修改r->prod.tail指向r->prod.head:只有r->prod.tail等于本地变量prod_head才能修改

struct rte_ring_headtail {
   volatile uint32_t head;  /**< Prod/consumer head. */
   volatile uint32_t tail;  /**< Prod/consumer tail. */
   uint32_t single;         /**< True if single prod/cons */
};

struct rte_ring {
   char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned; /**< Name of the ring. */
   int flags;               /**< Flags supplied at creation. */
   const struct rte_memzone *memzone;
         /**< Memzone, if any, containing the rte_ring */
   uint32_t size;           /**< Size of ring. */
   uint32_t mask;           /**< Mask (size-1) of ring. */
   uint32_t capacity;       /**< Usable size of ring */
 
   /** Ring producer status. */
   struct rte_ring_headtail prod __rte_aligned(PROD_ALIGN);
 
   /** Ring consumer status. */
   struct rte_ring_headtail cons __rte_aligned(CONS_ALIGN);
};

报文结构体

type fomart
Ethernet https://en.wikipedia.org/wiki/IEEE_802.1Q
ARP https://en.wikipedia.org/wiki/Address_Resolution_Protocol
IPv4 https://en.wikipedia.org/wiki/IPv4
ICMP https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
TCP https://en.wikipedia.org/wiki/Transmission_Control_Protocol
UDP https://en.wikipedia.org/wiki/User_Datagram_Protocol
VXLAN https://datatracker.ietf.org/doc/rfc7348/?include_text=1

以上各种报文在DPDK中的定义如下:

struct ether_addr {
   uint8_t addr_bytes[ETHER_ADDR_LEN]; /**< Addr bytes in tx order */ // 包含6个uint8_t的数组表示MAC地址
} __attribute__((__packed__));
 
struct ether_hdr {
   struct ether_addr d_addr; /**< Destination address. */ // 目的MAC地址
   struct ether_addr s_addr; /**< Source address. */      // 源MAC地址
   uint16_t ether_type;      /**< Frame type. */          // 不带VLAN时:类型(IP为0x0800、ARP为0x0806)
                                                          // 带VLAN时:TPID(0x8100)
} __attribute__((__packed__));
 
struct vlan_hdr {
   uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */ // 3位PCP + 1位DEI + 12位VID
   uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */          // 类型(IP为0x0800、ARP为0x0806)
} __attribute__((__packed__));

struct arp_ipv4 {
	struct ether_addr arp_sha;  /**< sender hardware address */ // 发送端以太网地址
	uint32_t          arp_sip;  /**< sender IP address */       // 发送端IP地址
	struct ether_addr arp_tha;  /**< target hardware address */ // 目的以太网地址
	uint32_t          arp_tip;  /**< target IP address */       // 目的IP地址
} __attribute__((__packed__));

struct arp_hdr {
	uint16_t arp_hrd;    /* format of hardware address */           // 硬件类型
#define ARP_HRD_ETHER     1  /* ARP Ethernet address format */

	uint16_t arp_pro;    /* format of protocol address */           // 协议类型
	uint8_t  arp_hln;    /* length of hardware address */           // 硬件地址长度
	uint8_t  arp_pln;    /* length of protocol address */           // 协议地址长度
	uint16_t arp_op;     /* ARP opcode (command) */
#define	ARP_OP_REQUEST    1 /* request to resolve address */
#define	ARP_OP_REPLY      2 /* response to previous request */
#define	ARP_OP_REVREQUEST 3 /* request proto addr given hardware */ 
#define	ARP_OP_REVREPLY   4 /* response giving protocol address */
#define	ARP_OP_INVREQUEST 8 /* request to identify peer */
#define	ARP_OP_INVREPLY   9 /* response identifying peer */

	struct arp_ipv4 arp_data;
} __attribute__((__packed__));
 
struct ipv4_hdr {
   uint8_t  version_ihl;     /**< version and header length */ // 4位版本 + 4位首部长度(word数)
   uint8_t  type_of_service;  /**< type of service */
   uint16_t total_length;    /**< length of packet */          // 总长度
   uint16_t packet_id;       /**< packet ID */
   uint16_t fragment_offset;  /**< fragmentation offset */
   uint8_t  time_to_live;    /**< time to live */
   uint8_t  next_proto_id;       /**< protocol ID */           // 协议(ICMP为1、TCP为6、UDP为17、GRE为47)
   uint16_t hdr_checksum;    /**< header checksum */
   uint32_t src_addr;    /**< source address */                // 源IP地址
   uint32_t dst_addr;    /**< destination address */           // 目的IP地址
} __attribute__((__packed__));

struct icmp_hdr {
   uint8_t  icmp_type;   /* ICMP packet type. */            // 类型
   uint8_t  icmp_code;   /* ICMP packet code. */            // 代码
   uint16_t icmp_cksum;  /* ICMP packet checksum. */        // 检验和
   uint16_t icmp_ident;  /* ICMP packet identifier. */      // 标识符
   uint16_t icmp_seq_nb; /* ICMP packet sequence number. */ // 序列号
} __attribute__((__packed__));

struct tcp_hdr {
   uint16_t src_port;  /**< TCP source port. */                         // 源端口号
   uint16_t dst_port;  /**< TCP destination port. */                    // 目的端口号
   uint32_t sent_seq;  /**< TX data sequence number. */                 // 序列号  
   uint32_t recv_ack;  /**< RX data acknowledgement sequence number. */ // 确认号
   uint8_t  data_off;  /**< Data offset. */                             // 4位首部长度(word数) + 4位保留
   uint8_t  tcp_flags; /**< TCP flags */                                // 2位保留 + FIN/SYN/RST/PSH/ACK/URG
   uint16_t rx_win;    /**< RX flow control window. */
   uint16_t cksum;     /**< TCP checksum. */
   uint16_t tcp_urp;   /**< TCP urgent pointer, if any. */
} __attribute__((__packed__));
 
struct udp_hdr {
   uint16_t src_port;    /**< UDP source port. */      // 源端口号
   uint16_t dst_port;    /**< UDP destination port. */ // 目的端口号
   uint16_t dgram_len;   /**< UDP datagram length */   // 总长度
   uint16_t dgram_cksum; /**< UDP datagram checksum */
} __attribute__((__packed__));

struct vxlan_hdr {
   uint32_t vx_flags; /**< flag (8) + Reserved (24). */ // 8位Flags(0x08) + 24位保留
   uint32_t vx_vni;   /**< VNI (24) + Reserved (8). */  // 24位VNI + 8位保留
} __attribute__((__packed__));

你可能感兴趣的:(DPDK)