diff --git a/protocols/bgp/server/bmp_router.go b/protocols/bgp/server/bmp_router.go index 08bc38f2f6796edddaaa2e5e34c42f4486ff14fc..46f0f0a80230acf1e2ae9ceb73fab4febafef723 100644 --- a/protocols/bgp/server/bmp_router.go +++ b/protocols/bgp/server/bmp_router.go @@ -58,7 +58,8 @@ func newRouter(addr net.IP, port uint16, rib4 *locRIB.LocRIB, rib6 *locRIB.LocRI } } -func (r *router) serve() { +func (r *router) serve(con net.Conn) { + r.con = con r.runMu.Lock() defer r.con.Close() defer r.runMu.Unlock() @@ -176,8 +177,7 @@ func (r *router) processTerminationMsg(msg *bmppkt.TerminationMessage) { r.con.Close() for n := range r.neighbors { - // TODO: Cleanup after neighbors - delete(r.neighbors, n) + r.peerDown(n) } } @@ -190,8 +190,21 @@ func (r *router) processPeerDownNotification(msg *bmppkt.PeerDownNotification) { return } - delete(r.neighbors, msg.PerPeerHeader.PeerAddress) - // TODO: Cleanup after neighbor + r.peerDown(msg.PerPeerHeader.PeerAddress) +} + +func (r *router) peerDown(addr [16]byte) { + if r.neighbors[addr].fsm != nil { + if r.neighbors[addr].fsm.ipv4Unicast != nil { + r.neighbors[addr].fsm.ipv4Unicast.bmpDispose() + } + + if r.neighbors[addr].fsm.ipv6Unicast != nil { + r.neighbors[addr].fsm.ipv6Unicast.bmpDispose() + } + } + + delete(r.neighbors, addr) } func (r *router) processPeerUpNotification(msg *bmppkt.PeerUpNotification) error { diff --git a/protocols/bgp/server/bmp_router_test.go b/protocols/bgp/server/bmp_router_test.go index 3b585c3780b8b8f4318f98440b1ac80ce1996f73..7ccd96b638d291271079128a37be18f2c326843f 100644 --- a/protocols/bgp/server/bmp_router_test.go +++ b/protocols/bgp/server/bmp_router_test.go @@ -17,6 +17,54 @@ import ( "github.com/stretchr/testify/assert" ) +func TestBMPRouterServe(t *testing.T) { + tests := []struct { + name string + msg []byte + wantFail bool + }{ + { + name: "Test #1", + msg: []byte{1, 2, 3}, + wantFail: true, + }, + } + + for _, test := range tests { + addr := net.IP{10, 20, 30, 40} + port := uint16(123) + rib4 := locRIB.New() + rib6 := locRIB.New() + conA, conB := net.Pipe() + + r := newRouter(addr, port, rib4, rib6) + buf := bytes.NewBuffer(nil) + r.logger.Out = buf + go r.serve(conA) + + conB.Write(test.msg) + + assert.Equalf(t, 0, len(buf.Bytes()), "Test %q", test.name) + } +} + +func TestStartStopBMP(t *testing.T) { + addr := net.IP{10, 20, 30, 40} + port := uint16(123) + rib4 := locRIB.New() + rib6 := locRIB.New() + + con := biotesting.NewMockConn() + + r := newRouter(addr, port, rib4, rib6) + go r.serve(con) + + r.stop <- struct{}{} + + r.runMu.Lock() + assert.Equal(t, true, r.con.(*biotesting.MockConn).Closed) +} + func TestConfigureBySentOpen(t *testing.T) { tests := []struct { name string diff --git a/protocols/bgp/server/bmp_server.go b/protocols/bgp/server/bmp_server.go index cff9f709d5c900afc9a7dce082df2679d67d133f..100e514cd7a0aebbd4e88de8ae2ac7c670440433 100644 --- a/protocols/bgp/server/bmp_server.go +++ b/protocols/bgp/server/bmp_server.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/bio-routing/bio-rd/protocols/bgp/packet" + bmppkt "github.com/bio-routing/bio-rd/protocols/bmp/packet" "github.com/bio-routing/bio-rd/routingtable/locRIB" log "github.com/sirupsen/logrus" "github.com/taktv6/tflow2/convert" @@ -55,9 +55,8 @@ func (b *BMPServer) AddRouter(addr net.IP, port uint16, rib4 *locRIB.LocRIB, rib } r.reconnectTime = 0 - r.con = c log.Infof("Connected to %s", r.address.String()) - r.serve() + r.serve(c) } }(r) } @@ -75,7 +74,7 @@ func (b *BMPServer) RemoveRouter(addr net.IP, port uint16) { func recvBMPMsg(c net.Conn) (msg []byte, err error) { buffer := make([]byte, defaultBufferLen) - _, err = io.ReadFull(c, buffer[0:packet.MinLen]) + _, err = io.ReadFull(c, buffer[0:bmppkt.MinLen]) if err != nil { return nil, fmt.Errorf("Read failed: %v", err) } @@ -88,7 +87,7 @@ func recvBMPMsg(c net.Conn) (msg []byte, err error) { } toRead := l - _, err = io.ReadFull(c, buffer[packet.MinLen:toRead]) + _, err = io.ReadFull(c, buffer[bmppkt.MinLen:toRead]) if err != nil { return nil, fmt.Errorf("Read failed: %v", err) } diff --git a/protocols/bgp/server/bmp_server_test.go b/protocols/bgp/server/bmp_server_test.go index 3ebef9a2535e35ecdedf1a4a560003ff3fd37c17..e2853952e6bdf949839af899bebe515bb279ad53 100644 --- a/protocols/bgp/server/bmp_server_test.go +++ b/protocols/bgp/server/bmp_server_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/bio-routing/bio-rd/routingtable/locRIB" + biotesting "github.com/bio-routing/bio-rd/testing" "github.com/stretchr/testify/assert" ) @@ -16,7 +17,7 @@ func TestNewServer(t *testing.T) { }, s) } -func TestIntegration(t *testing.T) { +func TestIntegrationPeerUpRouteMonitor(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) @@ -25,9 +26,8 @@ func TestIntegration(t *testing.T) { r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() - r.con = conB - go r.serve() + go r.serve(conB) // Peer Up Notification _, err := conA.Write([]byte{ @@ -134,16 +134,12 @@ func TestIntegration(t *testing.T) { }) if err != nil { - panic("write #1 failed") + panic("write failed") } time.Sleep(time.Millisecond * 50) assert.NotEmpty(t, r.neighbors) - if err != nil { - panic("Write #2 failed") - } - time.Sleep(time.Millisecond * 50) count := rib4.RouteCount() @@ -153,3 +149,562 @@ func TestIntegration(t *testing.T) { conA.Close() } + +func TestIntegrationIncompleteBMPMsg(t *testing.T) { + addr := net.IP{10, 20, 30, 40} + port := uint16(12346) + + rib4 := locRIB.New() + rib6 := locRIB.New() + + r := newRouter(addr, port, rib4, rib6) + con := biotesting.NewMockConn() + + // Peer Up Notification with invalid version number (4) + con.Write([]byte{ + // Common Header + 4, // Version + 0, 0, 0, 126, // Message Length + 3, // Msg Type = Peer Up Notification + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + // Peer Up Notification + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 41, // 10.20.30.41 local address + 0, 123, // Local Port + 0, 234, // Remote Port + + // Sent OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 200, // AS + 0, 180, // Hold Time + 1, 0, 0, 1, // BGP Identifier + 0, // Opt param length + + // Received OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 100, // AS + 0, 180, // Hold Time + 1, 0, 0, 255, // BGP Identifier + 0, // Opt param length + + // SECOND MESSAGE: + + // Common Header + 3, // Version + 0, 0, 0, 116, // Message Length + 0, // Msg Type = Route Monitoring Message + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + }) + + r.serve(con) + + if !con.Closed { + t.Errorf("Connection not closed although failure should have happened") + } +} + +func TestBMPFullRunWithWithdraw(t *testing.T) { + addr := net.IP{10, 20, 30, 40} + port := uint16(12346) + + rib4 := locRIB.New() + rib6 := locRIB.New() + + r := newRouter(addr, port, rib4, rib6) + con := biotesting.NewMockConn() + + go r.serve(con) + + con.Write([]byte{ + // ##################################################################### + // Initiation Message + // ##################################################################### + // Common Header + 3, + 0, 0, 0, 23, + 4, + 0, 1, // sysDescr + 0, 4, // Length + 42, 42, 42, 42, // AAAA + 0, 2, //sysName + 0, 5, // Length + 43, 43, 43, 43, 43, // BBBBB + + // ##################################################################### + // Peer UP Notification + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 126, // Message Length + 3, // Msg Type = Peer Up Notification + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + // Peer Up Notification + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 41, // 10.20.30.41 local address + 0, 123, // Local Port + 0, 234, // Remote Port + // Sent OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 200, // AS + 0, 180, // Hold Time + 1, 0, 0, 1, // BGP Identifier + 0, // Opt param length + // Received OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 100, // AS + 0, 180, // Hold Time + 1, 0, 0, 255, // BGP Identifier + 0, // Opt param length + + // ##################################################################### + // Route Monitoring Message #1 + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 116, // Message Length + 0, // Msg Type = Route Monitoring Message + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + // BGP Update + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 68, // Length + 2, // Update + + 0, 0, // Withdrawn Routes Length + 0, 41, // Total Path Attribute Length + + 255, // Attribute flags + 1, // Attribute Type code (ORIGIN) + 0, 1, // Length + 2, // INCOMPLETE + + 0, // Attribute flags + 2, // Attribute Type code (AS Path) + 12, // Length + 2, // Type = AS_SEQUENCE + 2, // Path Segment Length + 59, 65, // AS15169 + 12, 248, // AS3320 + 1, // Type = AS_SET + 2, // Path Segment Length + 59, 65, // AS15169 + 12, 248, // AS3320 + + 0, // Attribute flags + 3, // Attribute Type code (Next Hop) + 4, // Length + 10, 11, 12, 13, // Next Hop + + 0, // Attribute flags + 4, // Attribute Type code (MED) + 4, // Length + 0, 0, 1, 0, // MED 256 + + 0, // Attribute flags + 5, // Attribute Type code (Local Pref) + 4, // Length + 0, 0, 1, 0, // Local Pref 256 + + // NLRI + 24, + 192, 168, 0, + + // ##################################################################### + // Route Monitoring Message #2 (withdraw of prefix from #1) + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 75, // Message Length + 0, // Msg Type = Route Monitoring Message + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + // BGP Update + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 27, // Length + 2, // Update + + 0, 4, // Withdrawn Routes Length + 24, + 192, 168, 0, + 0, 0, // Total Path Attribute Length + }) + + time.Sleep(time.Millisecond * 50) + assert.NotEmpty(t, r.neighbors) + + time.Sleep(time.Millisecond * 50) + + count := rib4.RouteCount() + if count != 0 { + t.Errorf("Unexpected route count. Expected: 0 Got: %d", count) + } + +} + +func TestBMPFullRunWithPeerDownNotification(t *testing.T) { + addr := net.IP{10, 20, 30, 40} + port := uint16(12346) + + rib4 := locRIB.New() + rib6 := locRIB.New() + + r := newRouter(addr, port, rib4, rib6) + con := biotesting.NewMockConn() + + go r.serve(con) + + con.Write([]byte{ + // ##################################################################### + // Initiation Message + // ##################################################################### + // Common Header + 3, + 0, 0, 0, 23, + 4, + 0, 1, // sysDescr + 0, 4, // Length + 42, 42, 42, 42, // AAAA + 0, 2, //sysName + 0, 5, // Length + 43, 43, 43, 43, 43, // BBBBB + + // ##################################################################### + // Peer UP Notification + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 126, // Message Length + 3, // Msg Type = Peer Up Notification + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + // Peer Up Notification + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 41, // 10.20.30.41 local address + 0, 123, // Local Port + 0, 234, // Remote Port + // Sent OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 200, // AS + 0, 180, // Hold Time + 1, 0, 0, 1, // BGP Identifier + 0, // Opt param length + // Received OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 100, // AS + 0, 180, // Hold Time + 1, 0, 0, 255, // BGP Identifier + 0, // Opt param length + + // ##################################################################### + // Route Monitoring Message #1 + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 116, // Message Length + 0, // Msg Type = Route Monitoring Message + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + // BGP Update + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 68, // Length + 2, // Update + + 0, 0, // Withdrawn Routes Length + 0, 41, // Total Path Attribute Length + + 255, // Attribute flags + 1, // Attribute Type code (ORIGIN) + 0, 1, // Length + 2, // INCOMPLETE + + 0, // Attribute flags + 2, // Attribute Type code (AS Path) + 12, // Length + 2, // Type = AS_SEQUENCE + 2, // Path Segment Length + 59, 65, // AS15169 + 12, 248, // AS3320 + 1, // Type = AS_SET + 2, // Path Segment Length + 59, 65, // AS15169 + 12, 248, // AS3320 + + 0, // Attribute flags + 3, // Attribute Type code (Next Hop) + 4, // Length + 10, 11, 12, 13, // Next Hop + + 0, // Attribute flags + 4, // Attribute Type code (MED) + 4, // Length + 0, 0, 1, 0, // MED 256 + + 0, // Attribute flags + 5, // Attribute Type code (Local Pref) + 4, // Length + 0, 0, 1, 0, // Local Pref 256 + + // NLRI + 24, + 192, 168, 0, + + // ##################################################################### + // Peer Down Notification + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 49, // Message Length + 2, // Msg Type = Peer Down Notification + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + 4, // Reason + }) + + time.Sleep(time.Millisecond * 50) + assert.Empty(t, r.neighbors) + + time.Sleep(time.Millisecond * 50) + + count := rib4.RouteCount() + if count != 0 { + t.Errorf("Unexpected route count. Expected: 0 Got: %d", count) + } +} + +func TestBMPFullRunWithTerminationMessage(t *testing.T) { + addr := net.IP{10, 20, 30, 40} + port := uint16(12346) + + rib4 := locRIB.New() + rib6 := locRIB.New() + + r := newRouter(addr, port, rib4, rib6) + con := biotesting.NewMockConn() + + go r.serve(con) + + con.Write([]byte{ + // ##################################################################### + // Initiation Message + // ##################################################################### + // Common Header + 3, + 0, 0, 0, 23, + 4, + 0, 1, // sysDescr + 0, 4, // Length + 42, 42, 42, 42, // AAAA + 0, 2, //sysName + 0, 5, // Length + 43, 43, 43, 43, 43, // BBBBB + + // ##################################################################### + // Peer UP Notification + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 126, // Message Length + 3, // Msg Type = Peer Up Notification + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + // Peer Up Notification + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 41, // 10.20.30.41 local address + 0, 123, // Local Port + 0, 234, // Remote Port + // Sent OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 200, // AS + 0, 180, // Hold Time + 1, 0, 0, 1, // BGP Identifier + 0, // Opt param length + // Received OPEN message + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 29, // Length + 1, // Open message type + 4, // BGP Version + 0, 100, // AS + 0, 180, // Hold Time + 1, 0, 0, 255, // BGP Identifier + 0, // Opt param length + + // ##################################################################### + // Route Monitoring Message #1 + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 116, // Message Length + 0, // Msg Type = Route Monitoring Message + + // Per Peer Header + 0, // Peer Type + 0, // Peer Flags + 0, 0, 0, 0, 0, 0, 0, 0, // Peer Distinguisher + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 40, // 10.20.30.40 peer address + 0, 0, 0, 100, // Peer AS + 0, 0, 0, 255, // Peer BGP ID + 0, 0, 0, 0, // Timestamp s + 0, 0, 0, 0, // Timestamp µs + + // BGP Update + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 68, // Length + 2, // Update + + 0, 0, // Withdrawn Routes Length + 0, 41, // Total Path Attribute Length + + 255, // Attribute flags + 1, // Attribute Type code (ORIGIN) + 0, 1, // Length + 2, // INCOMPLETE + + 0, // Attribute flags + 2, // Attribute Type code (AS Path) + 12, // Length + 2, // Type = AS_SEQUENCE + 2, // Path Segment Length + 59, 65, // AS15169 + 12, 248, // AS3320 + 1, // Type = AS_SET + 2, // Path Segment Length + 59, 65, // AS15169 + 12, 248, // AS3320 + + 0, // Attribute flags + 3, // Attribute Type code (Next Hop) + 4, // Length + 10, 11, 12, 13, // Next Hop + + 0, // Attribute flags + 4, // Attribute Type code (MED) + 4, // Length + 0, 0, 1, 0, // MED 256 + + 0, // Attribute flags + 5, // Attribute Type code (Local Pref) + 4, // Length + 0, 0, 1, 0, // Local Pref 256 + + // NLRI + 24, + 192, 168, 0, + + // ##################################################################### + // Termination Message + // ##################################################################### + // Common Header + 3, // Version + 0, 0, 0, 12, // Message Length + 5, // Msg Type = Termination Message + + // TLV + 0, 0, 0, 2, + 42, 42, + }) + + time.Sleep(time.Millisecond * 50) + assert.Empty(t, r.neighbors) + + time.Sleep(time.Millisecond * 50) + + count := rib4.RouteCount() + if count != 0 { + t.Errorf("Unexpected route count. Expected: 0 Got: %d", count) + } +} diff --git a/protocols/bgp/server/fsm_address_family.go b/protocols/bgp/server/fsm_address_family.go index 01ee06b7533385f4358c0823298e936f407cb49b..ac1ace92cb7894b4fdf179497e6375a74598b0a7 100644 --- a/protocols/bgp/server/fsm_address_family.go +++ b/protocols/bgp/server/fsm_address_family.go @@ -71,6 +71,16 @@ func (f *fsmAddressFamily) bmpInit() { f.adjRIBIn.Register(f.rib) } +func (f *fsmAddressFamily) bmpDispose() { + f.rib.GetContributingASNs().Remove(f.fsm.peer.localASN) + + f.adjRIBIn.(*adjRIBIn.AdjRIBIn).Flush() + + f.adjRIBIn.Unregister(f.rib) + + f.adjRIBIn = nil +} + func (f *fsmAddressFamily) dispose() { if !f.initialized { return diff --git a/protocols/bmp/packet/decode.go b/protocols/bmp/packet/decode.go index d7989e28bb5955a294b195962d06c980cd0b645b..a76f6b7853e221126b77512039d9fc5296469496 100644 --- a/protocols/bmp/packet/decode.go +++ b/protocols/bmp/packet/decode.go @@ -61,7 +61,7 @@ func Decode(msg []byte) (Msg, error) { return sr, nil case PeerDownNotificationType: - pd, err := decodePeerUpNotification(buf, ch) + pd, err := decodePeerDownNotification(buf, ch) if err != nil { return nil, fmt.Errorf("Unable to decode peer down notification: %v", err) } diff --git a/protocols/bmp/packet/peer_down.go b/protocols/bmp/packet/peer_down.go index cdb72ffe33f72dc77e4c7373b6041a467bbbf836..7b0303043f489f93ce4c1ed4cc2610cbb87fa9e2 100644 --- a/protocols/bmp/packet/peer_down.go +++ b/protocols/bmp/packet/peer_down.go @@ -57,7 +57,7 @@ func decodePeerDownNotification(buf *bytes.Buffer, ch *CommonHeader) (*PeerDownN err = decoder.Decode(buf, fields) if err != nil { - return nil, err + return nil, fmt.Errorf("Unable to read Data: %v", err) } return p, nil diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go index 631f1d197cabc926056f186e21e1b6cd5d719afd..5bf7862334ece9b649baf5c75e42eff4936689f9 100644 --- a/routingtable/adjRIBIn/adj_rib_in.go +++ b/routingtable/adjRIBIn/adj_rib_in.go @@ -37,6 +37,19 @@ func New(exportFilter *filter.Filter, contributingASNs *routingtable.Contributin return a } +// Flush drops all routes from the AdjRIBIn +func (a *AdjRIBIn) Flush() { + a.mu.Lock() + defer a.mu.Unlock() + + routes := a.rt.Dump() + for _, route := range routes { + for _, path := range route.Paths() { + a.removePath(route.Prefix(), path) + } + } +} + // UpdateNewClient sends current state to a new client func (a *AdjRIBIn) UpdateNewClient(client routingtable.RouteTableClient) error { a.mu.RLock() @@ -124,6 +137,11 @@ func (a *AdjRIBIn) RemovePath(pfx net.Prefix, p *route.Path) bool { a.mu.Lock() defer a.mu.Unlock() + return a.removePath(pfx, p) +} + +// removePath removes the path for prefix `pfx` +func (a *AdjRIBIn) removePath(pfx net.Prefix, p *route.Path) bool { r := a.rt.Get(pfx) if r == nil { return false