Nftable が IP パケットの TOS 値と一致しません。

Nftable が IP パケットの TOS 値と一致しません。

これはUbuntu 20.04にあります。

次のルールを作成しようとしています。nftablesインターフェイスで受信したeth1すべてのIPパケットを特定のTOS値(0x02)と一致させます。これまでの私の試みは次のとおりです。

sudo nft add table raw
sudo nft -- add chain raw prerouting {type filter hook prerouting priority -300\;}
sudo nft add rule ip raw prerouting iifname eth1 ip dscp 2 counter
sudo nft add rule ip raw prerouting iifname eth1 udp dport 41378 counter

別のコンピュータからnftablesを実行しているコンピュータにUDPパケットを送信しています。この送信ソケットを設定するコードには、次のパケットにTOS設定が含まれます。

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    int optval = 2;
    setsockopt(sockfd, IPPROTO_IP, IP_TOS, &optval, sizeof(optval)); //Set TOS value
  
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(41378);
    servaddr.sin_addr.s_addr = inet_addr("192.168.10.100");

以下を使用して、到着したパケットを表示できますsudo tcpdump -i eth1 -vv

14:51:35.153295 IP (tos 0x2,ECT(0), ttl 64, id 7091, offset 0, flags [DF], proto UDP (17), length 50)
    192.168.12.10.49089 > ubuntu.41378: [udp sum ok] UDP, length 22

これに対する元のヘッダーは次のとおりです。

IP Header
    00 E0 4C 00 05 8B 3C 97 0E C7 E1 00 08 00 45 02         ..L...<.......E.
    00 31 7E 52                                             .1~R

デコード後、以下が表示されます。

IP Header
   |-IP Version        : 4
   |-IP Header Length  : 5 DWORDS or 20 Bytes
   |-Type Of Service   : 2
   |-IP Total Length   : 49  Bytes(Size of Packet)
   |-Identification    : 32338
   |-TTL      : 64
   |-Protocol : 17
   |-Checksum : 8873
   |-Source IP        : 192.168.12.10
   |-Destination IP   : 192.168.12.100

質問私が実行すると、sudo nft list ruleset以下が表示されます。

table ip raw {
        chain prerouting {
                type filter hook prerouting priority raw; policy accept;
                iifname "eth1" ip dscp 0x02 counter packets 0 bytes 0
                iifname "eth1" udp dport 41378 counter packets 8 bytes 392
        }
}

udp ターゲットポートに基づくルールマッチングはうまく機能しますが、0x02 dscp に基づくルールマッチングはうまく機能しません。

TOS 0x02に一致するルールを作成するには?

これまで、0x02が特別な場合に備えて、TOSに対して異なる値を試しました。私は10進数8、16、24、32を試しました。私が設定したTOS値を持つ受信パケットを見るたびに、nfttablesルールは計算されず、これは一致しないという意味だと思います。

便利なnftablesガイド: https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_ Minutes

名前のDSCP値への便利な参照: https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus1000/sw/4_0/qos/configuration/guide/nexus1000v_qos/qos_6dscp_val.pdf

ベストアンサー1

IPv4 ヘッダーの構成を詳しく見てみると、次のようになります。 https://en.wikipedia.org/wiki/IPv4#ヘッダ

TOSはバイト全体に割り当てられた名前ですが、DSCPは名前の最も重要な6ビットです。これに基づいて私は推測するTOS != DSCP。 TOS 0x20を使用するようにトランスポートコードを変更し、見つかったnftablesルールを修正しました0x20 >> 2 == 0x08(TOSを2桁右に移動してDSCP値に変換)。

sudo nft add rule ip raw prerouting iifname eth1 ip dscp 0x8 counter

この変更により、この新しいルールのカウンタが増えることがわかります。

table ip raw {
        chain prerouting {
                type filter hook prerouting priority raw; policy accept;
                iifname "eth1" ip dscp cs1 counter packets 12 bytes 590
                iifname "eth1" udp dport 41378 counter packets 12 bytes 590
        }
}

要約:

  • TOSはDSCPとは異なります。
  • DSCPはTOSの最も重要な6ビットです。
  • nftablesを使用してTOSを一致させるには、ip dscpTOSを2ビットの右側に移動してその値を一致させます。

この回答にはいくつかの重要な概念が欠けていると確信しています。

おすすめ記事