After a recent office clean up my work PC now sits about 10 meters away from the router which runs my home office. It’s an old workhorse, a D-link DAP 1522, but it still gets the job done.
Now the easy solution to my new problem would have been to go out and buy a 10 meter ethernet cable but the technologist in me wanted to find a different solution.
I’ve got an old wireless router sitting around, a ZyXEL NBG-419N, and I’m curious to see if I can get this to talk to the D-Link.
This is a good time for a network diagram.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
10.0.0.1 192.168.2.200 +---------------------+ | | ethernet eth0 +----------------+ wireless +----------------+ | Laptop +----------------------+ | connection | | | | | ZyXEL router +---------------------+ D-Link router | +-----------------+---+ | | | | | +----------------+ +--+-----------+-+ | | | | +----------------+ | | | | | | | +--------------------------+ WAN router | +---------++ +----+------+ wireless wlan0 | | | NAS | | Printer | +----------------+ | | | | +----------+ +-----------+ 192.168.1.1 wired via ethernet |
Make do and mend. I don’t want to spend money I don’t have to at the moment.
As can be seen above, I want to be able to access the private network via the eth0 interface and access the WAN via the wlan0 interface.
Getting the routers talking to each other
To do this, I needed to configure the ZyXEL router to operate in WISP mode, whereby it acts as a wireless client and connects to the D-Link router.
The default IP address for the router is 192.168.1.1 with login credentials being uid: admin and pwd:1234
You’ll need a PC with an IP address on the same subnet to access the router via a web browser.
Navigate to Expert Mode > Maintenance > Sys Op Mode and select ‘WISP mode’
Apply changes and then wait for the router to restart.
Then you’ll need to tell the ZyXEL about the router to which you want to connect.
This is done via Expert Mode > Configuration > Network > Wireless LAN > General
Enter the SSID and security details of the wireless router you are connecting to.
There appears to be a lot of misinformation out there on the settings required for a successful connection. You’ll likely have to play around with various combinations and see what works for you.
Then I was able to verify the connection by checking the log on the D-Link router
1 2 3 |
Uptime 3 day 05:25:23 [SYSACT]DHCP Server assign IP 192.168.2.47 TO Mac:xx:xx:xx:xx:xx:xx Uptime 3 day 05:25:22 [Wireless]4-way handshake success Uptime 3 day 05:25:22 [Wireless]Association Success: |
Note the ‘Association Success’. The Status > Device Information screen on the ZyXEL will show Connect Status as ‘Associated’ under WLAN information upon a successful connection.
Association: Once authentication is complete, mobile devices can associate (register) with an AP/router to gain full access to the network. Association allows the AP/router to record each mobile device so that frames are properly delivered. Association only occurs on wireless infrastructure networks, not in peer-peer mode. A station can only associate with one AP/router at a time.
Source: Intel
Adding a route to the private network
I assigned the ZyXEL router a static IP address of 10.0.0.1
The D-Link router is 192.168.2.200
To get everything up and running, a new route needs to be added to the routing table on my laptop.
sudo route add -net 192.168.2.0 netmask 255.255.255.0 gw 10.0.0.1
Then we check to confirm the route has been added using the route command.
1 2 3 4 5 6 7 |
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default 192.168.1.1 0.0.0.0 UG 0 0 0 wlan0 10.0.0.0 * 255.255.255.0 U 0 0 0 eth0 link-local * 255.255.0.0 U 1000 0 0 eth0 192.168.1.0 * 255.255.255.0 U 9 0 0 wlan0 192.168.2.0 10.0.0.1 255.255.255.0 UG 0 0 0 eth0 |
After testing connectivity to the other network, delete the route from the table. We now need to make this route persistent so it is automatically added after system restarts.
NB: When deleting an entry from the routing table, it’s important to add enough information to uniquely identify that entry in the routing table.
Making the new route persistent
Now that you’ve added a new route to the private network, you’ll want this new route to be persistent between system restarts.
I thought this would be easy, but was wrong.
I’m still using Ubuntu 14.04 aka ‘Trusty’ on my laptop. More like old and crusty as someone recently said in a tweet.
It’s old, but still works. If it ain’t broke, don’t fix it.
The interwebs suggest either of the following should work:
- Using a post-up command in /etc/network/interfaces
post-up route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.254 - Using a script placed in /etc/network/if-up.d
This is what I scraped together:
123456#!/bin/bashif [[ $IFACE == "eth0" ]]; thendt=$(date '+%d/%m/%Y %H:%M:%S');echo "$dt eth0 iface up: Adding route" >> /var/log/route.logip route add 192.168.2.0/24 via 10.0.0.1 dev $IFACEfi
You should use one approach only. Any scripts in /etc/network/ifup.d will run automatically. Ensure they are executable (chmod +x) and do NOT have a .sh file extension.
I prefer scripting things out as it provides greater flexibility. I also added a corresponding script in /etc/network/if-down.d to remove the route when the interface is dropped. Just good housekeeping
1 2 3 4 5 6 |
#!/bin/bash if [[ $IFACE == "eth0" ]]; then dt=$(date '+%d/%m/%Y %H:%M:%S'); echo "$dt eth0 iface down: Removing route" >> /var/log/route.log route del -net 192.168.2.0/24 fi |
By using these scripts I end up with a simple log file
1 2 3 4 |
18/10/2020 10:48:52 eth0 iface up: Adding route 20/10/2020 11:34:17 eth0 iface down: Removing route 20/10/2020 11:36:56 eth0 iface up: Adding route 20/10/2020 11:37:03 eth0 iface down: Removing route |
Problems when using a static IP address
When using a static IP address on the laptop, I encountered nothing but trouble. When I reconfigured for DHCP everything worked fine.
Here’s the /etc/network/interfaces file I was using:
1 2 3 4 5 6 7 |
auto eth0 iface eth0 inet static address 10.0.0.40 netmask 255.255.255.0 gateway 10.0.0.1 #up route add 192.168.2.0/24 via 10.0.0.1 || true #post-up route add -net 192.168.2.0 netmask 255.255.255.0 gw 10.0.0.1 |
When trying to drop the eth0 interface I’d get:
ifdown: interface eth0 not configured
The ‘not configured’ part seems to be a reference to eth0 not being present in /etc/network/run/ifstate. Note this is a temp filesystem and the file should not be edited.
I haven’t been able to solve this issue yet.
There’s a good discussion here on others having encountered similar problems
When trying to bring it up:
RTNETLINK answers: File exists. Failed to bring up eth0
Now I decided to take a look under the hood using strace.
Firstly it’s handy to use the -e flag with open to see what files are being used
sudo strace -e open ifup eth0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/etc/network/interfaces", O_RDONLY) = 3 open("/run/network/ifstate.eth0", O_RDWR|O_CREAT|O_APPEND, 0666) = 3 open("/run/network/.ifstate.lock", O_RDWR|O_CREAT|O_APPEND, 0666) = 4 open("/run/network/ifstate", O_RDWR|O_CREAT|O_APPEND, 0666) = 5 open("/run/network/.ifstate.tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 open("/run/network/ifup-eth0.pid", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=28979, si_status=0, si_utime=0, si_stime=0} --- RTNETLINK answers: File exists --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=28987, si_status=2, si_utime=0, si_stime=0} --- Failed to bring up eth0. open("/run/network/.ifstate.lock", O_RDWR|O_CREAT|O_APPEND, 0666) = 4 open("/run/network/ifstate", O_RDWR|O_CREAT|O_APPEND, 0666) = 5 open("/run/network/.ifstate.tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 +++ exited with 0 +++ |
sudo strace -e write ifup eth0
1 2 3 4 5 6 7 8 9 10 |
write(3, "eth0\n", 5) = 5 write(6, "lo=lo\neth0=eth0\n", 16) = 16 write(4, "7888", 4) = 4 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7889, si_status=0, si_utime=0, si_stime=0} --- RTNETLINK answers: File exists --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7897, si_status=2, si_utime=0, si_stime=0} --- write(1, "Failed to bring up eth0.\n", 25Failed to bring up eth0. ) = 25 write(3, "\n", 1) = 1 write(6, "lo=lo\n", 6) = 6 |
Note the return value = the new file descriptor (a nonnegative integer), or -1 if an error occurred.
A few notes on system calls in the strace output
- mmap – Map file to memory. See this SO post.
- fstat64 Get file status
- fcntl64 Manipulate file descriptor
I stumbled across this article which is worth a read.
Dave’s solution didn’t work for me, I really think the problem is with the waitpid call.
Restarting networking interfaces in Ubuntu
The easiest way to test if our new route will persist is to restart the networking interface. Rebooting the PC multiple times is unnecessary.
When it comes to restarting the interface, these are your choices.
- ifconfig, which is considered to be obsolete
I only use ifconfig to check interfaces. Old habit.
But here are the commands you need to use:
To drop the interface: sudo ifconfig eth0 down.
To bring the interface up: sudo ifconfig eth0 up - ifupdown
Notes from the above man page:
- The file /run/network/ifstate must be writable for ifup or ifdown to work properly.
- The program does not configure network interfaces directly; it runs low level utilities such as ip to do its dirty work.
To drop the interface: sudo ifdown eth0
To bring the inteface up: sudo ifup eth0 - The ip command, a newer more powerful alternative. Here’s a good cheat sheet from RedHat.
To drop the interface: ip link set eth0 down
To bring the interface up: ip link set eth0 up
Reinserting the NIC kernel module
This is worth being familiar with.
Firstly you’ll need to ascertain the name of the module which corresponds to your NIC. The easiest way is using
ethtool -i eth0
Here’s the output on my laptop
1 2 3 4 5 6 7 8 9 |
driver: r8169 version: 2.3LK-NAPI firmware-version: rtl8411-2_0.0.1 07/08/13 bus-info: 0000:05:00.1 supports-statistics: yes supports-test: no supports-eeprom-access: no supports-register-dump: yes supports-priv-flags: no |
Here, my driver is r8169
Before doing the following, it’s useful to run tail -f /var/log/kern.log in a command window to see what’s happening.
To remove the kernel module:
sudo rmmod r8169
Then re-insert it:
sudo modprobe r8169
Featue image by Jason Pofahl on Unsplash
Leave a Reply
1 Comment on "Wrestling with routers"
Good to hear from you. Didn’t understand much of that but convinced me you’re worth more money.