Skip to content
Snippets Groups Projects
Unverified Commit 7fd338f8 authored by takt's avatar takt Committed by GitHub
Browse files

Merge pull request #40 from bio-routing/feature/well_known_communities

basic rfc1997 (well known communities) filter, code deduplication
parents 8916eda2 b9a06317
Branches
No related tags found
No related merge requests found
......@@ -6,6 +6,11 @@ import (
"strings"
)
const (
WellKnownCommunityNoExport = 0xFFFFFF01
WellKnownCommunityNoAdvertise = 0xFFFFFF02
)
func CommunityStringForUint32(v uint32) string {
e1 := v >> 16
e2 := v - e1<<16
......
......@@ -723,6 +723,7 @@ func (fsm *FSM) established() int {
n := &routingtable.Neighbor{
Type: route.BGPPathType,
Address: tnet.IPv4ToUint32(fsm.remote),
IBGP: fsm.remoteASN == fsm.localASN,
}
clientOptions := routingtable.ClientOptions{
......
......@@ -35,7 +35,7 @@ func (a *AdjRIBOut) UpdateNewClient(client routingtable.RouteTableClient) error
// AddPath replaces the path for prefix `pfx`. If the prefix doesn't exist it is added.
func (a *AdjRIBOut) AddPath(pfx net.Prefix, p *route.Path) error {
if a.isOwnPath(p) {
if !routingtable.ShouldPropagateUpdate(pfx, p, a.neighbor) {
return nil
}
......@@ -56,7 +56,7 @@ func (a *AdjRIBOut) AddPath(pfx net.Prefix, p *route.Path) error {
// RemovePath removes the path for prefix `pfx`
func (a *AdjRIBOut) RemovePath(pfx net.Prefix, p *route.Path) bool {
if a.isOwnPath(p) {
if !routingtable.ShouldPropagateUpdate(pfx, p, a.neighbor) {
return false
}
......@@ -77,19 +77,6 @@ func (a *AdjRIBOut) RemovePath(pfx net.Prefix, p *route.Path) bool {
return true
}
func (a *AdjRIBOut) isOwnPath(p *route.Path) bool {
if p.Type != a.neighbor.Type {
return false
}
switch p.Type {
case route.BGPPathType:
return p.BGPPath.Source == a.neighbor.Address
}
return false
}
func (a *AdjRIBOut) removePathsFromClients(pfx net.Prefix, paths []*route.Path) {
for _, path := range paths {
for _, client := range a.ClientManager.Clients() {
......
......@@ -37,7 +37,7 @@ func (a *AdjRIBOutAddPath) UpdateNewClient(client routingtable.RouteTableClient)
// AddPath adds path p to prefix `pfx`
func (a *AdjRIBOutAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
if a.isOwnPath(p) {
if !routingtable.ShouldPropagateUpdate(pfx, p, a.neighbor) {
return nil
}
......@@ -63,7 +63,7 @@ func (a *AdjRIBOutAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
// RemovePath removes the path for prefix `pfx`
func (a *AdjRIBOutAddPath) RemovePath(pfx net.Prefix, p *route.Path) bool {
if a.isOwnPath(p) {
if !routingtable.ShouldPropagateUpdate(pfx, p, a.neighbor) {
return false
}
......
......@@ -7,4 +7,7 @@ type Neighbor struct {
// Type is the type / protocol used for routing inforation communitation
Type uint8
// IBGP returns if local ASN is equal to remote ASN
IBGP bool
}
package routingtable
import (
"strings"
"github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/bio-routing/bio-rd/route"
log "github.com/sirupsen/logrus"
)
// ShouldPropagateUpdate performs some default checks and returns if an route update should be propagated to a neighbor
func ShouldPropagateUpdate(pfx net.Prefix, p *route.Path, n *Neighbor) bool {
return !isOwnPath(p, n) && !isDisallowedByCommunity(p, n)
}
func isOwnPath(p *route.Path, n *Neighbor) bool {
if p.Type != n.Type {
return false
}
switch p.Type {
case route.BGPPathType:
return p.BGPPath.Source == n.Address
}
return false
}
func isDisallowedByCommunity(p *route.Path, n *Neighbor) bool {
if p.BGPPath == nil || len(p.BGPPath.Communities) == 0 {
return false
}
strs := strings.Split(p.BGPPath.Communities, " ")
for _, str := range strs {
com, err := packet.ParseCommunityString(str)
if err != nil {
log.WithField("Sender", "routingtable.ShouldAnnounce()").
WithField("community", str).
WithError(err).
Error("Could not parse community")
continue
}
if (com == packet.WellKnownCommunityNoExport && !n.IBGP) || com == packet.WellKnownCommunityNoAdvertise {
return true
}
}
return false
}
package routingtable
import (
"net"
"testing"
bnet "github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/route"
"github.com/stretchr/testify/assert"
)
func TestShouldPropagateUpdate(t *testing.T) {
tests := []struct {
name string
communities string
neighbor Neighbor
expected bool
}{
{
name: "arbitrary path",
expected: true,
},
{
name: "path was received from this peer before",
communities: "(1,2)",
neighbor: Neighbor{
Type: route.BGPPathType,
Address: bnet.IPv4ToUint32(net.ParseIP("192.168.1.1")),
},
expected: false,
},
{
name: "path with no-export community",
communities: "(1,2) (65535,65281)",
expected: false,
},
{
name: "path with no-export community (iBGP)",
communities: "(1,2) (65535,65281)",
neighbor: Neighbor{
IBGP: true,
},
expected: true,
},
{
name: "path with no-advertise community",
communities: "(1,2) (65535,65282)",
expected: false,
},
{
name: "path with no-advertise community (iBGP)",
communities: "(1,2) (65535,65282)",
neighbor: Neighbor{
IBGP: true,
},
expected: false,
},
}
for _, test := range tests {
t.Run(test.name, func(te *testing.T) {
pfx := bnet.NewPfx(0, 32)
pa := &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: test.communities,
Source: bnet.IPv4ToUint32(net.ParseIP("192.168.1.1")),
},
}
res := ShouldPropagateUpdate(pfx, pa, &test.neighbor)
assert.Equal(te, test.expected, res)
})
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment