Add an ability to specify metric for unsafe routes (#474)
This commit is contained in:
parent
bcabcfdaca
commit
b358bbab80
|
@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
removal of root trust). Default is `false`. Note, this will not currently recognize if a remote has changed
|
||||
certificates since the last handshake. (#370)
|
||||
|
||||
- New config option `unsafe_routes.<route>.metric` will set a metric for a specific unsafe route. It's useful if you have
|
||||
more than one identical route and want to prefer one against the other.
|
||||
|
||||
### Changed
|
||||
|
||||
- Build against go 1.17. (#553)
|
||||
|
|
|
@ -165,10 +165,13 @@ tun:
|
|||
# Unsafe routes allows you to route traffic over nebula to non-nebula nodes
|
||||
# Unsafe routes should be avoided unless you have hosts/services that cannot run nebula
|
||||
# NOTE: The nebula certificate of the "via" node *MUST* have the "route" defined as a subnet in its certificate
|
||||
# `mtu` will default to tun mtu if this option is not specified
|
||||
# `metric` will default to 0 if this option is not specified
|
||||
unsafe_routes:
|
||||
#- route: 172.16.1.0/24
|
||||
# via: 192.168.100.99
|
||||
# mtu: 1300 #mtu will default to tun mtu if this option is not sepcified
|
||||
# mtu: 1300
|
||||
# metric: 100
|
||||
|
||||
|
||||
# TODO
|
||||
|
|
|
@ -2,6 +2,7 @@ package nebula
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
|
@ -11,9 +12,10 @@ import (
|
|||
const DEFAULT_MTU = 1300
|
||||
|
||||
type route struct {
|
||||
mtu int
|
||||
route *net.IPNet
|
||||
via *net.IP
|
||||
mtu int
|
||||
metric int
|
||||
route *net.IPNet
|
||||
via *net.IP
|
||||
}
|
||||
|
||||
func parseRoutes(c *config.C, network *net.IPNet) ([]route, error) {
|
||||
|
@ -127,6 +129,23 @@ func parseUnsafeRoutes(c *config.C, network *net.IPNet) ([]route, error) {
|
|||
return nil, fmt.Errorf("entry %v.mtu in tun.unsafe_routes is below 500: %v", i+1, mtu)
|
||||
}
|
||||
|
||||
rMetric, ok := m["metric"]
|
||||
if !ok {
|
||||
rMetric = 0
|
||||
}
|
||||
|
||||
metric, ok := rMetric.(int)
|
||||
if !ok {
|
||||
_, err = strconv.ParseInt(rMetric.(string), 10, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("entry %v.metric in tun.unsafe_routes is not an integer: %v", i+1, err)
|
||||
}
|
||||
}
|
||||
|
||||
if metric < 0 || metric > math.MaxInt32 {
|
||||
return nil, fmt.Errorf("entry %v.metric in tun.unsafe_routes is not in range (0-%d) : %v", i+1, math.MaxInt32, metric)
|
||||
}
|
||||
|
||||
rVia, ok := m["via"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("entry %v.via in tun.unsafe_routes is not present", i+1)
|
||||
|
@ -148,8 +167,9 @@ func parseUnsafeRoutes(c *config.C, network *net.IPNet) ([]route, error) {
|
|||
}
|
||||
|
||||
r := route{
|
||||
via: &nVia,
|
||||
mtu: mtu,
|
||||
via: &nVia,
|
||||
mtu: mtu,
|
||||
metric: metric,
|
||||
}
|
||||
|
||||
_, r.route, err = net.ParseCIDR(fmt.Sprintf("%v", rRoute))
|
||||
|
|
|
@ -300,6 +300,7 @@ func (c Tun) Activate() error {
|
|||
LinkIndex: link.Attrs().Index,
|
||||
Dst: r.route,
|
||||
MTU: r.mtu,
|
||||
Priority: r.metric,
|
||||
AdvMSS: c.advMSS(r),
|
||||
Scope: unix.RT_SCOPE_LINK,
|
||||
}
|
||||
|
|
12
tun_test.go
12
tun_test.go
|
@ -208,24 +208,30 @@ func Test_parseUnsafeRoutes(t *testing.T) {
|
|||
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"},
|
||||
map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "1500", "metric": 1234, "route": "1.0.0.2/32"},
|
||||
}}
|
||||
routes, err = parseUnsafeRoutes(c, n)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, routes, 2)
|
||||
assert.Len(t, routes, 3)
|
||||
|
||||
tested := 0
|
||||
for _, r := range routes {
|
||||
if r.mtu == 8000 {
|
||||
assert.Equal(t, "1.0.0.1/32", r.route.String())
|
||||
tested++
|
||||
} else {
|
||||
} else if r.mtu == 9000 {
|
||||
assert.Equal(t, 9000, r.mtu)
|
||||
assert.Equal(t, "1.0.0.0/29", r.route.String())
|
||||
tested++
|
||||
} else {
|
||||
assert.Equal(t, 1500, r.mtu)
|
||||
assert.Equal(t, 1234, r.metric)
|
||||
assert.Equal(t, "1.0.0.2/32", r.route.String())
|
||||
tested++
|
||||
}
|
||||
}
|
||||
|
||||
if tested != 2 {
|
||||
if tested != 3 {
|
||||
t.Fatal("Did not see both unsafe_routes")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ func (c *Tun) Activate() error {
|
|||
|
||||
for _, r := range c.UnsafeRoutes {
|
||||
err = exec.Command(
|
||||
"C:\\Windows\\System32\\route.exe", "add", r.route.String(), r.via.String(), "IF", strconv.Itoa(iface.Index),
|
||||
"C:\\Windows\\System32\\route.exe", "add", r.route.String(), r.via.String(), "IF", strconv.Itoa(iface.Index), "METRIC", strconv.Itoa(r.metric),
|
||||
).Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add the unsafe_route %s: %v", r.route.String(), err)
|
||||
|
|
Loading…
Reference in New Issue