Skip to content

Commit

Permalink
tunspace: more robust uplink handling, and direct interface support
Browse files Browse the repository at this point in the history
  • Loading branch information
pktpls committed Sep 23, 2024
1 parent 6ea3e55 commit 1c54296
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
1 change: 1 addition & 0 deletions packages/tunspace/tunspace.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package 'tunspace'
config tunspace "tunspace"
option uplink_netns "uplink"
option uplink_ifname "br-wan"
option uplink_mode "bridge"
option maintenance_interval 15
option debug 0
Expand Down
48 changes: 27 additions & 21 deletions packages/tunspace/tunspace.uc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function load_config(name) {
"debug": int(ts.debug) != 0,
"uplink_netns": ""+ts.uplink_netns,
"uplink_ifname": ""+ts.uplink_ifname,
"uplink_mode": ""+ts.uplink_mode,
"maintenance_interval": int(ts.maintenance_interval),
"wireguard_servers": {},
"wireguard_interfaces": {},
Expand Down Expand Up @@ -393,32 +394,37 @@ function wireguard_maintenance(st, cfg) {
}

// TODO: ts_uplink interface leaks into default namespace when uplink namespace is deleted
function uplink_maintenance(nsid, netns, ifname) {
function uplink_maintenance(nsid, netns, ifname, mode) {
let netnsifname = UPLINK_NETNS_IFNAME;

if (interface_exists(netnsifname)) {
// the uplink interface will sometimes leak out of the namespace on shutdown
shell_command("ip link set "+netnsifname+" netns "+netns);
}

if (interface_exists_netns(netnsifname, netns)) {
// try dhcp for 5 seconds
shell_command("ip netns exec "+netns+" udhcpc -f -n -q -A 5 -i "+netnsifname+" -s /usr/share/tunspace/udhcpc.script 2>&1 | grep 'ip addr add'");
shell_command("ip -n "+netns+" link set "+netnsifname+" up");
} else if (!interface_exists(ifname)) {
log(sprintf("missing uplink interface %s", ifname));
return false;
} else if (mode == "direct") {
// move uplink interface directly:
shell_command("ip link set dev "+ifname+" netns "+netns);
shell_command("ip -n "+netns+" link set "+ifname+" name "+netnsifname);
shell_command("ip -n "+netns+" link set "+netnsifname+" up");
} else if (mode == "bridge") {
// or create a macvlan bridge:
shell_command("ip link add "+netnsifname+" link "+ifname+" type macvlan mode bridge");
shell_command("ip link set dev "+netnsifname+" netns "+netns);
shell_command("ip -n "+netns+" link set up "+netnsifname+"");
} else {
if (!interface_exists(ifname)) {
log(sprintf("missing uplink interface %s", ifname));
return false;
} else {
// move uplink interface directly:
// shell_command("ip link set dev "+ifname+" netns "+netns);
// shell_command("ip -n "+netns+" link set "+ifname+" up");
// shell_command("ip -n "+netns+" link set "+ifname+" name "+netnsifname);

// or create a macvlan bridge:
shell_command("ip link add "+netnsifname+" link "+ifname+" type macvlan mode bridge");
shell_command("ip link set dev "+netnsifname+" netns "+netns);
shell_command("ip -n "+netns+" link set up "+netnsifname+"");

// try dhcp for 5 seconds
shell_command("ip netns exec "+netns+" udhcpc -f -n -q -A 5 -i "+netnsifname+" -s /usr/share/tunspace/udhcpc.script 2>&1 | grep 'ip addr add'");
}
log(sprintf("uplink mode must be 'bridge' or 'direct', got '%s'", mode));
return false;
}

// try dhcp for 5 seconds
shell_command("ip netns exec "+netns+" udhcpc -f -n -q -A 5 -i "+netnsifname+" -s /usr/share/tunspace/udhcpc.script 2>&1 | grep 'ip addr add'");

return true;
}

Expand All @@ -444,7 +450,7 @@ function boot(st, cfg) {
function tick(st, cfg) {
debug("tick");

if (!uplink_maintenance(st.nsid, cfg.uplink_netns, cfg.uplink_ifname)) {
if (!uplink_maintenance(st.nsid, cfg.uplink_netns, cfg.uplink_ifname, cfg.uplink_mode)) {
log("uplink maintenance failed");
}
wireguard_maintenance(st, cfg);
Expand Down

0 comments on commit 1c54296

Please sign in to comment.