2021-11-11 23:37:29 +01:00
package overlay
2019-11-19 18:00:20 +01:00
import (
2020-04-06 20:33:30 +02:00
"fmt"
2019-11-19 18:00:20 +01:00
"net"
"testing"
2020-04-06 20:33:30 +02:00
2021-11-04 02:54:04 +01:00
"github.com/slackhq/nebula/config"
2021-12-06 15:35:31 +01:00
"github.com/slackhq/nebula/iputil"
2021-11-11 04:47:38 +01:00
"github.com/slackhq/nebula/test"
2020-04-06 20:33:30 +02:00
"github.com/stretchr/testify/assert"
2019-11-19 18:00:20 +01:00
)
2021-11-12 18:19:28 +01:00
func Test_parseRoutes ( t * testing . T ) {
2021-11-11 04:47:38 +01:00
l := test . NewLogger ( )
2021-11-04 02:54:04 +01:00
c := config . NewC ( l )
2019-11-19 18:00:20 +01:00
_ , n , _ := net . ParseCIDR ( "10.0.0.0/24" )
// test no routes config
2021-11-12 18:19:28 +01:00
routes , err := parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , err )
assert . Len ( t , routes , 0 )
// not an array
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : "hi" }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "tun.routes is not an array" )
// no routes
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , err )
assert . Len ( t , routes , 0 )
// weird route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { "asdf" } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1 in tun.routes is invalid" )
// no mtu
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.mtu in tun.routes is not present" )
// bad mtu
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "nope" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.mtu in tun.routes is not an integer: strconv.Atoi: parsing \"nope\": invalid syntax" )
// low mtu
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "499" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.mtu in tun.routes is below 500: 499" )
// missing route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "500" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.routes is not present" )
// unparsable route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "500" , "route" : "nope" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.routes failed to parse: invalid CIDR address: nope" )
// below network range
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "500" , "route" : "1.0.0.0/8" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.routes is not contained within the network attached to the certificate; route: 1.0.0.0/8, network: 10.0.0.0/24" )
// above network range
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "500" , "route" : "10.0.1.0/24" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.routes is not contained within the network attached to the certificate; route: 10.0.1.0/24, network: 10.0.0.0/24" )
// happy case
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } {
map [ interface { } ] interface { } { "mtu" : "9000" , "route" : "10.0.0.0/29" } ,
map [ interface { } ] interface { } { "mtu" : "8000" , "route" : "10.0.0.1/32" } ,
} }
2021-11-12 18:19:28 +01:00
routes , err = parseRoutes ( c , n )
2019-11-19 18:00:20 +01:00
assert . Nil ( t , err )
assert . Len ( t , routes , 2 )
tested := 0
for _ , r := range routes {
2021-11-11 23:37:29 +01:00
if r . MTU == 8000 {
assert . Equal ( t , "10.0.0.1/32" , r . Cidr . String ( ) )
2019-11-19 18:00:20 +01:00
tested ++
} else {
2021-11-11 23:37:29 +01:00
assert . Equal ( t , 9000 , r . MTU )
assert . Equal ( t , "10.0.0.0/29" , r . Cidr . String ( ) )
2019-11-19 18:00:20 +01:00
tested ++
}
}
if tested != 2 {
t . Fatal ( "Did not see both routes" )
}
}
2020-04-06 20:33:30 +02:00
2021-11-12 18:19:28 +01:00
func Test_parseUnsafeRoutes ( t * testing . T ) {
2021-11-11 04:47:38 +01:00
l := test . NewLogger ( )
2021-11-04 02:54:04 +01:00
c := config . NewC ( l )
2020-04-06 20:33:30 +02:00
_ , n , _ := net . ParseCIDR ( "10.0.0.0/24" )
// test no routes config
2021-11-12 18:19:28 +01:00
routes , err := parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , err )
assert . Len ( t , routes , 0 )
// not an array
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : "hi" }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "tun.unsafe_routes is not an array" )
// no routes
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , err )
assert . Len ( t , routes , 0 )
// weird route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { "asdf" } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1 in tun.unsafe_routes is invalid" )
// no via
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.via in tun.unsafe_routes is not present" )
// invalid via
for _ , invalidValue := range [ ] interface { } {
127 , false , nil , 1.0 , [ ] string { "1" , "2" } ,
} {
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : invalidValue } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , fmt . Sprintf ( "entry 1.via in tun.unsafe_routes is not a string: found %T" , invalidValue ) )
}
// unparsable via
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "mtu" : "500" , "via" : "nope" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.via in tun.unsafe_routes failed to parse address: nope" )
// missing route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "500" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.unsafe_routes is not present" )
// unparsable route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "500" , "route" : "nope" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.unsafe_routes failed to parse: invalid CIDR address: nope" )
// within network range
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "route" : "10.0.0.0/24" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.route in tun.unsafe_routes is contained within the network attached to the certificate; route: 10.0.0.0/24, network: 10.0.0.0/24" )
// below network range
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "route" : "1.0.0.0/8" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Len ( t , routes , 1 )
assert . Nil ( t , err )
// above network range
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "route" : "10.0.1.0/24" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Len ( t , routes , 1 )
assert . Nil ( t , err )
// no mtu
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "route" : "1.0.0.0/8" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Len ( t , routes , 1 )
2021-11-11 23:37:29 +01:00
assert . Equal ( t , DefaultMTU , routes [ 0 ] . MTU )
2020-04-06 20:33:30 +02:00
// bad mtu
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "nope" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.mtu in tun.unsafe_routes is not an integer: strconv.Atoi: parsing \"nope\": invalid syntax" )
// low mtu
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } { map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "499" } } }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.mtu in tun.unsafe_routes is below 500: 499" )
// happy case
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } {
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "9000" , "route" : "1.0.0.0/29" } ,
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "8000" , "route" : "1.0.0.1/32" } ,
2021-11-04 03:53:28 +01:00
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "1500" , "metric" : 1234 , "route" : "1.0.0.2/32" } ,
2020-04-06 20:33:30 +02:00
} }
2021-11-12 18:19:28 +01:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 20:33:30 +02:00
assert . Nil ( t , err )
2021-11-04 03:53:28 +01:00
assert . Len ( t , routes , 3 )
2020-04-06 20:33:30 +02:00
tested := 0
for _ , r := range routes {
2021-11-11 23:37:29 +01:00
if r . MTU == 8000 {
assert . Equal ( t , "1.0.0.1/32" , r . Cidr . String ( ) )
2020-04-06 20:33:30 +02:00
tested ++
2021-11-11 23:37:29 +01:00
} else if r . MTU == 9000 {
assert . Equal ( t , 9000 , r . MTU )
assert . Equal ( t , "1.0.0.0/29" , r . Cidr . String ( ) )
2020-04-06 20:33:30 +02:00
tested ++
2021-11-04 03:53:28 +01:00
} else {
2021-11-11 23:37:29 +01:00
assert . Equal ( t , 1500 , r . MTU )
assert . Equal ( t , 1234 , r . Metric )
assert . Equal ( t , "1.0.0.2/32" , r . Cidr . String ( ) )
2021-11-04 03:53:28 +01:00
tested ++
2020-04-06 20:33:30 +02:00
}
}
2021-11-04 03:53:28 +01:00
if tested != 3 {
2020-04-06 20:33:30 +02:00
t . Fatal ( "Did not see both unsafe_routes" )
}
}
2021-12-06 15:35:31 +01:00
func Test_makeRouteTree ( t * testing . T ) {
l := test . NewLogger ( )
c := config . NewC ( l )
_ , n , _ := net . ParseCIDR ( "10.0.0.0/24" )
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } {
map [ interface { } ] interface { } { "via" : "192.168.0.1" , "route" : "1.0.0.0/28" } ,
map [ interface { } ] interface { } { "via" : "192.168.0.2" , "route" : "1.0.0.1/32" } ,
} }
routes , err := parseUnsafeRoutes ( c , n )
assert . NoError ( t , err )
assert . Len ( t , routes , 2 )
routeTree , err := makeRouteTree ( routes , true )
assert . NoError ( t , err )
ip := iputil . Ip2VpnIp ( net . ParseIP ( "1.0.0.2" ) )
r := routeTree . MostSpecificContains ( ip )
assert . NotNil ( t , r )
assert . IsType ( t , iputil . VpnIp ( 0 ) , r )
assert . EqualValues ( t , iputil . Ip2VpnIp ( net . ParseIP ( "192.168.0.1" ) ) , r )
ip = iputil . Ip2VpnIp ( net . ParseIP ( "1.0.0.1" ) )
r = routeTree . MostSpecificContains ( ip )
assert . NotNil ( t , r )
assert . IsType ( t , iputil . VpnIp ( 0 ) , r )
assert . EqualValues ( t , iputil . Ip2VpnIp ( net . ParseIP ( "192.168.0.2" ) ) , r )
ip = iputil . Ip2VpnIp ( net . ParseIP ( "1.1.0.1" ) )
r = routeTree . MostSpecificContains ( ip )
assert . Nil ( t , r )
}