@@ -31,6 +31,7 @@ type tun struct {
3131 DefaultMTU int
3232 TXQueueLen int
3333 deviceIndex int
34+ ioctlFd uintptr
3435
3536 Routes atomic.Pointer [[]Route ]
3637 routeTree atomic.Pointer [cidr.Tree4 [iputil.VpnIp ]]
@@ -110,7 +111,6 @@ func newTunGeneric(c *config.C, l *logrus.Logger, file *os.File, cidr *net.IPNet
110111 ReadWriteCloser : file ,
111112 fd : int (file .Fd ()),
112113 cidr : cidr ,
113- DefaultMTU : c .GetInt ("tun.mtu" , DefaultMTU ),
114114 TXQueueLen : c .GetInt ("tun.tx_queue" , 500 ),
115115 useSystemRoutes : c .GetBool ("tun.use_system_route_table" , false ),
116116 l : l ,
@@ -132,12 +132,12 @@ func newTunGeneric(c *config.C, l *logrus.Logger, file *os.File, cidr *net.IPNet
132132}
133133
134134func (t * tun ) reload (c * config.C , initial bool ) error {
135- change , routes , err := getAllRoutesFromConfig (c , t .cidr , initial )
135+ routeChange , routes , err := getAllRoutesFromConfig (c , t .cidr , initial )
136136 if err != nil {
137137 return err
138138 }
139139
140- if ! initial && ! change {
140+ if ! initial && ! routeChange && ! c . HasChanged ( "tun.mtu" ) {
141141 return nil
142142 }
143143
@@ -146,24 +146,42 @@ func (t *tun) reload(c *config.C, initial bool) error {
146146 return err
147147 }
148148
149+ oldDefaultMTU := t .DefaultMTU
150+ oldMaxMTU := t .MaxMTU
151+ newDefaultMTU := c .GetInt ("tun.mtu" , DefaultMTU )
152+ newMaxMTU := newDefaultMTU
149153 for i , r := range routes {
150154 if r .MTU == 0 {
151- //TODO: This was horribly broken before, I have doubts anyone is using it
152- routes [i ].MTU = t .DefaultMTU
155+ routes [i ].MTU = newDefaultMTU
153156 }
154157
155158 if r .MTU > t .MaxMTU {
156- //TODO: This needs to be atomic but it is not used so maybe its fine?
157- //TODO: this is also not handled since it would adjust the main route and device mtu
158- t .MaxMTU = r .MTU
159+ newMaxMTU = r .MTU
159160 }
160161 }
161162
163+ t .MaxMTU = newMaxMTU
164+ t .DefaultMTU = newDefaultMTU
165+
162166 // Teach nebula how to handle the routes before establishing them in the system table
163167 oldRoutes := t .Routes .Swap (& routes )
164168 t .routeTree .Store (routeTree )
165169
166170 if ! initial {
171+ if oldMaxMTU != newMaxMTU {
172+ t .setMTU ()
173+ t .l .Infof ("Set max MTU to %v was %v" , t .MaxMTU , oldMaxMTU )
174+ }
175+
176+ if oldDefaultMTU != newDefaultMTU {
177+ err := t .setDefaultRoute ()
178+ if err != nil {
179+ t .l .Warn (err )
180+ } else {
181+ t .l .Infof ("Set default MTU to %v was %v" , t .DefaultMTU , oldDefaultMTU )
182+ }
183+ }
184+
167185 // Remove first, if the system removes a wanted route hopefully it will be re-added next
168186 t .removeRoutes (findRemovedRoutes (routes , * oldRoutes ))
169187
@@ -251,7 +269,7 @@ func (t *tun) Activate() error {
251269 if err != nil {
252270 return err
253271 }
254- fd : = uintptr (s )
272+ t . ioctlFd = uintptr (s )
255273
256274 ifra := ifreqAddr {
257275 Name : devName ,
@@ -262,50 +280,72 @@ func (t *tun) Activate() error {
262280 }
263281
264282 // Set the device ip address
265- if err = ioctl (fd , unix .SIOCSIFADDR , uintptr (unsafe .Pointer (& ifra ))); err != nil {
283+ if err = ioctl (t . ioctlFd , unix .SIOCSIFADDR , uintptr (unsafe .Pointer (& ifra ))); err != nil {
266284 return fmt .Errorf ("failed to set tun address: %s" , err )
267285 }
268286
269287 // Set the device network
270288 ifra .Addr .Addr = mask
271- if err = ioctl (fd , unix .SIOCSIFNETMASK , uintptr (unsafe .Pointer (& ifra ))); err != nil {
289+ if err = ioctl (t . ioctlFd , unix .SIOCSIFNETMASK , uintptr (unsafe .Pointer (& ifra ))); err != nil {
272290 return fmt .Errorf ("failed to set tun netmask: %s" , err )
273291 }
274292
275293 // Set the device name
276294 ifrf := ifReq {Name : devName }
277- if err = ioctl (fd , unix .SIOCGIFFLAGS , uintptr (unsafe .Pointer (& ifrf ))); err != nil {
295+ if err = ioctl (t . ioctlFd , unix .SIOCGIFFLAGS , uintptr (unsafe .Pointer (& ifrf ))); err != nil {
278296 return fmt .Errorf ("failed to set tun device name: %s" , err )
279297 }
280298
281- // Set the MTU on the device
282- ifm := ifreqMTU {Name : devName , MTU : int32 (t .MaxMTU )}
283- if err = ioctl (fd , unix .SIOCSIFMTU , uintptr (unsafe .Pointer (& ifm ))); err != nil {
284- // This is currently a non fatal condition because the route table must have the MTU set appropriately as well
285- t .l .WithError (err ).Error ("Failed to set tun mtu" )
286- }
299+ // Setup our default MTU
300+ t .setMTU ()
287301
288302 // Set the transmit queue length
289303 ifrq := ifreqQLEN {Name : devName , Value : int32 (t .TXQueueLen )}
290- if err = ioctl (fd , unix .SIOCSIFTXQLEN , uintptr (unsafe .Pointer (& ifrq ))); err != nil {
304+ if err = ioctl (t . ioctlFd , unix .SIOCSIFTXQLEN , uintptr (unsafe .Pointer (& ifrq ))); err != nil {
291305 // If we can't set the queue length nebula will still work but it may lead to packet loss
292306 t .l .WithError (err ).Error ("Failed to set tun tx queue length" )
293307 }
294308
295309 // Bring up the interface
296310 ifrf .Flags = ifrf .Flags | unix .IFF_UP
297- if err = ioctl (fd , unix .SIOCSIFFLAGS , uintptr (unsafe .Pointer (& ifrf ))); err != nil {
311+ if err = ioctl (t . ioctlFd , unix .SIOCSIFFLAGS , uintptr (unsafe .Pointer (& ifrf ))); err != nil {
298312 return fmt .Errorf ("failed to bring the tun device up: %s" , err )
299313 }
300314
301- // Set the routes
302315 link , err := netlink .LinkByName (t .Device )
303316 if err != nil {
304317 return fmt .Errorf ("failed to get tun device link: %s" , err )
305318 }
306-
307319 t .deviceIndex = link .Attrs ().Index
308320
321+ if err = t .setDefaultRoute (); err != nil {
322+ return err
323+ }
324+
325+ // Set the routes
326+ if err = t .addRoutes (false ); err != nil {
327+ return err
328+ }
329+
330+ // Run the interface
331+ ifrf .Flags = ifrf .Flags | unix .IFF_UP | unix .IFF_RUNNING
332+ if err = ioctl (t .ioctlFd , unix .SIOCSIFFLAGS , uintptr (unsafe .Pointer (& ifrf ))); err != nil {
333+ return fmt .Errorf ("failed to run tun device: %s" , err )
334+ }
335+
336+ return nil
337+ }
338+
339+ func (t * tun ) setMTU () {
340+ // Set the MTU on the device
341+ ifm := ifreqMTU {Name : t .deviceBytes (), MTU : int32 (t .MaxMTU )}
342+ if err := ioctl (t .ioctlFd , unix .SIOCSIFMTU , uintptr (unsafe .Pointer (& ifm ))); err != nil {
343+ // This is currently a non fatal condition because the route table must have the MTU set appropriately as well
344+ t .l .WithError (err ).Error ("Failed to set tun mtu" )
345+ }
346+ }
347+
348+ func (t * tun ) setDefaultRoute () error {
309349 // Default route
310350 dr := & net.IPNet {IP : t .cidr .IP .Mask (t .cidr .Mask ), Mask : t .cidr .Mask }
311351 nr := netlink.Route {
@@ -319,22 +359,11 @@ func (t *tun) Activate() error {
319359 Table : unix .RT_TABLE_MAIN ,
320360 Type : unix .RTN_UNICAST ,
321361 }
322- err = netlink .RouteReplace (& nr )
362+ err : = netlink .RouteReplace (& nr )
323363 if err != nil {
324364 return fmt .Errorf ("failed to set mtu %v on the default route %v; %v" , t .DefaultMTU , dr , err )
325365 }
326366
327- err = t .addRoutes (false )
328- if err != nil {
329- return err
330- }
331-
332- // Run the interface
333- ifrf .Flags = ifrf .Flags | unix .IFF_UP | unix .IFF_RUNNING
334- if err = ioctl (fd , unix .SIOCSIFFLAGS , uintptr (unsafe .Pointer (& ifrf ))); err != nil {
335- return fmt .Errorf ("failed to run tun device: %s" , err )
336- }
337-
338367 return nil
339368}
340369
@@ -499,5 +528,9 @@ func (t *tun) Close() error {
499528 t .ReadWriteCloser .Close ()
500529 }
501530
531+ if t .ioctlFd > 0 {
532+ os .NewFile (t .ioctlFd , "ioctlFd" ).Close ()
533+ }
534+
502535 return nil
503536}
0 commit comments