tc u32 — 최근 커널에서 L2 프로토콜을 일치시키는 방법은 무엇입니까?


12

해시 필터링을 사용하여 Linux 브리지에 구축 된 멋진 셰이퍼가 있습니다. 즉, br0연결 externalinternal물리적 인터페이스, VLAN 태그가 지정된 패킷은 "투명하게"브리지됩니다 (즉, VLAN 인터페이스가 없음).

이제 다른 커널이 다르게 작동합니다. 정확한 커널 버전 범위에 문제가있을 수 있습니다. 용서해주십시오. 감사.

2.6.26

따라서 데비안에서 2.6.26 이상 (최대 2.6.32까지) --- 이것은 작동합니다.

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

여기서 "kernel"은 "protocol"필드에서 2 바이트를 0x8100과 일치하지만 ip 패킷의 시작 부분을 "zero position"으로 계산합니다.

2.6.32

다시, 데비안에서는 (바닐라 커널을 만들지 않았습니다) 2.6.32-5 ---이 작동합니다 :

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 at 20 flowid 1:200

여기서 "커널"은 프로토콜과 동일하지만이 프로토콜 헤더의 시작 부분부터 오프셋을 계산합니다. --- 오프셋에 4 바이트를 추가해야합니다 (dst 주소의 경우 16이 아니라 20). 괜찮아요, 더 논리적으로 보입니다.

3.2.11, 최신 안정

이것은 802.1q 태그가 전혀없는 것처럼 작동합니다.

tc filter add dev internal protocol ip parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

문제는 지금까지 802.1q 태그와 일치하는 방법을 찾을 수 없다는 것입니다.

과거에 일치하는 802.1q 태그

다음과 같이 전에이 작업을 수행 할 수 있습니다.

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 match u16 0x0ed8 0x0fff at -4 flowid 1:300

지금은와 802.1Q 태그와 일치 할 수없는거야 at 0, at -2, at -4, at -6또는 같은 것을. 적중 횟수 가 0 인 주된 문제는 ---이 필터는 전혀 "잘못된 프로토콜"입니다.

제발, 누구든지 도와주세요 :-)

감사!

답변:


4

최근 커널에서는 VLAN 태그가 skb에서 제거되었습니다. skb에서 메타 일치를 수행하려면 다음과 같이하십시오.

tc filter add dev internal protocol all parent 1:0 prio 100 basic match 'meta(vlan mask 0xfff eq 0x0ed8)' flowid 1:300

에 대한 시도가 루트 필터를 추가하는 protocol all나에게 준다 RTNETLINK answers: Invalid argument(여기에 3.3.4 커널). 최신 커널로 이것을 테스트 할 것입니다. 감사합니다.
brownian

이것은 데비안 wheezy 커널 3.2.0에서 나를 위해 일했습니다. 자세한 내용과 함께 다른 답변을 추가했습니다.
Nick Craig-Wood

3

나는 이것을 정확하게해야했습니다. @Thusitha가 제안한 답변이 새로운 커널에 대한 올바른 방법이라는 것을 알았습니다.

데비안 wheezy 커널 3.2.0-4 및 iproute (tc 명령의 출처) 버전 20120521-3 + b3으로 테스트

다음은 완전한 스크립트입니다. tc filter줄은 @Thusitha에서 지정한 것과 거의 동일합니다.

function qos() {
    if="$1"
    vlan1="$2"
    vlan2="$3"

    # delete previous
    tc qdisc del dev $if root >/dev/null 2>&1
    tc qdisc del dev $if ingress >/dev/null 2>&1

    # Root HTB for $if
    tc qdisc add dev $if root handle 1: htb r2q 1 default 1

    # Root class to borrow from
    tc class add dev $if parent 1: classid 1:1 htb quantum 1000000 rate 500mbit ceil 500mbit burst 64k prio 2
    tc qdisc add dev $if parent 1:1 handle 101 sfq perturb 10

    # class for vlan1
    tc class add dev $if parent 1:1 classid 1:106 htb quantum 1000000 rate 1.00mbit ceil 1.00mbit burst 6k
    tc qdisc add dev $if parent 1:106 handle 107 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan1})" flowid 1:106

    # class for vlan2
    tc class add dev $if parent 1:1 classid 1:108 htb quantum 1000000 rate 1.00mbit ceil 10.00mbit burst 6k
    tc qdisc add dev $if parent 1:108 handle 108 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan2})" flowid 1:108

}

qos eth1 1234 1235
qos eth2 2345 2346

이상하게, protocol all바닐라 커널에서 오류가 발생했습니다. 좀 더 확인 해봐 감사합니다.
brownian

1

wireshark를 사용하여 사용자 공간에 표시되는 인터페이스를 통해 진행되는 작업을 캡처하고이를 사용하여 필터를 작성하는 것이 좋습니다. 인터페이스가 어떤 이유로 VLAN 태그를 제거하는지 궁금합니다 (투명하게 브리지되도록 구성되어 있음). 아마도 추가 태그 또는 무언가를 추가하고 있습니까?


아니요, VLAN 태그를 제거하지는 않습니다. 셰이퍼의 필터를 제외한 모든 기능이 작동합니다 (트래픽은 하드웨어 스위치의 트렁크를 통해 전환됨). 그러나 자세히 살펴볼 것입니다. VLAN 태그 오프로드 기능을 살펴 봤지만 해당 드라이버는 vid 오프로드를 수행 할 수 없습니다.
brownian

tcpdump모든 인터페이스 bridge와 포트 에서 VLAN ID를 표시합니다 .
brownian

이제 내 멋진 셰이퍼는 Linux 커널 3.3.4에서 작동하며 8021q 태그 필터링을 제외하고는 모두 잘 작동합니다. 문제는 해결되지 않은 채 남아 있습니다. 어쨌든 고마워
brownian

1

당신과 VLAN을 packtes 표시 할 수 있습니다 ebtables를 .

# mark packets according to the vlan id
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 1 -j mark --mark-set 1
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 5 -j mark --mark-set 2

그런 다음 표시에 따라 모양을 적용하십시오. ebtables 및 iptables는 동일한 표시를 공유합니다.

아직이 작업을 수행하지 않았습니다. 그래서 오히려 직감.


10Gb 링크에서 원활하게 작동하지 않을 것입니다 ... 표를 피하고 싶습니다. 어쨌든 제안 해 주셔서 감사합니다.
brownian

@brownian iproute2에서 정확히 동일한 필터링을 수행하면 성능이 향상 될 것이라고 생각하십니까? 동일한 커널, 동일한 코드 경로, 동일한 알고리즘입니다. 실수로 연결 추적 설정과 같은 작업을 수행하지 않는 한 차이가 없어야합니다. * 테이블 많은 복잡한 작업을 수행 할 수 있으므로 성능에 영향을 줄 수 있습니다 . 그러나 그것은 것을 의미하지 않는 것입니다 .
tylerl

@tylerl 내가 실제로 때문에 필터가 iproute2를 (같은 VLAN 고객의 수백, 필터 해시의 무리)와 - 모든 패킷에 다른 추가 검사 합니다 성능에 영향을, 나는 믿는다.
brownian

0

reorder_hdrVLAN 인터페이스 에서 옵션 을 끄십시오 . 헤더 순서 변경 옵션을 사용하면 프레임의 태그가 제거됩니다. 명령으로 확인하십시오 ip -d link list dev vlan_iface.


1
제거 할 때 와 다시 삽입 명확히 할 수 있습니까? 내 말은, 태그가 붙은 프레임이 리눅스 브리지에 들어간 다음 다른 인터페이스에서 빠져 나옵니다.이 태그 조작이 발생하는 시점과 장소 및 필터가 호출 되는 시점과 장소 는 무엇입니까? 지도 또는 이와 유사한 링크가 있습니까? 감사! tc
brownian

또 다른 생각 : 어떤 VLAN 인터페이스를 의미합니까? 이 브리지에는 VLAN 인터페이스가 하나도 없습니다 (첫 번째 단락에 "VLAN 인터페이스가 없습니다"라고 썼습니다).
brownian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.