3

私はいくつかのネットワーク ドライバーを開発しており、ip::tos 値に基づいてパケットを別のキューに割り当てようとしています。テスト目的で、私は実行しています:

ping -Q 1 10.0.0.2

ip::tos の値を 1 に設定します。問題は、このシステムで ping コマンドを実行することです。発信 skb には skb->priority==0 がありますが、1 にすべきだと思います。

「-Q 1」を設定すると skb->priority が 1 に設定されると想定していましたが、そうではありません。

誰でも理由を知っていますか?

4

2 に答える 2

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];
}

(そして ip_tos2prio テーブルは ipv4/route.c にあります)。

skb->優先度を0以外にするには、「TOS」バイトを少なくとも32に設定する必要があるようです。

ping -Q 1 は、TOS バイト全体を 1 に設定します。 TOS は、DSCPを支持して廃止されることに注意してください。下位 2 ビットは ECN に使用され、上位 6 ビットは DSCP 値 (「優先度」) に使用されます。

したがって、DSCP 優先度を 1 にするには 4 から開始する必要がありますが、上記の表によると、skb->priority を設定するには 32 から開始する必要があります。ping -Q 32 10.0.0.2

ただし、すべての場合に skb->priority も設定されるかどうかはわかりません。ツールが raw ソケットを使用してパケットを作成する場合ping、skb->priority の設定をバイパスする可能性があります。

ただし、ローカルで生成されたパケットの skb->priority は、次の場合に設定されます。

 int tos = 32; 
 setsockopt(sock_fd, IPPROTO_IP, IP_TOS,
                          &tos, sizeof(tos));

したがって、パケットを送信する前に、上記のことを行う小さなサンプル プログラムを作成する必要がある場合があります。

于 2013-11-06T11:35:32.933 に答える
2

上の答えは正解です ここで完成させましょう

static inline char rt_tos2priority(u8 tos)
{
    return ip_tos2prio[IPTOS_TOS(tos)>>1];
}

ここで、IPTOS_TOS はマクロで、「tos」値と 0x1E の AND を取ります

したがって、TOS を 0xFF として指定すると、上記の return ステートメントは次のようになります。

return ip_tos2prio[(0x1E & 0xFF)>>1];

さらに計算すると、(0x1E & 0xFF) は 0x1E に等しく、(0x1E >> 1) から 0x0F が得られます。これは 10 進数で 15 です。上記の return ステートメントは次と等しいと言えます

return ip_tos2prio[15];

「ip_tos2prio」は、このように事前定義された配列です

const __u8 ip_tos2prio[16]={0,0,0,0,2,2,2,2,6,6,6,4,4,4,4};

ここで、それぞれの値には意味があります。0->BESTEFFORT、2->BULK、4->INTERACTIVE BULK、6 ->INTERACTIVE。

return ステートメントに戻ると、ip_tos2prio配列の 15 番目の要素である 4 が返されます。

于 2016-02-05T21:23:02.717 に答える