web-dev-qa-db-ja.com

ソケットがデバイスにバインドされている場合のmacvlanインターフェイス間の通信の問題

モードブリッジの2つのmacvlanインターフェイスが同じIPサブネット内の同じ物理インターフェイスに追加されるLinuxセットアップがあります。

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

返信はありません。カーネルがloでARPを実行しようとしていることがわかりますが、応答がないため、機能しません。

  • たとえば、ルーティングテーブルまたはネイバーテーブルを操作することによって、これを機能させる方法はありますか?

  • これはLinuxカーネルのバグと見なす必要がありますか?結局のところ、モードmacvlanbridgeインターフェースはお互いを見ることができるはずです。

背景:これは、同じプロセスコンテキストで実行されている2つの組み込みデバイスのシミュレーションです。フレームワークは常にソケットをインターフェイスにバインドして、通信が実際に目的のインターフェイスを経由するようにします。通信は通常、UDPを介して行われます。 )

3
starblue

編集:以前のバージョンは発信パケット(UDP)に対してのみ機能しましたが、このバージョンは双方向(TCPとping)で機能します。)

あなたのようなセットアップにはさまざまな落とし穴があります。Linuxは、ネットワークインターフェイスアドレスと一致する送信元アドレスを持つ着信パケットをルーティングエラーと見なします(通常の状況ではルーティングループを示しているため)。また、デフォルトでは、カーネルが維持するlocalルーティングテーブルの優先度が最も高く、これにより、パケットがバインドされているインターフェイスから送信されなくなります。

ポリシールーティングに関する2番目の問題を解決できます。まず、重複するルートを削除します(これは問題を引き起こすだけです)。

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

他のすべての(送信)パケットはそれぞれに送信されます。宛先は、他のインターフェースでそれらを強制的に排除する特別なテーブルを使用します。

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
3
dirkt