zoukankan      html  css  js  c++  java
  • [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个一定是跑去了别的队列??? 咋回事捏???

  • 相关阅读:
    Javascript 如何识别数组
    新手 如何搭建一个vue项目详解
    javasScript 七种数据类型
    WPF实现动画的几种方式及其小案例
    问题清单
    2020软件工程个人作业06——软件工程实践总结作业
    我的“捡漏”生涯——小黄衫篇
    2020软件工程作业05
    2020软件工程作业03
    Python: list indices must be integers or slices, not float问题
  • 原文地址:https://www.cnblogs.com/hugetong/p/6612413.html
Copyright © 2011-2022 走看看