Permanent ip route

I have WG VPN client running on my GL-MV1000. The VPN tunnel is configured via VPN Policies to be used only for one device/server connected to my router. The WG VPN connection works fine. However, I need to configure a static ip route on the GL-MV1000 to reach the device/server from outside of my home network. The command “ip route add …” solves the problem. I can reach my device connected to the router successfully even when accessing the router from outside of my home network, but the static ip route is gone whenever I restart the router.
Question:
How do I configure the static ip route on my GL-MV1000 permanently? I found some help on the internet that tells me to create a script in “/etc/network/if-up.d/” or in “/etc/sysconfig/network-scripts/”. I don’t find these folders on my GL-MV1000. Can you tell me where to configure the static ip route permanently on my GL-MV1000? I am using firmware version 3.216.

You’re probably not finding them because the underlying OS, OpenWrt Linux, is far more specialized than standard Linuxes as found on mainstream servers, desktop computers.

If you have LuCI installed (GL GUI → System → Advanced Settings), you can add custom commands to /etc/rc.local via LuCI → System → Startup → Startup → Local Startup . It’ll fire on bootup.

Thank you for your quick feedback. I have added following lines to Luci - System - Startup - Local Startup:

#!/bin/sh
if [ “$IFACE” = “wan” ]; then
ip route add xxx.xx.xx.x/xx via 192.xxx.xxx.x
fi

I confirmed this by clicking on “Save”.
After rebooting the router and executing “ip route show” the static ip route is not displayed :frowning:

If I execute same “ip route add” command via ssh, the subsequent “ip route show” command does display the static ip route. Is there something wrong with the syntax of the lines I added to Local Startup? I tried twice, with and without “#!/bin/sh”

Standby… I need to pull up some scripts I’ve worked on to get you a variable to try for that if statement.

Please confirm this returns the IP of your WAN interface:

ip a | grep "eth0" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1

if not, check ip a for its named ethX.

That’s unneeded. Everything in /etc/rc.local is seen as one big ol’ shell script.

Okay, this is scripted using OpenWrt 19.0.7.1 which should be very close to the OWRT of GL f/w 3.x… IIRC it’s using OWRT 19.07.3:

myWANIP=$(ip a | grep "br-lan" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1)
if [[ ! -z "$myWANIP" ]]; then
  # do what you gotta do
fi

In my case the WAN interface I’m checking to see if it has a IP is br-lan. If it doesn’t have a IP, nothing happens. Your interface in question may be different hence my mention of ip a above.

The above command does not produce any output while command
ip a | grep “wan” | grep -E -o “([0-9]{1,3}[.]){3}[0-9]{1,3}” | head -n1
delivers the IP address of my GL-MV1000 in my home network:
192.168.188.7

What’s your WAN IP & interface per ip a?

This is the ip a output:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 532
    link/ether <ipv6/mac stuff> brd ff:ff:ff:ff:ff:ff
    inet6 <my ipv6>/64 scope link
       valid_lft forever preferred_lft forever
3: wan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether <ipv6/mac stuff> brd ff:ff:ff:ff:ff:ff
    inet 192.168.188.7/24 brd 192.168.188.255 scope global wan
       valid_lft forever preferred_lft forever
4: lan0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP group default qlen 1000
    link/ether <ipv6/mac stuff> brd ff:ff:ff:ff:ff:ff
5: lan1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP group default qlen 1000
    link/ether <ipv6/mac stuff> brd ff:ff:ff:ff:ff:ff
7: teql0: <NOARP> mtu 1500 qdisc noop state DOWN group default qlen 100
    link/void
8: usb0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel master br-lan state DOWN group default qlen 1000
    link/ether <ipv6/mac stuff> brd ff:ff:ff:ff:ff:ff
10: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 10.2.0.2/32 scope global wg0
       valid_lft forever preferred_lft forever
11: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether <ipv6/mac stuff> brd ff:ff:ff:ff:ff:ff
    inet 192.168.8.1/24 brd 192.168.8.255 scope global br-lan
       valid_lft forever preferred_lft forever

Well, we don’t want that one.

Ah, I see. I thought your LAN was the 192.168.188.0/24. This is actually your WAN to the Burme. Great. Swap br-lan for wan just as you intuited. That should do it.

The main router in my home network comes with IP 192.168.188.1.
The GL-MV1000 is just a client in my home network with IP 192.168.188.7.
The device/server behind my GL-MV1000 is the one I am trying to reach from outside. (I have configured GL-MV1000 to use WG VPN client connection for the device/server behind GL-MV1000.)
Accessing the device behind GL-MV1000 does not work unless I execute following command on GL-MV1000 via ssh:
ip route add 172.xx.xx.0/23 via 192.168.188.1
If I execute the above command, the subsequent ip route show command delivers following output:

...
172.xx.xx.0/23 via 192.168.188.1 dev wan
...

…and access to my device/server from outside of my network starts working.

What I am looking for now, is how to setup this ip route permanently.

Yes, I understand that. The code above featuring the $myWANIP is necessary to ensure your Burme has a IP assigned to its WAN interface downstream from your main router. Once it has checked for it, it can add your route.

Your attempt using $IFACE doesn’t account for this.

Change my posted above snippet showing the br-lan to wan, then add the route to replace the comment within the if/then statement.

Throw it all into /etc/rc.local via LuCI, just as you first tried but now with (hopefully) corrected code.

I tried that but it failed :frowning:
I put following code into /etc/rc.local via LuCI:

myWANIP=$(ip a | grep "wan" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1)
if [[ ! -z "$myWANIP" ]]; then
  ip route add ...
fi

After restarting Brume, the new ip route was not visible in the output of ip route show.
Does the location if the above code inside rc.local matter? I put it at the end of the file but infront of the last line:

/etc/init.d/gl_ipv6 reload 2>/dev/null

I also confirmed the presence of the new code in /etc/rc.local after restarting the router.

Command: ip a | grep "br-lan" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1
generates output: 192.168.8.1 which is the IP of Brume in its own subnetwork.

Command: ip a | grep "wan" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1
generates output: 192.168.188.7 which is the IP of Brume in my home network

This means the code you suggested is supposed to set myWANIP to 192.168.188.7.
As I am not really used to scripting, can you please tell me the meaning of
if [[ ! -z "$myWANIP" ]]; then ?

It seems to be a condition to execute the ip route add command, but I do not understand when this condition is fullfilled.

My Brume comes with OpenWrt 19.07.8.

@gonzoll

Yes, exactly: it is a conditional test in a block of code.

It does. Everything you add goes after everything else but before exit 0 in LuCI Startup.

If the variable $myWANIP doesn’t have (!) empty contents (-z) in it (eg: no 192.168.x.x), then […]

That is to say: $myWANIP must not be empty before executing the rest of the code block. If so, it skips the rest. If it is not ‘empty’ (because it has a IP assigned to it as it should & we would expect it to have) then it executes whatever’s after the then but before the fi.

This conditional test will always check to make sure your Burme has a IP assigned to its WAN interface from, in your particular case/setup, from your upstream/main router, regardless if the WAN IP is from another router or directly from your ISP’s modem. Only once your Burme’s WAN IP is known to be assigned will it add your route:

myWANIP=$(ip a | grep "wan" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1)
if [[ ! -z "$myWANIP" ]]; then
  ip route add xxx.xx.xx.x/xx via 192.xxx.xxx.x
fi

I’ve updated it. This entire block of code goes after everything else but before the exit 0.

Thank you for your additional explanations!

I did another test. I have edited file /etc/rc.local directly in vim.
I have moved your code to the very end of the file as I did not find any exit 0 call in there.
Finally I have modified your code by adding an additional line:

myWANIP=$(ip a | grep "wan" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n1)
if [[ ! -z "$myWANIP" ]]; then
  ip route add xxx.xx.xx.x/xx via 192.xxx.xxx.x
  touch /etc/WANIP
fi

The extra code is supposed to create a file - just to understand if the code gets executed on startup, at all.
I have rebooted the router and found the following afterwards:

  • File /etc/WANIP has been created
  • Call of ip route show does not display the requested static route

To me that means that the code has been executed on startup but the ip route add call still did not work as expected. To exclude any other issues I have executed same call in shell (ssh) and the subsequent call of ip route show proved the requested static route has been added.

To me there is only one logical explanation for this. Executing ip route add from /etc/rc.local does not work for some reason. Either it is too early to run this command at this stage or something else overrides this static route later. Any idea?

Wait a sec… ip route add … this is a UCI command, isn’t it? If so throw a uci commit on a line between the ip route & touch. Let me know if that does it.

If this works then I must apologise; I don’t use UCI as I’m just so used to going straight to the conf & editing to suit my needs… & I think it might be an option in your case, too:

Follow up: there’s an example how to translate

ip route add default via 10.72.197.110 table 100

into the proper configuration syntax within /etc/config/network … quite similar to what you’re looking to do.

See the example given @

Another example, creating a default route for table 100 with the gateway 10.72.197.110 :

I don’t think you need rc.local at all, really.

1 Like

You are right! I edited /etc/config/network and added an config route entry and it worked.
Thank you so much!

1 Like