@@ -20,12 +20,13 @@ const (
2020)
2121
2222type bgpServer struct {
23- listeners []listener
24- acceptCh chan net.Conn
25- peers * peerManager
26- routerID uint32
27- metrics * metricsService
28- logger log.LoggerInterface
23+ addListeners chan listener
24+ acceptedListeners []listener
25+ acceptCh chan net.Conn
26+ peers * peerManager
27+ routerID uint32
28+ metrics * metricsService
29+ logger log.LoggerInterface
2930}
3031
3132type BGPServer interface {
@@ -37,6 +38,7 @@ type BGPServer interface {
3738 GetPeerConfig (* bnet.IP ) * PeerConfig
3839 DisposePeer (* bnet.IP )
3940 GetPeers () []* bnet.IP
41+ GetPeerStatus (* bnet.IP ) string
4042 Metrics () (* metrics.BGPMetrics , error )
4143 GetRIBIn (peerIP * bnet.IP , afi uint16 , safi uint8 ) * adjRIBIn.AdjRIBIn
4244 GetRIBOut (peerIP * bnet.IP , afi uint16 , safi uint8 ) * adjRIBOut.AdjRIBOut
@@ -52,9 +54,10 @@ func NewBGPServer(routerID uint32) BGPServer {
5254
5355func newBGPServer (routerID uint32 ) * bgpServer {
5456 server := & bgpServer {
55- peers : newPeerManager (),
56- routerID : routerID ,
57- listeners : make ([]listener , 0 ),
57+ peers : newPeerManager (),
58+ routerID : routerID ,
59+ addListeners : make (chan listener , 256 ),
60+ acceptedListeners : make ([]listener , 0 ),
5861 logger : log .GetLogger ().WithFields (log.Fields {
5962 "router_id" : bnet .IPv4 (routerID ).String (),
6063 }),
@@ -99,12 +102,12 @@ func (d *dummyListener) setTCPMD5(net.IP, string) error {
99102func (b * bgpServer ) AddListener (l ... net.Listener ) error {
100103 for _ , l := range l {
101104 if ll , ok := l .(listener ); ok {
102- b .listeners = append ( b . listeners , ll )
105+ b .addListeners <- ll
103106 } else {
104107 d := & dummyListener {
105108 Listener : l ,
106109 logger : b .logger }
107- b .listeners = append ( b . listeners , d )
110+ b .addListeners <- d
108111 }
109112 }
110113
@@ -126,28 +129,30 @@ func (b *bgpServer) AddListenerFromAddrString(addrs ...string) error {
126129 return nil
127130}
128131
129- func (b * bgpServer ) Start () error {
130- if len (b .listeners ) > 0 {
131- acceptCh := make (chan net.Conn , 4096 )
132-
133- for _ , addr := range b .listeners {
134- go func (addr listener ) {
135- for {
136- conn , err := addr .Accept ()
137-
138- if err != nil {
139- b .logger .Errorf ("failed to accept connection: %v" , err )
140- continue
141- }
142-
143- acceptCh <- conn
144- }
145- }(addr )
132+ func (b * bgpServer ) accept (addr listener , acceptCh chan net.Conn ) {
133+ for {
134+ conn , err := addr .Accept ()
135+
136+ if err != nil {
137+ b .logger .Errorf ("failed to accept connection: %v" , err )
138+ continue
146139 }
147- b .acceptCh = acceptCh
148140
149- go b . incomingConnectionWorker ()
141+ acceptCh <- conn
150142 }
143+ }
144+
145+ func (b * bgpServer ) Start () error {
146+ b .acceptCh = make (chan net.Conn , 4096 )
147+
148+ go b .incomingConnectionWorker ()
149+
150+ go func () {
151+ for addr := range b .addListeners {
152+ go b .accept (addr , b .acceptCh )
153+ b .acceptedListeners = append (b .acceptedListeners , addr )
154+ }
155+ }()
151156
152157 return nil
153158}
@@ -264,7 +269,7 @@ func (b *bgpServer) AddPeer(c PeerConfig) error {
264269 }
265270
266271 if c .AuthenticationKey != "" {
267- for _ , l := range b .listeners {
272+ for _ , l := range b .acceptedListeners {
268273 err = l .setTCPMD5 (c .PeerAddress .ToNetIP (), c .AuthenticationKey )
269274 if err != nil {
270275 return fmt .Errorf ("unable to set TCP MD5 secret: %w" , err )
@@ -298,6 +303,19 @@ func (b *bgpServer) GetPeerConfig(addr *bnet.IP) *PeerConfig {
298303 return nil
299304}
300305
306+ // GetPeerStatus gets the status of a BGP peer by its address
307+ func (b * bgpServer ) GetPeerStatus (addr * bnet.IP ) string {
308+ p := b .peers .get (addr )
309+ if p != nil {
310+ p .fsms [0 ].stateMu .RLock ()
311+ defer p .fsms [0 ].stateMu .RUnlock ()
312+
313+ return stateName (p .fsms [0 ].state )
314+ }
315+
316+ return ""
317+ }
318+
301319func (b * bgpServer ) DisposePeer (addr * bnet.IP ) {
302320 p := b .peers .get (addr )
303321 if p == nil {
0 commit comments