diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go index 81416d9a488ac25711946d8b64f8bfe316a31a5a..2d8500240de4dcc34b571996ea5b50514c414c4a 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 0b0efca268d477d59728bbf44151f75d733845f3..be981ce240e59daa8d6c476d40a3768a2bc89a93 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 +}