我使用dpdk-19.02(但也尝试使用18.11),固件版本为6.01和6.8的x710 Lanner模块 操作系统:Ubuntu Desktop and Server 18.04 我正在开发网络应用程序,该应用程序基于Vlan标签对流量进行流量划分。效果很好。 x710模块可以跳过标记,并基于五元组执行RSS。 例如:
数据包(Ether()/ Dot1Q(vlan = 1)/ IP())将跳过或剥离vlan(在剥离情况下,它将vlan放入rte_mbuf结构中)并使rss进入队列区域(例如1-7) ) 如果是双标签,则两个EtherType均为0x8100(而不是第一个以太0x88a8) 与未标记的数据包相同。它将在队列区域(1-7)上rss 效果很好。 我可以控制它 选项:rte_eth_conf.rxmode.offloads和标志组DEV_RX_OFFLOAD _ *;
VLAN_EXTEND-> rss取消标记,单个标记或双重标记
VLAN_STRIP->将第一个VLAN放在元数据中(在dpdk中,它称为strip)。 (请勿使用rss双重标签)
VLAN_STRIP | VLAN_EXTEND->放置标签并执行rss
VLAN_EXTEND | QINQ_STRIP->在rss(外部或单个)中仅放置一个标签。
所有api都运作良好。 我想要的是:我的队列很少。我需要通过外部(或单个)标签选择队列组。 (通常,在一个物理上,但在一个DPDK进程中,我几乎不需要虚拟端口。)
一个例子:我要配置三组队列。 G0(仅未加标签)(第1-7类),G1(ID为1的外部或单个VLAN标签)(第9-15号队列)和G2(ID为2的外部或单个vlan标签)(在dpdk中这组称为池) / p>
(Ether()/ Dot1Q(vlan = 1)/ IP())-> G1
(Ether()/ Dot1Q(vlan = 1)/ Dot1Q(vlan = 8)/ IP())-> G1
(Ether()/ Dot1Q(vlan = 2)/ Dot1Q(vlan = 8)/ IP())-> G2
(Ether()/ IP())-> G0
我接受剥离警告:
(Ether()/ Dot1Q(vlan = 1)/ Dot1Q(vlan = 8)/ IP())
(Ether()/ Dot1Q(vlan = 1)/ Dot1Q(vlan = 8)/ IP())->剥除外部VLAN(id == 1)
(Ether()/ Dot1Q(vlan = 1)/ IP())->剥离单个VLAN
剥离两个VLAN。
Dpdk Api拥有这项技术,它就是VMDQ 在i40e dpdk驱动程序上dpdk忽略vmdq结构中的标志 rte_eth_vmdq_rx_conf.rx_mode,因此我无法禁用ETH_VMDQ_ACCEPT_UNTAG标志,并且决定于mac(而不是vlan),但可以接受。 但是当我尝试配置它时,我遇到了问题 万一
(Ether()/ Dot1Q(vlan = 1)/ Dot1Q(vlan = 8)/ IP())->仅去除了第二个vlan(vlan id 8)
(Ether()/ Dot1Q(vlan = 1)/ IP())->剥离的vlan 1
i我试图更改rte_eth_conf.rxmode.mq_mode标志 结果:
零标记->打断了第一个VLAN,但没有RSS
VLAN_EXTEND->单标签-不带标签,双标签-带第二标签(我需要第一个标签或不需要),但是RSS可以使用
QINQ_STRIP->剥离第一个标签(或单个),但不使用RSS
QINQ_STRIP | VLAN_EXTEND->(类似于没有QINIQ_STRIP的情况)
QINQ_STRIP | VLAN_STRIP | VLAN_EXTEND->仍然仅剥离第二个标签
这是我的配置rte_eth_conf的功能
void cGlobalConfig::portConfVmdq(rte_eth_conf *conf, uint32_t portId)
{
zeroStruct( *conf); // zero struct
conf->rxmode.mq_mode=ETH_MQ_RX_VMDQ_RSS; // SETTING RSS MODE
conf->rxmode.offloads= DEV_RX_OFFLOAD_VLAN_EXTEND
| DEV_RX_OFFLOAD_QINQ_STRIP
| DEV_RX_OFFLOAD_VLAN_STRIP ;// that flags i variate
conf->txmode.mq_mode=ETH_MQ_TX_VMDQ_ONLY;
conf->txmode.offloads=DEV_TX_OFFLOAD_VLAN_INSERT;
conf->txmode.hw_vlan_insert_pvid=1; // tx options
rte_eth_dev_info info=pInfo(portId);
rte_eth_vmdq_rx_conf & vmdq=conf->rx_adv_conf.vmdq_rx_conf;
rte_eth_vmdq_tx_conf & tvmdq=conf->tx_adv_conf.vmdq_tx_conf;
vmdq.rx_mode=ETH_VMDQ_ACCEPT_MULTICAST|ETH_VMDQ_ACCEPT_BROADCAST;
conf->rx_adv_conf.rss_conf.rss_hf=info.flow_type_rss_offloads;
vmdq.nb_queue_pools = (rte_eth_nb_pools)NB_POOLS;
vmdq.nb_pool_maps=NB_POOLS; // 8 in my case, cose i need 24 queue in each of 8 pools
vmdq.enable_default_pool=0;
vmdq.default_pool=0;
vmdq.enable_loop_back=0;
tvmdq.nb_queue_pools=(rte_eth_nb_pools)NB_POOLS;
for(uint i =0; i < vmdq.nb_pool_maps; ++i )
{
vmdq.pool_map[i].vlan_id = i; // binding vlans for pools (but it doesnt matter, because i40e dpdk driver ignors vmdq.rx_mode flags)
vmdq.pool_map[i].pools = (1UL << (i % NB_POOLS));
}
}```
I expect:
stripping first of sinle tag, forward to pool, based on VlanID and doing RSS