From f49d9de421e98bed3eedeabacf2055ba65ed8ae9 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 19 Nov 2019 14:20:11 +0000 Subject: [PATCH] Fix setting up of MTU when value is outside of acceptable bounds, also account for ethernet headers in calculations, notify about clipping to stdout --- src/tuntap/tun.go | 30 ++++++++++++++++++++++-------- src/tuntap/tun_bsd.go | 2 +- src/tuntap/tun_darwin.go | 5 +++-- src/tuntap/tun_linux.go | 2 +- src/tuntap/tun_other.go | 4 ++-- src/tuntap/tun_windows.go | 5 +++-- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index f0250c93..ffee63b6 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -63,9 +63,12 @@ type TunOptions struct { // Gets the maximum supported MTU for the platform based on the defaults in // defaults.GetDefaults(). -func getSupportedMTU(mtu int) int { - if mtu > defaults.GetDefaults().MaximumIfMTU { - return defaults.GetDefaults().MaximumIfMTU +func getSupportedMTU(mtu int, istapmode bool) int { + if mtu < 1280 { + return 1280 + } + if mtu > MaximumMTU(istapmode) { + return MaximumMTU(istapmode) } return mtu } @@ -80,7 +83,7 @@ func (tun *TunAdapter) Name() string { // the maximum value is determined by your platform. The returned value will // never exceed that of MaximumMTU(). func (tun *TunAdapter) MTU() int { - return getSupportedMTU(tun.mtu) + return getSupportedMTU(tun.mtu, tun.IsTAP()) } // IsTAP returns true if the adapter is a TAP adapter (Layer 2) or false if it @@ -97,7 +100,11 @@ func DefaultName() string { // DefaultMTU gets the default TUN/TAP interface MTU for your platform. This can // be as high as MaximumMTU(), depending on platform, but is never lower than 1280. func DefaultMTU() int { - return defaults.GetDefaults().DefaultIfMTU + ehbytes := 0 + if DefaultIsTAP() { + ehbytes = 14 + } + return defaults.GetDefaults().DefaultIfMTU - ehbytes } // DefaultIsTAP returns true if the default adapter mode for the current @@ -109,8 +116,12 @@ func DefaultIsTAP() bool { // MaximumMTU returns the maximum supported TUN/TAP interface MTU for your // platform. This can be as high as 65535, depending on platform, but is never // lower than 1280. -func MaximumMTU() int { - return defaults.GetDefaults().MaximumIfMTU +func MaximumMTU(iftapmode bool) int { + ehbytes := 0 + if iftapmode { + ehbytes = 14 + } + return defaults.GetDefaults().MaximumIfMTU - ehbytes } // Init initialises the TUN/TAP module. You must have acquired a Listener from @@ -167,6 +178,9 @@ func (tun *TunAdapter) _start() error { if err := tun.setup(ifname, iftapmode, addr, tun.mtu); err != nil { return err } + if tun.MTU() != current.IfMTU { + tun.log.Warnf("Warning: Interface MTU %d automatically adjusted to %d (supported range is 1280-%d)", current.IfMTU, tun.MTU(), MaximumMTU(tun.IsTAP())) + } } if ifname == "none" || ifname == "dummy" { tun.log.Debugln("Not starting TUN/TAP as ifname is none or dummy") @@ -176,7 +190,7 @@ func (tun *TunAdapter) _start() error { go tun.handler() tun.reader.Act(nil, tun.reader._read) // Start the reader tun.icmpv6.Init(tun) - if iftapmode { + if tun.IsTAP() { go tun.icmpv6.Solicit(tun.addr) } tun.ckr.init(tun) diff --git a/src/tuntap/tun_bsd.go b/src/tuntap/tun_bsd.go index 996f3140..78a4adab 100644 --- a/src/tuntap/tun_bsd.go +++ b/src/tuntap/tun_bsd.go @@ -99,7 +99,7 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int panic(err) } tun.iface = iface - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(mtu, iftapmode) return tun.setupAddress(addr) } diff --git a/src/tuntap/tun_darwin.go b/src/tuntap/tun_darwin.go index d7b46537..ab6f34e3 100644 --- a/src/tuntap/tun_darwin.go +++ b/src/tuntap/tun_darwin.go @@ -18,7 +18,8 @@ import ( // Configures the "utun" adapter with the correct IPv6 address and MTU. func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { if iftapmode { - tun.log.Warnln("TAP mode is not supported on this platform, defaulting to TUN") + tun.log.Warnln("Warning: TAP mode is not supported on this platform, defaulting to TUN") + iftapmode = false } config := water.Config{DeviceType: water.TUN} iface, err := water.New(config) @@ -26,7 +27,7 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int panic(err) } tun.iface = iface - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(mtu, iftapmode) return tun.setupAddress(addr) } diff --git a/src/tuntap/tun_linux.go b/src/tuntap/tun_linux.go index 764e56b9..d3e9c859 100644 --- a/src/tuntap/tun_linux.go +++ b/src/tuntap/tun_linux.go @@ -26,7 +26,7 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int panic(err) } tun.iface = iface - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(mtu, iftapmode) // The following check is specific to Linux, as the TAP driver only supports // an MTU of 65535-14 to make room for the ethernet headers. This makes sure // that the MTU gets rounded down to 65521 instead of causing a panic. diff --git a/src/tuntap/tun_other.go b/src/tuntap/tun_other.go index 48276b49..7d4f0643 100644 --- a/src/tuntap/tun_other.go +++ b/src/tuntap/tun_other.go @@ -21,13 +21,13 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int panic(err) } tun.iface = iface - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(mtu, iftapmode) return tun.setupAddress(addr) } // We don't know how to set the IPv6 address on an unknown platform, therefore // write about it to stdout and don't try to do anything further. func (tun *TunAdapter) setupAddress(addr string) error { - tun.log.Warnln("Platform not supported, you must set the address of", tun.iface.Name(), "to", addr) + tun.log.Warnln("Warning: Platform not supported, you must set the address of", tun.iface.Name(), "to", addr) return nil } diff --git a/src/tuntap/tun_windows.go b/src/tuntap/tun_windows.go index ea1515ff..d4fd1c3d 100644 --- a/src/tuntap/tun_windows.go +++ b/src/tuntap/tun_windows.go @@ -17,7 +17,8 @@ import ( // delegate the hard work to "netsh". func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { if !iftapmode { - tun.log.Warnln("TUN mode is not supported on this platform, defaulting to TAP") + tun.log.Warnln("Warning: TUN mode is not supported on this platform, defaulting to TAP") + iftapmode = true } config := water.Config{DeviceType: water.TAP} config.PlatformSpecificParams.ComponentID = "tap0901" @@ -60,7 +61,7 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int panic(err) } tun.iface = iface - tun.mtu = getSupportedMTU(mtu) + tun.mtu = getSupportedMTU(mtu, iftapmode) err = tun.setupMTU(tun.mtu) if err != nil { panic(err)