From bd2a12113e4e83113919080bf28cc078c36ec23b Mon Sep 17 00:00:00 2001
From: Maximilian Wilhelm <max@sdn.clinic>
Date: Tue, 3 Jul 2018 16:33:49 +0200
Subject: [PATCH] Add configuration parameters for route reflection (RFC4456)

  Add configuration parameters for route reflection and propagate config
  options into peer and FSM.

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
---
 config/peer.go                          | 34 ++++++++-------
 protocols/bgp/server/fsm_established.go | 16 +++----
 protocols/bgp/server/peer.go            | 56 +++++++++++++------------
 protocols/bgp/server/update_sender.go   |  2 +
 routingtable/neighbor.go                |  6 +++
 5 files changed, 65 insertions(+), 49 deletions(-)

diff --git a/config/peer.go b/config/peer.go
index a192e317..12124c7c 100644
--- a/config/peer.go
+++ b/config/peer.go
@@ -10,20 +10,22 @@ import (
 
 // Peer defines the configuration for a BGP session
 type Peer struct {
-	AdminEnabled      bool
-	ReconnectInterval time.Duration
-	KeepAlive         time.Duration
-	HoldTime          time.Duration
-	LocalAddress      bnet.IP
-	PeerAddress       bnet.IP
-	LocalAS           uint32
-	PeerAS            uint32
-	Passive           bool
-	RouterID          uint32
-	AddPathSend       routingtable.ClientOptions
-	AddPathRecv       bool
-	ImportFilter      *filter.Filter
-	ExportFilter      *filter.Filter
-	RouteServerClient bool
-	IPv6              bool
+	AdminEnabled            bool
+	ReconnectInterval       time.Duration
+	KeepAlive               time.Duration
+	HoldTime                time.Duration
+	LocalAddress            bnet.IP
+	PeerAddress             bnet.IP
+	LocalAS                 uint32
+	PeerAS                  uint32
+	Passive                 bool
+	RouterID                uint32
+	AddPathSend             routingtable.ClientOptions
+	AddPathRecv             bool
+	ImportFilter            *filter.Filter
+	ExportFilter            *filter.Filter
+	RouteServerClient       bool
+	RouteReflectorClient    bool
+	RouteReflectorClusterID uint32
+	IPv6                    bool
 }
diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go
index 3c5d9605..d881fa7e 100644
--- a/protocols/bgp/server/fsm_established.go
+++ b/protocols/bgp/server/fsm_established.go
@@ -77,13 +77,15 @@ func (s *establishedState) init() error {
 	}
 
 	n := &routingtable.Neighbor{
-		Type:              route.BGPPathType,
-		Address:           s.fsm.peer.addr,
-		IBGP:              s.fsm.peer.localASN == s.fsm.peer.peerASN,
-		LocalASN:          s.fsm.peer.localASN,
-		RouteServerClient: s.fsm.peer.routeServerClient,
-		LocalAddress:      localAddr,
-		CapAddPathRX:      s.fsm.options.AddPathRX,
+		Type:                 route.BGPPathType,
+		Address:              s.fsm.peer.addr,
+		IBGP:                 s.fsm.peer.localASN == s.fsm.peer.peerASN,
+		LocalASN:             s.fsm.peer.localASN,
+		RouteServerClient:    s.fsm.peer.routeServerClient,
+		LocalAddress:         localAddr,
+		CapAddPathRX:         s.fsm.options.AddPathRX,
+		RouteReflectorClient: s.fsm.peer.routeReflectorClient,
+		ClusterID:            s.fsm.peer.clusterID,
 	}
 
 	s.fsm.adjRIBOut = adjRIBOut.New(n, s.fsm.peer.exportFilter)
diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go
index 638d8b03..7e33cd5c 100644
--- a/protocols/bgp/server/peer.go
+++ b/protocols/bgp/server/peer.go
@@ -28,17 +28,19 @@ type peer struct {
 	fsms   []*FSM
 	fsmsMu sync.Mutex
 
-	rib               *locRIB.LocRIB
-	routerID          uint32
-	addPathSend       routingtable.ClientOptions
-	addPathRecv       bool
-	reconnectInterval time.Duration
-	keepaliveTime     time.Duration
-	holdTime          time.Duration
-	optOpenParams     []packet.OptParam
-	importFilter      *filter.Filter
-	exportFilter      *filter.Filter
-	routeServerClient bool
+	rib                  *locRIB.LocRIB
+	routerID             uint32
+	addPathSend          routingtable.ClientOptions
+	addPathRecv          bool
+	reconnectInterval    time.Duration
+	keepaliveTime        time.Duration
+	holdTime             time.Duration
+	optOpenParams        []packet.OptParam
+	importFilter         *filter.Filter
+	exportFilter         *filter.Filter
+	routeServerClient    bool
+	routeReflectorClient bool
+	clusterID            uint32
 }
 
 func (p *peer) snapshot() PeerInfo {
@@ -106,21 +108,23 @@ func newPeer(c config.Peer, rib *locRIB.LocRIB, server *bgpServer) (*peer, error
 		c.LocalAS = server.localASN
 	}
 	p := &peer{
-		server:            server,
-		addr:              c.PeerAddress,
-		peerASN:           c.PeerAS,
-		localASN:          c.LocalAS,
-		fsms:              make([]*FSM, 0),
-		rib:               rib,
-		addPathSend:       c.AddPathSend,
-		addPathRecv:       c.AddPathRecv,
-		reconnectInterval: c.ReconnectInterval,
-		keepaliveTime:     c.KeepAlive,
-		holdTime:          c.HoldTime,
-		optOpenParams:     make([]packet.OptParam, 0),
-		importFilter:      filterOrDefault(c.ImportFilter),
-		exportFilter:      filterOrDefault(c.ExportFilter),
-		routeServerClient: c.RouteServerClient,
+		server:               server,
+		addr:                 c.PeerAddress,
+		peerASN:              c.PeerAS,
+		localASN:             c.LocalAS,
+		fsms:                 make([]*FSM, 0),
+		rib:                  rib,
+		addPathSend:          c.AddPathSend,
+		addPathRecv:          c.AddPathRecv,
+		reconnectInterval:    c.ReconnectInterval,
+		keepaliveTime:        c.KeepAlive,
+		holdTime:             c.HoldTime,
+		optOpenParams:        make([]packet.OptParam, 0),
+		importFilter:         filterOrDefault(c.ImportFilter),
+		exportFilter:         filterOrDefault(c.ExportFilter),
+		routeServerClient:    c.RouteServerClient,
+		routeReflectorClient: c.RouteReflectorClient,
+		clusterID:            c.RouteReflectorClusterID,
 	}
 	p.fsms = append(p.fsms, NewActiveFSM2(p))
 
diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go
index a223ee17..146abf0f 100644
--- a/protocols/bgp/server/update_sender.go
+++ b/protocols/bgp/server/update_sender.go
@@ -17,6 +17,7 @@ type UpdateSender struct {
 	routingtable.ClientManager
 	fsm       *FSM
 	iBGP      bool
+	rrClient  bool
 	toSendMu  sync.Mutex
 	toSend    map[string]*pathPfxs
 	destroyCh chan struct{}
@@ -31,6 +32,7 @@ func newUpdateSender(fsm *FSM) *UpdateSender {
 	return &UpdateSender{
 		fsm:       fsm,
 		iBGP:      fsm.peer.localASN == fsm.peer.peerASN,
+		rrClient:  fsm.peer.routeReflectorClient,
 		destroyCh: make(chan struct{}),
 		toSend:    make(map[string]*pathPfxs),
 	}
diff --git a/routingtable/neighbor.go b/routingtable/neighbor.go
index bf6e97c6..6c0f24b5 100644
--- a/routingtable/neighbor.go
+++ b/routingtable/neighbor.go
@@ -22,6 +22,12 @@ type Neighbor struct {
 	// Peer is a route server client
 	RouteServerClient bool
 
+	// Peer is a route reflector client
+	RouteReflectorClient bool
+
+	// Our route reflection clusterID
+	ClusterID uint32
+
 	// CapAddPathRX indicates if the peer supports receiving multiple BGP paths
 	CapAddPathRX bool
 }
-- 
GitLab