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
|
removal of root trust). Default is `false`. Note, this will not currently recognize if a remote has changed
|
||||||
certificates since the last handshake. (#370)
|
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
|
### Changed
|
||||||
|
|
||||||
- Build against go 1.17. (#553)
|
- 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 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
|
# 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
|
# 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:
|
unsafe_routes:
|
||||||
#- route: 172.16.1.0/24
|
#- route: 172.16.1.0/24
|
||||||
# via: 192.168.100.99
|
# via: 192.168.100.99
|
||||||
# mtu: 1300 #mtu will default to tun mtu if this option is not sepcified
|
# mtu: 1300
|
||||||
|
# metric: 100
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
|
@ -2,6 +2,7 @@ package nebula
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ const DEFAULT_MTU = 1300
|
||||||
|
|
||||||
type route struct {
|
type route struct {
|
||||||
mtu int
|
mtu int
|
||||||
|
metric int
|
||||||
route *net.IPNet
|
route *net.IPNet
|
||||||
via *net.IP
|
via *net.IP
|
||||||
}
|
}
|
||||||
|
@ -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)
|
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"]
|
rVia, ok := m["via"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("entry %v.via in tun.unsafe_routes is not present", i+1)
|
return nil, fmt.Errorf("entry %v.via in tun.unsafe_routes is not present", i+1)
|
||||||
|
@ -150,6 +169,7 @@ func parseUnsafeRoutes(c *config.C, network *net.IPNet) ([]route, error) {
|
||||||
r := route{
|
r := route{
|
||||||
via: &nVia,
|
via: &nVia,
|
||||||
mtu: mtu,
|
mtu: mtu,
|
||||||
|
metric: metric,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, r.route, err = net.ParseCIDR(fmt.Sprintf("%v", rRoute))
|
_, r.route, err = net.ParseCIDR(fmt.Sprintf("%v", rRoute))
|
||||||
|
|
|
@ -300,6 +300,7 @@ func (c Tun) Activate() error {
|
||||||
LinkIndex: link.Attrs().Index,
|
LinkIndex: link.Attrs().Index,
|
||||||
Dst: r.route,
|
Dst: r.route,
|
||||||
MTU: r.mtu,
|
MTU: r.mtu,
|
||||||
|
Priority: r.metric,
|
||||||
AdvMSS: c.advMSS(r),
|
AdvMSS: c.advMSS(r),
|
||||||
Scope: unix.RT_SCOPE_LINK,
|
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{}{
|
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": "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": "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)
|
routes, err = parseUnsafeRoutes(c, n)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, routes, 2)
|
assert.Len(t, routes, 3)
|
||||||
|
|
||||||
tested := 0
|
tested := 0
|
||||||
for _, r := range routes {
|
for _, r := range routes {
|
||||||
if r.mtu == 8000 {
|
if r.mtu == 8000 {
|
||||||
assert.Equal(t, "1.0.0.1/32", r.route.String())
|
assert.Equal(t, "1.0.0.1/32", r.route.String())
|
||||||
tested++
|
tested++
|
||||||
} else {
|
} else if r.mtu == 9000 {
|
||||||
assert.Equal(t, 9000, r.mtu)
|
assert.Equal(t, 9000, r.mtu)
|
||||||
assert.Equal(t, "1.0.0.0/29", r.route.String())
|
assert.Equal(t, "1.0.0.0/29", r.route.String())
|
||||||
tested++
|
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")
|
t.Fatal("Did not see both unsafe_routes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ func (c *Tun) Activate() error {
|
||||||
|
|
||||||
for _, r := range c.UnsafeRoutes {
|
for _, r := range c.UnsafeRoutes {
|
||||||
err = exec.Command(
|
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()
|
).Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to add the unsafe_route %s: %v", r.route.String(), err)
|
return fmt.Errorf("failed to add the unsafe_route %s: %v", r.route.String(), err)
|
||||||
|
|
Loading…
Reference in New Issue