From 7801dcd8497d26aa5b83315550fc34ef3f220a57 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 27 Aug 2015 11:58:48 +0100 Subject: [PATCH] Factor out common loop receiving from netlink --- net/if.go | 47 ++++++++++++++++++++++++++++------------------- net/route.go | 49 ++++++++++++++++++++++--------------------------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/net/if.go b/net/if.go index 8270bcec..b99993ec 100644 --- a/net/if.go +++ b/net/if.go @@ -26,7 +26,7 @@ func ensureInterface(s *nl.NetlinkSocket, ifaceName string) (*net.Interface, err if iface, err := findInterface(ifaceName); err == nil { return iface, nil } - waitForIfUp(s, ifaceName) + netlinkReceiveUntil(s, matchIfName(ifaceName)) iface, err := findInterface(ifaceName) return iface, err } @@ -48,7 +48,7 @@ func EnsureInterfaceAndMcastRoute(ifaceName string) (*net.Interface, error) { if CheckRouteExists(ifaceName, dest) { return iface, err } - waitForRoute(s, ifaceName, dest) + netlinkReceiveUntil(s, matchRoute(ifaceName, dest)) return iface, err } @@ -62,30 +62,39 @@ func findInterface(ifaceName string) (iface *net.Interface, err error) { return } -func waitForIfUp(s *nl.NetlinkSocket, ifaceName string) error { +func netlinkReceiveUntil(s *nl.NetlinkSocket, f func(syscall.NetlinkMessage) (bool, error)) error { for { msgs, err := s.Receive() if err != nil { return err } for _, m := range msgs { - switch m.Header.Type { - case syscall.RTM_NEWLINK: // receive this type for link 'up' - ifmsg := nl.DeserializeIfInfomsg(m.Data) - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return err - } - name := "" - for _, attr := range attrs { - if attr.Attr.Type == syscall.IFA_LABEL { - name = string(attr.Value[:len(attr.Value)-1]) - } - } - if ifaceName == name && ifmsg.Flags&syscall.IFF_UP != 0 { - return nil - } + if done, err := f(m); done { + return err } } } } + +func matchIfName(ifaceName string) func(m syscall.NetlinkMessage) (bool, error) { + return func(m syscall.NetlinkMessage) (bool, error) { + switch m.Header.Type { + case syscall.RTM_NEWLINK: // receive this type for link 'up' + ifmsg := nl.DeserializeIfInfomsg(m.Data) + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return true, err + } + name := "" + for _, attr := range attrs { + if attr.Attr.Type == syscall.IFA_LABEL { + name = string(attr.Value[:len(attr.Value)-1]) + } + } + if ifaceName == name && ifmsg.Flags&syscall.IFF_UP != 0 { + return true, nil + } + } + return false, nil + } +} diff --git a/net/route.go b/net/route.go index 990458b3..65dcfc89 100644 --- a/net/route.go +++ b/net/route.go @@ -66,35 +66,30 @@ func CheckRouteExists(ifaceName string, dest net.IP) bool { return found } -func waitForRoute(s *nl.NetlinkSocket, ifaceName string, dest net.IP) error { - native := nl.NativeEndian() - for { - msgs, err := s.Receive() - if err != nil { - return err - } - for _, m := range msgs { - switch m.Header.Type { - case syscall.RTM_NEWROUTE: - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return err - } - var ip net.IP - var link netlink.Link - for _, attr := range attrs { - switch attr.Attr.Type { - case syscall.RTA_DST: - ip = attr.Value - case syscall.RTA_OIF: - index := int(native.Uint32(attr.Value[0:4])) - link, _ = netlink.LinkByIndex(index) - } - } - if link.Attrs().Name == ifaceName && ip.Equal(dest) { - return nil +func matchRoute(ifaceName string, dest net.IP) func(m syscall.NetlinkMessage) (bool, error) { + return func(m syscall.NetlinkMessage) (bool, error) { + switch m.Header.Type { + case syscall.RTM_NEWROUTE: + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return true, err + } + var ip net.IP + var link netlink.Link + for _, attr := range attrs { + switch attr.Attr.Type { + case syscall.RTA_DST: + ip = attr.Value + case syscall.RTA_OIF: + native := nl.NativeEndian() + index := int(native.Uint32(attr.Value[0:4])) + link, _ = netlink.LinkByIndex(index) } } + if link.Attrs().Name == ifaceName && ip.Equal(dest) { + return true, nil + } } + return false, nil } }