From 80dddfa1b934926de2a32c91f06fae7cef4e96e4 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 19 Aug 2015 11:38:52 +0100 Subject: [PATCH] Factor out common code to decode a binary netlink message into a Route struct --- route_linux.go | 79 ++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/route_linux.go b/route_linux.go index 9e76d44..42b980f 100644 --- a/route_linux.go +++ b/route_linux.go @@ -117,9 +117,7 @@ func RouteList(link Link, family int) ([]Route, error) { index = base.Index } - native := nl.NativeEndian() var res []Route -MsgLoop: for _, m := range msgs { msg := nl.DeserializeRtMsg(m) @@ -133,31 +131,14 @@ MsgLoop: continue } - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + route, err := DeserializeRoute(m) if err != nil { return nil, err } - route := Route{Scope: Scope(msg.Scope)} - for _, attr := range attrs { - switch attr.Attr.Type { - case syscall.RTA_GATEWAY: - route.Gw = net.IP(attr.Value) - case syscall.RTA_PREFSRC: - route.Src = net.IP(attr.Value) - case syscall.RTA_DST: - route.Dst = &net.IPNet{ - IP: attr.Value, - Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), - } - case syscall.RTA_OIF: - routeIndex := int(native.Uint32(attr.Value[0:4])) - if link != nil && routeIndex != index { - // Ignore routes from other interfaces - continue MsgLoop - } - route.LinkIndex = routeIndex - } + if link != nil && route.LinkIndex != index { + // Ignore routes from other interfaces + continue } res = append(res, route) } @@ -165,6 +146,36 @@ MsgLoop: return res, nil } +// DeserializeRoute decodes a binary netlink message into a Route struct +func DeserializeRoute(m []byte) (Route, error) { + route := Route{} + msg := nl.DeserializeRtMsg(m) + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return route, err + } + route.Scope = Scope(msg.Scope) + + native := nl.NativeEndian() + for _, attr := range attrs { + switch attr.Attr.Type { + case syscall.RTA_GATEWAY: + route.Gw = net.IP(attr.Value) + case syscall.RTA_PREFSRC: + route.Src = net.IP(attr.Value) + case syscall.RTA_DST: + route.Dst = &net.IPNet{ + IP: attr.Value, + Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), + } + case syscall.RTA_OIF: + routeIndex := int(native.Uint32(attr.Value[0:4])) + route.LinkIndex = routeIndex + } + } + return route, nil +} + // RouteGet gets a route to a specific destination from the host system. // Equivalent to: 'ip route get'. func RouteGet(destination net.IP) ([]Route, error) { @@ -192,32 +203,12 @@ func RouteGet(destination net.IP) ([]Route, error) { return nil, err } - native := nl.NativeEndian() var res []Route for _, m := range msgs { - msg := nl.DeserializeRtMsg(m) - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + route, err := DeserializeRoute(m) if err != nil { return nil, err } - - route := Route{} - for _, attr := range attrs { - switch attr.Attr.Type { - case syscall.RTA_GATEWAY: - route.Gw = net.IP(attr.Value) - case syscall.RTA_PREFSRC: - route.Src = net.IP(attr.Value) - case syscall.RTA_DST: - route.Dst = &net.IPNet{ - IP: attr.Value, - Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), - } - case syscall.RTA_OIF: - routeIndex := int(native.Uint32(attr.Value[0:4])) - route.LinkIndex = routeIndex - } - } res = append(res, route) } return res, nil