use pools in routes decoding

This commit is contained in:
Annika Hannig 2022-11-16 10:25:02 +01:00
parent 83c3d857cc
commit a8c3c11fd2
5 changed files with 46 additions and 25 deletions

View File

@ -228,9 +228,9 @@ func (communities ExtCommunities) Unique() ExtCommunities {
// BGPInfo is a set of BGP attributes // BGPInfo is a set of BGP attributes
type BGPInfo struct { type BGPInfo struct {
Origin string `json:"origin"` Origin *string `json:"origin"`
AsPath []int `json:"as_path"` AsPath []int `json:"as_path"`
NextHop string `json:"next_hop"` NextHop *string `json:"next_hop"`
Communities Communities `json:"communities"` Communities Communities `json:"communities"`
LargeCommunities Communities `json:"large_communities"` LargeCommunities Communities `json:"large_communities"`
ExtCommunities ExtCommunities `json:"ext_communities"` ExtCommunities ExtCommunities `json:"ext_communities"`

View File

@ -10,8 +10,11 @@ import "log"
// Neighbors stores neighbor IDs // Neighbors stores neighbor IDs
var Neighbors *String var Neighbors *String
// Networks stores network ip addresses // Networks4 stores network ip v4 addresses
var Networks *String var Networks4 *String
// Networks6 stores network ip v6 addresses
var Networks6 *String
// Interfaces stores interfaces like: eth0, bond0 etc... // Interfaces stores interfaces like: eth0, bond0 etc...
var Interfaces *String var Interfaces *String
@ -36,7 +39,8 @@ func init() {
log.Println("initializing memory pools") log.Println("initializing memory pools")
Neighbors = NewString() Neighbors = NewString()
Networks = NewString() Networks4 = NewString()
Networks6 = NewString()
Interfaces = NewString() Interfaces = NewString()
Gateways4 = NewString() Gateways4 = NewString()
Gateways6 = NewString() Gateways6 = NewString()

View File

@ -13,6 +13,7 @@ import (
"github.com/alice-lg/alice-lg/pkg/api" "github.com/alice-lg/alice-lg/pkg/api"
"github.com/alice-lg/alice-lg/pkg/decoders" "github.com/alice-lg/alice-lg/pkg/decoders"
"github.com/alice-lg/alice-lg/pkg/pools"
) )
// Convert server time string to time // Convert server time string to time
@ -230,6 +231,8 @@ func parseNeighborsShort(bird ClientResponse, config Config) (api.NeighborsStatu
// Parse route bgp info // Parse route bgp info
func parseRouteBgpInfo(data interface{}) *api.BGPInfo { func parseRouteBgpInfo(data interface{}) *api.BGPInfo {
gwpool := pools.Gateways4 // Let's see
bgpData, ok := data.(map[string]interface{}) bgpData, ok := data.(map[string]interface{})
if !ok { if !ok {
// Info is missing // Info is missing
@ -245,9 +248,11 @@ func parseRouteBgpInfo(data interface{}) *api.BGPInfo {
med, _ := strconv.Atoi(decoders.String(bgpData["med"], "0")) med, _ := strconv.Atoi(decoders.String(bgpData["med"], "0"))
bgp := &api.BGPInfo{ bgp := &api.BGPInfo{
Origin: decoders.String(bgpData["origin"], "unknown"), Origin: pools.Origins.Acquire(
AsPath: asPath, decoders.String(bgpData["origin"], "unknown")),
NextHop: decoders.String(bgpData["next_hop"], "unknown"), AsPath: pools.ASPaths.Acquire(asPath),
NextHop: gwpool.Acquire(
decoders.String(bgpData["next_hop"], "unknown")),
LocalPref: localPref, LocalPref: localPref,
Med: med, Med: med,
Communities: communities, Communities: communities,
@ -308,6 +313,9 @@ func parseRouteData(
config Config, config Config,
keepDetails bool, keepDetails bool,
) *api.Route { ) *api.Route {
gwpool := pools.Gateways4 // Let's see
netpool := pools.Networks4 // same...
age := parseRelativeServerTime(rdata["age"], config) age := parseRelativeServerTime(rdata["age"], config)
rtype := decoders.StringList(rdata["type"]) rtype := decoders.StringList(rdata["type"])
bgpInfo := parseRouteBgpInfo(rdata["bgp"]) bgpInfo := parseRouteBgpInfo(rdata["bgp"])
@ -322,7 +330,6 @@ func parseRouteData(
details = json.RawMessage(detailsJSON) details = json.RawMessage(detailsJSON)
} }
// Pool: Gateways
gateway := decoders.String(rdata["gateway"], "unknown gateway") gateway := decoders.String(rdata["gateway"], "unknown gateway")
learntFrom := decoders.String(rdata["learnt_from"], "") learntFrom := decoders.String(rdata["learnt_from"], "")
if learntFrom == "" { if learntFrom == "" {
@ -330,17 +337,20 @@ func parseRouteData(
} }
route := &api.Route{ route := &api.Route{
ID: decoders.String(rdata["network"], "unknown"), ID: decoders.String(rdata["network"], "unknown"),
NeighborID: decoders.String(rdata["from_protocol"], "unknown neighbor"),
Network: decoders.String(rdata["network"], "unknown net"), NeighborID: pools.Neighbors.Acquire(
Interface: decoders.String(rdata["interface"], "unknown interface"), decoders.String(rdata["from_protocol"], "unknown neighbor")),
Network: netpool.Acquire(
decoders.String(rdata["network"], "unknown net")),
Interface: pools.Interfaces.Acquire(
decoders.String(rdata["interface"], "unknown interface")),
Metric: decoders.Int(rdata["metric"], -1), Metric: decoders.Int(rdata["metric"], -1),
Primary: decoders.Bool(rdata["primary"], false), Primary: decoders.Bool(rdata["primary"], false),
LearntFrom: learntFrom, LearntFrom: gwpool.Acquire(learntFrom),
Gateway: gateway, Gateway: gwpool.Acquire(gateway),
Age: age, Age: age,
Type: rtype, Type: pools.Types.Acquire(rtype),
BGP: bgpInfo, BGP: bgpInfo,
Details: &details, Details: &details,

View File

@ -118,16 +118,16 @@ func (b *GenericBirdwatcher) filterProtocolsPipe(
func (b *GenericBirdwatcher) filterRoutesByPeerOrLearntFrom( func (b *GenericBirdwatcher) filterRoutesByPeerOrLearntFrom(
routes api.Routes, routes api.Routes,
peer string, peerPtr *string,
learntFrom string, learntFromPtr *string,
) api.Routes { ) api.Routes {
resultRoutes := make(api.Routes, 0, len(routes)) resultRoutes := make(api.Routes, 0, len(routes))
// Choose routes with next_hop == gateway of this neighbor // Choose routes with next_hop == gateway of this neighbor
for _, route := range routes { for _, route := range routes {
if (route.Gateway == peer) || if (route.Gateway == peerPtr) ||
(route.Gateway == learntFrom) || (route.Gateway == learntFromPtr) ||
(route.LearntFrom == peer) { (route.LearntFrom == peerPtr) {
resultRoutes = append(resultRoutes, route) resultRoutes = append(resultRoutes, route)
} }
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/alice-lg/alice-lg/pkg/api" "github.com/alice-lg/alice-lg/pkg/api"
"github.com/alice-lg/alice-lg/pkg/decoders" "github.com/alice-lg/alice-lg/pkg/decoders"
"github.com/alice-lg/alice-lg/pkg/pools"
) )
// MultiTableBirdwatcher implements a birdwatcher with // MultiTableBirdwatcher implements a birdwatcher with
@ -365,6 +366,7 @@ func (src *MultiTableBirdwatcher) fetchRequiredRoutes(
// Perform route deduplication // Perform route deduplication
importedRoutes := api.Routes{} importedRoutes := api.Routes{}
if len(receivedRoutes) > 0 { if len(receivedRoutes) > 0 {
// TODO: maybe we can utilize the ptr here
peer := receivedRoutes[0].Gateway peer := receivedRoutes[0].Gateway
learntFrom := receivedRoutes[0].LearntFrom learntFrom := receivedRoutes[0].LearntFrom
@ -682,8 +684,8 @@ func (src *MultiTableBirdwatcher) AllRoutes(
// We load the filtered routes asynchronously with workers. // We load the filtered routes asynchronously with workers.
type fetchFilteredReq struct { type fetchFilteredReq struct {
protocolID string protocolID string
peer string peer *string
learntFrom string learntFrom *string
} }
reqQ := make(chan fetchFilteredReq, 1000) reqQ := make(chan fetchFilteredReq, 1000)
resQ := make(chan api.Routes, 1000) resQ := make(chan api.Routes, 1000)
@ -710,11 +712,16 @@ func (src *MultiTableBirdwatcher) AllRoutes(
}() }()
} }
gwpool := pools.Gateways4
// Fill request queue // Fill request queue
go func() { go func() {
for protocolID, protocolsData := range protocolsBgp["protocols"].(map[string]interface{}) { for protocolID, protocolsData := range protocolsBgp["protocols"].(map[string]interface{}) {
peer := protocolsData.(map[string]interface{})["neighbor_address"].(string) peer := gwpool.Acquire(
learntFrom := decoders.String(protocolsData.(map[string]interface{})["learnt_from"], peer) protocolsData.(map[string]interface{})["neighbor_address"].(string))
learntFrom := gwpool.Acquire(
decoders.String(protocolsData.(map[string]interface{})["learnt_from"], *peer))
reqQ <- fetchFilteredReq{ reqQ <- fetchFilteredReq{
protocolID: protocolID, protocolID: protocolID,
peer: peer, peer: peer,