From 6403e7a11cfd10a6fb141477e15cd35eaca2dffc Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 1 Jul 2015 11:13:40 +0100 Subject: [PATCH 1/5] Add missing rule to rebuild netcheck when its source changes --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index f69d0969..8559d21b 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ $(WEAVER_EXE) $(WEAVEDNS_EXE) $(WEAVEPROXY_EXE) $(NETCHECK_EXE): common/*.go com $(WEAVER_EXE): router/*.go ipam/*.go ipam/*/*.go prog/weaver/main.go $(WEAVEDNS_EXE): nameserver/*.go prog/weavedns/main.go $(WEAVEPROXY_EXE): proxy/*.go prog/weaveproxy/main.go +$(NETCHECK_EXE): prog/netcheck/netcheck.go # Sigproxy and weavewait need separate rules as they fail the netgo check in # the main build stanza due to not importing net package From f05225da22b78c4c2980b59b17f0cb783df3f300 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 1 Jul 2015 11:14:37 +0100 Subject: [PATCH 2/5] 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) From c9a20ae10c34c3e63edbf333c12d08fa4ea4b99d Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 1 Jul 2015 11:15:31 +0100 Subject: [PATCH 3/5] Warn user if they are trying to use a specific address that clashes with an existing route --- weave | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weave b/weave index 39edfa75..f250ae44 100755 --- a/weave +++ b/weave @@ -858,6 +858,8 @@ ipam_cidrs() { IPAM_CIDRS="$IPAM_CIDRS $CIDR" ALL_CIDRS="$ALL_CIDRS $CIDR" else + # This is a plain IP address; warn if it clashes but carry on + command_exists netcheck && netcheck $1 || true ALL_CIDRS="$ALL_CIDRS $1" fi shift 1 From 91099694c9308ed5a1319587f5f1d9ab27ecf972 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 1 Jul 2015 11:21:16 +0100 Subject: [PATCH 4/5] Send error message to stderr --- prog/netcheck/netcheck.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prog/netcheck/netcheck.go b/prog/netcheck/netcheck.go index 85f6003b..96a26ed4 100644 --- a/prog/netcheck/netcheck.go +++ b/prog/netcheck/netcheck.go @@ -10,7 +10,7 @@ import ( ) func fatal(err error) { - fmt.Println(err) + fmt.Fprintln(os.Stderr, err) os.Exit(1) } From 84238a0262de201b82ae3bb8a0b269eef786d36c Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 1 Jul 2015 14:58:42 +0100 Subject: [PATCH 5/5] Amend error message to reflect usage situation --- net/route.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/route.go b/net/route.go index 5673117f..80df987a 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 existing route %s", subnet, route.Dst) + return fmt.Errorf("Network %s overlaps with existing route %s", subnet, route.Dst) } } return nil @@ -36,7 +36,7 @@ func CheckAddressOverlap(addr net.IP) error { } 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 fmt.Errorf("Address %s overlaps with existing route %s", addr, route.Dst) } } return nil