diff --git a/net/route.go b/net/route.go index 6d1722ad..bff99e2d 100644 --- a/net/route.go +++ b/net/route.go @@ -9,13 +9,17 @@ import ( // 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 { +func CheckNetworkFree(subnet *net.IPNet, ignoreIfName string) 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) { + if link, err := netlink.LinkByIndex(route.LinkIndex); err == nil && link.Attrs().Name == ignoreIfName { + continue + } + return fmt.Errorf("Network %s overlaps with existing route %s on host.", subnet, route.Dst) } } @@ -29,13 +33,16 @@ func overlaps(n1, n2 *net.IPNet) bool { // 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 { +func CheckAddressOverlap(addr net.IP, ignoreIfName string) 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) { + if link, err := netlink.LinkByIndex(route.LinkIndex); err == nil && link.Attrs().Name == ignoreIfName { + continue + } return fmt.Errorf("Address %s overlaps with existing route %s on host.", addr, route.Dst) } } diff --git a/prog/netcheck/netcheck.go b/prog/netcheck/netcheck.go index 96a26ed4..78261a0e 100644 --- a/prog/netcheck/netcheck.go +++ b/prog/netcheck/netcheck.go @@ -6,6 +6,7 @@ import ( "net" "os" + "github.com/docker/docker/pkg/mflag" weavenet "github.com/weaveworks/weave/net" ) @@ -15,19 +16,25 @@ func fatal(err error) { } func main() { - if len(os.Args) <= 1 { - os.Exit(0) + var ignoreIfaceName string + + mflag.StringVar(&ignoreIfaceName, []string{"-ignore-iface"}, "", "name of interface to ignore)") + mflag.Parse() + + if len(mflag.Args()) < 1 { + fmt.Fprintln(os.Stderr, "usage: netcheck [--ignore-iface ] network-cidr") + os.Exit(1) } - cidrStr := os.Args[1] + cidrStr := mflag.Args()[0] addr, ipnet, err := net.ParseCIDR(cidrStr) if err != nil { fatal(err) } if ipnet.IP.Equal(addr) { - err = weavenet.CheckNetworkFree(ipnet) + err = weavenet.CheckNetworkFree(ipnet, ignoreIfaceName) } else { - err = weavenet.CheckAddressOverlap(addr) + err = weavenet.CheckAddressOverlap(addr, ignoreIfaceName) } if err != nil { fatal(err) diff --git a/weave b/weave index 479ff2c5..9a10adb6 100755 --- a/weave +++ b/weave @@ -860,7 +860,7 @@ ipam_cidrs() { 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 + command_exists netcheck && netcheck --ignore-iface=$BRIDGE $1 || true ALL_CIDRS="$ALL_CIDRS $1" fi shift 1 @@ -998,7 +998,7 @@ launch_router() { eval "set -- $ARGS" if [ -z "$IPRANGE_SPECIFIED" ] ; then IPRANGE="10.32.0.0/12" - if command_exists netcheck && ! netcheck $IPRANGE ; then + if command_exists netcheck && ! netcheck --ignore-iface=$BRIDGE $IPRANGE ; then echo "Default --ipalloc-range $IPRANGE overlaps with existing route on host." >&2 echo "Please pick another range and set it on all hosts." >&2 exit 1