wgengine/router,ipn/ipnlocal: add MTU field to router config

The MacOS client can't set the MTU when creating the tun due to lack
of permissions, so add it to the router config and have MacOS set it
in the callback using a method that it does have permissions for.

Updates #8219

Signed-off-by: Val <valerie@tailscale.com>
This commit is contained in:
Val 2023-07-18 23:51:32 +02:00 committed by valscale
parent 9b5e29761c
commit 1138f4eb5f
3 changed files with 31 additions and 5 deletions

View File

@ -24,9 +24,16 @@ type CallbackRouter struct {
// will return ErrGetBaseConfigNotSupported.
GetBaseConfigFunc func() (dns.OSConfig, error)
mu sync.Mutex // protects all the following
rcfg *Config // last applied router config
dcfg *dns.OSConfig // last applied DNS config
// InitialMTU is the MTU the tun should be initialized with.
// Zero means don't change the MTU from the default. This MTU
// is applied only once, shortly after the TUN is created, and
// ignored thereafter.
InitialMTU uint32
mu sync.Mutex // protects all the following
didSetMTU bool // if we set the MTU already
rcfg *Config // last applied router config
dcfg *dns.OSConfig // last applied DNS config
}
// Up implements Router.
@ -41,6 +48,10 @@ func (r *CallbackRouter) Set(rcfg *Config) error {
if r.rcfg.Equal(rcfg) {
return nil
}
if r.didSetMTU == false {
r.didSetMTU = true
rcfg.NewMTU = int(r.InitialMTU)
}
r.rcfg = rcfg
return r.SetBoth(r.rcfg, r.dcfg)
}

View File

@ -67,6 +67,11 @@ type Config struct {
// routing rules apply.
LocalRoutes []netip.Prefix
// NewMTU is currently only used by the MacOS network extension
// app to set the MTU of the tun in the router configuration
// callback. If zero, the MTU is unchanged.
NewMTU int
// Linux-only things below, ignored on other platforms.
SubnetRoutes []netip.Prefix // subnets being advertised to other Tailscale nodes
SNATSubnetRoutes bool // SNAT traffic to local subnets

View File

@ -21,8 +21,8 @@ func mustCIDRs(ss ...string) []netip.Prefix {
func TestConfigEqual(t *testing.T) {
testedFields := []string{
"LocalAddrs", "Routes", "LocalRoutes", "SubnetRoutes",
"SNATSubnetRoutes", "NetfilterMode",
"LocalAddrs", "Routes", "LocalRoutes", "NewMTU",
"SubnetRoutes", "SNATSubnetRoutes", "NetfilterMode",
}
configType := reflect.TypeOf(Config{})
configFields := []string{}
@ -134,6 +134,16 @@ func TestConfigEqual(t *testing.T) {
&Config{NetfilterMode: preftype.NetfilterNoDivert},
true,
},
{
&Config{NewMTU: 0},
&Config{NewMTU: 0},
true,
},
{
&Config{NewMTU: 1280},
&Config{NewMTU: 0},
false,
},
}
for i, tt := range tests {
got := tt.a.Equal(tt.b)