@@ -4,26 +4,22 @@ import (
44 "context"
55 "fmt"
66 "github.com/BaiMeow/NetworkMonitor/graph/fetch"
7+ "github.com/BaiMeow/NetworkMonitor/utils"
78 apipb "github.com/osrg/gobgp/v3/api"
89 gobgplog "github.com/osrg/gobgp/v3/pkg/log"
910 "github.com/osrg/gobgp/v3/pkg/server"
1011 "github.com/pkg/errors"
1112 "log"
12- "math"
1313 "net/netip"
1414 "time"
1515)
1616
1717func init () {
1818 fetch .Register ("bgp" , func (m map [string ]any ) (fetch.Fetcher , error ) {
19- asnRaw , ok := m ["asn" ].(int )
20- if ! ok {
21- return nil , fmt .Errorf ("asn is not int" )
22- }
23- if asnRaw > math .MaxUint32 || asnRaw < 0 {
24- return nil , fmt .Errorf ("invalid asn number: %d" , asnRaw )
19+ asn , err := utils .MustASN (m ["asn" ])
20+ if err != nil {
21+ return nil , fmt .Errorf ("asn is not valid asn: %v" , err )
2522 }
26- asn := uint32 (asnRaw )
2723
2824 routerIdRaw , ok := m ["router-id" ].(string )
2925 if ! ok {
@@ -58,107 +54,141 @@ func init() {
5854 logger := gobgplog .NewDefaultLogger ()
5955 logger .SetLevel (gobgplog .ErrorLevel )
6056 bgpServer := server .NewBgpServer (server .LoggerOption (logger ))
61- go bgpServer .Serve ()
62- if err := bgpServer .StartBgp (context .Background (), & apipb.StartBgpRequest {
63- Global : & apipb.Global {
64- Asn : asn ,
65- RouterId : routerIdRaw ,
66- ListenPort : int32 (port ),
67- UseMultiplePaths : true ,
68- },
69- }); err != nil {
70- return nil , err
57+ ctx , cancel := context .WithCancel (context .Background ())
58+ bgp := & BGP {
59+ s : bgpServer ,
60+ cancel : cancel ,
7161 }
72-
73- if mode == "listen" {
74- if err := bgpServer .AddPeerGroup (context .Background (), & apipb.AddPeerGroupRequest {
75- PeerGroup : & apipb.PeerGroup {
76- Conf : & apipb.PeerGroupConf {
77- PeerGroupName : "route-collector" ,
78- LocalAsn : asn ,
79- },
80- EbgpMultihop : & apipb.EbgpMultihop {
81- Enabled : true ,
62+ go bgpServer .Serve ()
63+ go func () {
64+ for {
65+ select {
66+ case <- ctx .Done ():
67+ return
68+ default :
69+ }
70+ if err := bgpServer .StartBgp (ctx , & apipb.StartBgpRequest {
71+ Global : & apipb.Global {
72+ Asn : asn ,
73+ RouterId : routerIdRaw ,
74+ ListenPort : int32 (port ),
75+ UseMultiplePaths : true ,
8276 },
83- AfiSafis : []* apipb.AfiSafi {{
84- Config : & apipb.AfiSafiConfig {
85- Family : & apipb.Family {
86- Afi : apipb .Family_AFI_IP ,
87- Safi : apipb .Family_SAFI_UNICAST ,
88- },
89- },
90- AddPaths : & apipb.AddPaths {
91- Config : & apipb.AddPathsConfig {
92- Receive : true ,
93- },
94- },
95- }},
96- },
97- }); err != nil {
98- return nil , err
99- }
100- if err := bgpServer .AddDynamicNeighbor (context .Background (), & apipb.AddDynamicNeighborRequest {
101- DynamicNeighbor : & apipb.DynamicNeighbor {
102- Prefix : "0.0.0.0/0" ,
103- PeerGroup : "route-collector" ,
104- },
105- }); err != nil {
106- return nil , err
107- }
108- } else {
109- peerASN , ok := m ["peer-asn" ].(int )
110- if ! ok {
111- return nil , fmt .Errorf ("peer-asn is not int" )
112- }
113- if peerASN > math .MaxUint32 || peerASN < 0 {
114- return nil , fmt .Errorf ("invalid peer-asn number: %d" , asnRaw )
115- }
116-
117- neighborAddr , ok := m ["neighbor-addr" ].(string )
118- if ! ok {
119- return nil , fmt .Errorf ("neighbor-addr is not string" )
120- }
121- if _ , err := netip .ParseAddr (neighborAddr ); err != nil {
122- return nil , fmt .Errorf ("invalid neighbor-addr: %s" , neighborAddr )
77+ }); err != nil {
78+ log .Printf ("start bgp fail: %v" , err )
79+ time .Sleep (time .Second * 3 )
80+ continue
81+ }
82+ break
12383 }
12484
125- if err := bgpServer .AddPeer (context .Background (), & apipb.AddPeerRequest {
126- Peer : & apipb.Peer {
127- Conf : & apipb.PeerConf {
128- PeerAsn : uint32 (peerASN ),
129- NeighborAddress : neighborAddr ,
85+ if mode == "listen" {
86+ if err := bgpServer .AddPeerGroup (context .Background (), & apipb.AddPeerGroupRequest {
87+ PeerGroup : & apipb.PeerGroup {
88+ Conf : & apipb.PeerGroupConf {
89+ PeerGroupName : "route-collector" ,
90+ LocalAsn : asn ,
91+ },
92+ EbgpMultihop : & apipb.EbgpMultihop {
93+ Enabled : true ,
94+ },
95+ AfiSafis : []* apipb.AfiSafi {{
96+ Config : & apipb.AfiSafiConfig {
97+ Family : & apipb.Family {
98+ Afi : apipb .Family_AFI_IP ,
99+ Safi : apipb .Family_SAFI_UNICAST ,
100+ },
101+ },
102+ AddPaths : & apipb.AddPaths {
103+ Config : & apipb.AddPathsConfig {
104+ Receive : true ,
105+ },
106+ },
107+ }},
130108 },
131- EbgpMultihop : & apipb.EbgpMultihop {
132- Enabled : true ,
109+ }); err != nil {
110+ log .Printf ("add peer group fail: %v" , err )
111+ if err := bgp .CleanUp (); err != nil {
112+ log .Printf ("cleaup: %v" , err )
113+ }
114+ return
115+ }
116+ if err := bgpServer .AddDynamicNeighbor (context .Background (), & apipb.AddDynamicNeighborRequest {
117+ DynamicNeighbor : & apipb.DynamicNeighbor {
118+ Prefix : "0.0.0.0/0" ,
119+ PeerGroup : "route-collector" ,
133120 },
134- AfiSafis : []* apipb.AfiSafi {{
135- Config : & apipb.AfiSafiConfig {
136- Family : & apipb.Family {
137- Afi : apipb .Family_AFI_IP ,
138- Safi : apipb .Family_SAFI_UNICAST ,
139- },
121+ }); err != nil {
122+ log .Printf ("add dyn neighbor: %v" , err )
123+ if err := bgp .CleanUp (); err != nil {
124+ log .Printf ("cleaup: %v" , err )
125+ }
126+ return
127+ }
128+ } else {
129+ peerASN , err := utils .MustASN (m ["peer-asn" ])
130+ if err != nil {
131+ log .Printf ("peer-asn is not valid asn: %v" , err )
132+ if err := bgp .CleanUp (); err != nil {
133+ log .Printf ("cleaup: %v" , err )
134+ }
135+ return
136+ }
137+ neighborAddr , ok := m ["neighbor-addr" ].(string )
138+ if ! ok {
139+ log .Printf ("neighbor-addr is not string" )
140+ if err := bgp .CleanUp (); err != nil {
141+ log .Printf ("cleaup: %v" , err )
142+ }
143+ return
144+ }
145+ if _ , err := netip .ParseAddr (neighborAddr ); err != nil {
146+ log .Printf ("invalid neighbor-addr: %s" , neighborAddr )
147+ if err := bgp .CleanUp (); err != nil {
148+ log .Printf ("cleaup: %v" , err )
149+ }
150+ return
151+ }
152+ if err := bgpServer .AddPeer (context .Background (), & apipb.AddPeerRequest {
153+ Peer : & apipb.Peer {
154+ Conf : & apipb.PeerConf {
155+ PeerAsn : uint32 (peerASN ),
156+ NeighborAddress : neighborAddr ,
140157 },
141- AddPaths : & apipb.AddPaths {
142- Config : & apipb.AddPathsConfig {
143- Receive : true ,
144- },
158+ EbgpMultihop : & apipb.EbgpMultihop {
159+ Enabled : true ,
145160 },
146- }},
147- },
148- }); err != nil {
149- return nil , err
161+ AfiSafis : []* apipb.AfiSafi {{
162+ Config : & apipb.AfiSafiConfig {
163+ Family : & apipb.Family {
164+ Afi : apipb .Family_AFI_IP ,
165+ Safi : apipb .Family_SAFI_UNICAST ,
166+ },
167+ },
168+ AddPaths : & apipb.AddPaths {
169+ Config : & apipb.AddPathsConfig {
170+ Receive : true ,
171+ },
172+ },
173+ }},
174+ },
175+ }); err != nil {
176+ log .Printf ("add peer fail: %s" , neighborAddr )
177+ if err := bgp .CleanUp (); err != nil {
178+ log .Printf ("cleaup: %v" , err )
179+ }
180+ }
150181 }
151- }
182+ }()
152183
153- return & BGP {
154- s : bgpServer ,
155- }, nil
184+ return bgp , nil
156185 })
157186}
158187
159188type BGP struct {
160189 fetch.Base
161- s * server.BgpServer
190+ s * server.BgpServer
191+ cancel context.CancelFunc
162192}
163193
164194func (f * BGP ) GetData () (any , error ) {
@@ -201,7 +231,13 @@ func (f *BGP) GetData() (any, error) {
201231}
202232
203233func (f * BGP ) CleanUp () error {
204- f .s .StopBgp (context .Background (), nil )
234+ if f .cancel != nil {
235+ f .cancel ()
236+ }
237+ err := f .s .StopBgp (context .Background (), & apipb.StopBgpRequest {})
238+ if err != nil {
239+ log .Printf ("stop bgp: %v" , err )
240+ }
205241 f .s .Stop ()
206242 return nil
207243}
0 commit comments