Linux server as an unmanaged switch

I have a small Ubuntu x64 server, which provides dhcp, naming, file and such services to my home network. It's simply connected to unmanaged SOHO switch laying next to it and just works. But, it has unused 4xGbE i350 NIC card in PCIe slot and I had this idea of using this NIC instead of the current switch. It probably won't have any advantages if it will be also plain unmanaged switch like the current dedicated device but I wanted to learn something (and I could maybe turn it into managed switch later, maybe implement some IPS/IDS and further stuff). How I was surprised to find out I have no idea how. I did my share of searching of course, but it left me confused even more. First of all, why all howtos and articles configure bridges to achieve switching? With unmanaged switch all ports are equal, has no IPs and one of them leads to gateway. Is that even possible to create that on Linux server (ignoring it may not be really useful considering low price of a small switch)?


Solution 1:

Use the bridge driver.

The bridge is a software implementation of a Layer 2 switch, where each interface added into the bridge is a switchport.

Let's say you have your 4 i350 ports in bridge br0 with two other PCs plugged in:

[ Remote PC A - MAC aa:aa:aa:aa:aa ] ---- [ i350 #1 ] ---- .------------.
                                          [ i350 #2 ] ---- |  Linux PC  |
                                          [ i350 #3 ] ---- | bridge br0 |
[ Remote PC B - MAC bb:bb:bb:bb:bb ] ---- [ i350 #4 ] ---- '------------'

Remote PC A tries to reach Remote PC B.

PC A will ARP out to the broadcast destination MAC address (all ff) with its own source MAC (all aa).

The bridge will receive that ARP Request and learn that MAC aa is down bridgeport i350 #1.

The bridge then forwards that broadcast out all the other i350 ports, because that is the correct behaviour when a switch recieves a broadcast packet.

Remote PC B receives the ARP, and generates a reply to PC A with destination MAC of PC A (all aa) and its own source MAC (all bb).

The bridge will receive that ARP Reply and learn that MAC bb is down bridgeport i350 #4.

The bridge sees the destination MAC is aa, and the bridge knows that MAC aa is available down port i350 #1 and so sends the frame out that NIC.

You can add an IP address to a bridge and use it like a regular network interface, route with it, NAT with it, etc but you don't have to.

The above happens even if kernel tunable net.ipv4.ip_forward=0 is set, because the bridge driver is not performing IP forwarding or IP routing or IP NAT, it is performing Layer 2 packet switching like any other unmanaged Layer 2 switch.

You can also run Spanning Tree on the bridge if you are connecting it to a larger network.

You said you're using Ubuntu. The following should work for Ubuntu 20.04 using NetworkManager:

/etc/NetworkManager/system-connections/br0.nmconnection

[connection]
id=br0
type=bridge
interface-name=br0
permissions=

[bridge]
stp=false

[ipv4]
dns-search=
ignore-auto-dns=true
ignore-auto-routes=true
method=disabled
never-default=true

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
ignore-auto-dns=true
ignore-auto-routes=true
method=ignore
never-default=true

[proxy]

Repeat this file for each i350 named netX, using each NIC's correct MAC address:

/etc/NetworkManager/system-connections/netX.nmconnection

[connection]
id=netX
type=ethernet
interface-name=netX
master=br0
metered=2
permissions=
slave-type=bridge

[ethernet]
mac-address=xx:xx:xx:xx:xx:xx
mac-address-blacklist=

[bridge-port]