2

I have been using a Windows 7 computer to connect to a Windows 10 computer which is on the same physical network but on a different subnet. Before I added a static route to Windows 7 all traffic was going up to the main router and then back down to Windows 10. This was causing a long delay initiating an RDP connection so I added a static route to Windows 7 to avoid the top router. I made a mistake which ended up working, and I'm not sure why.

Network diagram

Network diagram

Static routes for Windows 7

1. None
2. route add 10.1.1.0 mask 255.255.255.0 10.1.0.99
3. route add 10.1.1.0 mask 255.255.255.0 10.1.1.3
  • Using route 1 tracert shows 10.1.0.98 -> 10.1.0.1 -> 10.1.0.99 -> 10.1.1.4
  • Using route 2 tracert shows 10.1.0.98 -> 10.1.0.99 -> 10.1.1.4
  • Using route 3 tracert shows 10.1.0.98 -> 10.1.0.99 -> 10.1.1.4

I understand why route 2 works, but I don't know why route 3 also works.

PS: If anyone can suggest a clearer title, please do.

chew socks
  • 383
  • 1
  • 17
  • Route 3 doesn’t work. So the answer to this is that your routing table was not as you thought or your traceroute info is not accurate. Could be either or both. Traceroute does not always show all hops. Was your gateway address on the Win 7 machine still 10.1.0.1? – Appleoddity Dec 02 '18 at 23:49
  • @Appleoddity Yes, the gateway was still 10.1.0.1 . 2 and 3 are the commands as typed. The reason I believe `tracert` is the performance difference. Establishing an RDP session is instantaneous with route 1 or 2. – chew socks Dec 03 '18 at 02:03
  • Did you do `route print` to check the entire routing table? 3 will not work. The only logical answer is that you left 2 active. – Appleoddity Dec 03 '18 at 02:22
  • @Appleoddity I did check there. I actually did 3 before 2; I made a mistake and then was surprised it worked. I think I figured it out, though. See if my answer below sounds right. – chew socks Dec 03 '18 at 02:28
  • @chewsocks: Can you also look for specific routes for the host you're pinging/tracing? (That is, with netmask 255.255.255.255?) harrymc's comment makes me suspect ICMP redirects sent by your main router. – u1686_grawity Dec 03 '18 at 12:10
  • @grawity The only /32 netmasks are for addresses at the 224, and 127 prefixes, and some broadcast addresses. – chew socks Dec 03 '18 at 18:12

2 Answers2

2

Route 3 works because of how ARP packets are process by the Ubuntu computer. An ARP request for 10.1.1.3 is sent out on 10.1.0.0/24 and received on the 10.1.0.99 interface. Since that computer also owns 10.1.1.3 it responds with the hardware address for its 10.1.0.99. When the Windows 7 computer later attempts to make an RDP connection to the Windows 10 computer it sends out packets destined for the 10.1.1.3 gateway but carrying the MAC address of computer on the same subnet, which the switch is able to forward directly.

To try and verify that

On Windows 7

.\Arping.exe -i 10.1.0.98 -T 10.1.1.3

On Ubuntu

22:19:51.275116 (Windows 7 MAC) > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 10.1.1.3 tell 10.1.0.98, length 46
chew socks
  • 383
  • 1
  • 17
  • It’s a logical explanation but still fundamentally flawed. Assuming all subnet masks (it is all 255.255.255.0 right?) are /24 then computers on 10.1.0.x/24 will not send out “an ARP request for 10.1.1.3” because it is not in the same subnet. The computer knows this, and because of that knows it has to send the packet to to default gateway or another route it has available. Therefore it creates an ARP request for the gateway IP 10.1.0.1 and sends the packet to that router for forwarding. It will never look on its local network for 10.1.1.x. – Appleoddity Dec 03 '18 at 02:34
  • I’d be interested in seeing if you can prove this theory as it does make sense, but should not technically happen. To do so, perform a tcpdump and post your results of the ARP requests and responses you theorize. If it is as you say, the premise is built on multiple things not functioning the way they are supposed to. – Appleoddity Dec 03 '18 at 02:37
  • @Appleoddity I posted an edit where I did a tcp dump. – chew socks Dec 03 '18 at 03:33
  • Ok. I see the tcpdump but you’re generating an ARP by “forcing” it with arpping. We need to see the actual arp request / reply on the network when you ping or traceroute 10.1.1.4. It will show up in a tcpdump or wireshark trace on the 10.1.0.0 network. Arpping, I assume, will always send the request you tell it to. – Appleoddity Dec 03 '18 at 04:15
  • @Appleoddity I assumed it would not send out ARP requests once it knew the answer, but it actually does. I captured the same requests even when I wasn't doing arpping – chew socks Dec 03 '18 at 04:20
  • @Appleoddity You are right, Arpping always sends out a request. I tried with 1.1.1.1 to check. – chew socks Dec 03 '18 at 04:21
  • @Appleoddity: Because the gateway has to be local by definition and by its usage, it would be normal for the OS to send ARP queries **regardless** of subnet mismatch. Linux has a manual 'onlink' flag for this, which I've used a few times. If Chew claims it's the default behavior on Windows (the other option would be rejecting the route add entirely), this answer makes a lot more sense than gratuitous-ARP and such. – u1686_grawity Dec 03 '18 at 11:14
1

The magic of route 3 works in part because of the Address Resolution Protocol and in part because of the forwarding table and in part because of the routing algorithms.

Wikipedia says:

The Address Resolution Protocol (ARP) is a communication protocol used for discovering the link layer address, such as a MAC address, associated with a given internet layer address (typically an IPv4 address).

Many operating systems perform gratuitous ARP during startup. That helps to resolve problems which would otherwise occur if, for example, a network card was recently changed (changing the IP-address-to-MAC-address mapping) and other hosts still have the old mapping in their ARP caches.

Ubuntu when starting has therefore announced its presence and interfaces on both subnets to which it is connected, so to your entire network. Any similar announcement done by Windows 10 was only within its subnet, so never reached Windows 7. Even if such an announcement was never received, Windows 7 will, to find a match, send a broadcast packet to the network using the ARP protocol to ask "who has 10.1.1.4".

A big hint here is that the tracert command didn't list the router among the hops. The request for 10.1.1.4 went straight to the Ubuntu computer even though Windows 7 does not know about 10.1.1.4.

What we see here in operation is the Windows IP Routing Table : Route Determination Process:

  • For each entry in a routing table, perform a bit-wise logical AND between the destination IP address and the network mask. Compare the result with the network ID of the entry for a match.

  • The list of matching routes is compiled. The route that has the longest match (the route that matched the most amount of bits with the destination IP address) is chosen. The longest matching route is the most specific route to the destination IP address. If multiple entries with the longest match are found (multiple routes to the same network ID, for example), the router uses the lowest metric to select the best route. If multiple entries exist that are the longest match and the lowest metric, the router is free to choose which routing table entry to use.

The Windows 7 routing found a common prefix between 10.1.1.4 and 10.1.1.3 which was 10.1.1. The other possibilities were the router or Ubuntu at 10.1.0.99, but whose common prefix was only 10.1, so they weren't chosen.

We see here in operation the forwarding table that is built on top of the routing table. While the routing table compiles routes based on IP addresses, the forwarding table contains the corresponding MAC addresses. So the forwarding table contained an entry saying: "For 10.1.1.X, forward packet to the MAC address of the Ubuntu computer". Once the packet arrived at the Ubuntu computer, it knew very well how to forward it to 10.1.1.4.

So this is how packets from Windows 7 would end up on Windows 10, and vice versa.

harrymc
  • 455,459
  • 31
  • 526
  • 924
  • Gratuitous ARP does not generate routing table entries in any OS that I've seen. You might have had a good guess if you were talking about ICMP Redirect packets coming from the Mikrotik router, which do generate a host route entry. – u1686_grawity Dec 03 '18 at 11:25
  • @grawity: I forgot the non-gratuitous ARP which I added. ARP is of course an integral part of the routing table and in several operating system these two lists are only displayed separately for readability. See for example section 3.2 of [rfc1433 Directed ARP](https://tools.ietf.org/html/rfc1433). – harrymc Dec 03 '18 at 11:45
  • That would be true for Directed ARP, except neither Windows nor Linux use that protocol. It was published as an 'experimental' RFC but never became widespread in practice. I just checked the Linux IPv4 FIB implementation and it's completely separate from the ARP/neighbour cache. Google says there are no mentions of "ARP helper" on microsoft.com, either. – u1686_grawity Dec 03 '18 at 12:07
  • @grawity: You are not seriously suggesting that an OS wouldn't use ARP for resolving IP addresses and find the matching MAC addresses? I don't see other mechanisms beside ARP+routing table+forwarding table, but I'm listening. – harrymc Dec 03 '18 at 12:28
  • No. I'm suggesting that these layers act completely independently from each other. The routing table _at most_ specifies the outgoing interface, but not the destination L2 address. – u1686_grawity Dec 03 '18 at 12:38
  • @grawity: A fast google found for example in [this article](http://www.sustworks.com/site/prod_ipnrx_help/html/RoutesHelp.html), quote: In Mac OS X, the ARP table is the part of the routing table that specifies hardware addresses. The table is displayed under separate "Routes" and "ARP" tabs to make it easier to consider each abstraction separately. endquote. I don't agree with "completely independently", because otherwise nothing would work, and especially the poster's problem becomes impossible to explain. – harrymc Dec 03 '18 at 12:49