Skip to content

IfState

We'll be using IfState for the network configuration of our routers.

Feel free to use its documentation, but please use our provided startup IfState configuration to keep a constistant interface naming for your router model.

Base setup

IfState is already installed by default on RKOS.

Firstly, create a network device via the hardware tab. Afterwards, create the configuration directory /etc/ifstate: mkdir /etc/ifstate.

Now the real magic begins. IfState can generate a starting configuration, which contains the hardware identifiers (MAC address, PCIe address, ...) of your network interfaces. This way, we don't have to rely on the kernel interface names and can also specify our own ones. Take a look and run ifstatecli identify by yourself!

rtr-pod1-bg1:~# ifstatecli identify
interfaces:
  eth0:
    link:
      kind: physical
    identify:
      perm_address: bc:24:11:d8:59:66
      parent_dev_name: virtio1
      parent_dev_bus_name: virtio
  eth1:
    link:
      kind: physical
    identify:
      perm_address: bc:24:11:49:53:75
      parent_dev_name: virtio3
      parent_dev_bus_name: virtio

Bootstrap your configuraion using ifstatecli identify > /etc/ifstate/ifstate.yaml. Now edit /etc/ifstate/ifstate.yaml using your favourite text editor and do the following changes: * Remove the perm_address entries. We don't need them, since parent_dev_name/parent_dev_bus_name is specific enough. * Rename your interfaces to reflect, what they are doing. You can use the slug of your ISP or IXP for example. * Set the link up. Under interfaces.xxx.link set state: up. * Add your IP addresses, which are speficied in the IPAM. Add a list under interfaces.xxx.addresses.

The result should look something like this:

interfaces:
  isp1:
    addresses:
      - 212.111.252.xxx/31
      - 2a01:7700:8080:fxxx::2/64
    link:
      kind: physical
      state: up
    identify:
      parent_dev_name: virtio1
      parent_dev_bus_name: virtio
  ixp1:
    addresses:
      - 212.111.252.xxx/28
      - 2a01:7700:8080:2xxx::2/64
    link:
      kind: physical
      state: up
    identify:
      parent_dev_name: virtio3
      parent_dev_bus_name: virtio

Now it is time to apply the changes. Do that by running ifstatecli apply:

rtr-pod1-bg1:~# ifstatecli apply
configure network namespaces...

configure sysctl settings...
   ipv6/optimistic_dad               change

configure interfaces...
 lo
   link                              ok
   addresses                         = 127.0.0.1/8
   addresses                         = ::1/128
 isp1
   ifname                            change
   link                              change
   addresses                         + 212.111.252.xxx/31
   addresses                         + 2a01:7700:8080:fxxx::2/64
 ixp1
   ifname                            change
   link                              change
   addresses                         + 212.111.252.xxx/28
   addresses                         + 2a01:7700:8080:2xxx::2/64

configure traffic control...
 lo
   tc                                ok
 isp1
   tc                                ok
 isp2
   tc                                ok

Now, we have to enable IfState to make it run the network configuration on each boot.

rtr-pod1-bg1:~# rc-update add ifstate boot
 * service ifstate added to runlevel boot

Loopback interface

Now we configure a routing loopback interface. Allocate the first IPv4 and IPv6 addresses from your assignments. It is configured like your other interfaces, it just has kind: dummy.

interfaces:
  loop:
    link:
      kind: dummy
      state: up
    addresses:
    - 2a01:7700:8080:xxxx::1/128
    - 212.111.xxx.1/32

IP forwarding

In order for your router to route packages, we have to enable forwarding for IPv4 and IPv6. These sysctl settings can be changed with IfState as well! Just append the following lines to your configuration file and run ifstatecli apply.

sysctl:
  all:
    ipv4:
      forwarding: 1
    ipv6:
      forwarding: 1

Tip

Now it is a good time to run lbu commit. 😉

Network namespaces

Later on, you might need to configure network namespaces. They are a pretty cool way to run multiple network environments on the same Linux kernel.

The interfaces section below defines the default namespace. Each interface can instead be assigned to another defined namespace. To do that, just move the interface definition into the namespace.

interfaces:
  eth0:
    addresses:
      - 192.168.10.1/24
    link:
      kind: physical
      state: up
    identify:
      parent_dev_name: virtio1
      parent_dev_bus_name: virtio
namespaces:
  netns1:
    interfaces:
      eth1:
        addresses:
          - 192.168.20.1/24
        link:
          kind: physical
          state: up
        identify:
          parent_dev_name: virtio3
          parent_dev_bus_name: virtio

Virtual Ethernet Devices

If you're using Docker or Podman, you might have seen some network interfaces beginning with veth. These are Virtual Ethernet Devices. Not much to explain here, they are like (virtual) ports with a patch cable between them.

This is how you would connect two network namespaces in IfState:

namespaces:
  netns1:
    interfaces:
      veth1:
        addresses:
          - 192.168.10.1/30
        link:
          state: up
          kind: veth
          peer: veth2
          peer_netns: netns2
  netns2:
    interfaces:
      veth2:
        addresses:
          - 192.168.10.2/30
        link:
          state: up   
          kind: veth
          peer: veth1
          peer_netns: netns1