From 19b37b04d3d35d437209b193af641b3b9e283c3c Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm <max@sdn.clinic> Date: Sun, 24 Jun 2018 00:56:11 +0200 Subject: [PATCH] Don't propagate path with detected AS loops to LocRIB or other clients. Signed-off-by: Maximilian Wilhelm <max@sdn.clinic> --- routingtable/adjRIBIn/adj_rib_in.go | 33 +++++++++++++++++++++++---- routingtable/contributing_asn_list.go | 11 +++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go index 81416d9a..2d850024 100644 --- a/routingtable/adjRIBIn/adj_rib_in.go +++ b/routingtable/adjRIBIn/adj_rib_in.go @@ -3,6 +3,7 @@ package adjRIBIn import ( "sync" + "github.com/bio-routing/bio-rd/protocols/bgp/packet" "github.com/bio-routing/bio-rd/routingtable/filter" "github.com/bio-routing/bio-rd/net" @@ -14,16 +15,18 @@ import ( // AdjRIBIn represents an Adjacency RIB In as described in RFC4271 type AdjRIBIn struct { routingtable.ClientManager - rt *routingtable.RoutingTable - mu sync.RWMutex - exportFilter *filter.Filter + rt *routingtable.RoutingTable + mu sync.RWMutex + exportFilter *filter.Filter + contributingASNs *routingtable.ContributingASNs } // New creates a new Adjacency RIB In func New(exportFilter *filter.Filter, contributingASNs *routingtable.ContributingASNs) *AdjRIBIn { a := &AdjRIBIn{ - rt: routingtable.NewRoutingTable(), - exportFilter: exportFilter, + rt: routingtable.NewRoutingTable(), + exportFilter: exportFilter, + contributingASNs: contributingASNs, } a.ClientManager = routingtable.NewClientManager(a) return a @@ -65,12 +68,32 @@ func (a *AdjRIBIn) AddPath(pfx net.Prefix, p *route.Path) error { return nil } + // Bail out - for all clients for now - if any of our ASNs is within the path + if a.ourASNsInPath(p) { + return nil + } + for _, client := range a.ClientManager.Clients() { client.AddPath(pfx, p) } return nil } +func (a *AdjRIBIn) ourASNsInPath(p *route.Path) bool { + // Don't accept path via iBGP which contain our ASN + ASPathAttr, _ := packet.ParseASPathStr(p.BGPPath.ASPath) + + for _, pathSegment := range ASPathAttr.Value.(packet.ASPath) { + for _, asn := range pathSegment.ASNs { + if a.contributingASNs.IsContributingASN(asn) { + return true + } + } + } + + return false +} + // RemovePath removes the path for prefix `pfx` func (a *AdjRIBIn) RemovePath(pfx net.Prefix, p *route.Path) bool { a.mu.Lock() diff --git a/routingtable/contributing_asn_list.go b/routingtable/contributing_asn_list.go index 0b0efca2..be981ce2 100644 --- a/routingtable/contributing_asn_list.go +++ b/routingtable/contributing_asn_list.go @@ -62,3 +62,14 @@ func (c *ContributingASNs) Remove(asn uint32) { } } } + +// IsContributingASN checks if a given ASN is part of the contributing ASNs +func (c *ContributingASNs) IsContributingASN(asn uint32) bool { + for _, cASN := range c.contributingASNs { + if asn == cASN.asn { + return true + } + } + + return false +} -- GitLab