From a2c125fb6cb3386f5a160c8f5205fedd0ee1c382 Mon Sep 17 00:00:00 2001 From: Anton Aksola Date: Fri, 9 Oct 2015 11:09:44 +0300 Subject: [PATCH] Add support for setting nexthop flags for routes There are few nexthop flags that are usable in some scenarios: onlink and pervasive. This patch allows to set, clear and list them. --- route.go | 40 ++++++++++++++++++++++++++++++++++++++-- route_linux.go | 2 ++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/route.go b/route.go index 578270f..789d39f 100644 --- a/route.go +++ b/route.go @@ -17,6 +17,13 @@ const ( SCOPE_NOWHERE Scope = syscall.RT_SCOPE_NOWHERE ) +type NextHopFlag int + +const ( + FLAG_ONLINK NextHopFlag = syscall.RTNH_F_ONLINK + FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE +) + // Route represents a netlink route. A route is associated with a link, // has a destination network, an optional source ip, and optional // gateway. Advanced route parameters and non-main routing tables are @@ -27,11 +34,40 @@ type Route struct { Dst *net.IPNet Src net.IP Gw net.IP + Flags int } func (r Route) String() string { - return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s}", r.LinkIndex, r.Dst, - r.Src, r.Gw) + return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s}", r.LinkIndex, r.Dst, + r.Src, r.Gw, r.ListFlags()) +} + +func (r *Route) SetFlag(flag NextHopFlag) { + r.Flags |= int(flag) +} + +func (r *Route) ClearFlag(flag NextHopFlag) { + r.Flags &^= int(flag) +} + +type flagString struct { + f NextHopFlag + s string +} + +var testFlags = []flagString{ + flagString{f: FLAG_ONLINK, s: "onlink"}, + flagString{f: FLAG_PERVASIVE, s: "pervasive"}, +} + +func (r *Route) ListFlags() []string { + var flags []string + for _, tf := range testFlags { + if r.Flags&int(tf.f) != 0 { + flags = append(flags, tf.s) + } + } + return flags } // RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE diff --git a/route_linux.go b/route_linux.go index 693e6cb..c8910e2 100644 --- a/route_linux.go +++ b/route_linux.go @@ -30,6 +30,7 @@ func routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error { } msg.Scope = uint8(route.Scope) + msg.Flags = uint32(route.Flags) family := -1 var rtAttrs []*nl.RtAttr @@ -155,6 +156,7 @@ func deserializeRoute(m []byte) (Route, error) { return route, err } route.Scope = Scope(msg.Scope) + route.Flags = int(msg.Flags) native := nl.NativeEndian() for _, attr := range attrs {