From fd5d65868f1c49a2e956e1712d951c764434f71f Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Tue, 19 Jan 2016 15:44:32 +0000 Subject: [PATCH] bypass netlink.LinkByIndex since we are seeing some cases where it returns "Link not found" when the link is in fact there. --- net/route.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/net/route.go b/net/route.go index a46000f066..1562045df5 100644 --- a/net/route.go +++ b/net/route.go @@ -10,7 +10,7 @@ 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, ignoreIfaceNames map[string]struct{}) error { - return forEachRoute(ignoreIfaceNames, func(name string, route netlink.Route) error { + return forEachRoute(ignoreIfaceNames, func(route netlink.Route) error { if route.Dst != nil && overlaps(route.Dst, subnet) { return fmt.Errorf("Network %s overlaps with existing route %s on host.", subnet, route.Dst) } @@ -26,7 +26,7 @@ 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, ignoreIfaceNames map[string]struct{}) error { - return forEachRoute(ignoreIfaceNames, func(name string, route netlink.Route) error { + return forEachRoute(ignoreIfaceNames, func(route netlink.Route) error { if route.Dst != nil && route.Dst.Contains(addr) { return fmt.Errorf("Address %s overlaps with existing route %s on host.", addr, route.Dst) } @@ -34,21 +34,22 @@ func CheckAddressOverlap(addr net.IP, ignoreIfaceNames map[string]struct{}) erro }) } -func forEachRoute(ignoreIfaceNames map[string]struct{}, check func(name string, r netlink.Route) error) error { +func forEachRoute(ignoreIfaceNames map[string]struct{}, check func(r netlink.Route) error) error { + ignoreIfaceIndices := make(map[int]struct{}) + for ifaceName := range ignoreIfaceNames { + if iface, err := net.InterfaceByName(ifaceName); err == nil { + ignoreIfaceIndices[iface.Index] = struct{}{} + } + } routes, err := netlink.RouteList(nil, netlink.FAMILY_V4) if err != nil { return err } for _, route := range routes { - link, err := netlink.LinkByIndex(route.LinkIndex) - if err != nil { - continue - } - ifaceName := link.Attrs().Name - if _, found := ignoreIfaceNames[ifaceName]; found { + if _, found := ignoreIfaceIndices[route.LinkIndex]; found { continue } - if err := check(ifaceName, route); err != nil { + if err := check(route); err != nil { return err } }