From 2b0f16dcc6a47bd8d6518746038b3d65ff55e8c4 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 10 May 2018 14:42:38 +0900 Subject: bmp: avoid huge memory allocation for sending paths initially We had to serialize all the paths once because the paths could be modified later. Now they are immutable so we don't need. Signed-off-by: FUJITA Tomonori --- server/bmp.go | 29 ++++++++++++++++----------- server/mrt.go | 3 +++ server/server.go | 60 +++++++++++++++++++++++++------------------------------- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/server/bmp.go b/server/bmp.go index dd5d102e..2e9db698 100644 --- a/server/bmp.go +++ b/server/bmp.go @@ -17,14 +17,15 @@ package server import ( "fmt" + "net" + "strconv" + "time" + "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" "github.com/osrg/gobgp/packet/bmp" "github.com/osrg/gobgp/table" log "github.com/sirupsen/logrus" - "net" - "strconv" - "time" ) type ribout map[string][]*table.Path @@ -166,16 +167,22 @@ func (b *bmpClient) loop() { ID: msg.PeerID, } if msg.Payload == nil { - pathList := make([]*table.Path, 0, len(msg.PathList)) - for _, p := range msg.PathList { - if b.ribout.update(p) { - pathList = append(pathList, p) + var pathList []*table.Path + if msg.Init { + pathList = msg.PathList + } else { + for _, p := range msg.PathList { + if b.ribout.update(p) { + pathList = append(pathList, p) + } } } - for _, u := range table.CreateUpdateMsgFromPaths(pathList) { - payload, _ := u.Serialize() - if err := write(bmpPeerRoute(bmp.BMP_PEER_TYPE_GLOBAL, msg.PostPolicy, 0, true, info, msg.Timestamp.Unix(), payload)); err != nil { - return false + for _, path := range pathList { + for _, u := range table.CreateUpdateMsgFromPaths([]*table.Path{path}) { + payload, _ := u.Serialize() + if err := write(bmpPeerRoute(bmp.BMP_PEER_TYPE_GLOBAL, msg.PostPolicy, 0, true, info, msg.Timestamp.Unix(), payload)); err != nil { + return false + } } } } else { diff --git a/server/mrt.go b/server/mrt.go index fe61f7a1..613f0b07 100644 --- a/server/mrt.go +++ b/server/mrt.go @@ -88,6 +88,9 @@ func (m *mrtWriter) loop() error { msg := make([]*mrt.MRTMessage, 0, 1) switch e := ev.(type) { case *WatchEventUpdate: + if e.Init { + return nil + } mp := mrt.NewBGP4MPMessage(e.PeerAS, e.LocalAS, 0, e.PeerAddress.String(), e.LocalAddress.String(), e.FourBytesAs, nil) mp.BGPMessagePayload = e.Payload isAddPath := e.Neighbor.IsAddPathReceiveEnabled(e.PathList[0].GetRouteFamily()) diff --git a/server/server.go b/server/server.go index 3c7bd336..251ce7cb 100644 --- a/server/server.go +++ b/server/server.go @@ -2585,6 +2585,7 @@ type WatchEventUpdate struct { Timestamp time.Time Payload []byte PostPolicy bool + Init bool PathList []*table.Path Neighbor *config.Neighbor } @@ -2862,24 +2863,19 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { for _, rf := range peer.configuredRFlist() { _, y := peer.fsm.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER] l, _ := peer.fsm.LocalHostPort() - for _, path := range peer.adjRibIn.PathList([]bgp.RouteFamily{rf}, false) { - msgs := table.CreateUpdateMsgFromPaths([]*table.Path{path}) - buf, _ := msgs[0].Serialize() - w.notify(&WatchEventUpdate{ - Message: msgs[0], - PeerAS: peer.fsm.peerInfo.AS, - LocalAS: peer.fsm.peerInfo.LocalAS, - PeerAddress: peer.fsm.peerInfo.Address, - LocalAddress: net.ParseIP(l), - PeerID: peer.fsm.peerInfo.ID, - FourBytesAs: y, - Timestamp: path.GetTimestamp(), - Payload: buf, - PostPolicy: false, - Neighbor: configNeighbor, - PathList: []*table.Path{path}, - }) - } + w.notify(&WatchEventUpdate{ + PeerAS: peer.fsm.peerInfo.AS, + LocalAS: peer.fsm.peerInfo.LocalAS, + PeerAddress: peer.fsm.peerInfo.Address, + LocalAddress: net.ParseIP(l), + PeerID: peer.fsm.peerInfo.ID, + FourBytesAs: y, + Init: true, + PostPolicy: false, + Neighbor: configNeighbor, + PathList: peer.adjRibIn.PathList([]bgp.RouteFamily{rf}, false), + }) + eor := bgp.NewEndOfRib(rf) eorBuf, _ := eor.Serialize() w.notify(&WatchEventUpdate{ @@ -2891,6 +2887,7 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { PeerID: peer.fsm.peerInfo.ID, FourBytesAs: y, Timestamp: time.Now(), + Init: true, Payload: eorBuf, PostPolicy: false, Neighbor: configNeighbor, @@ -2913,21 +2910,17 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { if peer, ok := s.neighborMap[peerInfo.Address.String()]; ok { configNeighbor = w.s.ToConfig(peer, false) } - for _, path := range paths { - msgs := table.CreateUpdateMsgFromPaths([]*table.Path{path}) - buf, _ := msgs[0].Serialize() - w.notify(&WatchEventUpdate{ - Message: msgs[0], - PeerAS: peerInfo.AS, - PeerAddress: peerInfo.Address, - PeerID: peerInfo.ID, - Timestamp: path.GetTimestamp(), - Payload: buf, - PostPolicy: true, - Neighbor: configNeighbor, - PathList: []*table.Path{path}, - }) - } + + w.notify(&WatchEventUpdate{ + PeerAS: peerInfo.AS, + PeerAddress: peerInfo.Address, + PeerID: peerInfo.ID, + PostPolicy: true, + Neighbor: configNeighbor, + PathList: paths, + Init: true, + }) + eor := bgp.NewEndOfRib(rf) eorBuf, _ := eor.Serialize() w.notify(&WatchEventUpdate{ @@ -2939,6 +2932,7 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { Payload: eorBuf, PostPolicy: true, Neighbor: configNeighbor, + Init: true, }) } } -- cgit v1.2.3