私の要件は、それぞれが同じサブネット上にIPアドレスを持つマルチタップインターフェイスを作成することです。
橋を架けてやってみた
br0 (192.168.1.199)
___________|_____________________________________
| | | | | |
eth0 tap0 tap1 tap2 tap3 tap4
(192.168.1.150) (.151) (.152) (.153) (.154)
外部PCからすべてのタップインターフェイスにアクセスできる必要があります。 Tap0から外部コンピュータにpingするとき、192.168.1.200と言います
ping -I tap0 192.168.1.200 -- the ping is not going through.
しかし、192.168.1.200から192.168.1.150(tap0)にpingすると、機能しますが、ブリッジのMACアドレス(br0)を取得します
私には2つの問題があります。
このタスクは XY問題 のように見えますが、私はそれを明らかにして、何が問題であるかを明確にして解決策を提供します。
インターフェイスでIPアドレスを割り当てると、カーネルはメインルーティングテーブルに直接接続されたルート(ip route list
に表示されるもの)と特別なルート(local
テーブルにあるbroadcast
とlocal
)を自動的に作成します。 ip route list table local
を参照してください)。
複数のインターフェースで重複または同じアドレス空間を割り当てると、ルーティングテーブルにいくつかの同一のルートが表示されます。明らかに、これは良いことではありません。
その結果、特定のルートの選択は、アドレスの割り当て順序やその他の要因に依存します。これを確認するには、ip route get 192.168.1.200
コマンドを使用できます。ブリッジインターフェイスを再作成しようとすると、192.168.1.0/24
サブネットへのルートがいずれかのタップインターフェイスを経由するため、接続が完全に失われる可能性があります。
この構成が機能するのは、同じサブネットを持つ他のインターフェースよりも前にブリッジインターフェースのアドレスが割り当てられている場合のみですが、保証はありません。したがって、主な結果:それがどのように機能するかを完全に理解していない場合は、いくつかのインターフェースの同じサブネットからアドレスを割り当てないでください。
この構成を機能させるためのより正しい方法は、プレフィックス長が/32
のタップインターフェイスにアドレスを割り当てることです。ほとんどの時間で期待どおりに動作します。
Linuxカーネルでは、IPアドレスはインターフェースとハードリンクされていません。小さなデモンストレーション:ホストに2つのNICにさまざまなアドレスがあり、それらの1つからケーブルを物理的に切断した場合、切断されたIPアドレスにpingできるNIC =作業中NIC外部から。
外部ホストとの通信用のインターフェースの選択は、pingの-I
オプションでIPアドレスを指定するときに、ルーティング構成によって定義されます。発信パケットの送信元アドレスを指定するだけで、出力インターフェイスは指定しません。 MACアドレスは、パケット送信の最後のステップで入力されます。実際のルートはip route get
コマンドで確認できます。
gw:~# ip r ls table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope Host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope Host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 192.168.1.0 dev br0 proto kernel scope link src 192.168.1.199
local 192.168.1.150 dev tap0 proto kernel scope Host src 192.168.1.150
local 192.168.1.151 dev tap1 proto kernel scope Host src 192.168.1.151
local 192.168.1.152 dev tap2 proto kernel scope Host src 192.168.1.152
local 192.168.1.153 dev tap3 proto kernel scope Host src 192.168.1.153
local 192.168.1.154 dev tap4 proto kernel scope Host src 192.168.1.154
local 192.168.1.199 dev br0 proto kernel scope Host src 192.168.1.199
broadcast 192.168.1.255 dev br0 proto kernel scope link src 192.168.1.199
gw:~# ip -4 r ls
192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.199
gw:~# ip r g 192.168.1.200
192.168.1.200 dev br0 src 192.168.1.199 uid 0
cache
gw:~# ip r g 192.168.1.200 from 192.168.1.150
192.168.1.200 from 192.168.1.150 dev br0 uid 0
cache
ただし、pingの-I
オプションでインターフェース名を指定すると、rawソケットが使用されます。この場合、出力インターフェイスは厳密に定義されており、ルーティング手順はスキップされます。ただし、他の回答で説明されているように、カーネルは指定されたインターフェース(非アクティブタップ)を介してパケットを送信しようとします。明らかに、それは失敗します。
したがって、XY問題の良い例があります。トピックスターターは、個別のホストをエミュレートしてブリッジングをテストしたかったと思います。これを行う簡単な方法の1つは、ネットワーク名前空間の使用です。
IPアドレス192.168.1.150
の簡単な例。
ip netns add VM150
br0
インターフェイスにブリッジポートとして接続します。ip link add name vethVM150 type veth peer vethIntVM150
ip link set dev vethIntVM150 netns VM150
ip link set dev vethVM150 master br0
ip link set dev evthVM150 up
192.168.1.200
ホストにpingします:ip netns exec VM150 bash
ip netns identify
output> VM150
ip link set up dev lo
ip link set up dev vethIntVM150
ip address 192.168.1.150/24 dev vethIntVM150
ping 192.168.1.200
...
GNU screen
またはtmux
を使用することをお勧めします)。イーサネットヘッダーに異なるMACアドレスが表示されます。tcpdump -ni eth0 -e
15:38:54.084416 0a:28:39:f0:04:ad > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.150 > 192.168.1.200: ICMP echo request, id 2037, seq 72, length 64
15:38:54.088262 0c:d6:26:25:f9:00 > 0a:28:39:f0:04:ad, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.150: ICMP echo reply, id 2037, seq 72, length 64
15:38:54.403666 0c:d6:26:c2:70:00 > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.199 > 192.168.1.200: ICMP echo request, id 2043, seq 15, length 64
15:38:54.407580 0c:d6:26:25:f9:00 > 0c:d6:26:c2:70:00, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.199: ICMP echo reply, id 2043, seq 15, length 64
15:38:55.085501 0a:28:39:f0:04:ad > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.150 > 192.168.1.200: ICMP echo request, id 2037, seq 73, length 64
15:38:55.087252 0c:d6:26:25:f9:00 > 0a:28:39:f0:04:ad, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.150: ICMP echo reply, id 2037, seq 73, length 64
15:38:55.405129 0c:d6:26:c2:70:00 > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.199 > 192.168.1.200: ICMP echo request, id 2043, seq 16, length 64
15:38:55.407533 0c:d6:26:25:f9:00 > 0c:d6:26:c2:70:00, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.199: ICMP echo reply, id 2043, seq 16, length 64
15:38:56.087472 0a:28:39:f0:04:ad > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.150 > 192.168.1.200: ICMP echo request, id 2037, seq 74, length 64
15:38:56.091242 0c:d6:26:25:f9:00 > 0a:28:39:f0:04:ad, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.150: ICMP echo reply, id 2037, seq 74, length 64
192.168.1.200
ホストの検証は非常に簡単です-ARPテーブルを十分に確認してくださいHost:~# ip n ls dev eth0
192.168.1.150 lladdr 0a:28:39:f0:04:ad REACHABLE
192.168.1.199 lladdr 0c:d6:26:c2:70:00 REACHABLE
質問1:
ping -I tap0
pingにtap0でpingパケットを送信するように指示します。これはブリッジをバイパスし、実際には指定された「物理」インターフェースでのみ送信します。つまり、実質的には、タップインターフェイスから「から」pingするのではなく、「から」にpingすることになります。
タップインターフェースから「ping」を送信する場合は、それに何かを接続し(OpenVPNなど)、タップインターフェースが接続されている仮想ケーブルの反対側からpingを送信する必要があります。
質問2:あなたは次のようなことを試すことができます
arp -i br0 -Ds 192.168.1.150 tap0 pub
等.