diff --git a/system/networking.nix b/system/networking.nix
index 0c35c5c..1aacee0 100644
--- a/system/networking.nix
+++ b/system/networking.nix
@@ -50,7 +50,6 @@ in
 
   systemd.network = {
     enable = true;
-    wait-online.ignoredInterfaces = [ "tailscale0" ];
     networks = {
       "10-lan" = {
         matchConfig.Name = interfaces.lan;
diff --git a/system/vpn.nix b/system/vpn.nix
index f9cfcc0..753708c 100644
--- a/system/vpn.nix
+++ b/system/vpn.nix
@@ -15,6 +15,54 @@ in
   networking.wireguard.enable = true;
   networking.firewall.trustedInterfaces = [ tailscaleInterface ];
 
+  systemd.network = {
+    # Fixes issues with other systemd networks when tailscale exist nodes are used
+    config.networkConfig = {
+      ManageForeignRoutes = false;
+      ManageForeignRoutingPolicyRules = false;
+    };
+    wait-online.ignoredInterfaces = [ "tailscale0" ];
+  };
+
+  services.networkd-dispatcher = {
+    enable = true;
+    rules = {
+      # exclude LANs from tailscale subnet routes (when using `--accept-routes`)
+      "50-tailscale-exclude-lan-routes" = {
+        onState = [ "routable" ];
+        script = ''
+          #!${pkgs.runtimeShell}
+          # shellcheck disable=SC2010
+
+          lan_interfaces=$(ls /sys/class/net | grep -E '^(enp|eth|wlp)')
+          if [[ "$lan_interfaces" == "" ]]; then exit 0; fi
+          echo "$lan_interfaces" | while IFS= read -r lan_if; do
+            for ipv in 4 6; do
+              subnets=$(${pkgs.iproute2}/bin/ip -"$ipv" route show dev "$lan_if" proto kernel | cut -f1 -d' ' | grep '/')
+              if [[ "$subnets" == "" ]]; then break; fi
+              echo "$subnets" | while IFS= read -r subnet; do
+                if ${pkgs.iproute2}/bin/ip -"$ipv" route show table 52 | grep -q "$subnet dev tailscale0"; then
+                  ${pkgs.iproute2}/bin/ip -"$ipv" route del "$subnet" dev tailscale0 table 52
+                  ${pkgs.iproute2}/bin/ip -"$ipv" route add throw "$subnet" table 52
+                fi
+              done
+            done
+          done
+        '';
+      };
+      # UDP throughput improvements
+      # https://tailscale.com/kb/1320/performance-best-practices?q=gro#linux-optimizations-for-subnet-routers-and-exit-nodes
+      "50-tailscale-rx-udp-gro-forwarding" = {
+        onState = [ "routable" ];
+        script = ''
+          for dev in $(${pkgs.iproute2}/bin/ip route show 0/0 | cut -f5 -d' '); do
+            ${lib.getExe pkgs.ethtool} -K "$dev" rx-udp-gro-forwarding on rx-gro-list off
+          done
+        '';
+      };
+    };
+  };
+
   services.tailscale = {
     enable = true;
     package = pkgs.unstable.tailscale;
@@ -27,7 +75,13 @@ in
     ];
   };
 
-  systemd.services.tailscaled.serviceConfig.Environment = [ "TS_DEBUG_FIREWALL_MODE=auto" ];
+  systemd.services.tailscaled = {
+    serviceConfig.Environment = [ "TS_DEBUG_FIREWALL_MODE=auto" ];
+    after = [
+      "network-online.target"
+      "systemd-resolved.service"
+    ];
+  };
 
   # call taiscale up without --auth-key
   systemd.services.tailscaled-autoconnect = lib.mkIf (cfg.authKeyFile == null) {