From f05225da22b78c4c2980b59b17f0cb783df3f300 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 1 Jul 2015 11:14:37 +0100 Subject: [PATCH] Check specific addresses differently to networks For a network, as used by IPAM, we care if *any* address in the range could possibly conflict with an existing address routed by the host. When given a single address, we only care if *that specific address* conflicts with an existing route. --- net/route.go | 17 ++++++++++++++++- prog/netcheck/netcheck.go | 13 +++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/net/route.go b/net/route.go index 0d8a1bab..5673117f 100644 --- a/net/route.go +++ b/net/route.go @@ -16,7 +16,7 @@ func CheckNetworkFree(subnet *net.IPNet) error { } 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 fmt.Errorf("Network %s would overlap with existing route %s", subnet, route.Dst) } } return nil @@ -26,3 +26,18 @@ func CheckNetworkFree(subnet *net.IPNet) error { func overlaps(n1, n2 *net.IPNet) bool { return n1.Contains(n2.IP) || n2.Contains(n1.IP) } + +// For a specific address, we only care if it is actually *inside* an +// existing route, because weave-local traffic never hits IP routing. +func CheckAddressOverlap(addr net.IP) error { + routes, err := netlink.RouteList(nil, netlink.FAMILY_V4) + if err != nil { + return err + } + for _, route := range routes { + if route.Dst != nil && route.Dst.Contains(addr) { + return fmt.Errorf("Address %s would overlap with existing route %s", addr, route.Dst) + } + } + return nil +} diff --git a/prog/netcheck/netcheck.go b/prog/netcheck/netcheck.go index 383f5d9b..85f6003b 100644 --- a/prog/netcheck/netcheck.go +++ b/prog/netcheck/netcheck.go @@ -1,4 +1,4 @@ -/* netcheck: check whether a given network overlaps with any existing routes */ +/* netcheck: check whether a given network or address overlaps with any existing routes */ package main import ( @@ -19,12 +19,17 @@ func main() { os.Exit(0) } - ipRangeStr := os.Args[1] - _, ipnet, err := net.ParseCIDR(ipRangeStr) + cidrStr := os.Args[1] + addr, ipnet, err := net.ParseCIDR(cidrStr) if err != nil { fatal(err) } - if err := weavenet.CheckNetworkFree(ipnet); err != nil { + if ipnet.IP.Equal(addr) { + err = weavenet.CheckNetworkFree(ipnet) + } else { + err = weavenet.CheckAddressOverlap(addr) + } + if err != nil { fatal(err) } os.Exit(0)