Keep in mind that I’m just another user and an enthusiast… I could possibly be wrong about some things in the explanation. (but the solution I list works for me )
Explanation (what I think is the case) -
This seems to be a problem with Windows, not Tailscale.
I don’t think anything “routes through” tailscale IP to local IP (100.x.x.x ↔ 192.168.x.x) because that makes no sense - there is no route from the virtual subnet to the physical one, but instead, I think Windows matches NETBIOS or some sort of domain names on both IPs and decides “the same system is behind both these IPs, better use the one with a higher bandwidth adapter” since Tailscale adapter states it’s bandwidth as 100 Gbps.
Another reason why I’m quite sure of this being the case - is because Resource Monitor (network tab) lists tailscale IP or local IP for a very short time (few seconds), but lists hostname afterwards instead when I check TCP connections on SMB ports, regardless of local or tailscale IP being used. The hostname of the computer is listed (the one you can change from advanced system properties). Either that, or some other name system causes this.
I tried the same approach as you @backpackhasjetz - tried everything I could to disable name systems, I prefer static IP anyway, but didn’t help, even blocking netbios ports on system process through a firewall didn’t work when I tried it, there could be some sort of caching or a way to remember which IP had which system last.
My personal solution - I ended up using a 3rd party firewall, and manually set a filter which blocks all network traffic where these 3 conditions match:
• Application is: System (ntoskrnl.exe)
• Specific IP (100.x.x.x)
• Port 139 or Port 445
I could also specify IP range here to block SMB on all tailscale IPs through the system (IP range 100.0.0.0-100.255.255.255).
Windows still tried to connect through tailscale first, but failed very quickly (you won’t even notice any slowdowns or extra time to connect) and falls back to the next best route after no connections can be made (which is most probably your actual router’s local IP), resulting in normal speeds over SMB again.
This way I can individually block port 139/445 traffic to/from any specific tailscale connected system on my virtual subnet (or even all of them if I specify IP range as 100.0.0.0 - 100.255.255.255), and I can simply enable/disable that rule with one click. Since I know that 2 of my desktops will always be on the same physical network, I left this rule enabled permanently on those, meanwhile I manually toggle that rule if I take my laptop somewhere else and need SMB to work over tailscale.
I used a paid firewall software for this but you could also use something free or maybe even Windows firewall too, haven’t tried that yet but it should work. This firewall blocking rule being enabled or not could be automated with a simple script if windows firewall is used, so you could have an automatic block if SMB connection can be made through local network.
Hope this simple solution works for you too