简称 | 全称 | 备注 |
---|---|---|
DPDK | Data Plane Development Kit | 数据平面开发套件 |
RTE | RunTime Environment | 运行时环境 |
EAL | Environment Abstraction Layer | 环境抽象层 |
lcore | logical core | EAL pthread |
TLS | Thread Local Storage | 线程本地存储 |
一个lcore就是一个基于pthread实现的线程,不一样的lcore能够亲和到不一样的logical CPU,它们之间是多对多的关系。在当前线程中调用rte_eal_init()后,当前线程会被设置成MASTER lcore,MASTER lcore会根据lcore的个数建立SLAVE lcorehtml
对于多个线程运行在一个logical CPU上的情形,有两种处理办法:web
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的大小tcp
一个rte_mbuf一般存储一个L2报文,比较大的L2报文可能须要多个rte_mbuf存储ide
调用rte_eth_rx_burst()收包后,网卡读上来的L2报文存储在rte_mbuf后面,经过宏rte_pktmbuf_mtod(m, struct ether_hdr*)能够获得L2报文的以太网头指针svg
http://dpdk-docs.readthedocs.io/en/latest/prog_guide/ring_lib.htmlui
一、修改r->prod.head指向本地变量prod_next(CAS操做)spa
二、修改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为一、TCP为六、UDP为1七、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__));