diff --git a/protocols/bgp/server/bmp_router.go b/protocols/bgp/server/bmp_router.go
index 8667a42e47c74e2d70e25b53b56c8eb4d48ad5a7..d03ccac419304c9e3ad22d137390d65a5e3c9e25 100644
--- a/protocols/bgp/server/bmp_router.go
+++ b/protocols/bgp/server/bmp_router.go
@@ -29,6 +29,9 @@ type router struct {
 	rib6             *locRIB.LocRIB
 	neighbors        map[[16]byte]*neighbor
 	neighborsMu      sync.Mutex
+	logger           *log.Logger
+	runMu            sync.Mutex
+	stop             chan struct{}
 }
 
 type neighbor struct {
@@ -40,24 +43,51 @@ type neighbor struct {
 	opt      *packet.DecodeOptions
 }
 
+func newRouter(addr net.IP, port uint16, rib4 *locRIB.LocRIB, rib6 *locRIB.LocRIB) *router {
+	return &router{
+		address:          addr,
+		port:             port,
+		reconnectTimeMin: 30,  // Suggested by RFC 7854
+		reconnectTimeMax: 720, // Suggested by RFC 7854
+		reconnectTimer:   time.NewTimer(time.Duration(0)),
+		rib4:             rib4,
+		rib6:             rib6,
+		neighbors:        make(map[[16]byte]*neighbor),
+		logger:           log.New(),
+		stop:             make(chan struct{}),
+	}
+}
+
 func (r *router) serve() {
+	r.runMu.Lock()
+	defer r.con.Close()
+	defer r.runMu.Unlock()
+
 	for {
+		select {
+		case <-r.stop:
+			return
+		default:
+		}
+
 		msg, err := recvBMPMsg(r.con)
 		if err != nil {
-			log.Errorf("Unable to get message: %v", err)
+			r.logger.Errorf("Unable to get message: %v", err)
 			return
 		}
 
 		bmpMsg, err := bmppkt.Decode(msg)
 		if err != nil {
-			log.Errorf("Unable to decode BMP message: %v", err)
-			fmt.Printf("msg: %v\n", msg)
+			r.logger.Errorf("Unable to decode BMP message: %v", err)
 			return
 		}
 
 		switch bmpMsg.MsgType() {
 		case bmppkt.PeerUpNotificationType:
-			r.processPeerUpNotification(bmpMsg.(*bmppkt.PeerUpNotification))
+			err = r.processPeerUpNotification(bmpMsg.(*bmppkt.PeerUpNotification))
+			if err != nil {
+				r.logger.Errorf("Unable to process peer up notification: %v", err)
+			}
 		case bmppkt.PeerDownNotificationType:
 			r.processPeerDownNotification(bmpMsg.(*bmppkt.PeerDownNotification))
 		case bmppkt.InitiationMessageType:
@@ -76,13 +106,14 @@ func (r *router) processRouteMonitoringMsg(msg *bmppkt.RouteMonitoringMsg) {
 	defer r.neighborsMu.Unlock()
 
 	if _, ok := r.neighbors[msg.PerPeerHeader.PeerAddress]; !ok {
-		log.Errorf("Received route monitoring message for non-existent neighbor %v on %s", msg.PerPeerHeader.PeerAddress, r.address.String())
+		r.logger.Errorf("Received route monitoring message for non-existent neighbor %v on %s", msg.PerPeerHeader.PeerAddress, r.address.String())
 		return
 	}
 
 	n := r.neighbors[msg.PerPeerHeader.PeerAddress]
 	s := n.fsm.state.(*establishedState)
-	s.msgReceived(msg.BGPUpdate, s.fsm.decodeOptions())
+	_, reason := s.msgReceived(msg.BGPUpdate, s.fsm.decodeOptions())
+	fmt.Printf("Reason: %v\n", reason)
 }
 
 func (r *router) processInitiationMsg(msg *bmppkt.InitiationMessage) {
@@ -105,7 +136,7 @@ func (r *router) processInitiationMsg(msg *bmppkt.InitiationMessage) {
 		}
 	}
 
-	log.Info(logMsg)
+	r.logger.Info(logMsg)
 }
 
 func (r *router) processTerminationMsg(msg *bmppkt.TerminationMessage) {
@@ -142,10 +173,11 @@ func (r *router) processTerminationMsg(msg *bmppkt.TerminationMessage) {
 		}
 	}
 
-	log.Warning(logMsg)
+	r.logger.Warning(logMsg)
 
 	r.con.Close()
 	for n := range r.neighbors {
+		// TODO: Cleanup after neighbors
 		delete(r.neighbors, n)
 	}
 }
@@ -155,11 +187,12 @@ func (r *router) processPeerDownNotification(msg *bmppkt.PeerDownNotification) {
 	defer r.neighborsMu.Unlock()
 
 	if _, ok := r.neighbors[msg.PerPeerHeader.PeerAddress]; !ok {
-		log.Warningf("Received peer down notification for %v: Peer doesn't exist.", msg.PerPeerHeader.PeerAddress)
+		r.logger.Warningf("Received peer down notification for %v: Peer doesn't exist.", msg.PerPeerHeader.PeerAddress)
 		return
 	}
 
 	delete(r.neighbors, msg.PerPeerHeader.PeerAddress)
+	// TODO: Cleanup after neighbor
 }
 
 func (r *router) processPeerUpNotification(msg *bmppkt.PeerUpNotification) error {
@@ -204,6 +237,7 @@ func (r *router) processPeerUpNotification(msg *bmppkt.PeerUpNotification) error
 	fsm := &FSM{
 		isBMP: true,
 		peer: &peer{
+			routerID:  sentOpen.BGPIdentifier,
 			addr:      peerAddress,
 			localAddr: localAddress,
 			peerASN:   msg.PerPeerHeader.PeerAS,
diff --git a/protocols/bgp/server/bmp_router_test.go b/protocols/bgp/server/bmp_router_test.go
index 9cf1060e98382c9a09c0b70ada87f8c413827847..1b183d1cbf7d4610bc4156ea3376887458dd18b3 100644
--- a/protocols/bgp/server/bmp_router_test.go
+++ b/protocols/bgp/server/bmp_router_test.go
@@ -1,6 +1,8 @@
 package server
 
 import (
+	"bytes"
+	"net"
 	"testing"
 
 	bnet "github.com/bio-routing/bio-rd/net"
@@ -10,6 +12,8 @@ import (
 	"github.com/bio-routing/bio-rd/routingtable/adjRIBIn"
 	"github.com/bio-routing/bio-rd/routingtable/filter"
 	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+	biotesting "github.com/bio-routing/bio-rd/testing"
+	log "github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -317,3 +321,251 @@ func TestProcessPeerUpNotification(t *testing.T) {
 	}
 
 }
+
+func TestProcessRouteMonitoringMsg(t *testing.T) {
+	tests := []struct {
+		name           string
+		r              *router
+		msg            *bmppkt.RouteMonitoringMsg
+		expectedLogBuf string
+		logOnly        bool
+		expected       *router
+	}{
+		{
+			name: "Unknown peer address",
+			r: &router{
+				address: net.IP{10, 20, 30, 40},
+				logger:  log.New(),
+			},
+			msg: &bmppkt.RouteMonitoringMsg{
+				PerPeerHeader: &bmppkt.PerPeerHeader{
+					PeerAddress: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+				},
+			},
+			expectedLogBuf: "level=error msg=\"Received route monitoring message for non-existent neighbor [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] on 10.20.30.40\"",
+			logOnly:        true,
+			expected:       &router{},
+		},
+	}
+
+	for _, test := range tests {
+		logBuf := bytes.NewBuffer(nil)
+		test.r.logger.Out = logBuf
+		test.r.logger.Formatter = biotesting.NewLogFormatter()
+
+		test.expected.logger = test.r.logger
+
+		test.r.processRouteMonitoringMsg(test.msg)
+
+		assert.Equalf(t, test.expectedLogBuf, string(logBuf.Bytes()), "Test %q", test.name)
+		if test.logOnly {
+			continue
+		}
+
+		assert.Equalf(t, test.expected, test.r, "Test %q", test.name)
+	}
+}
+
+func TestProcessInitiationMsg(t *testing.T) {
+	tests := []struct {
+		name        string
+		r           *router
+		msg         *bmppkt.InitiationMessage
+		expectedLog string
+	}{
+		{
+			name: "Test #1",
+			r: &router{
+				address: net.IP{10, 20, 30, 40},
+				logger:  log.New(),
+			},
+			msg: &bmppkt.InitiationMessage{
+				TLVs: []*bmppkt.InformationTLV{
+					{
+						InformationType: 0,
+						Information:     []byte("Foo Bar"),
+					},
+					{
+						InformationType: 1,
+						Information:     []byte("SYS DESCR"),
+					},
+					{
+						InformationType: 2,
+						Information:     []byte("core01.fra01"),
+					},
+				},
+			},
+			expectedLog: "level=info msg=\"Received initiation message from 10.20.30.40: Message: \\\"Foo Bar\\\" sysDescr.: SYS DESCR sysName.: core01.fra01\"",
+		},
+	}
+
+	for _, test := range tests {
+		logBuf := bytes.NewBuffer(nil)
+		test.r.logger.Out = logBuf
+		test.r.logger.Formatter = biotesting.NewLogFormatter()
+
+		test.r.processInitiationMsg(test.msg)
+
+		assert.Equalf(t, test.expectedLog, string(logBuf.Bytes()), "Test %q", test.name)
+	}
+}
+
+func TestProcessTerminationMsg(t *testing.T) {
+	tests := []struct {
+		name        string
+		r           *router
+		msg         *bmppkt.TerminationMessage
+		expectedLog string
+		expected    *router
+	}{
+		{
+			name: "Test shutdown",
+			r: &router{
+				con:     &biotesting.MockConn{},
+				address: net.IP{10, 20, 30, 40},
+				logger:  log.New(),
+				neighbors: map[[16]byte]*neighbor{
+					[16]byte{1, 2, 3}: &neighbor{},
+				},
+			},
+			msg: &bmppkt.TerminationMessage{
+				TLVs: []*bmppkt.InformationTLV{
+					{
+						InformationType: 0, // string type
+						Information:     []byte("Foo Bar"),
+					},
+				},
+			},
+			expectedLog: "level=warning msg=\"Received termination message from 10.20.30.40: Message: \\\"Foo Bar\\\"\"",
+			expected: &router{
+				con: &biotesting.MockConn{
+					Closed: true,
+				},
+				address:   net.IP{10, 20, 30, 40},
+				neighbors: map[[16]byte]*neighbor{},
+			},
+		},
+		{
+			name: "Test logs",
+			r: &router{
+				con:     &biotesting.MockConn{},
+				address: net.IP{10, 20, 30, 40},
+				logger:  log.New(),
+				neighbors: map[[16]byte]*neighbor{
+					[16]byte{1, 2, 3}: &neighbor{},
+				},
+			},
+			msg: &bmppkt.TerminationMessage{
+				TLVs: []*bmppkt.InformationTLV{
+					{
+						InformationType: 1, // reason type
+						Information:     []byte{0, 0},
+					},
+					{
+						InformationType: 1, // reason type
+						Information:     []byte{0, 1},
+					},
+					{
+						InformationType: 1, // reason type
+						Information:     []byte{0, 2},
+					},
+					{
+						InformationType: 1, // reason type
+						Information:     []byte{0, 3},
+					},
+					{
+						InformationType: 1, // reason type
+						Information:     []byte{0, 4},
+					},
+				},
+			},
+			expectedLog: "level=warning msg=\"Received termination message from 10.20.30.40: Session administratively downUnespcified reasonOut of resourcesRedundant connectionSession permanently administratively closed\"",
+			expected: &router{
+				con: &biotesting.MockConn{
+					Closed: true,
+				},
+				address:   net.IP{10, 20, 30, 40},
+				neighbors: map[[16]byte]*neighbor{},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		logBuf := bytes.NewBuffer(nil)
+		test.r.logger.Out = logBuf
+		test.r.logger.Formatter = biotesting.NewLogFormatter()
+
+		test.expected.logger = test.r.logger
+
+		test.r.processTerminationMsg(test.msg)
+
+		assert.Equalf(t, test.expectedLog, string(logBuf.Bytes()), "Test %q", test.name)
+		assert.Equalf(t, test.expected, test.r, "Test %q", test.name)
+	}
+}
+
+func TestProcessPeerDownNotification(t *testing.T) {
+	tests := []struct {
+		name        string
+		r           *router
+		msg         *bmppkt.PeerDownNotification
+		expectedLog string
+		expected    *router
+	}{
+		{
+			name: "Peer down notification for existing peer",
+			r: &router{
+				address: net.IP{10, 20, 30, 40},
+				logger:  log.New(),
+				neighbors: map[[16]byte]*neighbor{
+					[16]byte{1, 2, 3}: &neighbor{},
+				},
+			},
+			msg: &bmppkt.PeerDownNotification{
+				PerPeerHeader: &bmppkt.PerPeerHeader{
+					PeerAddress: [16]byte{1, 2, 3},
+				},
+			},
+			expectedLog: "",
+			expected: &router{
+				address:   net.IP{10, 20, 30, 40},
+				neighbors: map[[16]byte]*neighbor{},
+			},
+		},
+		{
+			name: "Peer down notification for non-existing peer",
+			r: &router{
+				address: net.IP{10, 20, 30, 40},
+				logger:  log.New(),
+				neighbors: map[[16]byte]*neighbor{
+					[16]byte{1, 2, 3}: &neighbor{},
+				},
+			},
+			msg: &bmppkt.PeerDownNotification{
+				PerPeerHeader: &bmppkt.PerPeerHeader{
+					PeerAddress: [16]byte{10, 20, 30},
+				},
+			},
+			expectedLog: "level=warning msg=\"Received peer down notification for [10 20 30 0 0 0 0 0 0 0 0 0 0 0 0 0]: Peer doesn't exist.\"",
+			expected: &router{
+				address: net.IP{10, 20, 30, 40},
+				neighbors: map[[16]byte]*neighbor{
+					[16]byte{1, 2, 3}: &neighbor{},
+				},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		logBuf := bytes.NewBuffer(nil)
+		test.r.logger.Out = logBuf
+		test.r.logger.Formatter = biotesting.NewLogFormatter()
+
+		test.expected.logger = test.r.logger
+
+		test.r.processPeerDownNotification(test.msg)
+
+		assert.Equalf(t, test.expectedLog, string(logBuf.Bytes()), "Test %q", test.name)
+		assert.Equalf(t, test.expected, test.r, "Test %q", test.name)
+	}
+}
diff --git a/protocols/bgp/server/bmp_server.go b/protocols/bgp/server/bmp_server.go
index 74f2ce775f42ffa6263668423721d520be40ee52..cff9f709d5c900afc9a7dce082df2679d67d133f 100644
--- a/protocols/bgp/server/bmp_server.go
+++ b/protocols/bgp/server/bmp_server.go
@@ -33,20 +33,11 @@ func NewServer() *BMPServer {
 
 // AddRouter adds a router to which we connect with BMP
 func (b *BMPServer) AddRouter(addr net.IP, port uint16, rib4 *locRIB.LocRIB, rib6 *locRIB.LocRIB) {
-	r := &router{
-		address:          addr,
-		port:             port,
-		reconnectTimeMin: 30,  // Suggested by RFC 7854
-		reconnectTimeMax: 720, // Suggested by RFC 7854
-		reconnectTimer:   time.NewTimer(time.Duration(0)),
-		rib4:             rib4,
-		rib6:             rib6,
-		neighbors:        make(map[[16]byte]*neighbor),
-	}
-
 	b.routersMu.Lock()
+	defer b.routersMu.Unlock()
+
+	r := newRouter(addr, port, rib4, rib6)
 	b.routers[fmt.Sprintf("%s:%d", r.address.String(), r.port)] = r
-	b.routersMu.Unlock()
 
 	go func(r *router) {
 		for {
@@ -71,6 +62,17 @@ func (b *BMPServer) AddRouter(addr net.IP, port uint16, rib4 *locRIB.LocRIB, rib
 	}(r)
 }
 
+// RemoveRouter removes a BMP monitored router
+func (b *BMPServer) RemoveRouter(addr net.IP, port uint16) {
+	b.routersMu.Lock()
+	defer b.routersMu.Unlock()
+
+	id := fmt.Sprintf("%s:%d", addr.String(), port)
+	r := b.routers[id]
+	r.stop <- struct{}{}
+	delete(b.routers, id)
+}
+
 func recvBMPMsg(c net.Conn) (msg []byte, err error) {
 	buffer := make([]byte, defaultBufferLen)
 	_, err = io.ReadFull(c, buffer[0:packet.MinLen])
diff --git a/protocols/bgp/server/bmp_server_test.go b/protocols/bgp/server/bmp_server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ebef9a2535e35ecdedf1a4a560003ff3fd37c17
--- /dev/null
+++ b/protocols/bgp/server/bmp_server_test.go
@@ -0,0 +1,155 @@
+package server
+
+import (
+	"net"
+	"testing"
+	"time"
+
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewServer(t *testing.T) {
+	s := NewServer()
+	assert.Equal(t, &BMPServer{
+		routers: map[string]*router{},
+	}, s)
+}
+
+func TestIntegration(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)
+	conA, conB := net.Pipe()
+	r.con = conB
+
+	go r.serve()
+
+	// Peer Up Notification
+	_, err := conA.Write([]byte{
+		// 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
+
+		// 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
+
+		// 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,
+	})
+
+	if err != nil {
+		panic("write #1 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()
+	if count != 1 {
+		t.Errorf("Unexpected route count. Expected: 1 Got: %d", count)
+	}
+
+	conA.Close()
+}
diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go
index 157657fce43f1a54a03163c19e551dc7811e7e74..6e11d6672aed81061d870e79c71183066e35a53e 100644
--- a/protocols/bgp/server/fsm.go
+++ b/protocols/bgp/server/fsm.go
@@ -331,6 +331,10 @@ func recvMsg(c net.Conn) (msg []byte, err error) {
 }
 
 func stopTimer(t *time.Timer) {
+	if t == nil {
+		return
+	}
+
 	if !t.Stop() {
 		select {
 		case <-t.C:
diff --git a/protocols/bgp/server/fsm_address_family.go b/protocols/bgp/server/fsm_address_family.go
index 01ee06b7533385f4358c0823298e936f407cb49b..af5318e4186efb714224dd503ed562fdc4b925de 100644
--- a/protocols/bgp/server/fsm_address_family.go
+++ b/protocols/bgp/server/fsm_address_family.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"fmt"
 	"time"
 
 	bnet "github.com/bio-routing/bio-rd/net"
@@ -113,7 +114,8 @@ func (f *fsmAddressFamily) updates(u *packet.BGPUpdate) {
 		path := f.newRoutePath()
 		f.processAttributes(u.PathAttributes, path)
 
-		f.adjRIBIn.AddPath(r.Prefix, path)
+		err := f.adjRIBIn.AddPath(r.Prefix, path)
+		fmt.Printf("add path err: %v\n", err)
 	}
 }
 
diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go
index 2758a506f017593d6c9b99f7c16dd110377438f3..05e540b597394424a5fde51461cc2aa55e42888b 100644
--- a/protocols/bgp/server/fsm_established.go
+++ b/protocols/bgp/server/fsm_established.go
@@ -153,16 +153,19 @@ func (s *establishedState) msgReceived(data []byte, opt *packet.DecodeOptions) (
 			s.fsm.sendNotification(bgperr.ErrorCode, bgperr.ErrorSubCode)
 		}
 		stopTimer(s.fsm.connectRetryTimer)
-		s.fsm.con.Close()
+		if s.fsm.con != nil {
+			s.fsm.con.Close()
+		}
 		s.fsm.connectRetryCounter++
-		return newIdleState(s.fsm), "Failed to decode BGP message"
+		return newIdleState(s.fsm), fmt.Sprintf("Failed to decode BGP message: %v", err)
 	}
+
 	switch msg.Header.Type {
 	case packet.NotificationMsg:
 		fmt.Println(data)
 		return s.notification()
 	case packet.UpdateMsg:
-		return s.update(msg)
+		return s.update(msg.Body.(*packet.BGPUpdate))
 	case packet.KeepaliveMsg:
 		return s.keepaliveReceived()
 	default:
@@ -178,13 +181,11 @@ func (s *establishedState) notification() (state, string) {
 	return newIdleState(s.fsm), "Received NOTIFICATION"
 }
 
-func (s *establishedState) update(msg *packet.BGPMessage) (state, string) {
+func (s *establishedState) update(u *packet.BGPUpdate) (state, string) {
 	if s.fsm.holdTime != 0 {
 		s.fsm.holdTimer.Reset(s.fsm.holdTime)
 	}
 
-	u := msg.Body.(*packet.BGPUpdate)
-
 	if s.fsm.ipv4Unicast != nil {
 		s.fsm.ipv4Unicast.processUpdate(u)
 	}
diff --git a/protocols/bgp/server/fsm_open_sent.go b/protocols/bgp/server/fsm_open_sent.go
index a66898541373f688a06aa9b2283e847095e9e332..82d1263aeb4709857268c4665064c0142f1d5cf0 100644
--- a/protocols/bgp/server/fsm_open_sent.go
+++ b/protocols/bgp/server/fsm_open_sent.go
@@ -141,6 +141,7 @@ func (s *openSentState) handleOpenMessage(openMsg *packet.BGPOpen) (state, strin
 	s.processOpenOptions(openMsg.OptParams)
 
 	if s.peerASNRcvd != s.fsm.peer.peerASN {
+		fmt.Printf("s.peerASNRcvd != s.fsm.peer.peerASN: %v != %v\n", s.peerASNRcvd, s.fsm.peer.peerASN)
 		s.fsm.sendNotification(packet.OpenMessageError, packet.BadPeerAS)
 		return newCeaseState(), fmt.Sprintf("Bad Peer AS %d, expected: %d", s.peerASNRcvd, s.fsm.peer.peerASN)
 	}
diff --git a/protocols/bgp/server/fsm_open_sent_test.go b/protocols/bgp/server/fsm_open_sent_test.go
index 708617b910775a28efcd89ec0866320905912455..395432f31bfe988c0a27ac11c1565a382ee1bea9 100644
--- a/protocols/bgp/server/fsm_open_sent_test.go
+++ b/protocols/bgp/server/fsm_open_sent_test.go
@@ -1,6 +1,7 @@
 package server
 
 import (
+	"net"
 	"testing"
 
 	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
@@ -69,7 +70,19 @@ func TestOpenMsgReceived(t *testing.T) {
 			fsm := newFSM(&peer{
 				peerASN: test.asn,
 			})
-			fsm.con = &btesting.MockConn{}
+
+			conA, conB := net.Pipe()
+			fsm.con = conB
+
+			go func() {
+				for {
+					buf := make([]byte, 1)
+					_, err := conA.Read(buf)
+					if err != nil {
+						return
+					}
+				}
+			}()
 
 			s := &openSentState{
 				fsm: fsm,
diff --git a/protocols/bmp/packet/decode_test.go b/protocols/bmp/packet/decode_test.go
index b3419725826e141b6225838f30d9e7d91296a2ba..b44a4d0689be0de048c9a7646fd1e51255e69cac 100644
--- a/protocols/bmp/packet/decode_test.go
+++ b/protocols/bmp/packet/decode_test.go
@@ -26,11 +26,11 @@ func TestDecode(t *testing.T) {
 		{
 			name: "Route monitoring ok",
 			input: []byte{
-				3, 0, 0, 0, 6 + 38 + 4, 0,
+				3, 0, 0, 0, 6 + PerPeerHeaderLen + 4, 0,
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -43,7 +43,7 @@ func TestDecode(t *testing.T) {
 			expected: &RouteMonitoringMsg{
 				CommonHeader: &CommonHeader{
 					Version:   3,
-					MsgLength: 6 + 38 + 4,
+					MsgLength: 6 + PerPeerHeaderLen + 4,
 					MsgType:   0,
 				},
 				PerPeerHeader: &PerPeerHeader{
@@ -62,11 +62,11 @@ func TestDecode(t *testing.T) {
 		{
 			name: "Route monitoring nok",
 			input: []byte{
-				3, 0, 0, 0, 6 + 38 + 4, 0,
+				3, 0, 0, 0, 6 + PerPeerHeaderLen + 4, 0,
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -80,11 +80,11 @@ func TestDecode(t *testing.T) {
 		{
 			name: "Statistic report ok",
 			input: []byte{
-				3, 0, 0, 0, 6 + 9 + 38, 1,
+				3, 0, 0, 0, 6 + 9 + PerPeerHeaderLen, 1,
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -98,7 +98,7 @@ func TestDecode(t *testing.T) {
 			expected: &StatsReport{
 				CommonHeader: &CommonHeader{
 					Version:   3,
-					MsgLength: 6 + 9 + 38,
+					MsgLength: 6 + 9 + PerPeerHeaderLen,
 					MsgType:   1,
 				},
 				PerPeerHeader: &PerPeerHeader{
@@ -124,11 +124,11 @@ func TestDecode(t *testing.T) {
 		{
 			name: "Statistic report nok",
 			input: []byte{
-				3, 0, 0, 0, 6 + 9 + 38, 1,
+				3, 0, 0, 0, 6 + 9 + PerPeerHeaderLen, 1,
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 			},
@@ -137,11 +137,11 @@ func TestDecode(t *testing.T) {
 		{
 			name: "peer down ok",
 			input: []byte{
-				3, 0, 0, 0, 6 + 9 + 38, 1,
+				3, 0, 0, 0, 6 + 9 + PerPeerHeaderLen, 1,
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -155,7 +155,7 @@ func TestDecode(t *testing.T) {
 			expected: &StatsReport{
 				CommonHeader: &CommonHeader{
 					Version:   3,
-					MsgLength: 6 + 9 + 38,
+					MsgLength: 6 + 9 + PerPeerHeaderLen,
 					MsgType:   1,
 				},
 				PerPeerHeader: &PerPeerHeader{
@@ -181,11 +181,11 @@ func TestDecode(t *testing.T) {
 		{
 			name: "peer down nok",
 			input: []byte{
-				3, 0, 0, 0, 6 + 9 + 38, 1,
+				3, 0, 0, 0, 6 + 9 + PerPeerHeaderLen, 1,
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -204,7 +204,7 @@ func TestDecode(t *testing.T) {
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -216,6 +216,9 @@ func TestDecode(t *testing.T) {
 				0, 200,
 
 				// OPEN Sent
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 34,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -224,6 +227,9 @@ func TestDecode(t *testing.T) {
 				1, 2, 3, 4, 5,
 
 				// OPEN Recv
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -253,6 +259,9 @@ func TestDecode(t *testing.T) {
 				LocalPort:    100,
 				RemotePort:   200,
 				SentOpenMsg: []byte{
+					255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+					0, 34,
+					1,
 					4,    // Version
 					1, 0, // ASN
 					2, 0, // Hold Time
@@ -261,7 +270,9 @@ func TestDecode(t *testing.T) {
 					1, 2, 3, 4, 5,
 				},
 				ReceivedOpenMsg: []byte{
-					// OPEN Recv
+					255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+					0, 29,
+					1,
 					4,    // Version
 					1, 0, // ASN
 					2, 0, // Hold Time
@@ -280,7 +291,7 @@ func TestDecode(t *testing.T) {
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -374,7 +385,7 @@ func TestDecode(t *testing.T) {
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -416,7 +427,7 @@ func TestDecode(t *testing.T) {
 
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0,
diff --git a/protocols/bmp/packet/peer_down_test.go b/protocols/bmp/packet/peer_down_test.go
index b1df8b55e84d9ae6bf5854e4a2aea51357d73c3a..58cdbed36e9cd6ce8244f960b8cd15cc64004451 100644
--- a/protocols/bmp/packet/peer_down_test.go
+++ b/protocols/bmp/packet/peer_down_test.go
@@ -32,7 +32,7 @@ func TestDecodePeerDownNotification(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -43,12 +43,12 @@ func TestDecodePeerDownNotification(t *testing.T) {
 				1, 2, 3,
 			},
 			ch: &CommonHeader{
-				MsgLength: CommonHeaderLen + 4 + 38,
+				MsgLength: CommonHeaderLen + 4 + PerPeerHeaderLen,
 			},
 			wantFail: false,
 			expected: &PeerDownNotification{
 				CommonHeader: &CommonHeader{
-					MsgLength: CommonHeaderLen + 4 + 38,
+					MsgLength: CommonHeaderLen + 4 + PerPeerHeaderLen,
 				},
 				PerPeerHeader: &PerPeerHeader{
 					PeerType:              1,
@@ -71,7 +71,7 @@ func TestDecodePeerDownNotification(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -106,7 +106,7 @@ func TestDecodePeerDownNotification(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0,
@@ -121,7 +121,7 @@ func TestDecodePeerDownNotification(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
diff --git a/protocols/bmp/packet/peer_up.go b/protocols/bmp/packet/peer_up.go
index 58adc4cc5e6cd294c88758333f6aa26c214f46b0..34d37a7cbc9786ec4459b50a56c917a037c261a4 100644
--- a/protocols/bmp/packet/peer_up.go
+++ b/protocols/bmp/packet/peer_up.go
@@ -9,7 +9,7 @@ import (
 
 const (
 	// OpenMsgMinLen is the minimal length of a BGP open message
-	OpenMsgMinLen = 10
+	OpenMsgMinLen = 29
 )
 
 // PeerUpNotification represents a peer up notification
diff --git a/protocols/bmp/packet/peer_up_test.go b/protocols/bmp/packet/peer_up_test.go
index d29ec7550cc757ee8e3332d1de69509e590948bd..0b66d6e8e059ddc6600104d83777791f6b22ae22 100644
--- a/protocols/bmp/packet/peer_up_test.go
+++ b/protocols/bmp/packet/peer_up_test.go
@@ -18,6 +18,7 @@ func TestPeerUpMsgType(t *testing.T) {
 		t.Errorf("Unexpected result")
 	}
 }
+
 func TestDecodePeerUp(t *testing.T) {
 	tests := []struct {
 		name     string
@@ -31,7 +32,7 @@ func TestDecodePeerUp(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -43,6 +44,9 @@ func TestDecodePeerUp(t *testing.T) {
 				0, 200,
 
 				// OPEN Sent
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 34,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -51,6 +55,9 @@ func TestDecodePeerUp(t *testing.T) {
 				1, 2, 3, 4, 5,
 
 				// OPEN Recv
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -60,12 +67,12 @@ func TestDecodePeerUp(t *testing.T) {
 				120, 140, 160, // Information
 			},
 			ch: &CommonHeader{
-				MsgLength: 47,
+				MsgLength: 126,
 			},
 			wantFail: false,
 			expected: &PeerUpNotification{
 				CommonHeader: &CommonHeader{
-					MsgLength: 47,
+					MsgLength: 126,
 				},
 				PerPeerHeader: &PerPeerHeader{
 					PeerType:              1,
@@ -81,6 +88,9 @@ func TestDecodePeerUp(t *testing.T) {
 				LocalPort:    100,
 				RemotePort:   200,
 				SentOpenMsg: []byte{
+					255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+					0, 34,
+					1,
 					4,    // Version
 					1, 0, // ASN
 					2, 0, // Hold Time
@@ -89,7 +99,9 @@ func TestDecodePeerUp(t *testing.T) {
 					1, 2, 3, 4, 5,
 				},
 				ReceivedOpenMsg: []byte{
-					// OPEN Recv
+					255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+					0, 29,
+					1,
 					4,    // Version
 					1, 0, // ASN
 					2, 0, // Hold Time
@@ -106,7 +118,7 @@ func TestDecodePeerUp(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -118,6 +130,9 @@ func TestDecodePeerUp(t *testing.T) {
 				0, 200,
 
 				// OPEN Sent
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 34,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -126,6 +141,9 @@ func TestDecodePeerUp(t *testing.T) {
 				1, 2, 3, 4, 5,
 
 				// OPEN Recv
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -133,12 +151,12 @@ func TestDecodePeerUp(t *testing.T) {
 				0, // Opt Parm Len
 			},
 			ch: &CommonHeader{
-				MsgLength: 44,
+				MsgLength: 82,
 			},
 			wantFail: false,
 			expected: &PeerUpNotification{
 				CommonHeader: &CommonHeader{
-					MsgLength: 44,
+					MsgLength: 82,
 				},
 				PerPeerHeader: &PerPeerHeader{
 					PeerType:              1,
@@ -154,6 +172,9 @@ func TestDecodePeerUp(t *testing.T) {
 				LocalPort:    100,
 				RemotePort:   200,
 				SentOpenMsg: []byte{
+					255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+					0, 34,
+					1,
 					4,    // Version
 					1, 0, // ASN
 					2, 0, // Hold Time
@@ -162,7 +183,9 @@ func TestDecodePeerUp(t *testing.T) {
 					1, 2, 3, 4, 5,
 				},
 				ReceivedOpenMsg: []byte{
-					// OPEN Recv
+					255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+					0, 29,
+					1,
 					4,    // Version
 					1, 0, // ASN
 					2, 0, // Hold Time
@@ -176,13 +199,13 @@ func TestDecodePeerUp(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0,
 			},
 			ch: &CommonHeader{
-				MsgLength: 47,
+				MsgLength: 51,
 			},
 			wantFail: true,
 		},
@@ -191,7 +214,7 @@ func TestDecodePeerUp(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -202,7 +225,7 @@ func TestDecodePeerUp(t *testing.T) {
 				0, 100,
 			},
 			ch: &CommonHeader{
-				MsgLength: 47,
+				MsgLength: 51,
 			},
 			wantFail: true,
 		},
@@ -211,7 +234,7 @@ func TestDecodePeerUp(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -223,12 +246,15 @@ func TestDecodePeerUp(t *testing.T) {
 				0, 200,
 
 				// OPEN Sent
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
 			},
 			ch: &CommonHeader{
-				MsgLength: 47,
+				MsgLength: 89,
 			},
 			wantFail: true,
 		},
@@ -237,7 +263,7 @@ func TestDecodePeerUp(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -248,12 +274,15 @@ func TestDecodePeerUp(t *testing.T) {
 				0, 200,
 
 				// OPEN Sent
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
 			},
 			ch: &CommonHeader{
-				MsgLength: 47,
+				MsgLength: 88,
 			},
 			wantFail: true,
 		},
@@ -265,6 +294,9 @@ func TestDecodePeerUp(t *testing.T) {
 				0, 200,
 
 				// OPEN Sent
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -273,6 +305,9 @@ func TestDecodePeerUp(t *testing.T) {
 				1, 2, 3, 4, 5,
 
 				// OPEN Recv
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+				0, 29,
+				1,
 				4,    // Version
 				1, 0, // ASN
 				2, 0, // Hold Time
@@ -280,7 +315,7 @@ func TestDecodePeerUp(t *testing.T) {
 				3, // Opt Parm Len
 			},
 			ch: &CommonHeader{
-				MsgLength: 47,
+				MsgLength: 85,
 			},
 			wantFail: true,
 		},
diff --git a/protocols/bmp/packet/per_peer_header.go b/protocols/bmp/packet/per_peer_header.go
index d03f8b43d5d52b6dd705329c0bb10f834d39a15d..da797d44237177a3c6ef4972ab2d7cd55d9d665a 100644
--- a/protocols/bmp/packet/per_peer_header.go
+++ b/protocols/bmp/packet/per_peer_header.go
@@ -9,14 +9,14 @@ import (
 
 const (
 	// PerPeerHeaderLen is the length of a per peer header
-	PerPeerHeaderLen = 38
+	PerPeerHeaderLen = 42
 )
 
 // PerPeerHeader represents a BMP per peer header
 type PerPeerHeader struct {
 	PeerType              uint8
 	PeerFlags             uint8
-	PeerDistinguisher     uint32
+	PeerDistinguisher     uint64
 	PeerAddress           [16]byte
 	PeerAS                uint32
 	PeerBGPID             uint32
@@ -28,7 +28,7 @@ type PerPeerHeader struct {
 func (p *PerPeerHeader) Serialize(buf *bytes.Buffer) {
 	buf.WriteByte(p.PeerType)
 	buf.WriteByte(p.PeerFlags)
-	buf.Write(convert.Uint32Byte(p.PeerDistinguisher))
+	buf.Write(convert.Uint64Byte(p.PeerDistinguisher))
 	buf.Write(p.PeerAddress[:])
 	buf.Write(convert.Uint32Byte(p.PeerAS))
 	buf.Write(convert.Uint32Byte(p.PeerBGPID))
diff --git a/protocols/bmp/packet/per_peer_header_test.go b/protocols/bmp/packet/per_peer_header_test.go
index de503a84edea465106787c5846ce26244c42c84a..679946e76c19d05696bd26fb06c9b03dfb6a6847 100644
--- a/protocols/bmp/packet/per_peer_header_test.go
+++ b/protocols/bmp/packet/per_peer_header_test.go
@@ -28,7 +28,7 @@ func TestPerPeerHeaderSerialize(t *testing.T) {
 			expected: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -59,7 +59,7 @@ func TestDecodePerPeerHeader(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -83,7 +83,7 @@ func TestDecodePerPeerHeader(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
diff --git a/protocols/bmp/packet/route_mirroring_test.go b/protocols/bmp/packet/route_mirroring_test.go
index c62799a37a2c1bfa53c01eafb90979aa896716be..87bcf2110ed6c34f230bca7fbb3ceb4eb1c97400 100644
--- a/protocols/bmp/packet/route_mirroring_test.go
+++ b/protocols/bmp/packet/route_mirroring_test.go
@@ -31,7 +31,7 @@ func TestDecodeRouteMirroringMsg(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -78,7 +78,7 @@ func TestDecodeRouteMirroringMsg(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 			},
@@ -92,7 +92,7 @@ func TestDecodeRouteMirroringMsg(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
diff --git a/protocols/bmp/packet/route_monitoring_test.go b/protocols/bmp/packet/route_monitoring_test.go
index d28169346d6312f757fd317b879c55e20dd43847..7534e6f31d0deb79159c188ce5184443a63e672a 100644
--- a/protocols/bmp/packet/route_monitoring_test.go
+++ b/protocols/bmp/packet/route_monitoring_test.go
@@ -31,7 +31,7 @@ func TestDecodeRouteMonitoringMsg(t *testing.T) {
 			input: []byte{
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
diff --git a/protocols/bmp/packet/stats_report_test.go b/protocols/bmp/packet/stats_report_test.go
index 2fc47cbb4a1b69c55834af7db122215dfdf32a2b..0bf372238be74e55b4b4b49ca2c993bf88fbe31c 100644
--- a/protocols/bmp/packet/stats_report_test.go
+++ b/protocols/bmp/packet/stats_report_test.go
@@ -32,7 +32,7 @@ func TestDecodeStatsReport(t *testing.T) {
 				// Per Peer Header
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -83,7 +83,7 @@ func TestDecodeStatsReport(t *testing.T) {
 				// Per Peer Header
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -96,7 +96,7 @@ func TestDecodeStatsReport(t *testing.T) {
 				// Per Peer Header
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
@@ -111,7 +111,7 @@ func TestDecodeStatsReport(t *testing.T) {
 				// Per Peer Header
 				1,
 				2,
-				0, 0, 0, 3,
+				0, 0, 0, 0, 0, 0, 0, 3,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 0, 200, 124,
 				0, 0, 0, 123,
diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go
index 631f1d197cabc926056f186e21e1b6cd5d719afd..279ed35a29bd51f7ec9b2b9157148191e8800b8d 100644
--- a/routingtable/adjRIBIn/adj_rib_in.go
+++ b/routingtable/adjRIBIn/adj_rib_in.go
@@ -72,6 +72,7 @@ func (a *AdjRIBIn) AddPath(pfx net.Prefix, p *route.Path) error {
 
 	// RFC4456 Sect. 8: Ignore route with our RouterID as OriginatorID
 	if p.BGPPath.OriginatorID == a.routerID {
+		panic("FKJK")
 		return nil
 	}
 
diff --git a/testing/conn_mock.go b/testing/conn_mock.go
index 9c89ea64e658ad2cb5c46f91f5ac368fe9d5a436..1be39e05208aa91d67fd841b2de740bfdc15d5da 100644
--- a/testing/conn_mock.go
+++ b/testing/conn_mock.go
@@ -1,34 +1,32 @@
 package testing
 
 import (
+	"bytes"
 	"net"
 )
 
 // MockConn mock an connection
 type MockConn struct {
 	net.Conn
-
-	// Bytes are the bytes written
-	Bytes []byte
+	Buf    *bytes.Buffer
+	Closed bool
 }
 
 func NewMockConn() *MockConn {
 	return &MockConn{
-		Bytes: make([]byte, 0),
+		Buf: bytes.NewBuffer(nil),
 	}
 }
 
 func (m *MockConn) Write(b []byte) (int, error) {
-	m.Bytes = append(m.Bytes, b...)
-	return len(b), nil
+	return m.Buf.Write(b)
 }
 
 func (m *MockConn) Read(b []byte) (n int, err error) {
-	count := len(b)
-	if count > len(m.Bytes) {
-		count = len(m.Bytes)
-	}
+	return m.Buf.Read(b)
+}
 
-	copy(b, m.Bytes[0:count])
-	return count, nil
+func (m *MockConn) Close() error {
+	m.Closed = true
+	return nil
 }
diff --git a/testing/conn_mock_test.go b/testing/conn_mock_test.go
index 9d964ffa9fecef3f577dd02c498ed9dc110bcf1b..5afe2e35d0e0bbad21910b2600f084bbf088d20b 100644
--- a/testing/conn_mock_test.go
+++ b/testing/conn_mock_test.go
@@ -1,25 +1,30 @@
 package testing
 
 import (
+	"bytes"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 )
 
 func TestWrite(t *testing.T) {
-	m := &MockConn{}
+	m := &MockConn{
+		Buf: bytes.NewBuffer(nil),
+	}
 
 	payload := []byte{1, 2, 3}
 	m.Write(payload)
 
-	assert.Equal(t, payload, m.Bytes)
+	assert.Equal(t, payload, m.Buf.Bytes())
 }
 
 func TestRead(t *testing.T) {
-	m := &MockConn{}
+	m := &MockConn{
+		Buf: bytes.NewBuffer(nil),
+	}
 
 	payload := []byte{1, 2, 3}
-	m.Bytes = payload
+	m.Buf.Write(payload)
 
 	buffer := make([]byte, 4)
 	n, _ := m.Read(buffer)
diff --git a/testing/log.go b/testing/log.go
new file mode 100644
index 0000000000000000000000000000000000000000..538b23ef199506c37fb4c392951cd960d33082cf
--- /dev/null
+++ b/testing/log.go
@@ -0,0 +1,26 @@
+package testing
+
+import (
+	"fmt"
+
+	"github.com/sirupsen/logrus"
+)
+
+// LogFormatter provides a log formatter for unit tests free of timestamps
+type LogFormatter struct{}
+
+// NewLogFormatter creates a new log formatter
+func NewLogFormatter() *LogFormatter {
+	return &LogFormatter{}
+}
+
+// Format formats a log entry
+func (l *LogFormatter) Format(e *logrus.Entry) ([]byte, error) {
+	var res string
+	if len(e.Data) == 0 {
+		res = fmt.Sprintf("level=%s msg=%q", e.Level, e.Message)
+	} else {
+		res = fmt.Sprintf("level=%s msg=%q fields=%v", e.Level, e.Message, e.Data)
+	}
+	return []byte(res), nil
+}