| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- package aerotun
- import (
- "fmt"
- "net"
- "github.com/vishvananda/netlink"
- )
- // Account for our authenticated header/tag plus UDP and the outer IP header.
- // Route MTU and link MTU are local upper bounds; a smaller remote path MTU can
- // still require an explicitly lower configured MTU.
- func packetHeaderSize(version int) int {
- if version == 3 {
- return secureHeaderSize
- }
- return headerSize
- }
- func underlayMTU(requested int, remote net.IP) (int, error) {
- return underlayMTUForHeader(requested, remote, headerSize)
- }
- func underlayMTUForHeader(requested int, remote net.IP, header int) (int, error) {
- routes, err := netlink.RouteGet(remote)
- if err != nil || len(routes) == 0 {
- // During system boot or temporary network disconnection, route may not be present yet.
- // Fallback gracefully to requested MTU if valid, or default 1360.
- if requested >= 576 {
- return requested, nil
- }
- return 1360, nil
- }
- link, err := netlink.LinkByIndex(routes[0].LinkIndex)
- if err != nil {
- if requested >= 576 {
- return requested, nil
- }
- return 1360, nil
- }
- limit := link.Attrs().MTU
- if routes[0].MTU > 0 && routes[0].MTU < limit {
- limit = routes[0].MTU
- }
- overhead := header + 16 + 8 + 20
- if remote.To4() == nil {
- overhead += 20
- }
- limit -= overhead
- if limit < 576 {
- return 0, fmt.Errorf("underlay MTU too small for AeroTUN")
- }
- if requested > limit {
- return limit, nil
- }
- return requested, nil
- }
- func (t *TunnelRunner) adjustMTU(remote net.IP, peerMTU int) error {
- mtu, err := underlayMTUForHeader(int(t.effectiveMTU.Load()), remote, packetHeaderSize(t.cfg.Protocol))
- if err != nil {
- return err
- }
- if peerMTU < mtu {
- mtu = peerMTU
- }
- if mtu == int(t.effectiveMTU.Load()) {
- return nil
- }
- ip, _, _ := net.ParseCIDR(t.cfg.LocalAddress)
- if ip.To4() == nil && mtu < 1280 {
- return fmt.Errorf("underlay cannot carry IPv6 tunnel MTU 1280")
- }
- names := []string{t.dev.Name()}
- if v, ok := t.dev.(*vethTun); ok {
- names = append(names, v.epName)
- }
- for _, name := range names {
- if _, err := runIP("link", "set", name, "mtu", fmt.Sprint(mtu)); err != nil {
- return err
- }
- }
- t.effectiveMTU.Store(int64(mtu))
- return nil
- }
|