Dedicated routing table for tinc

September 25, 2017

The need of a dedicated routing table

We use tinc to make decentralized friend-to-friend network. The network is organized in switch mode and presented as a virtual LAN. One of its use is to route networks otherwise inaccessible, for example a route,

172.28.0.0/16 via 192.168.7.56 dev f2f

It often rises that one node itself is part of the network it is designed gateway. In the above example, the node 192.168.7.56 has address 172.28.128.37, and tinc will use in vain its own virtual network to connect the node.

If only tinc is ordered to use a routing table without entries offered by itself. There are several ways to achieve this.

  1. Route the IP of the node explicitly with real interfaces, as 172.28.128.37 via 10.4.9.1 dev wlan0. The downside is that every node has to be entered into the route table.
  2. Run tinc as a specific user and allocate a route table to that user, discussed in fugoes' post. The downside is that a special user has to be maintained and tun/tap interfaces has to be created separately.
  3. Run tinc inside a net_cls cgroup, and allocate a route table to group, partially documented in netcls of linux kernel documentation. This post will discuss this approach.

Run tinc inside a netcls cgroup

I am running OpenRC on Debian, where tinc is started by OpenRC. Since OpenRC is cgroup-aware, to enable to cgroup feature, add

rc_controller_cgroups="YES"

into /etc/rc.conf. Next tinc started by OpenRC is assiged to netcls id 1337, by adding

rc_cgroup_net_cls="net_cls.classid 1337"

into /etc/conf.d/tinc.

When tinc is started by OpenRC, a subgroup called openrc_tinc will be created under /sys/fs/cgroup/net_cls with 1337 in net_cls.classid.

Let a sub-cgroup use a specific route table

First, mark packets from netcls.classid 1337 as fwmark 1337.

iptables -A OUTPUT -m cgroup --cgroup 1337 -j MARK --set-mark 1337

Then, create a table bare by putting 250 bare into /etc/iproute2/rt_tables, and let the packets marked 1337 look up table bare

ip rule add fwmark 1337 lookup bare

Finally, put the bare routes into bare,

ip route add table bare $(ip route show | grep default)

Something like default via 10.4.9.1 dev wlan0 should be in the output of ip route show table bare. The bare, however, is not automatically synchronized with main and each time the default route in main changes, the bare has to be updated manully. ip monitor and dhclient hooks are suitable to do it automatically although this post is not going to explore them.

These commands are independent of tinc, and can be put into /etc/rc.local for automatic execution during boot.

Summary and Discussion

By leveraging cgroup and OpenRC, a cleaner approach to direct tinc to a dedicated routing table is developed.