skb->priority and IP::tos and ping -Q

use*_*113 3 linux networking linux-device-driver

我正在开发一些网络驱动程序,我正在尝试根据 ip::tos 值将数据包分配到不同的队列。出于测试目的,我正在运行:

ping -Q 1 10.0.0.2
Run Code Online (Sandbox Code Playgroud)

将 ip::tos 值设置为 1。我遇到的问题是,在我运行 ping 命令的这个系统上 - 传出 skb 具有 skb->priority==0,但我认为它应该是 1。

我假设设置“-Q 1”会将 skb->priority 设置为 1,但事实并非如此。

有谁知道为什么?

nos*_*nos 5

首先,skb->priority 和 IP TOS 字段之间没有直接映射。在 linux 内核中是这样完成的:

sk->sk_priority = rt_tos2priority(val)
...

static inline char rt_tos2priority(u8 tos)
{
    return ip_tos2prio[IPTOS_TOS(tos)>>1];
}
Run Code Online (Sandbox Code Playgroud)

(ip_tos2prio 表可以在 ipv4/route.c 中找到)。

在我看来,您必须将“TOS”字节设置为至少 32,才能将 skb->priority 设置为 0 以外的任何值。

ping -Q 1 将整个 TOS 字节设置为 1。请注意,不推荐使用 TOS 以支持DSCP。低 2 位用于 ECN,而高 6 位用于 DSCP 值(“优先级”)。

所以你可能必须从 4 开始,以获得 1 的 DSCP 优先级,但根据上表,从 32 开始也可以设置 skb->priority,如 ping -Q 32 10.0.0.2

但是,我不确定在所有情况下都会设置 skb->priority。如果该ping工具使用原始套接字制作数据包,它可能会绕过设置 skb->priority。

但是,如果这样做,则将设置本地生成的数据包的 skb->priority

 int tos = 32; 
 setsockopt(sock_fd, IPPROTO_IP, IP_TOS,
                          &tos, sizeof(tos));
Run Code Online (Sandbox Code Playgroud)

因此,您可能需要在发送数据包之前编写一个执行上述操作的小型示例程序。