我为使用DPDK的Intel XL710卡而苦苦挣扎,以使其仅在每个端口上仅使用SRC IPV4或DST IPV4计算RSS哈希。 该卡具有4个10GE端口,无论我做什么,RSS配置都是全局的。我试图在PCTYPE中设置SRC / DST IPV4字段,并且应用的配置 last 仅起作用。
所以我要实现的行为。
假设我有上行数据包到达端口0:
SRC:10.10.10.1 和 DST:10.10.10.2
并回复下行数据包到达端口1:
SRC:10.10.10.2 和 DST:10.10.10.1
我希望卡上的端口0(在我们的示例中为上游)基于 SRC 地址 10.10.10.1 计算RSS哈希对于端口1(下游)使用 DST 地址计算哈希,在我们的示例中,该地址也将为 10.10.10.1 。因此,我们的想法是在RX队列之间分配数据包,使之只有SRC / DST地址分别影响这种分配。
我并没有专门针对RSS。只要技术允许,它就会做什么。
我使用的配置:
void setFilter(uint16_t portId, uint32_t value){
//Value = RTE_ETH_FLOW_NONFRAG_IPV4_TCP in that case
struct rte_eth_hash_filter_info info;
uint32_t ftype, idx, offset;
int ret;
if (rte_eth_dev_filter_supported(portId,
RTE_ETH_FILTER_HASH) < 0) {
printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
portId);
return;
}
memset(&info, 0, sizeof(info));
info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
info.info.global_conf.hash_func =
RTE_ETH_HASH_FUNCTION_DEFAULT;
ftype = value;
idx = ftype / UINT64_BIT;
offset = ftype % UINT64_BIT;
info.info.global_conf.valid_bit_mask[idx] |= (1ULL << offset);
info.info.global_conf.sym_hash_enable_mask[idx] |=
(1ULL << offset);
ret = rte_eth_dev_filter_ctrl(portId, RTE_ETH_FILTER_HASH,
RTE_ETH_FILTER_SET, &info);
if (ret < 0)
printf("Cannot set global hash configurations by port %d\n",
portId);
else
printf("Global hash configurations have been set "
"succcessfully by port %d\n", portId);
}
void setPctypeRss(uint16_t portId, uint16_t fieldIdx) {
/* Note that AVF_FILTER_PCTYPE_NONF_IPV4_TCP is define for
* Virtual Function. Defines are the same for Physical Functions
*/
int ret = -ENOTSUP;
enum rte_pmd_i40e_inset_type inset_type = INSET_HASH;
struct rte_pmd_i40e_inset inset;
ret = rte_pmd_i40e_inset_get(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to get input set.\n");
return;
}
memset(&inset, 0, sizeof(inset));
ret = rte_pmd_i40e_inset_set(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to CLEAR input set.\n");
return;
}
else
{
printf("Successfull cleared input set\n");
}
ret = rte_pmd_i40e_inset_get(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to get input set.\n");
return;
}
ret = rte_pmd_i40e_inset_field_set(&inset.inset, fieldIdx);
if (ret) {
printf("Failed to configure input set field.\n");
return;
}
ret = rte_pmd_i40e_inset_set(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
&inset, inset_type);
if (ret) {
printf("Failed to set input set.\n");
return;
}
if (ret == -ENOTSUP)
printf("Function not supported\n");
}
答案 0 :(得分:0)
IMO值得尝试一个更简单的解决方案。我们可以简单地使用rte_eth_dev_configure()
:
https://doc.dpdk.org/api/rte__ethdev_8h.html#a1a7d3a20b102fee222541fda50fd87bd
然后按照此处所述将eth_conf.rss_conf.rss_hf
设置为ETH_RSS_IP
:
https://doc.dpdk.org/api/structrte__eth__rss__conf.html#ad70f17882a835e5d4e38c64a9f872fdc
DPDK中很少有使用此功能的示例。而且大多数都工作正常;)