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 <irbe@tailscale.com>
This commit is contained in:
Irbe Krumina 2024-03-21 23:02:06 +01:00
parent 8444937c89
commit 0280459846
2 changed files with 17 additions and 9 deletions

View File

@ -121,6 +121,6 @@ func NewFakeIPTablesRunner() *iptablesRunner {
ipt4 := newFakeIPTables() ipt4 := newFakeIPTables()
ipt6 := newFakeIPTables() ipt6 := newFakeIPTables()
iptr := &iptablesRunner{ipt4, ipt6, true, true} iptr := &iptablesRunner{ipt4, ipt6, true, true, true}
return iptr return iptr
} }

View File

@ -36,8 +36,10 @@ type iptablesRunner struct {
ipt4 iptablesInterface ipt4 iptablesInterface
ipt6 iptablesInterface ipt6 iptablesInterface
v6Available bool v6Available bool // whether system supports IPv6
v6NATAvailable bool
v6IPTablesAvailable bool // whether system supports ip6tables
v6NATAvailable bool // whether system supports ip6tables NAT
} }
func checkIP6TablesExists() error { func checkIP6TablesExists() error {
@ -58,7 +60,7 @@ func newIPTablesRunner(logf logger.Logf) (*iptablesRunner, error) {
return nil, err return nil, err
} }
supportsV6, supportsV6NAT := false, false supportsV6, supportsIPTablesv6, supportsV6NAT := false, false, false
v6err := checkIPv6(logf) v6err := checkIPv6(logf)
ip6terr := checkIP6TablesExists() ip6terr := checkIP6TablesExists()
var ipt6 *iptables.IPTables 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) logf("disabling tunneled IPv6 due to missing ip6tables: %v", ip6terr)
default: default:
supportsV6 = true supportsV6 = true
supportsIPTablesv6 = true
ipt6, err = iptables.NewWithProtocol(iptables.ProtocolIPv6) ipt6, err = iptables.NewWithProtocol(iptables.ProtocolIPv6)
if err != nil { if err != nil {
return nil, err return nil, err
} }
supportsV6 = checkSupportsV6Filter(ipt6, logf) supportsIPTablesv6 = checkSupportsV6Filter(ipt6, logf)
if supportsV6 { if supportsIPTablesv6 {
supportsV6NAT = checkSupportsV6NAT(ipt6, logf) supportsV6NAT = checkSupportsV6NAT(ipt6, logf)
} }
logf("v6filter = %v, v6nat = %v", supportsV6, supportsV6NAT) 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 // checkSupportsV6Filter returns whether the system has a "filter" table in the
@ -142,6 +145,11 @@ func (i *iptablesRunner) HasIPV6() bool {
return i.v6Available 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. // HasIPV6NAT reports true if the system supports IPv6 NAT.
func (i *iptablesRunner) HasIPV6NAT() bool { func (i *iptablesRunner) HasIPV6NAT() bool {
return i.v6NATAvailable return i.v6NATAvailable
@ -189,7 +197,7 @@ func (i *iptablesRunner) DelLoopbackRule(addr netip.Addr) error {
// getTables gets the available iptablesInterface in iptables runner. // getTables gets the available iptablesInterface in iptables runner.
func (i *iptablesRunner) getTables() []iptablesInterface { func (i *iptablesRunner) getTables() []iptablesInterface {
if i.HasIPV6() { if i.HasIPV6Tables() {
return []iptablesInterface{i.ipt4, i.ipt6} return []iptablesInterface{i.ipt4, i.ipt6}
} }
return []iptablesInterface{i.ipt4} return []iptablesInterface{i.ipt4}
@ -286,7 +294,7 @@ func (i *iptablesRunner) AddBase(tunname string) error {
if err := i.addBase4(tunname); err != nil { if err := i.addBase4(tunname); err != nil {
return err return err
} }
if i.HasIPV6() { if i.HasIPV6Tables() {
if err := i.addBase6(tunname); err != nil { if err := i.addBase6(tunname); err != nil {
return err return err
} }