Linux

套接字綁定到設備時macvlan介面之間的通信問題

  • February 4, 2019

我有一個 Linux 設置,其中模式橋接中的兩個 macvlan 介面被添加到同一個物理介面上,在同一個 IP 子網中:

ip link add link eth2 dev mvl0 type macvlan mode bridge
ip link add link eth2 dev mvl1 type macvlan mode bridge
ip addr add 192.168.42.16/24 dev mvl0
ip addr add 192.168.42.17/24 dev mvl1
ip link set dev mvl0 up
ip link set dev mvl1 up

我想在綁定到介面的套接字之間進行通信mvl0mvl1使用它們,但這不起作用。例如,

# ping -I mvl0 192.168.42.17

沒有得到任何回复。我可以看到核心嘗試在 ARP 上執行 ARP lo,但這不起作用,因為它沒有得到回复。

  • 有沒有辦法使這項工作,例如通過操縱路由或鄰居表?
  • 這應該被認為是 Linux 核心中的錯誤嗎?畢竟macvlan模式下的介面bridge應該是可以互相看到的。

(*背景:*這是兩個嵌入式設備在同一個程序上下文中執行的模擬。我們的框架總是將套接字綁定到介面,以確保通信真正通過所需的介面。通信通常通過 UDP。)

編輯:以前的版本只適用於傳出數據包(UDP),這個版本適用於兩個方向(TCP和ping)。)

像您這樣的設置有各種陷阱:Linux 將具有與網路介面地址匹配的源地址的傳入數據包視為路由錯誤(因為在正常情況下它表示路由循環)。此外,預設情況下,核心維護的local路由表具有最高優先級,這將防止您的數據包從它所綁定的介面發出。

可以解決策略路由的第二個問題:首先,刪除重疊的路由(只會造成麻煩):

ip route list
# overlapping routes should look like:
ip route del 192.168.42.0/24 dev mvl0 proto kernel scope link src 192.168.42.16
ip route del 192.168.42.0/24 dev mvl1 proto kernel scope link src 192.168.42.17

接下來,給local表格一個較低的優先級(較高的數值):

ip rule add pref 1000 lookup local
ip rule del pref 0

我們需要通過將傳入的數據包發送到local表中來接受它們:

ip rule add pref 100 to 192.168.42.16 iif mvl0 lookup local
ip rule add pref 100 to 192.168.42.17 iif mvl1 lookup local

而所有其他(傳出)數據包到相應的。destination 將使用一個特殊的表來強制它們在另一個界面中出現:

ip rule add pref 200 to 192.168.42.17 lookup 100
ip rule add pref 200 to 192.168.42.16 lookup 101

ip route add default dev mvl0 table 100
ip route add default dev mvl1 table 101

此外,我們必須通過禁用反向路徑過濾(如果尚未禁用)並允許接受具有本地源的數據包來解決第一個問題:

echo "0" | tee /proc/sys/net/ipv4/conf/mvl{0,1}/rp_filter
echo "1" | tee /proc/sys/net/ipv4/conf/mvl{0,1}/accept_local

ping即使未綁定到其中一個mvl介面,現在也可以使用。TCP 和 UDP 也可以工作,測試socat

socat TCP4-LISTEN:9998,so-bindtodevice=mvl0 -
echo foo | socat - TCP4:192.168.42.16:9998,so-bindtodevice=mvl1

socat UDP4-RECV:9900,so-bindtodevice=mvl0 -
echo foo | socat - UDP4-SENDTO:192.168.42.16:9900,so-bindtodevice=mvl1

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