Skip to content

Commit f063866

Browse files
authored
[client] Add flag to configure MTU (#4213)
1 parent 9f84165 commit f063866

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+709
-433
lines changed

client/cmd/root.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const (
3939
extraIFaceBlackListFlag = "extra-iface-blacklist"
4040
dnsRouteIntervalFlag = "dns-router-interval"
4141
enableLazyConnectionFlag = "enable-lazy-connection"
42+
mtuFlag = "mtu"
4243
)
4344

4445
var (
@@ -72,6 +73,7 @@ var (
7273
anonymizeFlag bool
7374
dnsRouteInterval time.Duration
7475
lazyConnEnabled bool
76+
mtu uint16
7577
profilesDisabled bool
7678
updateSettingsDisabled bool
7779

client/cmd/root_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func TestSetFlagsFromEnvVars(t *testing.T) {
5454
cmd.PersistentFlags().StringVar(&interfaceName, interfaceNameFlag, iface.WgInterfaceDefault, "WireGuard interface name")
5555
cmd.PersistentFlags().BoolVar(&rosenpassEnabled, enableRosenpassFlag, false, "Enable Rosenpass feature Rosenpass.")
5656
cmd.PersistentFlags().Uint16Var(&wireguardPort, wireguardPortFlag, iface.DefaultWgPort, "WireGuard interface listening port")
57+
cmd.PersistentFlags().Uint16Var(&mtu, mtuFlag, iface.DefaultMTU, "Set MTU (Maximum Transmission Unit) for the WireGuard interface")
5758

5859
t.Setenv("NB_EXTERNAL_IP_MAP", "abc,dec")
5960
t.Setenv("NB_INTERFACE_NAME", "test-name")

client/cmd/up.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func init() {
6363
upCmd.PersistentFlags().BoolVarP(&foregroundMode, "foreground-mode", "F", false, "start service in foreground")
6464
upCmd.PersistentFlags().StringVar(&interfaceName, interfaceNameFlag, iface.WgInterfaceDefault, "WireGuard interface name")
6565
upCmd.PersistentFlags().Uint16Var(&wireguardPort, wireguardPortFlag, iface.DefaultWgPort, "WireGuard interface listening port")
66+
upCmd.PersistentFlags().Uint16Var(&mtu, mtuFlag, iface.DefaultMTU, "Set MTU (Maximum Transmission Unit) for the WireGuard interface")
6667
upCmd.PersistentFlags().BoolVarP(&networkMonitor, networkMonitorFlag, "N", networkMonitor,
6768
`Manage network monitoring. Defaults to true on Windows and macOS, false on Linux and FreeBSD. `+
6869
`E.g. --network-monitor=false to disable or --network-monitor=true to enable.`,
@@ -357,6 +358,11 @@ func setupSetConfigReq(customDNSAddressConverted []byte, cmd *cobra.Command, pro
357358
req.WireguardPort = &p
358359
}
359360

361+
if cmd.Flag(mtuFlag).Changed {
362+
m := int64(mtu)
363+
req.Mtu = &m
364+
}
365+
360366
if cmd.Flag(networkMonitorFlag).Changed {
361367
req.NetworkMonitor = &networkMonitor
362368
}
@@ -436,6 +442,13 @@ func setupConfig(customDNSAddressConverted []byte, cmd *cobra.Command, configFil
436442
ic.WireguardPort = &p
437443
}
438444

445+
if cmd.Flag(mtuFlag).Changed {
446+
if err := iface.ValidateMTU(mtu); err != nil {
447+
return nil, err
448+
}
449+
ic.MTU = &mtu
450+
}
451+
439452
if cmd.Flag(networkMonitorFlag).Changed {
440453
ic.NetworkMonitor = &networkMonitor
441454
}
@@ -533,6 +546,14 @@ func setupLoginRequest(providedSetupKey string, customDNSAddressConverted []byte
533546
loginRequest.WireguardPort = &wp
534547
}
535548

549+
if cmd.Flag(mtuFlag).Changed {
550+
if err := iface.ValidateMTU(mtu); err != nil {
551+
return nil, err
552+
}
553+
m := int64(mtu)
554+
loginRequest.Mtu = &m
555+
}
556+
536557
if cmd.Flag(networkMonitorFlag).Changed {
537558
loginRequest.NetworkMonitor = &networkMonitor
538559
}

client/iface/bind/ice_bind.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ type ICEBind struct {
5656
muUDPMux sync.Mutex
5757
udpMux *UniversalUDPMuxDefault
5858
address wgaddr.Address
59+
mtu uint16
5960
activityRecorder *ActivityRecorder
6061
}
6162

62-
func NewICEBind(transportNet transport.Net, filterFn FilterFn, address wgaddr.Address) *ICEBind {
63+
func NewICEBind(transportNet transport.Net, filterFn FilterFn, address wgaddr.Address, mtu uint16) *ICEBind {
6364
b, _ := wgConn.NewStdNetBind().(*wgConn.StdNetBind)
6465
ib := &ICEBind{
6566
StdNetBind: b,
@@ -69,6 +70,7 @@ func NewICEBind(transportNet transport.Net, filterFn FilterFn, address wgaddr.Ad
6970
endpoints: make(map[netip.Addr]net.Conn),
7071
closedChan: make(chan struct{}),
7172
closed: true,
73+
mtu: mtu,
7274
address: address,
7375
activityRecorder: NewActivityRecorder(),
7476
}
@@ -80,6 +82,10 @@ func NewICEBind(transportNet transport.Net, filterFn FilterFn, address wgaddr.Ad
8082
return ib
8183
}
8284

85+
func (s *ICEBind) MTU() uint16 {
86+
return s.mtu
87+
}
88+
8389
func (s *ICEBind) Open(uport uint16) ([]wgConn.ReceiveFunc, uint16, error) {
8490
s.closed = false
8591
s.closedChanMu.Lock()
@@ -158,6 +164,7 @@ func (s *ICEBind) createIPv4ReceiverFn(pc *ipv4.PacketConn, conn *net.UDPConn, r
158164
Net: s.transportNet,
159165
FilterFn: s.filterFn,
160166
WGAddress: s.address,
167+
MTU: s.mtu,
161168
},
162169
)
163170
return func(bufs [][]byte, sizes []int, eps []wgConn.Endpoint) (n int, err error) {

client/iface/bind/udp_mux_ios.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ package bind
44

55
func (m *UDPMuxDefault) notifyAddressRemoval(addr string) {
66
// iOS doesn't support nbnet hooks, so this is a no-op
7-
}
7+
}

client/iface/bind/udp_mux_universal.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/pion/stun/v2"
1919
"github.com/pion/transport/v3"
2020

21+
"github.com/netbirdio/netbird/client/iface/bufsize"
2122
"github.com/netbirdio/netbird/client/iface/wgaddr"
2223
)
2324

@@ -44,6 +45,7 @@ type UniversalUDPMuxParams struct {
4445
Net transport.Net
4546
FilterFn FilterFn
4647
WGAddress wgaddr.Address
48+
MTU uint16
4749
}
4850

4951
// NewUniversalUDPMuxDefault creates an implementation of UniversalUDPMux embedding UDPMux
@@ -84,7 +86,7 @@ func NewUniversalUDPMuxDefault(params UniversalUDPMuxParams) *UniversalUDPMuxDef
8486
// just ignore other packets printing an warning message.
8587
// It is a blocking method, consider running in a go routine.
8688
func (m *UniversalUDPMuxDefault) ReadFromConn(ctx context.Context) {
87-
buf := make([]byte, 1500)
89+
buf := make([]byte, m.params.MTU+bufsize.WGBufferOverhead)
8890
for {
8991
select {
9092
case <-ctx.Done():

client/iface/bufsize/bufsize.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package bufsize
2+
3+
const (
4+
// WGBufferOverhead represents the additional buffer space needed beyond MTU
5+
// for WireGuard packet encapsulation (WG header + UDP + IP + safety margin)
6+
// Original hardcoded buffers were 1500, default MTU is 1280, so overhead = 220
7+
// TODO: Calculate this properly based on actual protocol overhead instead of using hardcoded difference
8+
WGBufferOverhead = 220
9+
)

client/iface/device.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type WGTunDevice interface {
1717
Up() (*bind.UniversalUDPMuxDefault, error)
1818
UpdateAddr(address wgaddr.Address) error
1919
WgAddress() wgaddr.Address
20+
MTU() uint16
2021
DeviceName() string
2122
Close() error
2223
FilteredDevice() *device.FilteredDevice

client/iface/device/device_android.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type WGTunDevice struct {
2121
address wgaddr.Address
2222
port int
2323
key string
24-
mtu int
24+
mtu uint16
2525
iceBind *bind.ICEBind
2626
tunAdapter TunAdapter
2727
disableDNS bool
@@ -33,7 +33,7 @@ type WGTunDevice struct {
3333
configurer WGConfigurer
3434
}
3535

36-
func NewTunDevice(address wgaddr.Address, port int, key string, mtu int, iceBind *bind.ICEBind, tunAdapter TunAdapter, disableDNS bool) *WGTunDevice {
36+
func NewTunDevice(address wgaddr.Address, port int, key string, mtu uint16, iceBind *bind.ICEBind, tunAdapter TunAdapter, disableDNS bool) *WGTunDevice {
3737
return &WGTunDevice{
3838
address: address,
3939
port: port,
@@ -58,7 +58,7 @@ func (t *WGTunDevice) Create(routes []string, dns string, searchDomains []string
5858
searchDomainsToString = ""
5959
}
6060

61-
fd, err := t.tunAdapter.ConfigureInterface(t.address.String(), t.mtu, dns, searchDomainsToString, routesString)
61+
fd, err := t.tunAdapter.ConfigureInterface(t.address.String(), int(t.mtu), dns, searchDomainsToString, routesString)
6262
if err != nil {
6363
log.Errorf("failed to create Android interface: %s", err)
6464
return nil, err
@@ -137,6 +137,10 @@ func (t *WGTunDevice) WgAddress() wgaddr.Address {
137137
return t.address
138138
}
139139

140+
func (t *WGTunDevice) MTU() uint16 {
141+
return t.mtu
142+
}
143+
140144
func (t *WGTunDevice) FilteredDevice() *FilteredDevice {
141145
return t.filteredDevice
142146
}

client/iface/device/device_darwin.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type TunDevice struct {
2121
address wgaddr.Address
2222
port int
2323
key string
24-
mtu int
24+
mtu uint16
2525
iceBind *bind.ICEBind
2626

2727
device *device.Device
@@ -30,7 +30,7 @@ type TunDevice struct {
3030
configurer WGConfigurer
3131
}
3232

33-
func NewTunDevice(name string, address wgaddr.Address, port int, key string, mtu int, iceBind *bind.ICEBind) *TunDevice {
33+
func NewTunDevice(name string, address wgaddr.Address, port int, key string, mtu uint16, iceBind *bind.ICEBind) *TunDevice {
3434
return &TunDevice{
3535
name: name,
3636
address: address,
@@ -42,7 +42,7 @@ func NewTunDevice(name string, address wgaddr.Address, port int, key string, mtu
4242
}
4343

4444
func (t *TunDevice) Create() (WGConfigurer, error) {
45-
tunDevice, err := tun.CreateTUN(t.name, t.mtu)
45+
tunDevice, err := tun.CreateTUN(t.name, int(t.mtu))
4646
if err != nil {
4747
return nil, fmt.Errorf("error creating tun device: %s", err)
4848
}
@@ -111,6 +111,10 @@ func (t *TunDevice) WgAddress() wgaddr.Address {
111111
return t.address
112112
}
113113

114+
func (t *TunDevice) MTU() uint16 {
115+
return t.mtu
116+
}
117+
114118
func (t *TunDevice) DeviceName() string {
115119
return t.name
116120
}

0 commit comments

Comments
 (0)