2021-11-11 15:37:29 -07:00
package overlay
2019-11-19 10:00:20 -07:00
import (
2020-04-06 12:33:30 -06:00
"fmt"
2019-11-19 10:00:20 -07:00
"net"
"testing"
2020-04-06 12:33:30 -06:00
2021-11-03 19:54:04 -06:00
"github.com/slackhq/nebula/config"
2021-12-06 07:35:31 -07:00
"github.com/slackhq/nebula/iputil"
2021-11-10 20:47:38 -07:00
"github.com/slackhq/nebula/test"
2020-04-06 12:33:30 -06:00
"github.com/stretchr/testify/assert"
2019-11-19 10:00:20 -07:00
)
2021-11-12 10:19:28 -07:00
func Test_parseRoutes ( t * testing . T ) {
2021-11-10 20:47:38 -07:00
l := test . NewLogger ( )
2021-11-03 19:54:04 -06:00
c := config . NewC ( l )
2019-11-19 10:00:20 -07:00
_ , n , _ := net . ParseCIDR ( "10.0.0.0/24" )
// test no routes config
2021-11-12 10:19:28 -07:00
routes , err := parseRoutes ( c , n )
2019-11-19 10:00:20 -07:00
assert . Nil ( t , err )
assert . Len ( t , routes , 0 )
// not an array
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : "hi" }
2021-11-12 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07:00
assert . Nil ( t , err )
assert . Len ( t , routes , 0 )
// weird route
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "routes" : [ ] interface { } { "asdf" } }
2021-11-12 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07: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 10:19:28 -07:00
routes , err = parseRoutes ( c , n )
2019-11-19 10:00:20 -07:00
assert . Nil ( t , err )
assert . Len ( t , routes , 2 )
tested := 0
for _ , r := range routes {
2023-04-10 11:32:37 -06:00
assert . True ( t , r . Install )
2021-11-11 15:37:29 -07:00
if r . MTU == 8000 {
assert . Equal ( t , "10.0.0.1/32" , r . Cidr . String ( ) )
2019-11-19 10:00:20 -07:00
tested ++
} else {
2021-11-11 15:37:29 -07:00
assert . Equal ( t , 9000 , r . MTU )
assert . Equal ( t , "10.0.0.0/29" , r . Cidr . String ( ) )
2019-11-19 10:00:20 -07:00
tested ++
}
}
if tested != 2 {
t . Fatal ( "Did not see both routes" )
}
}
2020-04-06 12:33:30 -06:00
2021-11-12 10:19:28 -07:00
func Test_parseUnsafeRoutes ( t * testing . T ) {
2021-11-10 20:47:38 -07:00
l := test . NewLogger ( )
2021-11-03 19:54:04 -06:00
c := config . NewC ( l )
2020-04-06 12:33:30 -06:00
_ , n , _ := net . ParseCIDR ( "10.0.0.0/24" )
// test no routes config
2021-11-12 10:19:28 -07:00
routes , err := parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06:00
assert . Len ( t , routes , 1 )
2021-12-14 09:52:28 -07:00
assert . Equal ( t , 0 , routes [ 0 ] . MTU )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06: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 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06:00
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.mtu in tun.unsafe_routes is below 500: 499" )
2023-04-10 11:32:37 -06:00
// bad install
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" , "install" : "nope" } } }
routes , err = parseUnsafeRoutes ( c , n )
assert . Nil ( t , routes )
assert . EqualError ( t , err , "entry 1.install in tun.unsafe_routes is not a boolean: strconv.ParseBool: parsing \"nope\": invalid syntax" )
2020-04-06 12:33:30 -06:00
// happy case
c . Settings [ "tun" ] = map [ interface { } ] interface { } { "unsafe_routes" : [ ] interface { } {
2023-04-10 11:32:37 -06:00
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "9000" , "route" : "1.0.0.0/29" , "install" : "t" } ,
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "8000" , "route" : "1.0.0.1/32" , "install" : 0 } ,
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "1500" , "metric" : 1234 , "route" : "1.0.0.2/32" , "install" : 1 } ,
2021-11-03 20:53:28 -06:00
map [ interface { } ] interface { } { "via" : "127.0.0.1" , "mtu" : "1500" , "metric" : 1234 , "route" : "1.0.0.2/32" } ,
2020-04-06 12:33:30 -06:00
} }
2021-11-12 10:19:28 -07:00
routes , err = parseUnsafeRoutes ( c , n )
2020-04-06 12:33:30 -06:00
assert . Nil ( t , err )
2023-04-10 11:32:37 -06:00
assert . Len ( t , routes , 4 )
2020-04-06 12:33:30 -06:00
tested := 0
for _ , r := range routes {
2021-11-11 15:37:29 -07:00
if r . MTU == 8000 {
assert . Equal ( t , "1.0.0.1/32" , r . Cidr . String ( ) )
2023-04-10 11:32:37 -06:00
assert . False ( t , r . Install )
2020-04-06 12:33:30 -06:00
tested ++
2021-11-11 15:37:29 -07:00
} else if r . MTU == 9000 {
assert . Equal ( t , 9000 , r . MTU )
assert . Equal ( t , "1.0.0.0/29" , r . Cidr . String ( ) )
2023-04-10 11:32:37 -06:00
assert . True ( t , r . Install )
2020-04-06 12:33:30 -06:00
tested ++
2021-11-03 20:53:28 -06:00
} else {
2021-11-11 15:37:29 -07:00
assert . Equal ( t , 1500 , r . MTU )
assert . Equal ( t , 1234 , r . Metric )
assert . Equal ( t , "1.0.0.2/32" , r . Cidr . String ( ) )
2023-04-10 11:32:37 -06:00
assert . True ( t , r . Install )
2021-11-03 20:53:28 -06:00
tested ++
2020-04-06 12:33:30 -06:00
}
}
2023-04-10 11:32:37 -06:00
if tested != 4 {
t . Fatal ( "Did not see all unsafe_routes" )
2020-04-06 12:33:30 -06:00
}
}
2021-12-06 07:35:31 -07: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 )
2021-12-14 09:52:28 -07:00
routeTree , err := makeRouteTree ( l , routes , true )
2021-12-06 07:35:31 -07:00
assert . NoError ( t , err )
ip := iputil . Ip2VpnIp ( net . ParseIP ( "1.0.0.2" ) )
2023-11-02 16:05:08 -06:00
ok , r := routeTree . MostSpecificContains ( ip )
assert . True ( t , ok )
assert . Equal ( t , iputil . Ip2VpnIp ( net . ParseIP ( "192.168.0.1" ) ) , r )
2021-12-06 07:35:31 -07:00
ip = iputil . Ip2VpnIp ( net . ParseIP ( "1.0.0.1" ) )
2023-11-02 16:05:08 -06:00
ok , r = routeTree . MostSpecificContains ( ip )
assert . True ( t , ok )
assert . Equal ( t , iputil . Ip2VpnIp ( net . ParseIP ( "192.168.0.2" ) ) , r )
2021-12-06 07:35:31 -07:00
ip = iputil . Ip2VpnIp ( net . ParseIP ( "1.1.0.1" ) )
2023-11-02 16:05:08 -06:00
ok , r = routeTree . MostSpecificContains ( ip )
assert . False ( t , ok )
2021-12-06 07:35:31 -07:00
}