summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJordan Whited <jwhited@subspace.com>2020-08-10 09:43:54 -0700
committerFUJITA Tomonori <fujita.tomonori@gmail.com>2020-08-12 20:56:11 +0900
commita4d5d004cc3d97c90de0c2d91f2312525e055d68 (patch)
tree88f5d6ed07117fa3ebd048c70db03ace2e5a6f1b
parentc6f0eba8f4d8544ede83c70d6b5f07560ff6c7ce (diff)
best path selection - compare neigh addr
-rw-r--r--internal/pkg/table/destination.go31
-rw-r--r--internal/pkg/table/destination_test.go22
2 files changed, 53 insertions, 0 deletions
diff --git a/internal/pkg/table/destination.go b/internal/pkg/table/destination.go
index 2880f662..0b438d78 100644
--- a/internal/pkg/table/destination.go
+++ b/internal/pkg/table/destination.go
@@ -50,6 +50,7 @@ const (
BPR_ROUTER_ID
BPR_OLDER
BPR_NON_LLGR_STALE
+ BPR_NEIGH_ADDR
)
var BestPathReasonStringMap = map[BestPathReason]string{
@@ -68,6 +69,7 @@ var BestPathReasonStringMap = map[BestPathReason]string{
BPR_ROUTER_ID: "Router ID",
BPR_OLDER: "Older",
BPR_NON_LLGR_STALE: "no LLGR Stale",
+ BPR_NEIGH_ADDR: "Neighbor Address",
}
func (r *BestPathReason) String() string {
@@ -481,6 +483,10 @@ func (dst *Destination) sort() BestPathReason {
reason = BPR_ROUTER_ID
}
if better == nil {
+ better = compareByNeighborAddress(path1, path2)
+ reason = BPR_NEIGH_ADDR
+ }
+ if better == nil {
reason = BPR_UNKNOWN
better = path1
}
@@ -918,6 +924,31 @@ func compareByRouterID(path1, path2 *Path) (*Path, error) {
}
}
+func compareByNeighborAddress(path1, path2 *Path) *Path {
+ // Select the route received from the peer with the lowest peer address as
+ // per RFC 4271 9.1.2.2. g
+ log.WithFields(log.Fields{
+ "Topic": "Table",
+ }).Debug("enter compareByNeighborAddress")
+
+ p1 := path1.GetSource().Address
+ if p1 == nil {
+ return path1
+ }
+ p2 := path2.GetSource().Address
+ if p2 == nil {
+ return path2
+ }
+
+ cmp := bytes.Compare(p1, p2)
+ if cmp < 0 {
+ return path1
+ } else if cmp > 0 {
+ return path2
+ }
+ return nil
+}
+
func compareByAge(path1, path2 *Path) *Path {
if !path1.IsIBGP() && !path2.IsIBGP() && !SelectionOptions.ExternalCompareRouterId {
age1 := path1.GetTimestamp().UnixNano()
diff --git a/internal/pkg/table/destination_test.go b/internal/pkg/table/destination_test.go
index b1c1b2e8..3534cb6c 100644
--- a/internal/pkg/table/destination_test.go
+++ b/internal/pkg/table/destination_test.go
@@ -118,6 +118,28 @@ func TestCalculate2(t *testing.T) {
assert.Equal(t, len(d.knownPathList), 3)
}
+func TestNeighAddrTieBreak(t *testing.T) {
+ nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0")
+
+ peer0 := &PeerInfo{AS: 65001, LocalAS: 1, Address: net.IP{2, 2, 2, 2}, ID: net.IP{2, 2, 2, 2}}
+
+ p0 := func() *Path {
+ aspath := bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001})})
+ attrs := []bgp.PathAttributeInterface{aspath, bgp.NewPathAttributeMultiExitDisc(0)}
+ return NewPath(peer0, nlri, false, attrs, time.Now(), false)
+ }()
+
+ peer1 := &PeerInfo{AS: 65001, LocalAS: 1, Address: net.IP{3, 3, 3, 3}, ID: net.IP{2, 2, 2, 2}} // same ID as peer0, separate eBGP session
+
+ p1 := func() *Path {
+ aspath := bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001})})
+ attrs := []bgp.PathAttributeInterface{aspath, bgp.NewPathAttributeMultiExitDisc(0)}
+ return NewPath(peer1, nlri, false, attrs, time.Now(), false)
+ }()
+
+ assert.Equal(t, compareByNeighborAddress(p0, p1), p0)
+}
+
func TestMedTieBreaker(t *testing.T) {
nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0")