|
|
@@ -0,0 +1,851 @@
|
|
|
+// Copyright 2019 the Kilo authors
|
|
|
+//
|
|
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+// you may not use this file except in compliance with the License.
|
|
|
+// You may obtain a copy of the License at
|
|
|
+//
|
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+//
|
|
|
+// Unless required by applicable law or agreed to in writing, software
|
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+// See the License for the specific language governing permissions and
|
|
|
+// limitations under the License.
|
|
|
+
|
|
|
+package mesh
|
|
|
+
|
|
|
+import (
|
|
|
+ "testing"
|
|
|
+
|
|
|
+ "github.com/kylelemons/godebug/pretty"
|
|
|
+ "github.com/vishvananda/netlink"
|
|
|
+ "golang.org/x/sys/unix"
|
|
|
+
|
|
|
+ "github.com/squat/kilo/pkg/encapsulation"
|
|
|
+)
|
|
|
+
|
|
|
+func TestRoutes(t *testing.T) {
|
|
|
+ nodes, peers, key, port := setup(t)
|
|
|
+ kiloIface := 0
|
|
|
+ privIface := 1
|
|
|
+ tunlIface := 2
|
|
|
+ mustTopoForGranularityAndHost := func(granularity Granularity, hostname string) *Topology {
|
|
|
+ return mustTopo(t, nodes, peers, granularity, hostname, port, key, DefaultKiloSubnet, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, tc := range []struct {
|
|
|
+ name string
|
|
|
+ local bool
|
|
|
+ topology *Topology
|
|
|
+ strategy encapsulation.Strategy
|
|
|
+ routes []*netlink.Route
|
|
|
+ rules []*netlink.Rule
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ name: "logical from a",
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].cidrs[1],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from b",
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from c",
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "full from a",
|
|
|
+ topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "full from b",
|
|
|
+ topology: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "full from c",
|
|
|
+ topology: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].cidrs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from a local",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["c"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from a local always",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name),
|
|
|
+ strategy: encapsulation.Always,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["c"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from b local",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["a"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["c"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["c"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from b local always",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name),
|
|
|
+ strategy: encapsulation.Always,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["a"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["c"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["c"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["c"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ Table: kiloTableIndex,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ rules: []*netlink.Rule{
|
|
|
+ defaultRule(&netlink.Rule{
|
|
|
+ Src: nodes["b"].Subnet,
|
|
|
+ Dst: nodes["c"].InternalIP,
|
|
|
+ Table: kiloTableIndex,
|
|
|
+ }),
|
|
|
+ defaultRule(&netlink.Rule{
|
|
|
+ Dst: nodes["c"].InternalIP,
|
|
|
+ IifName: DefaultKiloInterface,
|
|
|
+ Table: kiloTableIndex,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from c local",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["a"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: privIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "logical from c local always",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name),
|
|
|
+ strategy: encapsulation.Always,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[0].wireGuardIP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["a"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[1].wireGuardIP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].InternalIP,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ Table: kiloTableIndex,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: nodes["b"].InternalIP.IP,
|
|
|
+ LinkIndex: tunlIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ rules: []*netlink.Rule{
|
|
|
+ defaultRule(&netlink.Rule{
|
|
|
+ Src: nodes["c"].Subnet,
|
|
|
+ Dst: nodes["b"].InternalIP,
|
|
|
+ Table: kiloTableIndex,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "full from a local",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["c"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "full from b local",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["a"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["c"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["c"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "full from c local",
|
|
|
+ local: true,
|
|
|
+ topology: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name),
|
|
|
+ strategy: encapsulation.Never,
|
|
|
+ routes: []*netlink.Route{
|
|
|
+ {
|
|
|
+ Dst: nodes["a"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["a"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[0].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: nodes["b"].Subnet,
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: oneAddressCIDR(nodes["b"].InternalIP.IP),
|
|
|
+ Flags: int(netlink.FLAG_ONLINK),
|
|
|
+ Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[1].wireGuardIP,
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["a"].AllowedIPs[1],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Dst: peers["b"].AllowedIPs[0],
|
|
|
+ LinkIndex: kiloIface,
|
|
|
+ Protocol: unix.RTPROT_STATIC,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ } {
|
|
|
+ routes, rules := tc.topology.Routes(DefaultKiloInterface, kiloIface, privIface, tunlIface, tc.local, encapsulation.NewIPIP(tc.strategy))
|
|
|
+ if diff := pretty.Compare(routes, tc.routes); diff != "" {
|
|
|
+ t.Errorf("test case %q: got diff: %v", tc.name, diff)
|
|
|
+ }
|
|
|
+ if diff := pretty.Compare(rules, tc.rules); diff != "" {
|
|
|
+ t.Errorf("test case %q: got diff: %v", tc.name, diff)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|