44package overlay
55
66import (
7+ "errors"
78 "fmt"
89 "io"
910 "net"
@@ -101,12 +102,18 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu
101102 }
102103 }
103104
105+ tunNameTemplate := c .GetString ("tun.dev" , "nebula%d" )
106+ tunName , err := findNextTunName (tunNameTemplate )
107+ if err != nil {
108+ return nil , err
109+ }
110+
104111 var req ifReq
105112 req .Flags = uint16 (unix .IFF_TUN | unix .IFF_NO_PI )
106113 if multiqueue {
107114 req .Flags |= unix .IFF_MULTI_QUEUE
108115 }
109- copy (req .Name [:], c . GetString ( "tun.dev" , "" ) )
116+ copy (req .Name [:], tunName )
110117 if err = ioctl (uintptr (fd ), uintptr (unix .TUNSETIFF ), uintptr (unsafe .Pointer (& req ))); err != nil {
111118 return nil , err
112119 }
@@ -123,6 +130,38 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu
123130 return t , nil
124131}
125132
133+ func findNextTunName (tunName string ) (string , error ) {
134+ if ! strings .HasSuffix (tunName , "%d" ) {
135+ return tunName , nil
136+ }
137+ if len (tunName ) == 2 {
138+ return "" , errors .New ("please don't name your tun device '%d'" )
139+ }
140+ tunNameTemplate := tunName [:len (tunName )- 2 ]
141+ links , err := netlink .LinkList ()
142+ if err != nil {
143+ return "" , err
144+ }
145+ var candidateName string
146+ for i := 0 ; i < 100000 ; i ++ {
147+ candidateName = fmt .Sprintf ("%s%d" , tunNameTemplate , i )
148+ good := true
149+ for _ , link := range links {
150+ if candidateName == link .Attrs ().Name {
151+ good = false
152+ break
153+ }
154+ }
155+ if good {
156+ if len (candidateName ) > 16 {
157+ return "" , errors .New ("you have too many nebula networks" )
158+ }
159+ return candidateName , nil
160+ }
161+ }
162+ return "" , errors .New ("failed to find a tun device name" )
163+ }
164+
126165func newTunGeneric (c * config.C , l * logrus.Logger , file * os.File , vpnNetworks []netip.Prefix ) (* tun , error ) {
127166 t := & tun {
128167 ReadWriteCloser : file ,
@@ -582,9 +621,7 @@ func (t *tun) isGatewayInVpnNetworks(gwAddr netip.Addr) bool {
582621}
583622
584623func (t * tun ) getGatewaysFromRoute (r * netlink.Route ) routing.Gateways {
585-
586624 var gateways routing.Gateways
587-
588625 link , err := netlink .LinkByName (t .Device )
589626 if err != nil {
590627 t .l .WithField ("Devicename" , t .Device ).Error ("Ignoring route update: failed to get link by name" )
@@ -633,9 +670,7 @@ func (t *tun) getGatewaysFromRoute(r *netlink.Route) routing.Gateways {
633670}
634671
635672func (t * tun ) updateRoutes (r netlink.RouteUpdate ) {
636-
637673 gateways := t .getGatewaysFromRoute (& r .Route )
638-
639674 if len (gateways ) == 0 {
640675 // No gateways relevant to our network, no routing changes required.
641676 t .l .WithField ("route" , r ).Debug ("Ignoring route update, no gateways" )
0 commit comments