I am trying to create virtual network devices in order to test and develop multicast programs. My computer has a single NIC with one Ethernet port, which is connected to the Internet. I want a second (virtual) NIC, connected to a bridge, which has 2 other computers connected to it for testing. In other words:
- Create a virtual NIC.
- Create a virtual bridge/switch.
- Connect the virtual NIC to the virtual bridge.
- Create two additional virtual NIC devices (to be used as remote hosts) and connect them to the virtual bridge.
As I understand it, creating a virtual bridge in Linux implicitly creates and connects a virtual NIC to it, which is accessible as a network interface. I answered a question explaining this here (although I may be wrong).
I know that I could test multicast programs with VMs, but this is quite cumbersome, and my understanding was that with the proper routing tables I should be able to run programs natively if I bind them to the appropriate virtual network device and address. So far, I can't even get pinging to work, much less multicast. This is what I have:
ip link add br0 type bridge ip link add dum0 type dummy ip link add dum1 type dummy ip link set dev dum0 master br0 ip link set dev dum1 master br0 ip addr add 10.0.0.1/24 brd + dev br0 ip addr add 10.0.0.2/24 brd + dev dum0 ip addr add 10.0.0.3/24 brd + dev dum1 ip link set br0 up ip link set dum0 up ip link set dum1 up ip route del 10.0.0.0/24 dev dum0 ip route del 10.0.0.0/24 dev dum1 ip route del broadcast 10.0.0.0 dev dum0 ip route del broadcast 10.0.0.0 dev dum1 ip route del broadcast 10.0.0.255 dev dum0 ip route del broadcast 10.0.0.255 dev dum1 ip route del local 10.0.0.2 ip route del local 10.0.0.3
For convenience, you can use the following to undo that:
ip link del dev dum1 ip link del dev dum0 ip link del dev br0
Upon inspection everything is configured exactly as it would be with physical hardware:
$ ip addr show br0 41: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 56:47:31:fd:10:c0 brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/24 brd 10.0.0.255 scope global br0 valid_lft forever preferred_lft forever inet6 fe80::5447:31ff:fefd:10c0/64 scope link valid_lft forever preferred_lft forever $ ip addr show dum0 42: dum0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN group default qlen 1000 link/ether 56:47:31:fd:10:c0 brd ff:ff:ff:ff:ff:ff inet 10.0.0.2/24 brd 10.0.0.255 scope global dum0 valid_lft forever preferred_lft forever inet6 fe80::5447:31ff:fefd:10c0/64 scope link valid_lft forever preferred_lft forever $ ip addr show dum1 43: dum1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN group default qlen 1000 link/ether d2:47:c8:19:4a:60 brd ff:ff:ff:ff:ff:ff inet 10.0.0.3/24 brd 10.0.0.255 scope global dum1 valid_lft forever preferred_lft forever inet6 fe80::d047:c8ff:fe19:4a60/64 scope link valid_lft forever preferred_lft forever $ ip route show table main 10.0.0.0/24 dev br0 proto kernel scope link src 10.0.0.1 $ ip route show table local broadcast 10.0.0.0 dev br0 proto kernel scope link src 10.0.0.1 local 10.0.0.1 dev br0 proto kernel scope host src 10.0.0.1 broadcast 10.0.0.255 dev br0 proto kernel scope link src 10.0.0.1 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 $ ip route get to 10.0.0.1 local 10.0.0.1 dev lo src 10.0.0.1 uid 1000 cache <local> $ ip route get to 10.0.0.2 10.0.0.2 dev br0 src 10.0.0.1 uid 1000 cache
... with one exception: the MAC address of
br0 is the same. This worries me, because it suggests that my understanding of the bridge device is wrong, that it isn't actually a virtual NIC connected to the bridge device, but instead some sort of weird neither-bridge-nor-NIC that can't be used normally. In any case, I don't think this interferes with the rest of the testing. Routing through the dummy devices doesn't work either.
As for the testing, I can only ping any of the devices through the loopback device (
lo). The routing table correctly routes packets through
dum1, but it returns
Destination Host Unreachable:
$ ping -c 2 10.0.0.1 # br0 through lo OK PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.053 ms 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.029 ms --- 10.0.0.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 56ms rtt min/avg/max/mdev = 0.029/0.041/0.053/0.012 ms $ ping -c 2 10.0.0.2 # dum0 through br0 BAD PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. From 10.0.0.1 icmp_seq=1 Destination Host Unreachable From 10.0.0.1 icmp_seq=2 Destination Host Unreachable --- 10.0.0.2 ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 62ms pipe 2 $ ping -c 2 -I lo 10.0.0.2 # dum0 through lo OK ping: Warning: source address might be selected on device other than lo. PING 10.0.0.2 (10.0.0.2) from x.x.x.x lo: 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.047 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.033 ms --- 10.0.0.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 35ms rtt min/avg/max/mdev = 0.033/0.040/0.047/0.007 ms
At this point I really don't know what I could be doing wrong. I patched everything through my firewall. I think the only thing are the dummy devices. I tried researching how to "just create a virtual NIC," and that has been extremely frustrating. The
ip-link(8) man page lists literally dozens of possible devices, giving absolutely no idea what they do differently from each other or when you would use them. I can't stress enough how hard I tried to research this, because it seems simple enough, but it is very difficult to find information on it (if you don't know so already).
I have read that dummy devices may simply discard data (from one obscure source and nowhere else), in which case maybe they drop ARP requests and I can't find their MAC address (if that is even necessary in this virtual configuration). I also tried using
ip tuntap (Linux taps), and that didn't work either, but if I understand those correctly, they provide the raw IP packets (for tunnels) or Ethernet frames (for taps) to programs that request them from the kernel, and otherwise drop all data too.
So, what kind of device do I need? Is this even going to work to test multicast programs? Will I be able to bind to the address of a device, send multicast traffic from it, have it sent across the bridge, and received by a multicast program bound to another device address? This has been quite involved, so I appreciate any help and anyone that can read through it. Thanks!
ip netns(which does a bit more than just network namespaces, but let's say that's the same).