在使用pf_ring的过程中,发现pf_ring有自身的rss功能。网卡已经有了rss(receive side scaling)功能,pf_ring的rss有何存在的必要?
通过测试,发现Intel 82599的rss功能不能保证同一个流被分配到队列上 (同一个流的五元组是不同的,IN方向的是[PROTO, SIP, SPORT, DIP, DPORT],out方向的则是[PROTO, DIP, DPORT, SIP, SPORT])。而pf_ring的rss则能确保同一个流的数据进入了同一个ring,参见前文《
pf_ring 5.4.0 rss原理、适用场景与局限》。
接下来看一下为什么网卡的rss做不到这一点。
Intel 82599的rss原理主要参考《Intel? 82599 10 GbE Controller Datasheet》,结合源码的分析后续补上
82599网卡rss原理
1)网卡会对数据包进行解包,解析出与源目的ip地址、源目的port信息
2)网卡选根据配置选择一个hash函数
3)将hash值的低7位作为key决定redirection table的下标,同时每个table项有4位,代表rss hash后的queue id(注:实际使用过程中发现82599只能启用16个队列,个人推测与这里的四位redirection table项密切相关)
查看了一下intel 82599驱动的安装手册,果然提到16个队列的限制:
http://www.intel.com/support/cn/network/adapter/pro100/sb/cs-032530.htm
0= 禁用 RSS
1= 启用 RSS,
并将描述符队列计数为 16 或数量的
联机 CPU, 取两者中较小。
2-16= 启用 RSS, 用 2-16 队列
rss函数key类型:
1)TCPIPV4 [SIP, DIP, SPORT, DPROT]
2)IPV4 [SIP, DIP]
3)TCPIPV6 [SIP, DIP, SPORT, DPROT]
4)IPV6 [SIP, DIP]
5)UDPIPV4 [SIP, DIP, SPORT, DPROT]
6)UDPIPV6 [SIP, DIP, SPORT, DPROT]
hash算法
ComputeHash(input[], N)
For hash-input input[] of length N bytes (8N bits) and a random secret key
K of 320 bits
Result = 0;
For each bit b in input[] {
if (b == 1) then Result ^= (left-most 32 bits of K);
shift K left 1 bit position;
}
return Result;
换成文字描述,就是:选取一个320位的随机数K, 对于N字节的每一位,如果该位为1,则Result=Result异或K的最高32为位。否则,Result不变。K左移一位。
那么着N是多少呢?如何组成呢?
对于TCPIPV4,hash函数调用为Result = ComputeHash(Input, 12);
这12字节是[SIP(4Bytes),DIP(4Bytes), SPort(2Bytes), DPort(2Bytes)]
对于UDPIPV4, hash函数调用为Result = ComputeHash(Input, 12);
这12字节是[SIP(4Bytes),DIP(4Bytes), SPort(2Bytes), DPort(2Bytes)]
对于IPV4,hash函数调用Result = ComputeHash(Input, 8)
这8字节是[SIP(4Bytes),DIP(4Bytes)}
从这里可以看出,
当同一个流的SIP,DIP,SPort,DPort交换位置时,算出来的hash值是大部分时候不同的,因此也就无法保证hash到同一个队列。