首页 > 代码库 > [daily][dpdk] 网卡offload识别包类型;如何模拟环境构造一个vlan包

[daily][dpdk] 网卡offload识别包类型;如何模拟环境构造一个vlan包

 

第一部分 硬件识别包类型

网卡,是可以识别包类型的。在dpdk的API中。识别完之后,存在这个结构里:

struct rte_mbuf { 
......
        union {                                                                 
                uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */  
                struct {                                                        
                        uint32_t l2_type:4; /**< (Outer) L2 type. */            
                        uint32_t l3_type:4; /**< (Outer) L3 type. */            
                        uint32_t l4_type:4; /**< (Outer) L4 type. */            
                        uint32_t tun_type:4; /**< Tunnel type. */               
                        uint32_t inner_l2_type:4; /**< Inner L2 type. */        
                        uint32_t inner_l3_type:4; /**< Inner L3 type. */        
                        uint32_t inner_l4_type:4; /**< Inner L4 type. */        
                };                                                              
        };                
... ...
}

这非常厉害,利用硬件能力;但是遗憾的是,有一些硬件并不能这么干,因为他们比较low,然后我们就需要软件实现。参考例子l3fwd,加一个回调替代硬件功能,提高兼容性:

static uint16_t callback(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[], 
                        uint16_t nb_pkts, uint16_t max_pkts, void *user_param)  
{                                                                               
}   


                void* cb_handler;                                               
                cb_handler = rte_eth_add_rx_callback(port_id, i,                
                        callback, NULL);                                        
                if (!cb_handler) {                                              
                        perror("rte_eth_add_rx_callback: ");                    
                        return -1;                                              
                }       

所以,在实现这个函数之前,必须要了解硬件的行为模式。

 

第二部分 硬件的行为是啥样的

一个包来了之后,硬件会为 l2_type l3_type l4_type 赋值,值都是宏,见源码。如果是tunnel或者IP in IP等,也有相应的值变量可以付。但是我比较关系vlan。

而且发现,在 l2_type 定义的值之中,并没有VLAN存在。然后我构建了一组vlan包(见下一节)来实验,发现vlan包也能被正确识别到各层协议,那么它如何将这个一个

vlan包的信息传递出来呢?经过测试,发现用到了下面这个变量:

/**                                                                             
 * The generic rte_mbuf, containing a packet mbuf.                              
 */                                                                             
struct rte_mbuf {         
        uint64_t ol_flags;        /**< Offload features. */                     
                                                               
}

如果是vlan包,会设置标记:

                                                                                
/**                                                                             
 * RX packet is a 802.1q VLAN packet. This flag was set by PMDs when            
 * the packet is recognized as a VLAN, but the behavior between PMDs            
 * was not the same. This flag is kept for some time to avoid breaking          
 * applications and should be replaced by PKT_RX_VLAN_STRIPPED.                 
 */                                                                             
#define PKT_RX_VLAN_PKT      (1ULL << 0)                                        
                           

 

至此,硬件行为基本清晰,已经基本满足我当前的需求,可以进行软件模拟了。

 

第三部分 构造一个VLAN包

做前文的实验中,为了验证硬件行为,需要自行构建vlan包。是这么干的。

1. 开一个虚拟机。单独建立一个网卡,与本地tap设备链接。

2. 在两端安装vconfig工具,并加载 8021q 内核模块,使用vconfig工具网卡增加一个虚拟的vlan网卡。

/home/tong/Data [tong@T7] [14:38]
> pkgfile vconfig
community/vlan
/home/tong/Data [tong@T7] [14:38]
> pacman -Ss vlan
community/vlan 1.9-4
    Virtual LAN configuration utility
/home/tong/Data [tong@T7] [14:38]
> sudo pacman -S vlan
/home/tong/Data [tong@T7] [14:40]
> modprobe 8021q
/home/tong/Data [tong@T7] [14:48]
> sudo vconfig add tap-dpdk-1 3
Added VLAN with VID == 3 to IF -:tap-dpdk-1:-

这时候能看见多了一个网卡

/home/tong/Data [tong@T7] [14:49]
> ip link
21: tap-dpdk-1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether d2:75:44:af:2b:20 brd ff:ff:ff:ff:ff:ff
25: tap-dpdk-1.3@tap-dpdk-1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether d2:75:44:af:2b:20 brd ff:ff:ff:ff:ff:ff

3. 在虚拟机里同样操作,设成同样的vlan id = 3 ,也是会有两个网卡 eth1 和 eth1.3

4. 在host主机上,给 tap-dpdk-1.3 发包。 在 guest 主机上,eth1和eth1.3上,都会看见发来的包,区别是,eth1.3看见的包已经去除了vlan,而eth1上的包是带着vlan的。

所以,抓eth1,就把带着vlan的pcap,抓出来了。。。。

5. 我真是太聪明了,我这都是跟谁学的。。。。。

 

第四部分 补充

测以上内容,用来两个网卡

0000:03:00.0 82599EB 10-Gigabit SFI/SFP+ Network Connection drv=igb_uio unused=ixgbe
0000:09:00.0 82583V Gigabit Network Connection drv=igb_uio unused=e1000e

不用说,82599EB 肯定是支持硬件offload的。82583v 不仅不支持offload,连多队列都不支持。。。。

 

另:82599EB 配成一个队列的时候,竟然无法收到全部的包,发了51个,只收到30个,另外20个一定是跑去了别的队列??? 咋回事捏???

 

[daily][dpdk] 网卡offload识别包类型;如何模拟环境构造一个vlan包