From 828504696286be786baa11f775f57ff4b7791950 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 11 Jun 2015 14:53:15 +0100 Subject: [PATCH] Function to check if a network overlaps with existing routes --- net/route.go | 28 ++++++++++++++++++++++++++++ net/route_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 net/route.go create mode 100644 net/route_test.go diff --git a/net/route.go b/net/route.go new file mode 100644 index 00000000..0d8a1bab --- /dev/null +++ b/net/route.go @@ -0,0 +1,28 @@ +package net + +import ( + "fmt" + "net" + + "github.com/vishvananda/netlink" +) + +// A network is considered free if it does not overlap any existing +// routes on this host. This is the same approach taken by Docker. +func CheckNetworkFree(subnet *net.IPNet) error { + routes, err := netlink.RouteList(nil, netlink.FAMILY_V4) + if err != nil { + return err + } + for _, route := range routes { + if route.Dst != nil && overlaps(route.Dst, subnet) { + return fmt.Errorf("network %s would overlap with route %s", subnet, route.Dst) + } + } + return nil +} + +// Two networks overlap if the start-point of one is inside the other. +func overlaps(n1, n2 *net.IPNet) bool { + return n1.Contains(n2.IP) || n2.Contains(n1.IP) +} diff --git a/net/route_test.go b/net/route_test.go new file mode 100644 index 00000000..e907fadf --- /dev/null +++ b/net/route_test.go @@ -0,0 +1,25 @@ +package net + +import ( + "net" + "testing" + + wt "github.com/weaveworks/weave/testing" +) + +func TestOverlap(t *testing.T) { + _, subnet1, _ := net.ParseCIDR("10.0.3.0/24") + _, subnet2, _ := net.ParseCIDR("10.0.4.0/24") + _, subnet3, _ := net.ParseCIDR("10.0.3.128/25") + _, subnet4, _ := net.ParseCIDR("10.0.3.192/25") + _, universe, _ := net.ParseCIDR("10.0.0.0/8") + wt.AssertEquals(t, overlaps(subnet1, subnet2), false) + wt.AssertEquals(t, overlaps(subnet2, subnet1), false) + wt.AssertEquals(t, overlaps(subnet1, subnet1), true) + wt.AssertEquals(t, overlaps(subnet1, subnet3), true) + wt.AssertEquals(t, overlaps(subnet1, subnet4), true) + wt.AssertEquals(t, overlaps(subnet2, subnet4), false) + wt.AssertEquals(t, overlaps(subnet4, subnet2), false) + wt.AssertEquals(t, overlaps(universe, subnet1), true) + wt.AssertEquals(t, overlaps(subnet1, universe), true) +}