Skip to content
Snippets Groups Projects
Commit 19b37b04 authored by Maximilian Wilhelm's avatar Maximilian Wilhelm
Browse files

Don't propagate path with detected AS loops to LocRIB or other clients.

parent b67c2b5d
No related branches found
No related tags found
No related merge requests found
......@@ -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()
......
......@@ -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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment