diff --git a/config/netlink.go b/config/netlink.go index 3b18b77353604170235d85b63f65f4d663890033..6fc1937d5908101cddac7a9a3681c4b699a844a6 100644 --- a/config/netlink.go +++ b/config/netlink.go @@ -8,10 +8,10 @@ import ( // Constants for default routing tables in the Linux Kernel const ( - RtLocal int = 255 // according to man ip-route: 255 is reserved fro built-in use - RtMain int = 254 // This is the default table where routes are inserted - RtDefault int = 253 // according to man ip-route: 253 is reserved fro built-in use - RtUnspec int = 0 // according to man ip-route: 0 is reserved fro built-in use + RtLocal uint32 = 255 // according to man ip-route: 255 is reserved for built-in use + RtMain uint32 = 254 // This is the default table where routes are inserted + RtDefault uint32 = 253 // according to man ip-route: 253 is reserved for built-in use + RtUnspec uint32 = 0 // according to man ip-route: 0 is reserved for built-in use ) @@ -19,7 +19,7 @@ const ( type Netlink struct { HoldTime time.Duration UpdateInterval time.Duration - RoutingTable int + RoutingTable uint32 ImportFilter *filter.Filter // Which routes are imported from the Kernel ExportFilter *filter.Filter // Which routes are exported to the Kernel } diff --git a/net/prefix.go b/net/prefix.go index 3554c63322e0f414f234c8f6fc2008b4834e21ef..524a7643a61e134a5511f0b8e8f0bb6401a07451 100644 --- a/net/prefix.go +++ b/net/prefix.go @@ -3,7 +3,7 @@ package net import ( "fmt" "math" - "net" + gonet "net" "strconv" "strings" ) @@ -22,8 +22,8 @@ func NewPfx(addr IP, pfxlen uint8) Prefix { } } -// NewPfxFromIPNet creates a Prefix object from an net.IPNet object -func NewPfxFromIPNet(ipNet *net.IPNet) Prefix { +// NewPfxFromIPNet creates a Prefix object from an gonet.IPNet object +func NewPfxFromIPNet(ipNet *gonet.IPNet) Prefix { ones, _ := ipNet.Mask.Size() ip, _ := IPFromBytes(ipNet.IP) @@ -72,16 +72,16 @@ func (pfx Prefix) String() string { return fmt.Sprintf("%s/%d", pfx.addr, pfx.pfxlen) } -// GetIPNet returns the net.IP object for a Prefix object -func (pfx Prefix) GetIPNet() *net.IPNet { - var dstNetwork net.IPNet +// GetIPNet returns the gonet.IP object for a Prefix object +func (pfx Prefix) GetIPNet() *gonet.IPNet { + var dstNetwork gonet.IPNet dstNetwork.IP = pfx.Addr().Bytes() pfxLen := int(pfx.Pfxlen()) if pfx.Addr().IsIPv4() { - dstNetwork.Mask = net.CIDRMask(pfxLen, 32) + dstNetwork.Mask = gonet.CIDRMask(pfxLen, 32) } else { - dstNetwork.Mask = net.CIDRMask(pfxLen, 128) + dstNetwork.Mask = gonet.CIDRMask(pfxLen, 128) } return &dstNetwork diff --git a/protocols/netlink/netlink_reader.go b/protocols/netlink/netlink_reader.go index b4d16ea50b2f9994dc371d8c8fefca31f97d5c64..abe223070c7861d526ba53066ab8d0d9a07e8e0f 100644 --- a/protocols/netlink/netlink_reader.go +++ b/protocols/netlink/netlink_reader.go @@ -44,14 +44,12 @@ func NewNetlinkReader(options *config.Netlink) *NetlinkReader { // Read reads routes from the kernel func (nr *NetlinkReader) Read() { - log.WithField("rt_table", nr.options.RoutingTable).Info("Started netlink server") - // Start fetching the kernel routes after the hold time time.Sleep(nr.options.HoldTime) for { // Family doesn't matter. I only filter by the rt_table here - routes, err := netlink.RouteListFiltered(IPFamily4, &netlink.Route{Table: nr.options.RoutingTable}, netlink.RT_FILTER_TABLE) + routes, err := netlink.RouteListFiltered(int(IPFamily4), &netlink.Route{Table: int(nr.options.RoutingTable)}, netlink.RT_FILTER_TABLE) if err != nil { log.WithError(err).Panic("Failed to read routes from kernel") } @@ -96,8 +94,7 @@ func (nr *NetlinkReader) addPathsToClients(routes []netlink.Route) { nr.mu.RUnlock() for _, r := range advertise { - // Is it a BIO-Written route? if so, skip it, dont advertise it - if r.Protocol == route.ProtoBio { + if isBioRoute(r) { log.WithFields(routeLogFields(r)).Debug("Skipping bio route") continue } @@ -113,7 +110,6 @@ func (nr *NetlinkReader) addPathsToClients(routes []netlink.Route) { continue } - // Apply filter (if existing) if nr.filter != nil { var reject bool // TODO: Implement filter that cann handle netlinkRoute objects @@ -138,6 +134,11 @@ func (nr *NetlinkReader) addPathsToClients(routes []netlink.Route) { } } +// Is route a BIO-Written route? +func isBioRoute(r netlink.Route) bool { + return uint32(r.Protocol) == route.ProtoBio +} + // Remove given paths from clients func (nr *NetlinkReader) removePathsFromClients(routes []netlink.Route) { nr.mu.RLock() @@ -169,7 +170,6 @@ func (nr *NetlinkReader) removePathsFromClients(routes []netlink.Route) { continue } - // Apply filter (if existing) if nr.filter != nil { var reject bool // TODO: Implement filter that cann handle netlinkRoute objects diff --git a/protocols/netlink/netlink_writer.go b/protocols/netlink/netlink_writer.go index 80bae679c65587d1b2d8cf2415a94633cbbc0ac0..1ebe54205ce1b86105788401a5605276bd7be6a8 100644 --- a/protocols/netlink/netlink_writer.go +++ b/protocols/netlink/netlink_writer.go @@ -19,16 +19,16 @@ type NetlinkWriter struct { filter *filter.Filter // Routingtable for buffering, to ensure no double writes (a.k.a rtnetlink: file exists) - mu sync.RWMutex - pt map[bnet.Prefix][]*route.Path + mu sync.RWMutex + pathTable map[bnet.Prefix][]*route.Path } // NewNetlinkWriter creates a new NetlinkWriter object and returns the pointer to it func NewNetlinkWriter(options *config.Netlink) *NetlinkWriter { return &NetlinkWriter{ - options: options, - filter: options.ExportFilter, - pt: make(map[bnet.Prefix][]*route.Path), + options: options, + filter: options.ExportFilter, + pathTable: make(map[bnet.Prefix][]*route.Path), } } @@ -56,19 +56,19 @@ func (nw *NetlinkWriter) Unregister(routingtable.RouteTableClient) { func (nw *NetlinkWriter) RouteCount() int64 { nw.mu.RLock() defer nw.mu.RUnlock() - return int64(len(nw.pt)) + return int64(len(nw.pathTable)) } // AddPath adds a path to the Kernel using netlink. This function is triggered by the loc_rib, cause we are subscribed as client in the loc_rib func (nw *NetlinkWriter) AddPath(pfx bnet.Prefix, path *route.Path) error { // check if for this prefix already a route is existing - existingPaths, ok := nw.pt[pfx] + existingPaths, ok := nw.pathTable[pfx] // if no route exists, add that route if existingPaths == nil || !ok { paths := make([]*route.Path, 1) paths = append(paths, path) - nw.pt[pfx] = paths + nw.pathTable[pfx] = paths // add the route to kernel return nw.addKernel(pfx, path) @@ -82,7 +82,7 @@ func (nw *NetlinkWriter) AddPath(pfx bnet.Prefix, path *route.Path) error { } existingPaths = append(existingPaths, path) - nw.pt[pfx] = existingPaths + nw.pathTable[pfx] = existingPaths // now add to netlink return nw.addKernel(pfx, path) @@ -91,7 +91,7 @@ func (nw *NetlinkWriter) AddPath(pfx bnet.Prefix, path *route.Path) error { // RemovePath removes a path from the Kernel using netlink This function is triggered by the loc_rib, cause we are subscribed as client in the loc_rib func (nw *NetlinkWriter) RemovePath(pfx bnet.Prefix, path *route.Path) bool { // check if for this prefix already a route is existing - existingPaths, ok := nw.pt[pfx] + existingPaths, ok := nw.pathTable[pfx] // if no route exists, nothing to do if existingPaths == nil || !ok { @@ -118,7 +118,7 @@ func (nw *NetlinkWriter) RemovePath(pfx bnet.Prefix, path *route.Path) bool { if remove { existingPaths = append(existingPaths[:removeIdx], existingPaths[removeIdx+1:]...) - nw.pt[pfx] = existingPaths + nw.pathTable[pfx] = existingPaths } return true @@ -201,8 +201,8 @@ func (nw *NetlinkWriter) createRouteFromNetlink(pfx bnet.Prefix, path *route.Pat Gw: nlPath.NextHop.Bytes(), Priority: nlPath.Priority, Type: nlPath.Type, - Table: nw.options.RoutingTable, // config dependent - Protocol: route.ProtoBio, // fix + Table: int(nw.options.RoutingTable), // config dependent + Protocol: route.ProtoBio, // fix }, nil } @@ -220,8 +220,8 @@ func (nw *NetlinkWriter) createRouteFromBGPPath(pfx bnet.Prefix, path *route.Pat return &netlink.Route{ Dst: pfx.GetIPNet(), Gw: bgpPath.NextHop.Bytes(), - Table: nw.options.RoutingTable, // config dependent - Protocol: route.ProtoBio, // fix + Table: int(nw.options.RoutingTable), // config dependent + Protocol: route.ProtoBio, // fix }, nil }