Nftable이 IP 패킷의 TOS 값과 일치하지 않습니다.

Nftable이 IP 패킷의 TOS 값과 일치하지 않습니다.

이것은 우분투 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에 대해 다른 값을 시도했습니다. 나는 십진수 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를 두 자리 오른쪽으로 이동하여 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비트 오른쪽으로 이동하고 해당 값을 일치시키십시오.

이 답변에는 몇 가지 핵심 개념이 누락되어 있다고 확신하므로 이에 대해 더 많이 아는 사람이 더 유용한 답변을 제공하도록 권장합니다.

관련 정보