Nodes without private IPs
Allow nodes to have no private IPs. Nodes without private IPs will automatically be put into their own location.
This commit is contained in:
parent
92825ba0c7
commit
3a201ba0fa
59
pkg/encapsulation/noop.go
Normal file
59
pkg/encapsulation/noop.go
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2021 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 encapsulation
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/squat/kilo/pkg/iptables"
|
||||
)
|
||||
|
||||
// Noop is an encapsulation that does nothing.
|
||||
type Noop Strategy
|
||||
|
||||
// CleanUp will also do nothing.
|
||||
func (n Noop) CleanUp() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gw will also do nothing.
|
||||
func (n Noop) Gw(_ net.IP, _ net.IP, _ *net.IPNet) net.IP {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Index will also do nothing.
|
||||
func (n Noop) Index() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Init will also do nothing.
|
||||
func (n Noop) Init(_ int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rules will also do nothing.
|
||||
func (n Noop) Rules(_ []*net.IPNet) []iptables.Rule {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set will also do nothing.
|
||||
func (n Noop) Set(_ *net.IPNet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Strategy will finally do nothing.
|
||||
func (n Noop) Strategy() Strategy {
|
||||
return Strategy(n)
|
||||
}
|
@ -209,7 +209,11 @@ func (nb *nodeBackend) Set(name string, node *mesh.Node) error {
|
||||
}
|
||||
n := old.DeepCopy()
|
||||
n.ObjectMeta.Annotations[endpointAnnotationKey] = node.Endpoint.String()
|
||||
n.ObjectMeta.Annotations[internalIPAnnotationKey] = node.InternalIP.String()
|
||||
if node.InternalIP == nil {
|
||||
n.ObjectMeta.Annotations[internalIPAnnotationKey] = ""
|
||||
} else {
|
||||
n.ObjectMeta.Annotations[internalIPAnnotationKey] = node.InternalIP.String()
|
||||
}
|
||||
n.ObjectMeta.Annotations[keyAnnotationKey] = string(node.Key)
|
||||
n.ObjectMeta.Annotations[lastSeenAnnotationKey] = strconv.FormatInt(node.LastSeen, 10)
|
||||
if node.WireGuardIP == nil {
|
||||
@ -289,6 +293,8 @@ func translateNode(node *v1.Node, topologyLabel string) *mesh.Node {
|
||||
// remote node's agent has not yet set its IP address;
|
||||
// in this case the IP will be nil and
|
||||
// the mesh can wait for the node to be updated.
|
||||
// It is valid for the InternalIP to be nil,
|
||||
// if the given node only has public IP addresses.
|
||||
Endpoint: endpoint,
|
||||
InternalIP: internalIP,
|
||||
Key: []byte(node.ObjectMeta.Annotations[keyAnnotationKey]),
|
||||
|
@ -187,6 +187,33 @@ func TestTranslateNode(t *testing.T) {
|
||||
},
|
||||
subnet: "10.2.1.0/24",
|
||||
},
|
||||
{
|
||||
name: "no InternalIP",
|
||||
annotations: map[string]string{
|
||||
endpointAnnotationKey: "10.0.0.1:51820",
|
||||
internalIPAnnotationKey: "",
|
||||
keyAnnotationKey: "foo",
|
||||
lastSeenAnnotationKey: "1000000000",
|
||||
locationAnnotationKey: "b",
|
||||
persistentKeepaliveKey: "25",
|
||||
wireGuardIPAnnotationKey: "10.4.0.1/16",
|
||||
},
|
||||
labels: map[string]string{
|
||||
RegionLabelKey: "a",
|
||||
},
|
||||
out: &mesh.Node{
|
||||
Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: net.ParseIP("10.0.0.1")}, Port: 51820},
|
||||
InternalIP: nil,
|
||||
Key: []byte("foo"),
|
||||
LastSeen: 1000000000,
|
||||
Leader: false,
|
||||
Location: "b",
|
||||
PersistentKeepalive: 25,
|
||||
Subnet: &net.IPNet{IP: net.ParseIP("10.2.1.0"), Mask: net.CIDRMask(24, 32)},
|
||||
WireGuardIP: &net.IPNet{IP: net.ParseIP("10.4.0.1"), Mask: net.CIDRMask(16, 32)},
|
||||
},
|
||||
subnet: "10.2.1.0/24",
|
||||
},
|
||||
} {
|
||||
n := &v1.Node{}
|
||||
n.ObjectMeta.Annotations = tc.annotations
|
||||
|
@ -70,7 +70,7 @@ type Node struct {
|
||||
// Ready indicates whether or not the node is ready.
|
||||
func (n *Node) Ready() bool {
|
||||
// Nodes that are not leaders will not have WireGuardIPs, so it is not required.
|
||||
return n != nil && n.Endpoint != nil && !(n.Endpoint.IP == nil && n.Endpoint.DNS == "") && n.Endpoint.Port != 0 && n.Key != nil && n.InternalIP != nil && n.Subnet != nil && time.Now().Unix()-n.LastSeen < int64(resyncPeriod)*2/int64(time.Second)
|
||||
return n != nil && n.Endpoint != nil && !(n.Endpoint.IP == nil && n.Endpoint.DNS == "") && n.Endpoint.Port != 0 && n.Key != nil && n.Subnet != nil && time.Now().Unix()-n.LastSeen < int64(resyncPeriod)*2/int64(time.Second)
|
||||
}
|
||||
|
||||
// Peer represents a peer in the network.
|
||||
|
@ -30,9 +30,7 @@ import (
|
||||
// - private IP to which hostname resolves
|
||||
// - private IP assigned to interface of default route
|
||||
// - private IP assigned to local interface
|
||||
// - public IP to which hostname resolves
|
||||
// - public IP assigned to interface of default route
|
||||
// - public IP assigned to local interface
|
||||
// - nil if no private IP was found
|
||||
// It selects the public IP address in the following order:
|
||||
// - public IP to which hostname resolves
|
||||
// - public IP assigned to interface of default route
|
||||
@ -153,7 +151,8 @@ func getIP(hostname string, ignoreIfaces ...int) (*net.IPNet, *net.IPNet, error)
|
||||
return nil, nil, errors.New("no valid IP was found")
|
||||
}
|
||||
if len(priv) == 0 {
|
||||
priv = pub
|
||||
// If no private IPs were found, use nil.
|
||||
priv = append(priv, nil)
|
||||
}
|
||||
if len(pub) == 0 {
|
||||
pub = priv
|
||||
|
@ -70,7 +70,11 @@ func (t *Topology) Dot() (string, error) {
|
||||
return "", fmt.Errorf("failed to add rank to node")
|
||||
}
|
||||
}
|
||||
if err := g.Nodes.Lookup[graphEscape(s.hostnames[j])].Attrs.Add(string(gographviz.Label), nodeLabel(s.location, s.hostnames[j], s.cidrs[j], s.privateIPs[j], wg, endpoint)); err != nil {
|
||||
var priv net.IP
|
||||
if s.privateIPs != nil {
|
||||
priv = s.privateIPs[j]
|
||||
}
|
||||
if err := g.Nodes.Lookup[graphEscape(s.hostnames[j])].Attrs.Add(string(gographviz.Label), nodeLabel(s.location, s.hostnames[j], s.cidrs[j], priv, wg, endpoint)); err != nil {
|
||||
return "", fmt.Errorf("failed to add label to node")
|
||||
}
|
||||
}
|
||||
@ -155,7 +159,9 @@ func nodeLabel(location, name string, cidr *net.IPNet, priv, wgIP net.IP, endpoi
|
||||
location,
|
||||
name,
|
||||
cidr.String(),
|
||||
priv.String(),
|
||||
}
|
||||
if priv != nil {
|
||||
label = append(label, priv.String())
|
||||
}
|
||||
if wgIP != nil {
|
||||
label = append(label, wgIP.String())
|
||||
|
@ -71,7 +71,7 @@ type Mesh struct {
|
||||
wireGuardIP *net.IPNet
|
||||
|
||||
// nodes and peers are mutable fields in the struct
|
||||
// and needs to be guarded.
|
||||
// and need to be guarded.
|
||||
nodes map[string]*Node
|
||||
peers map[string]*Peer
|
||||
mu sync.Mutex
|
||||
@ -125,17 +125,23 @@ func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularit
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find public IP: %v", err)
|
||||
}
|
||||
ifaces, err := interfacesForIP(privateIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find interface for private IP: %v", err)
|
||||
}
|
||||
privIface := ifaces[0].Index
|
||||
if enc.Strategy() != encapsulation.Never {
|
||||
if err := enc.Init(privIface); err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize encapsulator: %v", err)
|
||||
var privIface int
|
||||
if privateIP != nil {
|
||||
ifaces, err := interfacesForIP(privateIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find interface for private IP: %v", err)
|
||||
}
|
||||
privIface := ifaces[0].Index
|
||||
if enc.Strategy() != encapsulation.Never {
|
||||
if err := enc.Init(privIface); err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize encapsulator: %v", err)
|
||||
}
|
||||
}
|
||||
level.Debug(logger).Log("msg", fmt.Sprintf("using %s as the private IP address", privateIP.String()))
|
||||
} else {
|
||||
enc = encapsulation.Noop(enc.Strategy())
|
||||
level.Debug(logger).Log("msg", "running without a private IP address")
|
||||
}
|
||||
level.Debug(logger).Log("msg", fmt.Sprintf("using %s as the private IP address", privateIP.String()))
|
||||
level.Debug(logger).Log("msg", fmt.Sprintf("using %s as the public IP address", publicIP.String()))
|
||||
ipTables, err := iptables.New()
|
||||
if err != nil {
|
||||
|
@ -97,9 +97,9 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
|
||||
LinkIndex: privIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
}, enc.Strategy(), t.privateIP, tunlIface))
|
||||
}
|
||||
for i := range segment.privateIPs {
|
||||
// Add routes to the private IPs of nodes in other segments.
|
||||
// Number of CIDRs and private IPs always match so
|
||||
// we can reuse the loop.
|
||||
routes = append(routes, encapsulateRoute(&netlink.Route{
|
||||
Dst: oneAddressCIDR(segment.privateIPs[i]),
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
@ -126,7 +126,9 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
|
||||
for _, segment := range t.segments {
|
||||
// Add routes for the current segment if local is true.
|
||||
if segment.location == t.location {
|
||||
if local {
|
||||
// If the local node does not have a private IP address,
|
||||
// then skip adding routes, because the node is in its own location.
|
||||
if local && t.privateIP != nil {
|
||||
for i := range segment.cidrs {
|
||||
// Don't add routes for the local node.
|
||||
if segment.privateIPs[i].Equal(t.privateIP.IP) {
|
||||
@ -165,6 +167,8 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
|
||||
}
|
||||
}
|
||||
}
|
||||
// Continuing here prevents leaders form adding routes via WireGuard to
|
||||
// nodes in their own location.
|
||||
continue
|
||||
}
|
||||
for i := range segment.cidrs {
|
||||
@ -180,7 +184,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
|
||||
// equals the external IP. This means that the node
|
||||
// is only accessible through an external IP and we
|
||||
// cannot encapsulate traffic to an IP through the IP.
|
||||
if segment.privateIPs[i].Equal(segment.endpoint.IP) {
|
||||
if segment.privateIPs == nil || segment.privateIPs[i].Equal(segment.endpoint.IP) {
|
||||
continue
|
||||
}
|
||||
// Add routes to the private IPs of nodes in other segments.
|
||||
|
@ -74,6 +74,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[2].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -110,6 +117,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[2].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -160,6 +174,20 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: privIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[2].wireGuardIP),
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: nodes["b"].InternalIP.IP,
|
||||
LinkIndex: privIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[2].cidrs[0],
|
||||
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),
|
||||
@ -183,6 +211,70 @@ func TestRoutes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "logical from d",
|
||||
topology: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].Name),
|
||||
strategy: encapsulation.Never,
|
||||
routes: []*netlink.Route{
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].Name).segments[0].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].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["d"].Name).segments[0].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].Name).segments[1].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].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["d"].Name).segments[1].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].Name).segments[1].cidrs[1],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["d"].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["d"].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: "full from a",
|
||||
topology: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name),
|
||||
@ -216,6 +308,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[3].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[3].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -266,6 +365,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[3].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[3].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -316,6 +422,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[3].cidrs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[3].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -367,6 +480,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -418,6 +538,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["a"].Name).segments[2].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -462,6 +589,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: privIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -514,6 +648,13 @@ func TestRoutes(t *testing.T) {
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
Table: kiloTableIndex,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(LogicalGranularity, nodes["b"].Name).segments[2].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -584,6 +725,20 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: privIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[2].wireGuardIP),
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: nodes["b"].InternalIP.IP,
|
||||
LinkIndex: privIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].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),
|
||||
@ -656,6 +811,20 @@ func TestRoutes(t *testing.T) {
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
Table: kiloTableIndex,
|
||||
},
|
||||
{
|
||||
Dst: oneAddressCIDR(mustTopoForGranularityAndHost(LogicalGranularity, nodes["c"].Name).segments[2].wireGuardIP),
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: nodes["b"].InternalIP.IP,
|
||||
LinkIndex: tunlIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: nodes["b"].InternalIP.IP,
|
||||
LinkIndex: tunlIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
@ -720,6 +889,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["a"].Name).segments[3].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -771,6 +947,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["b"].Name).segments[3].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
@ -822,6 +1005,13 @@ func TestRoutes(t *testing.T) {
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: nodes["d"].Subnet,
|
||||
Flags: int(netlink.FLAG_ONLINK),
|
||||
Gw: mustTopoForGranularityAndHost(FullGranularity, nodes["c"].Name).segments[3].wireGuardIP,
|
||||
LinkIndex: kiloIface,
|
||||
Protocol: unix.RTPROT_STATIC,
|
||||
},
|
||||
{
|
||||
Dst: peers["a"].AllowedIPs[0],
|
||||
LinkIndex: kiloIface,
|
||||
|
@ -22,6 +22,11 @@ import (
|
||||
"github.com/squat/kilo/pkg/wireguard"
|
||||
)
|
||||
|
||||
const (
|
||||
logicalLocationPrefix = "location:"
|
||||
nodeLocationPrefix = "node:"
|
||||
)
|
||||
|
||||
// Topology represents the logical structure of the overlay network.
|
||||
type Topology struct {
|
||||
// key is the private key of the node creating the topology.
|
||||
@ -77,18 +82,24 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
||||
var location string
|
||||
switch granularity {
|
||||
case LogicalGranularity:
|
||||
location = node.Location
|
||||
location = logicalLocationPrefix + node.Location
|
||||
if node.InternalIP == nil {
|
||||
location = nodeLocationPrefix + node.Name
|
||||
}
|
||||
case FullGranularity:
|
||||
location = node.Name
|
||||
location = nodeLocationPrefix + node.Name
|
||||
}
|
||||
topoMap[location] = append(topoMap[location], node)
|
||||
}
|
||||
var localLocation string
|
||||
switch granularity {
|
||||
case LogicalGranularity:
|
||||
localLocation = nodes[hostname].Location
|
||||
localLocation = logicalLocationPrefix + nodes[hostname].Location
|
||||
if nodes[hostname].InternalIP == nil {
|
||||
localLocation = nodeLocationPrefix + hostname
|
||||
}
|
||||
case FullGranularity:
|
||||
localLocation = hostname
|
||||
localLocation = nodeLocationPrefix + hostname
|
||||
}
|
||||
|
||||
t := Topology{key: key, port: port, hostname: hostname, location: localLocation, persistentKeepalive: persistentKeepalive, privateIP: nodes[hostname].InternalIP, subnet: nodes[hostname].Subnet}
|
||||
@ -110,10 +121,13 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
||||
// - the node's allocated subnet
|
||||
// - the node's WireGuard IP
|
||||
// - the node's internal IP
|
||||
allowedIPs = append(allowedIPs, node.Subnet, oneAddressCIDR(node.InternalIP.IP))
|
||||
allowedIPs = append(allowedIPs, node.Subnet)
|
||||
if node.InternalIP != nil {
|
||||
allowedIPs = append(allowedIPs, oneAddressCIDR(node.InternalIP.IP))
|
||||
privateIPs = append(privateIPs, node.InternalIP.IP)
|
||||
}
|
||||
cidrs = append(cidrs, node.Subnet)
|
||||
hostnames = append(hostnames, node.Name)
|
||||
privateIPs = append(privateIPs, node.InternalIP.IP)
|
||||
}
|
||||
t.segments = append(t.segments, &segment{
|
||||
allowedIPs: allowedIPs,
|
||||
|
@ -33,6 +33,7 @@ func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32) {
|
||||
e1 := &net.IPNet{IP: net.ParseIP("10.1.0.1").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
e2 := &net.IPNet{IP: net.ParseIP("10.1.0.2").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
e3 := &net.IPNet{IP: net.ParseIP("10.1.0.3").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
e4 := &net.IPNet{IP: net.ParseIP("10.1.0.4").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
i1 := &net.IPNet{IP: net.ParseIP("192.168.0.1").To4(), Mask: net.CIDRMask(32, 32)}
|
||||
i2 := &net.IPNet{IP: net.ParseIP("192.168.0.2").To4(), Mask: net.CIDRMask(32, 32)}
|
||||
nodes := map[string]*Node{
|
||||
@ -57,11 +58,19 @@ func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32) {
|
||||
Name: "c",
|
||||
Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e3.IP}, Port: DefaultKiloPort},
|
||||
InternalIP: i2,
|
||||
// Same location a node b.
|
||||
// Same location as node b.
|
||||
Location: "2",
|
||||
Subnet: &net.IPNet{IP: net.ParseIP("10.2.3.0"), Mask: net.CIDRMask(24, 32)},
|
||||
Key: []byte("key3"),
|
||||
},
|
||||
"d": {
|
||||
Name: "d",
|
||||
Endpoint: &wireguard.Endpoint{DNSOrIP: wireguard.DNSOrIP{IP: e4.IP}, Port: DefaultKiloPort},
|
||||
// Same location as node a, but without private IP
|
||||
Location: "1",
|
||||
Subnet: &net.IPNet{IP: net.ParseIP("10.2.4.0"), Mask: net.CIDRMask(24, 32)},
|
||||
Key: []byte("key4"),
|
||||
},
|
||||
}
|
||||
peers := map[string]*Peer{
|
||||
"a": {
|
||||
@ -97,6 +106,7 @@ func TestNewTopology(t *testing.T) {
|
||||
w1 := net.ParseIP("10.4.0.1").To4()
|
||||
w2 := net.ParseIP("10.4.0.2").To4()
|
||||
w3 := net.ParseIP("10.4.0.3").To4()
|
||||
w4 := net.ParseIP("10.4.0.4").To4()
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
granularity Granularity
|
||||
@ -110,7 +120,7 @@ func TestNewTopology(t *testing.T) {
|
||||
result: &Topology{
|
||||
hostname: nodes["a"].Name,
|
||||
leader: true,
|
||||
location: nodes["a"].Location,
|
||||
location: logicalLocationPrefix + nodes["a"].Location,
|
||||
subnet: nodes["a"].Subnet,
|
||||
privateIP: nodes["a"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
|
||||
@ -119,7 +129,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodes["a"].Location,
|
||||
location: logicalLocationPrefix + nodes["a"].Location,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
@ -129,12 +139,22 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodes["b"].Location,
|
||||
location: logicalLocationPrefix + nodes["b"].Location,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
|
||||
hostnames: []string{"b", "c"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w2,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
@ -146,7 +166,7 @@ func TestNewTopology(t *testing.T) {
|
||||
result: &Topology{
|
||||
hostname: nodes["b"].Name,
|
||||
leader: true,
|
||||
location: nodes["b"].Location,
|
||||
location: logicalLocationPrefix + nodes["b"].Location,
|
||||
subnet: nodes["b"].Subnet,
|
||||
privateIP: nodes["b"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
|
||||
@ -155,7 +175,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodes["a"].Location,
|
||||
location: logicalLocationPrefix + nodes["a"].Location,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
@ -165,12 +185,22 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodes["b"].Location,
|
||||
location: logicalLocationPrefix + nodes["b"].Location,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
|
||||
hostnames: []string{"b", "c"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w2,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
@ -182,7 +212,7 @@ func TestNewTopology(t *testing.T) {
|
||||
result: &Topology{
|
||||
hostname: nodes["c"].Name,
|
||||
leader: false,
|
||||
location: nodes["b"].Location,
|
||||
location: logicalLocationPrefix + nodes["b"].Location,
|
||||
subnet: nodes["c"].Subnet,
|
||||
privateIP: nodes["c"].InternalIP,
|
||||
wireGuardCIDR: nil,
|
||||
@ -191,7 +221,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodes["a"].Location,
|
||||
location: logicalLocationPrefix + nodes["a"].Location,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
@ -201,12 +231,22 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodes["b"].Location,
|
||||
location: logicalLocationPrefix + nodes["b"].Location,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet, nodes["c"].Subnet},
|
||||
hostnames: []string{"b", "c"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP, nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w2,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
@ -218,7 +258,7 @@ func TestNewTopology(t *testing.T) {
|
||||
result: &Topology{
|
||||
hostname: nodes["a"].Name,
|
||||
leader: true,
|
||||
location: nodes["a"].Name,
|
||||
location: nodeLocationPrefix + nodes["a"].Name,
|
||||
subnet: nodes["a"].Subnet,
|
||||
privateIP: nodes["a"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
|
||||
@ -227,7 +267,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodes["a"].Name,
|
||||
location: nodeLocationPrefix + nodes["a"].Name,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
@ -237,7 +277,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodes["b"].Name,
|
||||
location: nodeLocationPrefix + nodes["b"].Name,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||
hostnames: []string{"b"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||
@ -247,12 +287,22 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["c"].Endpoint,
|
||||
key: nodes["c"].Key,
|
||||
location: nodes["c"].Name,
|
||||
location: nodeLocationPrefix + nodes["c"].Name,
|
||||
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||
hostnames: []string{"c"},
|
||||
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w4,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
@ -264,7 +314,7 @@ func TestNewTopology(t *testing.T) {
|
||||
result: &Topology{
|
||||
hostname: nodes["b"].Name,
|
||||
leader: true,
|
||||
location: nodes["b"].Name,
|
||||
location: nodeLocationPrefix + nodes["b"].Name,
|
||||
subnet: nodes["b"].Subnet,
|
||||
privateIP: nodes["b"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
|
||||
@ -273,7 +323,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodes["a"].Name,
|
||||
location: nodeLocationPrefix + nodes["a"].Name,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
@ -283,7 +333,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodes["b"].Name,
|
||||
location: nodeLocationPrefix + nodes["b"].Name,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||
hostnames: []string{"b"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||
@ -293,12 +343,22 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["c"].Endpoint,
|
||||
key: nodes["c"].Key,
|
||||
location: nodes["c"].Name,
|
||||
location: nodeLocationPrefix + nodes["c"].Name,
|
||||
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||
hostnames: []string{"c"},
|
||||
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w4,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
@ -310,7 +370,7 @@ func TestNewTopology(t *testing.T) {
|
||||
result: &Topology{
|
||||
hostname: nodes["c"].Name,
|
||||
leader: true,
|
||||
location: nodes["c"].Name,
|
||||
location: nodeLocationPrefix + nodes["c"].Name,
|
||||
subnet: nodes["c"].Subnet,
|
||||
privateIP: nodes["c"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w3, Mask: net.CIDRMask(16, 32)},
|
||||
@ -319,7 +379,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodes["a"].Name,
|
||||
location: nodeLocationPrefix + nodes["a"].Name,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
@ -329,7 +389,7 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodes["b"].Name,
|
||||
location: nodeLocationPrefix + nodes["b"].Name,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||
hostnames: []string{"b"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||
@ -339,12 +399,78 @@ func TestNewTopology(t *testing.T) {
|
||||
allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["c"].Endpoint,
|
||||
key: nodes["c"].Key,
|
||||
location: nodes["c"].Name,
|
||||
location: nodeLocationPrefix + nodes["c"].Name,
|
||||
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||
hostnames: []string{"c"},
|
||||
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w4,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "full from d",
|
||||
granularity: FullGranularity,
|
||||
hostname: nodes["d"].Name,
|
||||
result: &Topology{
|
||||
hostname: nodes["d"].Name,
|
||||
leader: true,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
subnet: nodes["d"].Subnet,
|
||||
privateIP: nil,
|
||||
wireGuardCIDR: &net.IPNet{IP: w4, Mask: net.CIDRMask(16, 32)},
|
||||
segments: []*segment{
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["a"].Endpoint,
|
||||
key: nodes["a"].Key,
|
||||
location: nodeLocationPrefix + nodes["a"].Name,
|
||||
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||
hostnames: []string{"a"},
|
||||
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||
wireGuardIP: w1,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["b"].Subnet, nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["b"].Endpoint,
|
||||
key: nodes["b"].Key,
|
||||
location: nodeLocationPrefix + nodes["b"].Name,
|
||||
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||
hostnames: []string{"b"},
|
||||
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||
wireGuardIP: w2,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["c"].Subnet, nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["c"].Endpoint,
|
||||
key: nodes["c"].Key,
|
||||
location: nodeLocationPrefix + nodes["c"].Name,
|
||||
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||
hostnames: []string{"c"},
|
||||
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||
wireGuardIP: w3,
|
||||
},
|
||||
{
|
||||
allowedIPs: []*net.IPNet{nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||
endpoint: nodes["d"].Endpoint,
|
||||
key: nodes["d"].Key,
|
||||
location: nodeLocationPrefix + nodes["d"].Name,
|
||||
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||
hostnames: []string{"d"},
|
||||
privateIPs: nil,
|
||||
wireGuardIP: w4,
|
||||
},
|
||||
},
|
||||
peers: []*Peer{peers["a"], peers["b"]},
|
||||
},
|
||||
@ -390,6 +516,12 @@ Endpoint = 10.1.0.2:51820
|
||||
AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.2.3.0/24, 192.168.0.2/32, 10.4.0.2/32
|
||||
PersistentKeepalive = 25
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
Endpoint = 10.1.0.4:51820
|
||||
AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
|
||||
PersistentKeepalive = 25
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
|
||||
@ -414,6 +546,11 @@ PersistentKeepalive = 25
|
||||
Endpoint = 10.1.0.1:51820
|
||||
AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
Endpoint = 10.1.0.4:51820
|
||||
AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
|
||||
@ -436,6 +573,11 @@ PersistentKeepalive = 25
|
||||
Endpoint = 10.1.0.1:51820
|
||||
AllowedIPs = 10.2.1.0/24, 192.168.0.1/32, 10.4.0.1/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
Endpoint = 10.1.0.4:51820
|
||||
AllowedIPs = 10.2.4.0/24, 10.4.0.3/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
|
||||
@ -465,6 +607,12 @@ PersistentKeepalive = 25
|
||||
AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
|
||||
PersistentKeepalive = 25
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
Endpoint = 10.1.0.4:51820
|
||||
AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
|
||||
PersistentKeepalive = 25
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
|
||||
@ -494,6 +642,11 @@ PersistentKeepalive = 25
|
||||
Endpoint = 10.1.0.3:51820
|
||||
AllowedIPs = 10.2.3.0/24, 192.168.0.2/32, 10.4.0.3/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
Endpoint = 10.1.0.4:51820
|
||||
AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
|
||||
@ -521,6 +674,11 @@ PersistentKeepalive = 25
|
||||
Endpoint = 10.1.0.2:51820
|
||||
AllowedIPs = 10.2.2.0/24, 192.168.0.1/32, 10.4.0.2/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
Endpoint = 10.1.0.4:51820
|
||||
AllowedIPs = 10.2.4.0/24, 10.4.0.4/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = key4
|
||||
AllowedIPs = 10.5.0.1/24, 10.5.0.2/24
|
||||
|
Loading…
Reference in New Issue
Block a user