Route-based IPsec hands the routing table a decision that policy selectors used to make. On Linux the piece that makes this possible is the XFRM interface: a virtual device whose traffic is matched to IPsec state by an interface identifier rather than by a selector. Creating one takes a single command and proves nothing about whether a tunnel exists. The device is a hook between routing and security policy, and both sides of that hook need to be configured before anything is protected.

What the device is and what it is not

An XFRM interface is a routing handle. Packets routed into it are matched against XFRM policies that reference the same interface identifier, and if a policy and a state exist, they are encapsulated. Without those, the interface exists, counters stay still, and the traffic goes nowhere useful.

That is the first diagnostic split. A route into the device is a routing fact, an installed state is a security fact, and a rising counter on the device is neither. When people say the tunnel is up because the interface shows UP, they are describing the link flags of a virtual device that has no peer of its own. The flag means the device was created and enabled, nothing more.

One more boundary: the interface identifier is not a name. Two devices with similar names and different identifiers do not share state, and a connection configured with the wrong identifier installs state that no route will ever use.

Build one in the right order

Start with the outer device and a number you will also put in the daemon configuration. The example uses eth0 as the outer interface and 42 as the identifier, addresses you should replace with your own.

Bring the device up, then confirm the identifier the kernel recorded before touching the VPN configuration:

sudo ip link add xfrm0 type xfrm dev eth0 if_id 42
sudo ip link set xfrm0 up
ip -d link show xfrm0 | grep -o 'if_id [0-9]*'

Now configure the connection in strongSwan with the same identifier, since the daemon has to install policies and states that reference it. Set the local and remote traffic selectors to the range you intend to route, then route that range into the device. The daemon configuration and the route table have to agree on both the identifier and the destinations, and neither one supplies the other.

Keep IKE and ESP out of the tunnel route

A default route pointing into the XFRM device captures the encapsulated packets as well as the traffic they carry. The result is a loop: the gateway tries to send its own ESP through the tunnel that ESP is supposed to build.

The fix is a more specific route for the peer's outer address through the physical interface, which wins over the default because it matches more bits. Mark-based routing does the same job when several tunnels share a table, and strongSwan documents both approaches for route-based deployments.

Whatever you choose, verify that the outer packet leaves unencapsulated. A quick check is to ping the peer's outer address after the tunnel is up; if that fails while the interface is up, suspect capture rather than reachability. The same reasoning applies to the IKE port, because the daemon's own UDP traffic must not be routed into the device it is trying to establish.

Check counters in two places before blaming encryption

Interface counters and state counters measure different stages. Packets routed into the device increment the device even when no state matches, while the state counters only move for traffic that was actually encapsulated.

Read both, then read the daemon's view of the child association:

ip -s link show xfrm0
sudo ip xfrm state list | grep -E 'src|proto|mode'
sudo swanctl --list-sas

Device counters rising with empty state output means routing works and policy does not match, usually an identifier or selector mistake. State counters rising while the remote side reports nothing means the packets leave but do not arrive or fail authentication, which points at the path or the peer configuration. A listed child with zero traffic is a selector problem on one end, not a broken cipher.

Decide who installs the routes

Two owners for one route table is the usual source of flapping. If the daemon installs routes automatically, your network manager must not also install a default route through the same device, and a manual route added by a startup script will be removed the next time the daemon reconfigures.

Pick one owner and write it down. When the daemon owns routes, keep the startup script out of the table and let the connection definition describe the traffic selectors. When the network manager owns them, disable automatic installation and accept that the daemon will not repair a missing route on reconnect.

Forwarding and firewall rules are a separate decision on top of that, because a gateway passing other hosts' traffic needs both. Route-based IPsec makes that traffic easy to express with ordinary routing tools; it does not make the policy layer optional.

Barruulee wal qabatan