26

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?

Adrian May
  • 361
  • 1
  • 3
  • 3

6 Answers6

27

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..

Jamie Prince
  • 371
  • 3
  • 2
  • 1
    Yes. It worked in the end, but I had to do two more things: A) delete some IP routes on the host computer. B) add DNS server on the host computer: "sudo nano /etc/resolv.conf # set the nameserver to IP address of wlan0 gateway. Thanks! :-) – xerostomus Jul 17 '21 at 20:54
12

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.

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • OK, but it's only one of the wireless clients that I want routed in this way. How do I tell the router to send packets from just that one client the long way round? – Adrian May Feb 10 '19 at 16:52
  • @AdrianMay You'll probably have to route it and firewall it. – Michael Hampton Feb 10 '19 at 16:58
  • @MichaelHampton i do have the same issue and i really don't know how to fix it. could you please have a look into it ? https://serverfault.com/questions/1016591/could-not-set-dhcpv4-route-nexthop-has-invalid-gateway-network-is-unreachable – αԋɱҽԃ αмєяιcαη May 11 '20 at 12:58
12

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.

osexp2000
  • 385
  • 3
  • 5
  • 1
    This only raises the link on layer 2 (which is already up, which you can see from the console output in his logs). The OP's problem is a routing (layer 3) problem. Yes the link needs to be up but you cannot send packets to a different network unless you either have a direct link to that network, or you send the packet via a router. – nevelis Mar 12 '20 at 23:01
  • @nevelis you are right. "Direct connection" is a must. – osexp2000 Mar 17 '20 at 08:49
  • 1
    I upvoted this because it does solve the problem as stated in the title. – Nathan Chappell Oct 30 '20 at 19:51
8

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".

Nicron
  • 81
  • 1
  • 1
  • 4
    Not Worked for me! 'Nexthop device required for onlink' – Milad Yarmohammadi Dec 13 '20 at 07:18
  • 1
    @MilaDroid you need some more args in there `dev somedevice` where somedevice is the device that has a `10.7.0.0/x` address on it. I don't think this is actually possible for the question here (where wls1 has only `10.0.0.2/24`), but it worked for my case where the subnet was always the same and simple but for no apparent reason I would get that error doing it normally. – Peter Oct 26 '21 at 17:32
  • Interface which can reach the address is also required, and one may also need metric to lower the priority of this new route, which may break the original default route: `ip route add default via 10.7.0.6 dev xxxx onlink metric 200` – clarkttfu Apr 03 '23 at 10:48
1

I suffered the same problem with OpenPVN tunnels and finally solved by using tap device instead tun.

I think network layer 2 bypasses the problem trying to route every packet independently of the interface state (not really sure about this but it eventually works).

If you are using OpenVPN, change dev in every ovpn config file (server and clients):

;dev tun
dev tap

Other non OpenVPN setup has to be solved differently (please, comment it here if also solved with tap interfaces).

caligari
  • 111
  • 3
1

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
Mathias Weidner
  • 417
  • 3
  • 10
  • I managed to add a route for an openvpn POINTTOPOINT tun; I don't know how openvpn added the existing routes that look like what I wanted, and I don't know how to do it with `ip r add ... [scope link]` which says "RTNETLINK answers: File exists" (it exists, but not as scope link... "x via x dev tun" ... same ip both places) ...but with `route add -host dev ` (which makes the vpn router scope link), then I can add the route I expect to use the VPN for any particular IP (eg. `ip r add via `), and `ping` there works, and `mtr` shows it uses the VPN as the first hop. – Peter Nov 03 '22 at 17:38