DPDK VLAN报文解析

480 阅读1分钟

简介

IEEE 802.1Q标准对以太帧格式进行了修改,在源MAC地址字段和协议类型字段之间加入4字节的802.1Q Tag。802.1Q Tag也称为VLAN Tag,带有VLAN Tag的以太帧称为VLAN帧。

帧格式

image.png

示例

报文 image.png

rte_eth.h

#ifndef _RTE_ETHER_H_
#define _RTE_ETHER_H_

...
/**
 * Ethernet header: Contains the destination address, source address
 * and frame type.
 */
struct rte_ether_hdr {
	struct rte_ether_addr d_addr; /**< Destination address. */
	struct rte_ether_addr s_addr; /**< Source address. */
	uint16_t ether_type;      /**< Frame type. */
} __attribute__((aligned(2)));

/**
 * Ethernet VLAN Header.
 * Contains the 16-bit VLAN Tag Control Identifier and the Ethernet type
 * of the encapsulated frame.
 */
struct rte_vlan_hdr {
	uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
	uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */
} __attribute__((__packed__));

/* Ethernet frame types */
#define RTE_ETHER_TYPE_IPV4 0x0800 /**< IPv4 Protocol. */
#define RTE_ETHER_TYPE_IPV6 0x86DD /**< IPv6 Protocol. */
#define RTE_ETHER_TYPE_ARP  0x0806 /**< Arp Protocol. */
#define RTE_ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */
#define RTE_ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */
#define RTE_ETHER_TYPE_QINQ 0x88A8 /**< IEEE 802.1ad QinQ tagging. */
#define RTE_ETHER_TYPE_PPPOE_DISCOVERY 0x8863 /**< PPPoE Discovery Stage. */
#define RTE_ETHER_TYPE_PPPOE_SESSION 0x8864 /**< PPPoE Session Stage. */
#define RTE_ETHER_TYPE_ETAG 0x893F /**< IEEE 802.1BR E-Tag. */
#define RTE_ETHER_TYPE_1588 0x88F7
	/**< IEEE 802.1AS 1588 Precise Time Protocol. */
#define RTE_ETHER_TYPE_SLOW 0x8809 /**< Slow protocols (LACP and Marker). */
#define RTE_ETHER_TYPE_TEB  0x6558 /**< Transparent Ethernet Bridging. */
#define RTE_ETHER_TYPE_LLDP 0x88CC /**< LLDP Protocol. */
#define RTE_ETHER_TYPE_MPLS 0x8847 /**< MPLS ethertype. */
#define RTE_ETHER_TYPE_MPLSM 0x8848 /**< MPLS multicast ethertype. */ 
...

解析

#include <rte_eth.h>

...
if(rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) == ether_hdr->ether_type) 
{
    // VLAN报文
    pkt_hdr->pkt_flags |= PKT_FLAGS_CVLAN;
    pkt_hdr->cvlan_hdr = (struct rte_vlan_hdr *)(ether_hdr + 1);
} 
...