Linux

我可以在每個設備上使用多個 qdisc 嗎?

  • June 21, 2021

我可以使用 tc 將多個 qdisc 添加到同一設備,還是每個設備只能使用一個 qdisc?

另外,一個 qdisc 可以包含子 qdis,還是只包含子類?即有可能tc qdisc add parent <existing qdisc> handle <child qdisc> <qdisc type>嗎?

在 OP 的問題中沒有要解決的實際問題,所以我將提供一個使用網路命名空間的非常簡單的範例

  • 建立通訊
ip -n test1 link add up type veth peer netns test2
ip -n test2 link set veth0 up
ip -n test1 address add 192.0.2.11/24 dev veth0
ip -n test2 address add 192.0.2.12/24 dev veth0
  • 初步測試
# ip netns exec test1 ping -c1 192.0.2.12
PING 192.0.2.12 (192.0.2.12) 56(84) bytes of data.
64 bytes from 192.0.2.12: icmp_seq=1 ttl=64 time=0.068 ms

--- 192.0.2.12 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.068/0.068/0.068/0.000 ms
  • 添加第一個基本 qdisc:netem
tc -n test1 qdisc add dev veth0 root handle 1: netem delay 100ms
  • 測試結果
# ip -n test1 neigh flush all
# ip netns exec test1 ping -c2 192.0.2.12
PING 192.0.2.12 (192.0.2.12) 56(84) bytes of data.
64 bytes from 192.0.2.12: icmp_seq=1 ttl=64 time=200 ms
64 bytes from 192.0.2.12: icmp_seq=2 ttl=64 time=100 ms

--- 192.0.2.12 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 100.152/150.223/200.294/50.071 ms

(除了 IP 延遲之外,第一次 ping 還獲得了 ARP 延遲,這就是為什麼它是延遲的兩倍)

  • 再次添加一個 qdisc,前一個為父級
tc -n test1 qdisc add dev veth0 parent 1: handle 2: netem delay 350ms
  • 再次測試
# ip -n test1 neigh flush all
# ip netns exec test1 ping -c2 192.0.2.12
PING 192.0.2.12 (192.0.2.12) 56(84) bytes of data.
64 bytes from 192.0.2.12: icmp_seq=1 ttl=64 time=900 ms
64 bytes from 192.0.2.12: icmp_seq=2 ttl=64 time=450 ms

--- 192.0.2.12 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 450.228/675.272/900.317/225.044 ms

如您所見,使用了兩個netem qdisc:100+350=450ms(由於第一個是 ARP 而兩次)

只要 qdisc 的特定屬性有意義,就可以繼續:

tc -n test1 qdisc add dev veth0 parent 2: handle 3: prio

直到它沒有意義(prio 是一個有的qdisc):

# tc -n test1 qdisc add dev veth0 parent 3: handle 4: sfq
Error: Specified class not found.

或者沒有支持(可能是因為它沒有意義):

# tc -n test1 qdisc del dev veth0 parent 2: handle 3:
# tc -n test1 qdisc add dev veth0 parent 2: handle 3: sfq
# tc -n test1 qdisc add dev veth0 parent 3: handle 4: netem delay 100ms
RTNETLINK answers: Operation not supported

但是不能為某物添加第二個 qdisc(這就是為什麼有類 qdisc 提供多個類的原因):

# tc -n test1 qdisc add dev veth0 root handle 5: netem delay 100ms
Error: NLM_F_REPLACE needed to override.

結論:

  • 是的,每個設備總共可以有多個qdisc,但是在給定的層次結構中,只有一個qdisc。要“在同一級別”擁有多個 qdisc 將需要一個qdisc,它提供多個,每個類都可以是qdisc的父級。
  • 並且(僅非分類)qdisc可以有另一個qdisc作為子級。

在最有用的情況下,使用帶有classes的有**類qdisc ,附加的 qdisc 添加了作為父類的,並且有過濾器來選擇如何選擇類。

這是一個 Q/A,我在第二部分對此方案做出了回答:限制 CentOS 7 中特定埠的頻寬?

引用自:https://unix.stackexchange.com/questions/654559