Skip to content

Commit a99301b

Browse files
Paul Cclaude
andcommitted
auto-detect Tailscale and add iptables rule to prevent routing loop
When wolfnet starts and detects tailscaled running, it adds an iptables OUTPUT rule to block Tailscale WireGuard traffic (port 41641) from being routed into the wolfnet subnet. This prevents a feedback loop where Tailscale routes its own tunnel traffic through wolfnet, which sends it back through Tailscale, causing both to spike to 90%+ CPU. The rule is idempotent (checks before adding) and only targets Tailscale's WireGuard port — wolfnet traffic on its own port is unaffected. Bumps to 0.5.17. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8f25240 commit a99301b

3 files changed

Lines changed: 22 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "wolfnet"
3-
version = "0.5.16"
3+
version = "0.5.17"
44
edition = "2021"
55
authors = ["Wolf Software Systems Ltd"]
66
description = "Secure private mesh networking over the internet"

src/tun.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,26 @@ impl TunDevice {
126126
.args(["device", "set", &self.name, "managed", "no"])
127127
.output();
128128

129+
// Prevent Tailscale routing loop — if Tailscale is running, its WireGuard
130+
// traffic (port 41641) can get routed into wolfnet0 via the subnet route,
131+
// creating a feedback loop where Tailscale traffic goes through WolfNet
132+
// and back through Tailscale. Block it with an iptables OUTPUT rule.
133+
if std::process::Command::new("pidof").arg("tailscaled").output()
134+
.map(|o| o.status.success()).unwrap_or(false)
135+
{
136+
let subnet = format!("{}/{}", address, subnet);
137+
// Check if the rule already exists before adding
138+
let exists = std::process::Command::new("iptables")
139+
.args(["-C", "OUTPUT", "-p", "udp", "--dport", "41641", "-d", &subnet, "-j", "DROP"])
140+
.output()
141+
.map(|o| o.status.success()).unwrap_or(false);
142+
if !exists {
143+
let _ = std::process::Command::new("iptables")
144+
.args(["-I", "OUTPUT", "-p", "udp", "--dport", "41641", "-d", &subnet, "-j", "DROP"])
145+
.status();
146+
}
147+
}
148+
129149
Ok(())
130150
}
131151

0 commit comments

Comments
 (0)