github.phpd.cn/cilium/cilium@v1.6.12/pkg/mtu/mtu.go (about) 1 // Copyright 2018 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mtu 16 17 const ( 18 // MaxMTU is the highest MTU that can be used for devices and routes 19 // handled by Cilium. It will typically be used to configure inbound 20 // paths towards containers where it is guaranteed that the packet will 21 // not be rerouted to another node, and therefore will not lead to 22 // any form of IP fragmentation. 23 // One might expect this to be 65535, however Linux seems to cap the 24 // MTU of routes at 65520, so we use this value below. 25 MaxMTU = 65520 26 27 // EthernetMTU is the standard MTU for Ethernet devices. It is used 28 // as the MTU for container devices when running direct routing mode. 29 EthernetMTU = 1500 30 31 // TunnelOverhead is an approximation for bytes used for tunnel 32 // encapsulation. It accounts for: 33 // (Outer ethernet is not accounted against MTU size) 34 // Outer IPv4 header: 20B 35 // Outer UDP header: 8B 36 // Outer VXLAN header: 8B 37 // Original Ethernet: 14B 38 // --- 39 // Total extra bytes: 50B 40 TunnelOverhead = 50 41 42 // EncryptionIPsecOverhead is an approximation for bytes used for 43 // encryption. Depending on key size and encryption type the actual 44 // size may vary here we do calculations for 128B keys and Auth. The 45 // overhead is accounted for as: 46 // Outer IP header: 20B 47 // SPI: 4B 48 // Sequece Numbers: 4B 49 // Next Header: 1B 50 // ICV: 16B 51 // Padding: 16B 52 // 128bit Auth: 16B 53 // --- 54 // Total extra bytes: 77B 55 EncryptionIPsecOverhead = 77 56 57 // EncryptionDefaultAuthKeyLength is 16 representing 128B key recommended 58 // size for GCM(AES*) in RFC4106. Users may input other lengths via 59 // key secrets. 60 EncryptionDefaultAuthKeyLength = 16 61 ) 62 63 // Configuration is an MTU configuration as returned by NewConfiguration 64 type Configuration struct { 65 // standardMTU is the regular MTU used for configuring devices and 66 // routes where packets are expected to be delivered outside the node. 67 // 68 // Note that this is a singleton for the process including this 69 // package. This means, for instance, that when using this from the 70 // ``pkg/plugins/*`` sources, it will not respect the settings 71 // configured inside the ``daemon/``. 72 standardMTU int 73 74 // tunnelMTU is the MTU used for configuring a tunnel mesh for 75 // inter-node connectivity. 76 // 77 // Similar to StandardMTU, this is a singleton for the process. 78 tunnelMTU int 79 80 // encryptMTU is the MTU used for configurations a encryption route 81 // without tunneling. If tunneling is enabled the tunnelMTU is used 82 // which will include additional encryption overhead if needed. 83 encryptMTU int 84 85 encapEnabled bool 86 encryptEnabled bool 87 } 88 89 // NewConfiguration returns a new MTU configuration. The MTU can be manually 90 // specified, otherwise it will be automatically detected. if encapEnabled is 91 // true, the MTU is adjusted to account for encapsulation overhead for all 92 // routes involved in node to node communication. 93 func NewConfiguration(authKeySize int, encryptEnabled bool, encapEnabled bool, mtu int) Configuration { 94 encryptOverhead := 0 95 96 if mtu == 0 { 97 var err error 98 99 mtu, err = autoDetect() 100 if err != nil { 101 log.WithError(err).Warning("Unable to automatically detect MTU") 102 mtu = EthernetMTU 103 } 104 } 105 106 if encryptEnabled { 107 // Add the difference between the default and the actual key sizes here 108 // to account for users specifying non-default auth key lengths. 109 encryptOverhead = EncryptionIPsecOverhead + (authKeySize - EncryptionDefaultAuthKeyLength) 110 } 111 112 conf := Configuration{ 113 standardMTU: mtu, 114 tunnelMTU: mtu - (TunnelOverhead + encryptOverhead), 115 encryptMTU: mtu - encryptOverhead, 116 encapEnabled: encapEnabled, 117 encryptEnabled: encryptEnabled, 118 } 119 120 if conf.tunnelMTU < 0 { 121 conf.tunnelMTU = 0 122 } 123 124 return conf 125 } 126 127 // GetRouteMTU returns the MTU to be used on the network. When running in 128 // tunneling mode and/or with encryption enabled, this will have tunnel and 129 // encryption overhead accounted for. 130 func (c *Configuration) GetRouteMTU() int { 131 if !c.encapEnabled && !c.encryptEnabled { 132 return c.GetDeviceMTU() 133 } 134 135 if c.encryptEnabled && !c.encapEnabled { 136 if c.encryptMTU == 0 { 137 return EthernetMTU - EncryptionIPsecOverhead 138 } 139 return c.encryptMTU 140 } 141 142 if c.tunnelMTU == 0 { 143 if c.encryptEnabled { 144 return EthernetMTU - (TunnelOverhead + EncryptionIPsecOverhead) 145 } 146 return EthernetMTU - TunnelOverhead 147 } 148 149 return c.tunnelMTU 150 } 151 152 // GetDeviceMTU returns the MTU to be used on workload facing devices. 153 func (c *Configuration) GetDeviceMTU() int { 154 if c.standardMTU == 0 { 155 return EthernetMTU 156 } 157 158 return c.standardMTU 159 }