Linux-Networking

為什麼我與 multiq 的綁定介面忽略了 tc 的隊列選擇?

  • October 1, 2020

在 Debian Buster,核心 5.4.51 上,我有兩個介面tap0,並tap1以模式加入了一個綁定介面balance-xor以增加吞吐量。但是,有些流量必須通過tap0. 其餘的我不在乎。

從理論上講,bond 驅動程序可以使用tc過濾器和 multiq 來做到這一點,如驅動程序文件中所述。我可以在統計數據中看到聲稱使用了隊列,但是檢查兩個介面上的流量表明過濾器沒有得到尊重。

這是我所做的:

我將每個分路介面分配給綁定上的隊列,將排隊規則設置為多隊列,然後用於tc覆蓋綁定的排隊決策以強制流量192.168.1.100(例如)始終使用tap0.

# echo "tap0:1" > /sys/class/net/bond0/bonding/queue_id
# echo "tap1:2" > /sys/class/net/bond0/bonding/queue_id

# tc qdisc add dev bond0 handle 1 root multiq

# tc filter add dev bond0 protocol ip parent 1: prio 1 u32 match ip dst \
   192.168.1.100 action skbedit queue_mapping 1

tc統計資訊中,您可以看到實際使用了不同的隊列:

# tc -s class show dev bond0
class multiq 1:1 parent 1: 
Sent 377256252 bytes 2526104 pkt (dropped 0, overlimits 0 requeues 0) 
backlog 0b 0p requeues 0
class multiq 1:2 parent 1: 
Sent 21031 bytes 2982 pkt (dropped 0, overlimits 0 requeues 0) 
backlog 0b 0p requeues 0
class multiq 1:3 parent 1: 
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
backlog 0b 0p requeues 0

大多數流量採用通用隊列,特殊流量採用兩個特定於介面的隊列中的第一個。如果我再次刪除tc filter,則特定隊列 1:2 上的數據包計數器將停止。

(注意bonding driver和tc之間的queue編號偏移1,所以queue 1:1的意思是“讓driver決定”,queue 1:2的意思是“一直通過tap0”,queue 1:3的意思是“一直走”通過tap1“)

隊列也映射到介面:

# cat /proc/net/bonding/bond
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: load balancing (xor)
Transmit Hash Policy: layer3+4 (1)
MII Status: up
MII Polling Interval (ms): 1000
Up Delay (ms): 0
Down Delay (ms): 0
Peer Notification Delay (ms): 0

Slave Interface: tap0
MII Status: up
Speed: 10 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: xx:xx:xx:xx:xx:89
Slave queue ID: 1

Slave Interface: tap1
MII Status: up
Speed: 10 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: xx:xx:xx:xx:xx:d6
Slave queue ID: 2

如果我tcpdump分別在接收端的兩個tap,我可以清楚地看到無論使用哪個隊列,特殊流量實際上仍然使用balance-xor規則使用任一介面。現在 - 我在哪裡錯過了什麼?

好的,深入探勘,文件中有這樣的評論:

此功能首次出現在綁定驅動程序版本 3.7.0 中,並且對輸出從屬選擇的支持僅限於循環和主動備份模式。

Debian Buster 有 3.7.1,顯然支持仍然僅限於這兩種模式,所以我目前正在嘗試做的事情是不可能的。您可以將模式設置為active-backup並立即尊重隊列。這當然違背了負載平衡的目的。我曾希望使用任何其他模式會引起某種警告,但事實並非如此。司機只是高興地忽略了你告訴它做什麼。

您可能需要做的唯一一件事是允許在非活動介面上輸入數據包,否則您重定向的數據包tc將被丟棄:

# echo 1 > /sys/class/net/bond0/bonding/all_slaves_active

我假設,如果真的想要,他們現在可以使用一些tc魔法來基本上重新實現balance-xor那裡的邏輯並覆蓋每個數據包的目標隊列。然後可以離開該模式active-backup但實現負載平衡。或者只是在綁定驅動程序中實現此功能。

引用自:https://serverfault.com/questions/1035912