Route missing in routing table but present in netifd

Every now and then, I run into the situation that my VPN connection adds a route to netifd but the route is not in the routing table.

The network vpn uses ip4table=3 but the default route is missing:

$ ip r show table 3
unreachable default metric 200 
10.12.1.2 dev vpn proto static scope link 
10.12.1.1 dev vpn proto static scope link src 10.12.1.2 
192.168.0.0/24 dev br-lan proto static scope link

There's a single call to proto_send_update with one address and the two routes.
netifd appears to be receiving them correctly:

$ ubus call network.interface.vpn status
..
	"route": [
		{
			"target": "10.12.1.1",
			"mask": 32,
			"nexthop": "0.0.0.0",
			"source": "10.12.1.2/32"
		},
		{
			"target": "0.0.0.0",
			"mask": 0,
			"nexthop": "10.12.1.1",
			"source": "0.0.0.0/0"
		}
	],
..

I don't see any error messages in the log (but often the log was already rotated by the time I notice the problem).
Anyone have an idea?

Can you post the whole ifstatus vpn ?

@trendy hi and thanks for your reply!

{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 102406,
	"l3_device": "l2tp-vpn",
	"proto": "l2tp",
	"updated": [
		"addresses",
		"routes",
		"data"
	],
	"ip4table": 3,
	"ip6table": 3,
	"metric": 0,
	"dns_metric": 0,
	"delegation": true,
	"ipv4-address": [
		{
			"address": "10.12.1.2",
			"mask": 32
		}
	],
	"ipv6-address": [
		
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		
	],
	"route": [
		{
			"target": "10.12.1.1",
			"mask": 32,
			"nexthop": "0.0.0.0",
			"source": "10.12.1.2/32"
		},
		{
			"target": "0.0.0.0",
			"mask": 0,
			"nexthop": "10.10.1.1",
			"source": "0.0.0.0/0"
		}
	],
	"dns-server": [
		
	],
	"dns-search": [
		
	],
	"neighbors": [
		
	],
	"inactive": {
		"ipv4-address": [
			
		],
		"ipv6-address": [
			
		],
		"route": [
			
		],
		"dns-server": [
			
		],
		"dns-search": [
			
		],
		"neighbors": [
			
		]
	},
	"data": {
		"tunnel_id": 36558
	}
}

handy. i've been typing ubus call network.interface.vpn status all the time..

This looks like a race condition, assuming that L2TP is natively supported by netifd.
As a workaround, you can create a delayed default route with hotplug extras:

mkdir -p /etc/hotplug.d/online
cat << "EOF" > /etc/hotplug.d/online/10-l2tp
PROTO="$(uci -q get network."${INTERFACE}".proto)"
TABLE="$(uci -q get network."${INTERFACE}".ip4table)"
if [ "${PROTO}" != "l2tp" ]; then exit 0; fi
sleep 10
. /lib/functions/network.sh
network_flush_cache
network_get_device DEVICE "${INTERFACE}"
network_get_gateway GATEWAY "${INTERFACE}"
ip route add default dev "${DEVICE}" \
via "${GATEWAY}" table "${TABLE:-main}"
EOF
cat << "EOF" >> /etc/sysupgrade.conf
/etc/hotplug.d/online/10-l2tp
EOF
1 Like

Thanks - I didn't know that there was such a hotplug handler!
Yes, this 'l2tp' protocol is supported. It connects to a REST API (URL and secret from UCI) to learn the L2TP parameters, does some holepunching, and creates a tunnel using the newfound connection.

Because I was seeing the issue with other (established) protocols as well, I created a component that (idempotently) adds the routes known to netifd - this hotplug handler is perfectly suited for that kind of work!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.