From fd9f32a735625a667db5765292b34e989dce3bc0 Mon Sep 17 00:00:00 2001
From: takt <oliver.peter.herms@gmail.com>
Date: Sun, 3 Feb 2019 18:59:32 +0100
Subject: [PATCH] Add BGP learning benchmark (#190)

* Completing benchmark

* Fix atomic stuff
---
 protocols/bgp/server/fsm_established.go |  1 -
 protocols/bgp/server/peer.go            |  6 +++++-
 protocols/bgp/server/server.go          | 22 +++++++++++++++++-----
 protocols/bgp/server/tcplistener.go     |  2 +-
 routingtable/locRIB/loc_rib.go          | 19 +++++++++++++++++++
 5 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go
index 153a41e6..ae4265e7 100644
--- a/protocols/bgp/server/fsm_established.go
+++ b/protocols/bgp/server/fsm_established.go
@@ -32,7 +32,6 @@ func (s establishedState) run() (state, string) {
 	}
 
 	opt := s.fsm.decodeOptions()
-
 	for {
 		select {
 		case e := <-s.fsm.eventCh:
diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go
index c2db07d7..0fe90fad 100644
--- a/protocols/bgp/server/peer.go
+++ b/protocols/bgp/server/peer.go
@@ -17,6 +17,7 @@ type peer struct {
 	server    *bgpServer
 	addr      bnet.IP
 	localAddr bnet.IP
+	passive   bool
 	peerASN   uint32
 	localASN  uint32
 
@@ -123,6 +124,7 @@ func newPeer(c config.Peer, server *bgpServer) (*peer, error) {
 	p := &peer{
 		server:               server,
 		addr:                 c.PeerAddress,
+		passive:              c.Passive,
 		peerASN:              c.PeerAS,
 		localASN:             c.LocalAS,
 		fsms:                 make([]*FSM, 0),
@@ -185,7 +187,9 @@ func newPeer(c config.Peer, server *bgpServer) (*peer, error) {
 		Value: caps,
 	})
 
-	p.fsms = append(p.fsms, NewActiveFSM(p))
+	if !p.passive {
+		p.fsms = append(p.fsms, NewActiveFSM(p))
+	}
 
 	return p, nil
 }
diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go
index 7de68483..7c8d5aee 100644
--- a/protocols/bgp/server/server.go
+++ b/protocols/bgp/server/server.go
@@ -15,7 +15,7 @@ const (
 
 type bgpServer struct {
 	listeners []*TCPListener
-	acceptCh  chan *net.TCPConn
+	acceptCh  chan net.Conn
 	peers     *peerManager
 	routerID  uint32
 	localASN  uint32
@@ -25,10 +25,13 @@ type BGPServer interface {
 	RouterID() uint32
 	Start(*config.Global) error
 	AddPeer(config.Peer) error
+	ConnectMockPeer(peer config.Peer, con net.Conn)
 }
 
 func NewBgpServer() BGPServer {
-	return &bgpServer{}
+	return &bgpServer{
+		peers: newPeerManager(),
+	}
 }
 
 func (b *bgpServer) RouterID() uint32 {
@@ -45,7 +48,7 @@ func (b *bgpServer) Start(c *config.Global) error {
 	b.localASN = c.LocalASN
 
 	if c.Listen {
-		acceptCh := make(chan *net.TCPConn, 4096)
+		acceptCh := make(chan net.Conn, 4096)
 		for _, addr := range c.LocalAddressList {
 			l, err := NewTCPListener(addr, c.Port, acceptCh)
 			if err != nil {
@@ -66,7 +69,6 @@ func (b *bgpServer) incomingConnectionWorker() {
 		c := <-b.acceptCh
 
 		peerAddr, _ := bnetutils.BIONetIPFromAddr(c.RemoteAddr().String())
-
 		peer := b.peers.get(peerAddr)
 		if peer == nil {
 			c.Close()
@@ -94,6 +96,14 @@ func (b *bgpServer) incomingConnectionWorker() {
 	}
 }
 
+func (b *bgpServer) ConnectMockPeer(peer config.Peer, con net.Conn) {
+	acceptCh := make(chan net.Conn, 4096)
+	b.acceptCh = acceptCh
+	go b.incomingConnectionWorker()
+
+	b.acceptCh <- con
+}
+
 func (b *bgpServer) AddPeer(c config.Peer) error {
 	peer, err := newPeer(c, b)
 	if err != nil {
@@ -102,7 +112,9 @@ func (b *bgpServer) AddPeer(c config.Peer) error {
 
 	peer.routerID = c.RouterID
 	b.peers.add(peer)
-	peer.Start()
+	if !c.Passive {
+		peer.Start()
+	}
 
 	return nil
 }
diff --git a/protocols/bgp/server/tcplistener.go b/protocols/bgp/server/tcplistener.go
index 04607c74..9b4baca5 100644
--- a/protocols/bgp/server/tcplistener.go
+++ b/protocols/bgp/server/tcplistener.go
@@ -16,7 +16,7 @@ type TCPListener struct {
 	closeCh chan struct{}
 }
 
-func NewTCPListener(address net.IP, port uint16, ch chan *net.TCPConn) (*TCPListener, error) {
+func NewTCPListener(address net.IP, port uint16, ch chan net.Conn) (*TCPListener, error) {
 	proto := "tcp4"
 	if address.To4() == nil {
 		proto = "tcp6"
diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go
index fe4f2905..3890e26d 100644
--- a/routingtable/locRIB/loc_rib.go
+++ b/routingtable/locRIB/loc_rib.go
@@ -18,6 +18,12 @@ type LocRIB struct {
 	rt               *routingtable.RoutingTable
 	mu               sync.RWMutex
 	contributingASNs *routingtable.ContributingASNs
+	countTarget      *countTarget
+}
+
+type countTarget struct {
+	target uint64
+	ch     chan struct{}
 }
 
 // New creates a new routing information base
@@ -45,6 +51,14 @@ func (a *LocRIB) Count() uint64 {
 	return uint64(len(a.rt.Dump()))
 }
 
+// SetCountTarget sets a target and a channel to send a message to when a certain route count is reached
+func (a *LocRIB) SetCountTarget(count uint64, ch chan struct{}) {
+	a.countTarget = &countTarget{
+		target: count,
+		ch:     ch,
+	}
+}
+
 // UpdateNewClient sends current state to a new client
 func (a *LocRIB) UpdateNewClient(client routingtable.RouteTableClient) error {
 	a.mu.RLock()
@@ -89,6 +103,11 @@ func (a *LocRIB) AddPath(pfx net.Prefix, p *route.Path) error {
 	newRoute := r.Copy()
 
 	a.propagateChanges(oldRoute, newRoute)
+	if a.countTarget != nil {
+		if a.RouteCount() == int64(a.countTarget.target) {
+			a.countTarget.ch <- struct{}{}
+		}
+	}
 	return nil
 }
 
-- 
GitLab