Skip to content

Commit

Permalink
Merge branch '1.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
bboreham committed Jan 20, 2016
2 parents dd7271a + 13ec517 commit 6570b0b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 25 deletions.
19 changes: 14 additions & 5 deletions net/if.go
Expand Up @@ -52,16 +52,25 @@ func EnsureInterfaceAndMcastRoute(ifaceName string) (*net.Interface, error) {
return nil, err
}
dest := net.IPv4(224, 0, 0, 0)
check := func(route netlink.Route) bool {
return route.LinkIndex == iface.Index && route.Dst.IP.Equal(dest)
}
// check for currently-existing route after subscribing, to avoid race
if CheckRouteExists(ifaceName, dest) {
return iface, err
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
for _, route := range routes {
if check(route) {
return iface, nil
}
}
for update := range ch {
link, _ := netlink.LinkByIndex(update.Route.LinkIndex)
if link.Attrs().Name == ifaceName && update.Route.Dst.IP.Equal(dest) {
break
if check(update.Route) {
return iface, nil
}
}
// should never get here
return iface, nil
}

Expand Down
32 changes: 12 additions & 20 deletions net/route.go
Expand Up @@ -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)
}
Expand All @@ -26,40 +26,32 @@ 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)
}
return nil
})
}

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 {
if _, found := ignoreIfaceNames[link.Attrs().Name]; found {
continue
}
if _, found := ignoreIfaceIndices[route.LinkIndex]; found {
continue
}
if err := check(link.Attrs().Name, route); err != nil {
if err := check(route); err != nil {
return err
}
}
return nil
}

func CheckRouteExists(ifaceName string, dest net.IP) bool {
found := false
forEachRoute(map[string]struct{}{}, func(name string, route netlink.Route) error {
if name == ifaceName && route.Dst.IP.Equal(dest) {
found = true
}
return nil
})
return found
}

0 comments on commit 6570b0b

Please sign in to comment.