DPDK总结(基础知识)

名词解释

简称全称备注
DPDKData Plane Development Kit数据平面开发套件
RTERunTime Environment运行时环境
EALEnvironment Abstraction Layer环境抽象层
lcorelogical coreEAL pthread
TLSThread 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);
};

报文结构体

typefomart
Ethernethttps://en.wikipedia.org/wiki/IEEE_802.1Q
ARPhttps://en.wikipedia.org/wiki/Address_Resolution_Protocol
IPv4https://en.wikipedia.org/wiki/IPv4
ICMPhttps://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
TCPhttps://en.wikipedia.org/wiki/Transmission_Control_Protocol
UDPhttps://en.wikipedia.org/wiki/User_Datagram_Protocol
VXLANhttps://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__));
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值