Automatic renumbering of LAN in case of conflict with WAN

There is a closed thread already here, exactly stating my issue:

However, I consider the accepted solution not as fool proof. There is a non-zero possibility, that openwrt-device receives IP from 172.29.223.1/24 . I consider the org proposed solution to be more reliable. Any comments ?

You need to know the difference between private and public IP addresses.

Especially when you connect a private ip address to wan.

1 Like

I think the solution does depend on your specific requirements. In my case, I had some devices which would be configured with static ip addresses, which would not really be able to handle a change of the local network numbering.
That said, having the br-lan network essentially unconfigured until the wan connection is up might be an option for some. Then, an admin or local process can randomly choose a different local lan network, and bring it up using that range. Any devices connecting would only ever see that random range.
It doesn’t handle the case where the upstream network doesn’t connect, or eg wifi credentials are required before it can connect, to be provided by a local tech. I suppose a temporary setup network could be created, and torn down as soon as a successful upstream connection is achieved. But these are the sorts of considerations one has to address to handle this sort of situation.
@flygarn12 sure, I think we both understand that having NAT from a private network to another private network is not ideal. But sometimes it is the hand we are dealt.

1 Like

Yes but it isn’t up to automatic ip number setting to sort this out.

Not 100% sure what you are saying here. Is there an existing automatic LAN renumbering tool, but it is not the right solution to this problem? Or trying to renumber the LAN AUTOMATICALLY is not the right solution? Or, trying to renumber the LAN is not the right solution under any circumstances?

Another approach I just thought of is to ignore the provided netmask of the WAN interface, and force it to /32. That way there is always a more direct route to that specific gateway address via the wan interface, and internet traffic should always work. There may still be a “blind spot” if that same address is assigned to a device on the local network, but that reduces the odds from 1 in 256256 (10.x.y.0/24) to 1 in 256256*256, which seems like a significant improvement to me.

Conceptionally, there would be another alternative - keep WAN disabled in case of a detected subnet overlap.

I have a situation, that two identical routers are daisy-chained. Router A has WWAN via cell, and connects its LAN to router Bs WAN. So, B receives an IP 192.168.0.x/24 from A, but also sets up br-lan to have 192.168.0.1/24. Which should create some problem. I thought about using hotplug to modify Bs br-lan IP myself, but then found the thread, stating 172.29.223.1/24 to be the accepted solution. Which made me really wonder. Now, according to the discussion here, using hotplug seems to be the correct way. UPDATE: hotplug is not "talkative" enough. Although I remember, in the past it also provided IP, for example. Not any more; so dhcp_client_script might be a better way to go.

I could see this automatic LAN address re-assignment as useful in one type of context -- the road warrior travel router environment. In these situations, the user doesn't necessarily have any information about a given upstream network until they have connected their travel router, but the upstream network addressing will likely be different at each location. So simplifying and automating the process of ensuring that the subnets don't overlap could be a useful thing.

If such a feature would be developed, I would propose that it might work as follows;

  • The user would define a preferred default IP/subnet for the router's LAN.
  • Optionally, the user could define alternate IPs/subnets as fail-over addresses.
  • A script would evaluate the WAN address (and subnet -- this is critical) and determine if the LAN is conflicting/overlapping with the upstream address/network.
    • If the LAN does overlap, it would look at the alternate preferred addresses and run that same calculation... it would go down the list of alternates until it finds one that doesn't overlap, or if none fit the criteria, the script could select a random network (of user defined size, default maybe /24) out of the RFC1918 addresses that does not conflict with the upstream network and would set the LAN accordingly.

This type of feature would be a natural fit for Travelmate or a similar companion package.

FWIW, I do not see such a feature as terribly valuable in any non-travel type contexts. In a home or business environment, the network is likely fairly well defined and static (i.e. the subnet is not changing frequently, if ever, unlike the upstream networks when traveling and connecting in various different locations). IMO, the LAN address of the OpenWrt router should be manually configured to meet the objectives of the network topology. The LAN could be a static IP assignment or DHCP client (if using in a dumb AP or similar type of context). The user should easily have access to information about the upstream network to set the LAN appropriately and won't need to change this often, if ever).

All of that said, some thoughts about what has been said/proposed...

This is true for all RFC1918 ranges, but there are some ranges that are more common (like 192.168.1.0./24, 192.168.0.0/24, 10.0.1.0/24, etc.). Avoiding those ranges is a good start. But a script like what I described can be written to compare the upstream against the local networks and take action in the event of a conflict.

No, this would not work. It would break upstream connectivity because the upstream gateway would necessarily be out of the forced /32 subnet on the WAN. So for example, if you had a WAN IP of 192.168.2.52/32, the gateway on the WAN (for example 192.168.2.1) would be out of the defined WAN subnet, so the router would have no ability to reach the gateway to route traffic upstream (i.e. to the internet or any upstream resources).

This also doesn't prevent the LAN from overlapping the /32 on the WAN -- if the LAN is set to 192.168.2.1/24, the LAN also includes 192.168.2.52 (the WAN address in this example), so the problem remains.

This doesn't help, as I described above, since the /32 on the WAN breaks connectivity and still could overlap with the LAN. What is good is to keep the size of the LAN at /24 or smaller and to avoid common ranges.

I'm not sure that this really achieves anything better than the current behavior. If the LAN and WAN networks are the same or overlapping, routing will not work, but it obviously won't work if it is disabled, either. LAN access to the router still works in this context, though. And the benefit of having the WAN enabled is that the user can see that there is a conflict.

I think it is the accepted solution simply because it is not one of the common subnets. Any RFC1918 address/subnet is acceptable as long as it doesn't overlap with the WAN's subnet.

I think all you need is for the hotplug trigger to occur. You can use scripting to gather the rest of the information and perform the appropriate calculations/evaluations and subsequent actions. Hotplug would simply trigger an event when the WAN comes up.

For OP, the accepted solution was taken not as “use this specific network range”, but rather “choose a random network somewhere inside rfc1918 space, explicitly avoiding the most common 192.168.0.0, etc networks”.
W.r.t the /32 idea, the intention was not to have a network route for a /32, which indeed wouldn’t work, but rather to have a specific host route to the upstream gateway via the wan interface.
This would be a more specific route than the /24 on the lan interface, and therefore should take precedence.

However, what I didn’t consider was that the upstream gateway might match the IP assigned to the router itself. Ie my router lan ip might be 192.168.0.1, and my upstream gateway’s ip might also be 192.168.0.1. In which case, that route would probably be ignored, as a local address would likely take precedence over a remote one?
Another approach might be to use link local address space (rfc3927 - 169.254.0.0/16) to provide an intermediate “transit” network in between the lan and wan networks. This could be achieved by using network namespaces and veth interfaces, effectively isolating the WAN and LAN networks from each other.
That however would likely break all of the OpenWrt configuration metaphors, which is also not ideal. Perhaps policy routing might be a solution for this?

1 Like

I'm not sure I'm following your logic. If the OpenWrt router in question is set to 192.168.1.1/24, and the upstream router (also 192.168.1.1/24) assigns the OpenWrt WAN 192.168.1.210/24, how would forcing the wan to use 192.168.1.210/32 solve an overlap issue? and how would it actually route to the upstream network? Even if the two routers have different addresses but in the same subnet (so let's say the upstream router is 192.168.1.254/24) -- I still don't see how a /32 on the OpenWrt WAN fixes the problem.

It seems like you're kind of proposing a double-NAT within the same router. I'd have to give thought into if/how this would work in general, but I don't think you can use RFC3927 addresses for that purpose -- that range is specifically designed as non-routable, very different in nature than the RFC1918 ranges that are routable but designed for private networks only (not globally routable). The routing engine and linux kernel may puke on the link local addresses.

This daisy chain of openwrt devices is not so uncommon. In my country, the ISPs provide cheap openwrt devices as wifi-routers, i.e. WE826. Running standard openwrt, they use 192.168.0.1/24 for br-lan. When testing my own openwrt device, connected to theirs, I explicitly use something like 192.168.20.1/24 for br-lan.
Using /etc/dhcpc.user seems to be more appropiate than hotplug, because I can not see, that any hotplug script provides the IP assigned to the interface. (I think, it was different in the past.) dhcpc.user does.
Question to the experts here: How to get the subnet mask from upstream router ?

I agree that it is not uncommon. IMO, though, the user should configure the LAN to avoid a conflict with the upstream network in any normal 'fixed' network situation (i.e. not a travel context where each place may have different upstream network subnets). It is only necessary to do this once for a normal home network.

parse the output of ifconfig or ip commands if you want to be able to see the address and the subnet. Or route is another way to see the subnet mask.

For example, eth0 is my upstream (WAN) port, and I actually have my OpenWrt router behind my main router:

root@OpenWrt:~# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:15:6D:C5:F7:79  
          inet addr:10.0.1.5  Bcast:10.0.1.255  Mask:255.255.255.0
          inet6 addr: fe80::215:6dff:fec5:f779/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:21769532 errors:0 dropped:73769 overruns:0 frame:0
          TX packets:3366488 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:618834071 (590.1 MiB)  TX bytes:2396501124 (2.2 GiB)
          Interrupt:4 


root@OpenWrt:~# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
    link/ether 00:15:6d:c5:f7:79 brd ff:ff:ff:ff:ff:ff
    inet 10.0.1.5/24 brd 10.0.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:6dff:fec5:f779/64 scope link 
       valid_lft forever preferred_lft forever

root@OpenWrt:~# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         10.0.1.1        0.0.0.0         UG    0      0        0 eth0
10.0.1.0        *               255.255.255.0   U     0      0        0 eth0
10.0.20.0       *               255.255.255.0   U     0      0        0 br-lan

cat << "EOF" > /etc/udhcpc.user
LAN_IP="$(uci get network.lan.ipaddr)"
case "${ip}" in
(192.168.*.*) NEW_IP="172.16.1.1" ;;
(*) NEW_IP="192.168.1.1" ;;
esac
if [ "${LAN_IP%%/*}" = "${NEW_IP}" ]
then exit 0
fi
uci set network.lan.ipaddr="${NEW_IP}"
uci commit network
ifup lan
EOF
1 Like

This fits a special case. However, I am thinking about a general solution, implemeted in udhcpc.user.
Taking subnets into consideration, too.

Otherwise this is not worth the hassle as in general case you need to take care of multiple LANs, WANs and VPNs, each of those can connect/disconnect and change its address/subnet dynamically at any moment with many different protocols not limited to DHCP.

1 Like

Yeah, you are correct in this case, as I acknowledged in the same post:

As you can see from the below, my home network is in the 192.168.201.0/24 network. If I try to ping 192.168.201.2, you would expect that to go out the br-lan interface normally. However, if I add a specific route for that IP address via br-wan, tcpdump will show the kernel trying to reach that IP address via the br-wan interface.

root@rb760igs:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
...
192.168.201.0   0.0.0.0         255.255.255.0   U     0      0        0 br-lan
...
root@rb760igs:~# route add 192.168.201.2 dev br-wan
root@rb760igs:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
...
192.168.201.0   0.0.0.0         255.255.255.0   U     0      0        0 br-lan
192.168.201.2   0.0.0.0         255.255.255.255 UH    0      0        0 br-wan
...
root@rb760igs:~# tcpdump -nli br-wan host 192.168.201.2 &
root@rb760igs:~# 
listening on br-wan, link-type EN10MB (Ethernet), capture size 262144 bytes

root@rb760igs:~# ping 192.168.201.2
PING 192.168.201.2 (192.168.201.2): 56 data bytes
12:06:09.184487 ARP, Request who-has 192.168.201.2 tell 192.145.148.113, length 28
12:06:10.203837 ARP, Request who-has 192.168.201.2 tell 192.145.148.113, length 28
^C
--- 192.168.201.2 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
root@rb760igs:~# 12:06:11.227828 ARP, Request who-has 192.168.201.2 tell 192.145.148.113, length 28
fg
tcpdump -nli br-wan host 192.168.201.2
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
root@rb760igs:~# 

It is the same way that you can have a local subnet in the 10.15.20.0/24 range, and have a less specific route to the rest of the 10/8 network (or even a default route, which is the least specific /0 mask), and you can reach both your local /24 network, as well as the rest of the 10/8, or 0/0.

I have a very specific use case, where we supply a smart device (WiFi) and a wifi router which communicates back to our server. That router may connect using LTE or local Ethernet or local WiFi (if the company is prepared to let us use their infrastructure rather than pay LTE fees).

In that case, we need to deal with whatever upstream IP address we are assigned. Choosing a random subnet works in our case, but there is still a chance that we collide. Disabling br-lan would also work, until an upstream connection is established back to our server, and we can decide whether to renumber the local network. Or the udhcpc.user solution presented above would also work, and has the benefit of providing a working br-lan for a local tech to connect to if necessary.

LTE gives public IP so you will never have a problem there.
Local Ethernet or wifi, i doubt the company you work for will spread the IP address randomly on all three public IP address groups there are to choose between.

So if you work for a company they should be able to give you IP addresses for the project.

Not necessarily. This depends on the provider. Many providers use CG-NAT or even RFC1918 addresses.

^^^ this. Yes.

You are correct. But does that mean, no need at least to start with a real solution, instead of relying on probability, or hope, better to say ?
Frankly speaking, slowly I understand the degradation of software quality.