Vivian Voss

One ifconfig for Every Interface

like for like freebsd networking netplan

A server arrives with two network ports, and the switch team want them bundled with LACP and the machine reachable on VLAN 10. It is an ordinary Tuesday job, the sort of thing that should take ten minutes and occasionally takes the afternoon.

On Ubuntu 26.04 the job starts in /etc/netplan/. The minimal installation pulls in netplan and iproute2 and leaves the old net-tools package out, so ifconfig is not there unless someone asks for it. The way to do it is a YAML file:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0: {}
    enp2s0: {}
  bonds:
    bond0:
      interfaces: [enp1s0, enp2s0]
      parameters:
        mode: 802.3ad
  vlans:
    vlan10:
      id: 10
      link: bond0
      addresses: [192.0.2.10/24]

Sixteen lines, all of them needed, and readable enough once the indentation is right. Then netplan try applies the file and, in the words of its manual, "automatically rolls it back if the user does not confirm the configuration within a time limit", 120 seconds by default.

Between the file and the kernel

The YAML is not what the kernel receives. netplan generate "converts Netplan YAML into configuration files understood by the back ends", systemd-networkd on a server and NetworkManager on a desktop, and those back ends then talk to the kernel. The generator runs again at every boot, and with every apply or try.

At the prompt the same bond speaks another language entirely. Building it by hand, which is what one does when testing or mending, is a fiddly business with ip:

ip link add bond0 type bond mode 802.3ad
ip link set enp1s0 down
ip link set enp1s0 master bond0
ip link set enp2s0 down
ip link set enp2s0 master bond0
ip link set bond0 up
ip link add link bond0 name vlan10 type vlan id 10
ip addr add 192.0.2.10/24 dev vlan10
ip link set vlan10 up

Nine commands, and their words appear nowhere in the YAML. The file says interfaces: where the prompt says master, and even the shared word link means something else in each. An administrator on Ubuntu keeps two vocabularies for one job, and a generator stands between them.

From the configuration to the kernel Ubuntu 26.04 FreeBSD 15.1 /etc/netplan/*.yaml 16 lines of YAML netplan generate at every boot and apply /run/systemd/network .netdev and .network files systemd-networkd talks to the kernel prompt ip link, ip addr kernel two vocabularies, a generator between them /etc/rc.conf 4 lines rc.d/netif hands the words over prompt same words ifconfig one binary, one vocabulary kernel what is tested at the prompt is what is kept

The generator also has a memory problem, which its own manual is honest about: netplan apply "will not remove virtual devices such as bridges and bonds that have been created, even if they are no longer described in the Netplan configuration", because "Netplan operates statelessly". Take the bond out of the YAML and it stays in the kernel until someone runs ip link delete or reboots.

The same job on FreeBSD

On FreeBSD the job is four lines in /etc/rc.conf, straight from the patterns in the Handbook:

cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto lacp laggport em0 laggport em1 up"
vlans_lagg0="10"
ifconfig_lagg0_10="inet 192.0.2.10/24"

The first line creates the bundle, the second gives it its protocol and its two members, the third hangs VLAN 10 off it, and the fourth gives that VLAN its address. rc.conf(5) spells out the third line: for each entry in vlans_lagg0, "a vlan(4) interface will be created", named after the tag. At boot, /etc/rc.d/netif reads these lines and hands the quoted words to ifconfig, the same binary in the same base system.

At the prompt it is two commands:

ifconfig lagg0 create laggproto lacp laggport em0 laggport em1 up
ifconfig lagg0.10 create vlan 10 vlandev lagg0 inet 192.0.2.10/24

The words between the quotes in rc.conf are the words typed at the prompt. There is one vocabulary, and nothing translates it. Taking the bundle away again is just as plain: ifconfig lagg0 destroy at the prompt, and on a restart netif calls clone_down for the interfaces it created, so the machine ends up with exactly what rc.conf describes.

Bond plus VLAN, like for like Ubuntu 26.04 FreeBSD 15.1 On disk 16 lines of YAML 4 lines of rc.conf At the prompt 9 ip commands 2 ifconfig commands Vocabularies 2 1 Translation layer netplan generate none Removed on restart no, by design yes, clone_down

Trying it safely

The real fear with remote network changes is the one netplan try answers: you lose the session, and with it the machine. FreeBSD handles it with parts that have been in the base system all along, and the shared vocabulary is what makes them work. Schedule a reboot first, shutdown -r +5. Build the new bundle at the prompt with ifconfig; that changes the running system and leaves rc.conf as it was. If the session dies, the machine reboots into the configuration it had. If it survives, kill the pending shutdown, which its manual says is all it takes, and copy the very same words into rc.conf. The lines that go into rc.conf are the ones that have just been tested.

The limit

The safety net takes one line. netplan try packages the rollback in a single step; on FreeBSD the administrator schedules the five-minute reboot before touching anything, and the base system does the rest.

ip reaches further on Linux because Linux needs it to. Network namespaces and policy routing live in ip there. FreeBSD gives the same jobs to the jail and the FIB, and ifconfig takes part in both: vnet moves an interface into a jail with its own network stack, and fib assigns an interface to a routing table.

FreeBSD speaks netlink too. Since FreeBSD 13.2 the kernel offers the netlink protocol as well, so tools written for Linux can talk to it. The native path stays ifconfig, and the Linux path is now there for those who bring their own.

Desktops are a different conversation. On a laptop that wanders between Wi-Fi networks, NetworkManager earns its keep. A server's network configuration is written once and then read for years.

On FreeBSD the words you test at the prompt are the words you keep.