My requirement is to create a multiple tap interfaces, each with ip address on same subnet.
I tried this by creating a bridge
br0 (192.168.1.199)
___________|_____________________________________
| | | | | |
eth0 tap0 tap1 tap2 tap3 tap4
(192.168.1.150) (.151) (.152) (.153) (.154)
I need all the tap interface be reachable from external PC. When i ping from tap0 to external computer say 192.168.1.200
ping -I tap0 192.168.1.200 -- the ping is not going through.
But when i ping from 192.168.1.200 to 192.168.1.150 (tap0) it is working, but i get the mac address of the bridge (br0)
I have two problems:
- How to ping from tap interface to external
- How to get the mac address of the right tap interface, when pinged from outside.
Best Answer
This task seems like the XY problem, but I'll try to clarify, what is wrong with it and provide the solution.
When you assign the ip address on the interface, the kernel automatically creates the directly-connected route in the main routing table (what you see in the
ip route list
) and special routes (local
andbroadcast
in thelocal
table; what you see in theip route list table local
).When you assign the overlapped or the same address spaces on several interfaces, you will get the several identical routes in the routing tables. Obviously, this isn't a good thing.
At result the select of particular route depends on address assignment order and some other factor. To check it you can use the
ip route get 192.168.1.200
command. When you will try recreate the bridge interface, likely you will lost the connectivity completely, because the route to192.168.1.0/24
subnet will point through one of tap interfaces.This configuration will works only in one case: when the address on the bridge interface is assigned before, than on other interfaces with same subnet, but there isn't a guarantee. So, the main result: don't assign the addresses from same subnet on several interfaces if you're not complete understand how it will work.
More correct way to make this configuration to work is assignment of addresseses on the tap interfaces with
/32
prefix length. It works as expected in most part of time.In the linux kernel, the ip addresses are not hard linked with interface. Small demonstration: if your host have two NIC with various address and you physically disconnect cable from one of them, you will able ping to ip address on the disconnected NIC through working NIC from outside.
Selection of interface for communication with external hosts is defined by routing configuration when you specify an ip address in the
-I
option of the ping. It just the specify the source address of outgoing packets, but not specify the output interface. The mac address is filled at last steps of sending of the packets. You can check the actual route withip route get
command:But when you specify an interface name in the
-I
option of the ping, the raw socket will be used. In this case the output interface is hard defined and the routing step is skipped. But, as described in other answer, the kernel will attempt to send the packet through specified interface (inactive tap). Obviously, it fails.So we have the good example of the XY problem. I think the topic starter wanted to test the bridging with emulating of separate hosts. One of simple ways to do it is usage of network namespaces.
Small example
Brief example for ip address
192.168.1.150
.br0
interface as a bridge port.192.168.1.200
host from it:GNU screen
or thetmux
). You will see the different mac address in the ethernet headers.192.168.1.200
host is pretty simple - enough check the ARP table