Why "Nexthop has invalid gateway" when it seems to be defined?

I have my own wireless router to which a remote VPN client, 10.7.0.6, is connected. I want traffic from one of the wireless clients to go through it, but I'm getting "Nexthop has invalid gateway". (I'm aware that I'll have to persuade 10.7.0.6 to play ball, but the present problem comes before that I think.)

This is the router, 10.0.0.1:

[ad@rout ~]$ ip addr
1: lo: ...
2: wlp0s20f0u1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 78:32:1b:06:18:1b brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 brd 10.0.0.255 scope global wlp0s20f0u1
       valid_lft forever preferred_lft forever
...
6: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/none 
    inet 10.7.0.1 peer 10.7.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever
...
23: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp 
    inet 82.69.221.62 peer 62.3.89.162/32 scope global ppp0
       valid_lft forever preferred_lft forever

[ad@rout ~]$ ip route
default dev ppp0 scope link 
10.0.0.0/24 dev wlp0s20f0u1 proto kernel scope link src 10.0.0.1 
10.7.0.0/24 via 10.7.0.2 dev tun0 
10.7.0.2 dev tun0 proto kernel scope link src 10.7.0.1 
62.3.89.162 dev ppp0 proto kernel scope link src 82.69.221.62 

and this is the client, 10.0.0.2, before I start mucking around:

ad@blackmail:~$ ip addr
1: ...
2: ...
3: wls1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 60:57:18:43:12:fa brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 brd 10.0.0.255 scope global noprefixroute wls1
       valid_lft forever preferred_lft forever
    inet6 fe80::6257:18ff:fe43:12fa/64 scope link 
       valid_lft forever preferred_lft forever

ad@blackmail:~$ ip route
default via 10.0.0.1 dev wls1 proto dhcp src 10.0.0.2 metric 303 mtu 1492 
10.0.0.0/24 dev wls1 proto dhcp scope link src 10.0.0.2 metric 303 mtu 1492 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 

ad@blackmail:~$ ping google.com
PING google.com (216.58.198.238) 56(84) bytes of data.
64 bytes from lhr26s04-in-f238.1e100.net (216.58.198.238): icmp_seq=1 ttl=53 time=17.0 ms

ad@blackmail:~$ ping 10.7.0.6
PING 10.7.0.6 (10.7.0.6) 56(84) bytes of data.
64 bytes from 10.7.0.6: icmp_seq=1 ttl=63 time=626 ms

ad@blackmail:~$ traceroute 10.7.0.6
traceroute to 10.7.0.6 (10.7.0.6), 30 hops max, 60 byte packets
 1  rout (10.0.0.1)  3.777 ms  5.372 ms  7.143 ms
 2  10.7.0.6 (10.7.0.6)  153.924 ms  153.948 ms  153.999 ms

Now I try to make it go via 10.7.0.6:

ad@blackmail:~$ su
Password:

[root@blackmail ~]# ip route del default

[root@blackmail ~]# ip route add 10.7.0.0/24 via 10.0.0.1

[root@blackmail ~]# ping 10.7.0.6
PING 10.7.0.6 (10.7.0.6) 56(84) bytes of data.
64 bytes from 10.7.0.6: icmp_seq=1 ttl=63 time=428 ms

[root@blackmail ~]# ip route add default via 10.7.0.6
Error: Nexthop has invalid gateway.

Why?


Solution 1:

A gateway address can only be on a directly connected network. The 10.7.0.0/24 network is not directly connected to your host 10.0.0.2, but is instead separated by another network, which is connected to the host at 10.0.0.1.

You must use 10.0.0.1 as your gateway for this network, and that host must also be configured to route the packets in the desired manner.

Solution 2:

Perhaps something like:

ip route add <gateway IP> dev <interface on which it should be reachable>

and then

ip route add default via <gateway ip>

"Direct connection" can be part of a Layer 2 bridge, as I found, very useful for assigning spare public IPs to internal devices without having to resort to NAT nastiness and complexity..

Solution 3:

I've also encountered the problem, you need

ip link set LINK_NAME up

be aware that if the link has dependencies on other links, such as veth pair, you also need enable them too.

Solution 4:

I think this command could solve your problem :

ip route add default via 10.7.0.6 onlink

In this case, we consider gateway is always "onlink".

Solution 5:

You need policy based routing at your router because the client has no direct connection to the next hop. There is a quick introduction to policy based routing and it was also discussed at this question at superuser.

In your case it could look like this:

ip rule add from 10.0.0.2/32 table viavpn
ip route add 0.0.0.0/0 via 10.7.0.6 dev eth4 table viavpn