diff options
-rw-r--r-- | packet/bgp/bgp.go | 6 | ||||
-rw-r--r-- | server/server.go | 77 |
2 files changed, 61 insertions, 22 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index 43ea66d6..9b7dfc97 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -7202,7 +7202,9 @@ func (msg *BGPUpdate) IsEndOfRib() (bool, RouteFamily) { return true, RF_IPv4_UC } else if len(msg.PathAttributes) == 1 && msg.PathAttributes[0].GetType() == BGP_ATTR_TYPE_MP_UNREACH_NLRI { unreach := msg.PathAttributes[0].(*PathAttributeMpUnreachNLRI) - return true, AfiSafiToRouteFamily(unreach.AFI, unreach.SAFI) + if len(unreach.Value) == 0 { + return true, AfiSafiToRouteFamily(unreach.AFI, unreach.SAFI) + } } } return false, RouteFamily(0) @@ -7225,7 +7227,7 @@ func NewEndOfRib(family RouteFamily) *BGPMessage { PathAttribute: PathAttribute{ Flags: PathAttrFlags[t], Type: t, - Length: 0, + Length: 3, }, AFI: afi, SAFI: safi, diff --git a/server/server.go b/server/server.go index 4ac89039..902b6c8a 100644 --- a/server/server.go +++ b/server/server.go @@ -2323,41 +2323,78 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { if peer.fsm.state != bgp.BGP_FSM_ESTABLISHED { continue } - for _, path := range peer.adjRibIn.PathList(peer.configuredRFlist(), false) { - msgs := table.CreateUpdateMsgFromPaths([]*table.Path{path}) - buf, _ := msgs[0].Serialize() + 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, + }) + } + eor := bgp.NewEndOfRib(rf) + eorBuf, _ := eor.Serialize() w.notify(&WatchEventUpdate{ - Message: msgs[0], + Message: eor, 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, + Timestamp: time.Now(), + Payload: eorBuf, PostPolicy: false, }) } } } - if w.opts.postUpdate { - for _, path := range s.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, s.globalRib.GetRFlist()) { - msgs := table.CreateUpdateMsgFromPaths([]*table.Path{path}) - buf, _ := msgs[0].Serialize() - w.notify(&WatchEventUpdate{ - PeerAS: path.GetSource().AS, - PeerAddress: path.GetSource().Address, - PeerID: path.GetSource().ID, - Message: msgs[0], - Timestamp: path.GetTimestamp(), - Payload: buf, - PostPolicy: true, - }) + if w.opts.initPostUpdate { + for _, rf := range s.globalRib.GetRFlist() { + if len(s.globalRib.Tables[rf].GetDestinations()) == 0 { + continue + } + pathsByPeer := make(map[*table.PeerInfo][]*table.Path) + for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, []bgp.RouteFamily{rf}) { + pathsByPeer[path.GetSource()] = append(pathsByPeer[path.GetSource()], path) + } + for peerInfo, paths := range pathsByPeer { + 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, + }) + } + eor := bgp.NewEndOfRib(rf) + eorBuf, _ := eor.Serialize() + w.notify(&WatchEventUpdate{ + Message: eor, + PeerAS: peerInfo.AS, + PeerAddress: peerInfo.Address, + PeerID: peerInfo.ID, + Timestamp: time.Now(), + Payload: eorBuf, + PostPolicy: true, + }) + } } - } go w.loop() |