ipn/{ipnlocal,localapi},net/netkernelconf,client/tailscale,cmd/containerboot: optionally enable UDP GRO forwarding for containers (#12410)

Add a new TS_EXPERIMENTAL_ENABLE_FORWARDING_OPTIMIZATIONS env var
that can be set for tailscale/tailscale container running as
a subnet router or exit node to enable UDP GRO forwarding
for improved performance.
See https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
This is currently considered an experimental approach;
the configuration support is partially to allow further experimentation
with containerized environments to evaluate the performance
improvements.

Updates tailscale/tailscale#12295

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
Irbe Krumina
2024-06-10 19:19:03 +01:00
committed by GitHub
parent 6f2bae019f
commit bc53ebd4a0
6 changed files with 140 additions and 19 deletions

View File

@@ -5537,6 +5537,38 @@ func (b *LocalBackend) CheckUDPGROForwarding() error {
return warn
}
// SetUDPGROForwarding enables UDP GRO forwarding for the default network
// interface of this machine. It can be done to improve performance for nodes
// acting as Tailscale subnet routers or exit nodes. Currently (9/5/2024) this
// functionality is considered experimental and only safe to use via explicit
// user opt-in for ephemeral devices, such as containers.
// https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
func (b *LocalBackend) SetUDPGROForwarding() error {
if b.sys.IsNetstackRouter() {
return errors.New("UDP GRO forwarding cannot be enabled in userspace mode")
}
tunSys, ok := b.sys.Tun.GetOK()
if !ok {
return errors.New("[unexpected] unable to retrieve tun device configuration")
}
tunInterface, err := tunSys.Name()
if err != nil {
return errors.New("[unexpected] unable to determine name of the tun device")
}
netmonSys, ok := b.sys.NetMon.GetOK()
if !ok {
return errors.New("[unexpected] unable to retrieve tailscale netmon configuration")
}
state := netmonSys.InterfaceState()
if state == nil {
return errors.New("[unexpected] unable to retrieve machine's network interface state")
}
if err := netkernelconf.SetUDPGROForwarding(tunInterface, state.DefaultRouteInterface); err != nil {
return fmt.Errorf("error enabling UDP GRO forwarding: %w", err)
}
return nil
}
// DERPMap returns the current DERPMap in use, or nil if not connected.
func (b *LocalBackend) DERPMap() *tailcfg.DERPMap {
b.mu.Lock()