From 60f8ce22620d914f6b798ad4fb85d3293ab8b42a Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm <max@sdn.clinic> Date: Tue, 3 Jul 2018 16:36:15 +0200 Subject: [PATCH] Use BGP OriginatorID instead of RouterID for tie breaking, if present. According to RFC4456 Section 9 the OriginatorID has to be used instead of the Originator/RouterID when breaking ties, if an OriginatorID set by a route reflector is present. In addition a shorter ClusterList (none -> lenght 0) wins the best path election right after the aforementioned check. Signed-off-by: Maximilian Wilhelm <max@sdn.clinic> --- route/bgp_path.go | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/route/bgp_path.go b/route/bgp_path.go index ee9aca83..4b0b852c 100644 --- a/route/bgp_path.go +++ b/route/bgp_path.go @@ -27,6 +27,8 @@ type BGPPath struct { Communities []uint32 LargeCommunities []types.LargeCommunity UnknownAttributes []types.UnknownPathAttribute + OriginatorID uint32 + ClusterList []uint32 } // Length get's the length of serialized path @@ -110,12 +112,33 @@ func (b *BGPPath) Compare(c *BGPPath) int8 { // e) TODO: interiour cost (hello IS-IS and OSPF) - // f) - if c.BGPIdentifier < b.BGPIdentifier { + // f) + RFC4456 9. (Route Reflection) + bgpIdentifierC := c.BGPIdentifier + bgpIdentifierB := b.BGPIdentifier + + // IF an OriginatorID (set by an RR) is present, use this instead of Originator + if c.OriginatorID != 0 { + bgpIdentifierC = c.OriginatorID + } + + if b.OriginatorID != 0 { + bgpIdentifierB = b.OriginatorID + } + + if bgpIdentifierC < bgpIdentifierB { + return 1 + } + + if bgpIdentifierC > bgpIdentifierB { + return -1 + } + + // Additionally check for the shorter ClusterList + if len(c.ClusterList) < len(b.ClusterList) { return 1 } - if c.BGPIdentifier > b.BGPIdentifier { + if len(c.ClusterList) > len(b.ClusterList) { return -1 } -- GitLab