Making a SIMPLE bridge is so COMPLICATED under linux.

Aristotle : only the idiots make stuff that are complex look simple.
Feynman : Science is the belief in the ignorance of the expert making anything look to complex for you.
Software defined network is begnining with virtual ip, ethernet bonding, software bridge, software vlan, tap interface, ip tunnel. You don't actually plug HARDWARE, hence it's software defined.

As funny as it can be, most of these hardware are full of the same software code we run on our computer. BSD being the most borrowed TCP stack used in network appliance, linux coming second, but other OSes are used (QNX for instance). In a way, all networks are actually software defined. But it is classier to say you do « software defined networks » than to say I am a « network techie ».

So, so, so....

Yesterday, I managed to make sense of And I must say, I was kind of pissed.

You see, I began linux with the linux bible HOWTOs printed on paper when internet was sparse and it was helpful.

HOWTOs differ from doc in that they do not give you the solution, they also help you improve your understanding.

So before you can give a network in which your host and guest can talk, you need to understand what you do :D




The bridge is like a device to route to and from to LAN and use the magic of STP (Spanning Tree Protocol) to decide if a packet goes in a direction or the other.

TUN/TAP devices are like ethernet cards for user space code. Enabling code to have a full fledge device driver looking like an ethernet card that is all made of software. You cannot be more into «software defined network» than this.

Making the script was straightforward to connect all of this ...

One to setup :
$cat qemu.net.sh 
#!/usr/bin/env bash
TAP=${TAP:-tap0}
BRIDGE=${BRIDGE:-br0}
HOST_ETH=${HOST_ETH:-eno1}
USER=${USER:-jul}

#create tuntap device accessible to the user for the guest
ip tuntap add dev $TAP mode tap user $USER
ip link set $TAP up
# create bridge

ip link add $BRIDGE type bridge 
# plug host and guest on the bridge
ip link set dev $HOST_ETH master $BRIDGE
ip link set dev $TAP master $BRIDGE
ip link set $BRIDGE up
sleep 1
# get an ip for the bridge
dhclient $BRIDGE
sleep 1
# re-get an IP for the host
dhclient $HOST_ETH
one to cleanup
$cat qemu.net.cleanup.sh 
#!/usr/bin/env bash

TAP=${TAP:-tap0}
BRIDGE=${BRIDGE:-br0}
HOST_ETH=${HOST_ETH:-eno1}
# turn off bridge
ip  link set $BRIDGE down
# unplug  guest 
ip  link set $TAP down
# remove bridge
ip link delete $BRIDGE
# delete tun/tap
ip link delete $TAP
ip tuntap del dev tap mod tap
sleep 1
# re-get an IP for the host assuming you use dhcp
dhclient $HOST_ETH

Notice all the variables... br0, tap0 are used in so many example that they may already have been used by ... docker, kvm, or any other virtualization solution. To avoid conflict in this case I used variables that can be set with environment variable. eno1 shoudl be replaced with YOUR ethernet interface on YOUR linux ... Name of the interfaces varies according to version, direction of the wind and systemd humor. Gone are the good old days when eth0 was univoquely the name of your ethernet card when you had only one.

The qemu startup script will thus look like this:
#!/usr/bin/env bash
TAP=${TAP:-tap0}
qemu-system-x86_64 -m 3g -smp 2 -nographic \
	/home/jul/src/fbsd/FreeBSD-14.1-BETA3-amd64.qcow2 \
    -net nic -net tap,ifname=$TAP,script=no,downscript=no
The two scripts requires root to run them. But funnily enough, to work ... I discovered by trial and error that I needed to shut down my ethernet host interface in network manager, else you have two network interfaces trying to fight for the same IP network.

Qemu freebsd's equivalent, behyve have the nicety to put it in the Freebsd's handbook. The place where the motd redirects you at login.

I spared you the kvm pages on the topic that uses the deprecated brctl interface to do the same, while technically kvm is just a layer of shit above qemu, and above which openstack is another layer of poo, because my problem was understanding why network manager conflicts with the script. Long story short, I admit my defeat. I don't know why I must disable my ethernet interface in network manager. It makes sense, somehow. That I have to redefine my network connection « à l'ancienne » in /etc/network/interfaces. Which is bothering when you have wifi.

If you have (as I do) a local custom DNS server with black holer as a forwarder, you must not forget to tell dhclient TO NOT override your DNS.

In normal distros edit /etc/dhclient.conf (/etc/dhcp/dhclient.conf on debian based distro like ubuntu or linux mint) and add
prepend domain-name-servers 127.0.0.1;

On freebsd you must do the same and also disable this wonderful piece of software coming from linux's world : resolvconf by doing :
sysrc resolv_enable="NO"


What I learned today is the shift of normality in documentation. When linux began and blog posts were not simple « cookbooks » for one problem, we had « howtos » that were not only giving actual example but also knowledge. Nowadays, commands are thrown at your face to deal with it, as if it was trivial. It is not.

My latest series of posts are looking like cookbooks, but actually, they are just me having fun and not pretending to do anything more than a log of having fun reinventing the wheel with less lines of code. The networl part is my least favourite and the command lines are not self explanatory.

Anyway, next post, now that we have pubsub running in a jail with a way to setup the network nicely is adding TLS and login/pass like a troll ! And then making a python library for the protocol (actually it is finished).

No comments: