From 028045984654d350a5490c87f24d6ea592394b51 Mon Sep 17 00:00:00 2001 From: Irbe Krumina Date: Thu, 21 Mar 2024 23:02:06 +0100 Subject: [PATCH] util/linuxfw: allow IPv6 routes when ip6tables are unavailable It seems like in some cases (Synology) ip6tables are not usable, but the system should still be able to configure route table with IPv6 routes. This PR allows to disable ip6tables supports whilst still allowing for router setup if the system can support IPv6. Updates https://github.com/tailscale/tailscale/issues/11434 Signed-off-by: Irbe Krumina --- util/linuxfw/fake.go | 2 +- util/linuxfw/iptables_runner.go | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/util/linuxfw/fake.go b/util/linuxfw/fake.go index e76431d00..8fd26dca7 100644 --- a/util/linuxfw/fake.go +++ b/util/linuxfw/fake.go @@ -121,6 +121,6 @@ func NewFakeIPTablesRunner() *iptablesRunner { ipt4 := newFakeIPTables() ipt6 := newFakeIPTables() - iptr := &iptablesRunner{ipt4, ipt6, true, true} + iptr := &iptablesRunner{ipt4, ipt6, true, true, true} return iptr } diff --git a/util/linuxfw/iptables_runner.go b/util/linuxfw/iptables_runner.go index 090356798..189fcb8ee 100644 --- a/util/linuxfw/iptables_runner.go +++ b/util/linuxfw/iptables_runner.go @@ -36,8 +36,10 @@ type iptablesRunner struct { ipt4 iptablesInterface ipt6 iptablesInterface - v6Available bool - v6NATAvailable bool + v6Available bool // whether system supports IPv6 + + v6IPTablesAvailable bool // whether system supports ip6tables + v6NATAvailable bool // whether system supports ip6tables NAT } func checkIP6TablesExists() error { @@ -58,7 +60,7 @@ func newIPTablesRunner(logf logger.Logf) (*iptablesRunner, error) { return nil, err } - supportsV6, supportsV6NAT := false, false + supportsV6, supportsIPTablesv6, supportsV6NAT := false, false, false v6err := checkIPv6(logf) ip6terr := checkIP6TablesExists() var ipt6 *iptables.IPTables @@ -69,17 +71,18 @@ func newIPTablesRunner(logf logger.Logf) (*iptablesRunner, error) { logf("disabling tunneled IPv6 due to missing ip6tables: %v", ip6terr) default: supportsV6 = true + supportsIPTablesv6 = true ipt6, err = iptables.NewWithProtocol(iptables.ProtocolIPv6) if err != nil { return nil, err } - supportsV6 = checkSupportsV6Filter(ipt6, logf) - if supportsV6 { + supportsIPTablesv6 = checkSupportsV6Filter(ipt6, logf) + if supportsIPTablesv6 { supportsV6NAT = checkSupportsV6NAT(ipt6, logf) } logf("v6filter = %v, v6nat = %v", supportsV6, supportsV6NAT) } - return &iptablesRunner{ipt4, ipt6, supportsV6, supportsV6NAT}, nil + return &iptablesRunner{ipt4, ipt6, supportsV6, supportsIPTablesv6, supportsV6NAT}, nil } // checkSupportsV6Filter returns whether the system has a "filter" table in the @@ -142,6 +145,11 @@ func (i *iptablesRunner) HasIPV6() bool { return i.v6Available } +// HasIPV6 reports true if the system supports IPv6. +func (i *iptablesRunner) HasIPV6Tables() bool { + return i.v6IPTablesAvailable +} + // HasIPV6NAT reports true if the system supports IPv6 NAT. func (i *iptablesRunner) HasIPV6NAT() bool { return i.v6NATAvailable @@ -189,7 +197,7 @@ func (i *iptablesRunner) DelLoopbackRule(addr netip.Addr) error { // getTables gets the available iptablesInterface in iptables runner. func (i *iptablesRunner) getTables() []iptablesInterface { - if i.HasIPV6() { + if i.HasIPV6Tables() { return []iptablesInterface{i.ipt4, i.ipt6} } return []iptablesInterface{i.ipt4} @@ -286,7 +294,7 @@ func (i *iptablesRunner) AddBase(tunname string) error { if err := i.addBase4(tunname); err != nil { return err } - if i.HasIPV6() { + if i.HasIPV6Tables() { if err := i.addBase6(tunname); err != nil { return err }