mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-04 23:45:34 +00:00
WIP
This commit is contained in:
parent
91d28e7155
commit
d067c7cf41
@ -377,7 +377,7 @@ func (r *linuxRouter) Up() error {
|
|||||||
if err := r.addIPRules(); err != nil {
|
if err := r.addIPRules(); err != nil {
|
||||||
return fmt.Errorf("adding IP rules: %w", err)
|
return fmt.Errorf("adding IP rules: %w", err)
|
||||||
}
|
}
|
||||||
if err := r.setNetfilterMode(netfilterOff); err != nil {
|
if err := r.setNetfilterMode(netfilterOff, true); err != nil {
|
||||||
return fmt.Errorf("setting netfilter mode: %w", err)
|
return fmt.Errorf("setting netfilter mode: %w", err)
|
||||||
}
|
}
|
||||||
if err := r.upInterface(); err != nil {
|
if err := r.upInterface(); err != nil {
|
||||||
@ -398,7 +398,7 @@ func (r *linuxRouter) Close() error {
|
|||||||
if err := r.delIPRules(); err != nil {
|
if err := r.delIPRules(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := r.setNetfilterMode(netfilterOff); err != nil {
|
if err := r.setNetfilterMode(netfilterOff, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := r.delRoutes(); err != nil {
|
if err := r.delRoutes(); err != nil {
|
||||||
@ -421,15 +421,15 @@ func (r *linuxRouter) Set(cfg *Config) error {
|
|||||||
|
|
||||||
// Because the tailnet may have IPv4 disabled, check if we have any v4
|
// Because the tailnet may have IPv4 disabled, check if we have any v4
|
||||||
// prefixes from addresses, routes, or local routes.
|
// prefixes from addresses, routes, or local routes.
|
||||||
r.hasV4Prefix = false
|
var foundV4 bool
|
||||||
findV4 := func(arr []netip.Prefix) {
|
findV4 := func(arr []netip.Prefix) {
|
||||||
// Skip useless loop if we've already found a v4 prefix
|
// Skip useless loop if we've already found a v4 prefix
|
||||||
if r.hasV4Prefix {
|
if foundV4 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, pref := range arr {
|
for _, pref := range arr {
|
||||||
if pref.Addr().Is4() {
|
if pref.Addr().Is4() {
|
||||||
r.hasV4Prefix = true
|
foundV4 = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,7 +439,18 @@ func (r *linuxRouter) Set(cfg *Config) error {
|
|||||||
findV4(cfg.LocalRoutes)
|
findV4(cfg.LocalRoutes)
|
||||||
findV4(cfg.SubnetRoutes)
|
findV4(cfg.SubnetRoutes)
|
||||||
|
|
||||||
if err := r.setNetfilterMode(cfg.NetfilterMode); err != nil {
|
if !foundV4 && !r.v6Available {
|
||||||
|
return fmt.Errorf("No IPv4 routes and IPv6 isn't available")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update our "have IPv4" setting after we're done with this function;
|
||||||
|
// we can't do this earlier because both 'setNetfilterMode' and the
|
||||||
|
// SNAT rules need to know what the previous value was.
|
||||||
|
defer func() {
|
||||||
|
r.hasV4Prefix = foundV4
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := r.setNetfilterMode(cfg.NetfilterMode, foundV4); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +476,7 @@ func (r *linuxRouter) Set(cfg *Config) error {
|
|||||||
case cfg.SNATSubnetRoutes == r.snatSubnetRoutes:
|
case cfg.SNATSubnetRoutes == r.snatSubnetRoutes:
|
||||||
// state already correct, nothing to do.
|
// state already correct, nothing to do.
|
||||||
case cfg.SNATSubnetRoutes:
|
case cfg.SNATSubnetRoutes:
|
||||||
if err := r.addSNATRule(); err != nil {
|
if err := r.addSNATRule(foundV4); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -482,14 +493,27 @@ func (r *linuxRouter) Set(cfg *Config) error {
|
|||||||
// mode. Netfilter state is created or deleted appropriately to
|
// mode. Netfilter state is created or deleted appropriately to
|
||||||
// reflect the new mode, and r.snatSubnetRoutes is updated to reflect
|
// reflect the new mode, and r.snatSubnetRoutes is updated to reflect
|
||||||
// the current state of subnet SNATing.
|
// the current state of subnet SNATing.
|
||||||
func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error {
|
func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode, foundV4 bool) error {
|
||||||
if distro.Get() == distro.Synology {
|
if distro.Get() == distro.Synology {
|
||||||
mode = netfilterOff
|
mode = netfilterOff
|
||||||
}
|
}
|
||||||
if r.netfilterMode == mode {
|
if r.netfilterMode == mode && r.hasV4Prefix == foundV4 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In the (unlikely) case where we change whether or not we install
|
||||||
|
// IPv4 rules, recreate everything rather than complicating our diff
|
||||||
|
// logic. This should only happen if the user changes the tailnet-wide
|
||||||
|
// "DisableIPv4" setting.
|
||||||
|
if r.hasV4Prefix != foundV4 {
|
||||||
|
// Turn off netfilter (recursively) to force the code below to
|
||||||
|
// recreate things in the "correct" mode.
|
||||||
|
// TODO(andrew): this is a bit janky; think about this before merging
|
||||||
|
if err := r.setNetfilterMode(netfilterOff, r.hasV4Prefix); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Depending on the netfilter mode we switch from and to, we may
|
// Depending on the netfilter mode we switch from and to, we may
|
||||||
// have created the Tailscale netfilter chains. If so, we have to
|
// have created the Tailscale netfilter chains. If so, we have to
|
||||||
// go back through existing router state, and add the netfilter
|
// go back through existing router state, and add the netfilter
|
||||||
@ -1499,15 +1523,17 @@ func (r *linuxRouter) delNetfilterHooks() error {
|
|||||||
|
|
||||||
// addSNATRule adds a netfilter rule to SNAT traffic destined for
|
// addSNATRule adds a netfilter rule to SNAT traffic destined for
|
||||||
// local subnets.
|
// local subnets.
|
||||||
func (r *linuxRouter) addSNATRule() error {
|
func (r *linuxRouter) addSNATRule(foundV4 bool) error {
|
||||||
if r.netfilterMode == netfilterOff {
|
if r.netfilterMode == netfilterOff {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{"-m", "mark", "--mark", tailscaleSubnetRouteMark + "/" + tailscaleFwmarkMask, "-j", "MASQUERADE"}
|
args := []string{"-m", "mark", "--mark", tailscaleSubnetRouteMark + "/" + tailscaleFwmarkMask, "-j", "MASQUERADE"}
|
||||||
|
if foundV4 {
|
||||||
if err := r.ipt4.Append("nat", "ts-postrouting", args...); err != nil {
|
if err := r.ipt4.Append("nat", "ts-postrouting", args...); err != nil {
|
||||||
return fmt.Errorf("adding %v in v4/nat/ts-postrouting: %w", args, err)
|
return fmt.Errorf("adding %v in v4/nat/ts-postrouting: %w", args, err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if r.v6NATAvailable {
|
if r.v6NATAvailable {
|
||||||
if err := r.ipt6.Append("nat", "ts-postrouting", args...); err != nil {
|
if err := r.ipt6.Append("nat", "ts-postrouting", args...); err != nil {
|
||||||
return fmt.Errorf("adding %v in v6/nat/ts-postrouting: %w", args, err)
|
return fmt.Errorf("adding %v in v6/nat/ts-postrouting: %w", args, err)
|
||||||
@ -1524,9 +1550,11 @@ func (r *linuxRouter) delSNATRule() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
args := []string{"-m", "mark", "--mark", tailscaleSubnetRouteMark + "/" + tailscaleFwmarkMask, "-j", "MASQUERADE"}
|
args := []string{"-m", "mark", "--mark", tailscaleSubnetRouteMark + "/" + tailscaleFwmarkMask, "-j", "MASQUERADE"}
|
||||||
|
if r.hasV4Prefix {
|
||||||
if err := r.ipt4.Delete("nat", "ts-postrouting", args...); err != nil {
|
if err := r.ipt4.Delete("nat", "ts-postrouting", args...); err != nil {
|
||||||
return fmt.Errorf("deleting %v in v4/nat/ts-postrouting: %w", args, err)
|
return fmt.Errorf("deleting %v in v4/nat/ts-postrouting: %w", args, err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if r.v6NATAvailable {
|
if r.v6NATAvailable {
|
||||||
if err := r.ipt6.Delete("nat", "ts-postrouting", args...); err != nil {
|
if err := r.ipt6.Delete("nat", "ts-postrouting", args...); err != nil {
|
||||||
return fmt.Errorf("deleting %v in v6/nat/ts-postrouting: %w", args, err)
|
return fmt.Errorf("deleting %v in v6/nat/ts-postrouting: %w", args, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user