diff --git a/protocols/bgp/packet/path_attributes_test.go b/protocols/bgp/packet/path_attributes_test.go
index 1527f8cf6e7d3d3ff9365068272aa3fad52e41d0..248b731714389096a62e2381a548780beb8318e7 100644
--- a/protocols/bgp/packet/path_attributes_test.go
+++ b/protocols/bgp/packet/path_attributes_test.go
@@ -1580,6 +1580,212 @@ func TestSerialize(t *testing.T) {
 	}
 }
 
+func TestSerializeAddPath(t *testing.T) {
+	tests := []struct {
+		name     string
+		msg      *BGPUpdateAddPath
+		expected []byte
+		wantFail bool
+	}{
+		{
+			name: "Withdraw only",
+			msg: &BGPUpdateAddPath{
+				WithdrawnRoutes: &NLRIAddPath{
+					PathIdentifier: 257,
+					IP:             strAddr("100.110.120.0"),
+					Pfxlen:         24,
+				},
+			},
+			expected: []byte{
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0, 31, // Length
+				2,    // Msg Type
+				0, 8, // Withdrawn Routes Length
+				0, 0, 1, 1, // Path Identifier
+				24, 100, 110, 120, // NLRI
+				0, 0, // Total Path Attribute Length
+			},
+		},
+		{
+			name: "NLRI only",
+			msg: &BGPUpdateAddPath{
+				NLRI: &NLRIAddPath{
+					PathIdentifier: 257,
+					IP:             strAddr("100.110.128.0"),
+					Pfxlen:         17,
+				},
+			},
+			expected: []byte{
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0, 31, // Length
+				2,    // Msg Type
+				0, 0, // Withdrawn Routes Length
+				0, 0, // Total Path Attribute Length
+				0, 0, 1, 1, // Path Identifier
+				17, 100, 110, 128, // NLRI
+			},
+		},
+		{
+			name: "Path Attributes only",
+			msg: &BGPUpdateAddPath{
+				PathAttributes: &PathAttribute{
+					Optional:   true,
+					Transitive: true,
+					TypeCode:   OriginAttr,
+					Value:      uint8(0), // IGP
+				},
+			},
+			expected: []byte{
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0, 27, // Length
+				2,    // Msg Type
+				0, 0, // Withdrawn Routes Length
+				0, 4, // Total Path Attribute Length
+				64, // Attr. Flags
+				1,  // Attr. Type Code
+				1,  // Length
+				0,  // Value
+			},
+		},
+		{
+			name: "Full test",
+			msg: &BGPUpdateAddPath{
+				WithdrawnRoutes: &NLRIAddPath{
+					IP:     strAddr("10.0.0.0"),
+					Pfxlen: 8,
+					Next: &NLRIAddPath{
+						IP:     strAddr("192.168.0.0"),
+						Pfxlen: 16,
+					},
+				},
+				PathAttributes: &PathAttribute{
+					TypeCode: OriginAttr,
+					Value:    uint8(0),
+					Next: &PathAttribute{
+						TypeCode: ASPathAttr,
+						Value: ASPath{
+							{
+								Type: 2,
+								ASNs: []uint32{100, 155, 200},
+							},
+							{
+								Type: 1,
+								ASNs: []uint32{10, 20},
+							},
+						},
+						Next: &PathAttribute{
+							TypeCode: NextHopAttr,
+							Value:    strAddr("10.20.30.40"),
+							Next: &PathAttribute{
+								TypeCode: MEDAttr,
+								Value:    uint32(100),
+								Next: &PathAttribute{
+									TypeCode: LocalPrefAttr,
+									Value:    uint32(500),
+									Next: &PathAttribute{
+										TypeCode: AtomicAggrAttr,
+										Next: &PathAttribute{
+											TypeCode: AggregatorAttr,
+											Value:    uint16(200),
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+				NLRI: &NLRIAddPath{
+					IP:     strAddr("8.8.8.0"),
+					Pfxlen: 24,
+					Next: &NLRIAddPath{
+						IP:     strAddr("185.65.240.0"),
+						Pfxlen: 22,
+					},
+				},
+			},
+			expected: []byte{
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0, 102, // Length
+				2, // Msg Type
+
+				// Withdraws
+				0, 13, // Withdrawn Routes Length
+				0, 0, 0, 0, // Path Identifier
+				8, 10, // Withdraw 10/8
+				0, 0, 0, 0, // Path Identifier
+				16, 192, 168, // Withdraw 192.168/16
+
+				0, 50, // Total Path Attribute Length
+
+				// ORIGIN
+				64, // Attr. Flags
+				1,  // Attr. Type Code
+				1,  // Length
+				0,  // Value
+				// ASPath
+				64,                     // Attr. Flags
+				2,                      // Attr. Type Code
+				14,                     // Attr. Length
+				2,                      // Path Segment Type = AS_SEQUENCE
+				3,                      // Path Segment Length
+				0, 100, 0, 155, 0, 200, // ASNs
+				1,            // Path Segment Type = AS_SET
+				2,            // Path Segment Type = AS_SET
+				0, 10, 0, 20, // ASNs
+				// Next Hop
+				64,             // Attr. Flags
+				3,              // Attr. Type Code
+				4,              // Length
+				10, 20, 30, 40, // Next Hop Address
+				// MED
+				128,          // Attr. Flags
+				4,            // Attr Type Code
+				4,            // Length
+				0, 0, 0, 100, // MED = 100
+				// LocalPref
+				64,           // Attr. Flags
+				5,            // Attr. Type Code
+				4,            // Length
+				0, 0, 1, 244, // Localpref
+				// Atomic Aggregate
+				64, // Attr. Flags
+				6,  // Attr. Type Code
+				0,  // Length
+				// Aggregator
+				192,    // Attr. Flags
+				7,      // Attr. Type Code
+				2,      // Length
+				0, 200, // Aggregator ASN = 200
+
+				// NLRI
+				0, 0, 0, 0, // Path Identifier
+				24, 8, 8, 8, // 8.8.8.0/24
+				0, 0, 0, 0, // Path Identifier
+				22, 185, 65, 240, // 185.65.240.0/22
+			},
+		},
+	}
+
+	for _, test := range tests {
+		res, err := test.msg.SerializeUpdate()
+		if err != nil {
+			if test.wantFail {
+				continue
+			}
+
+			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
+			continue
+		}
+
+		if test.wantFail {
+			t.Errorf("Unexpected success for test %q", test.name)
+			continue
+		}
+
+		assert.Equalf(t, test.expected, res, "%s", test.name)
+	}
+}
+
 func TestParseASPathStr(t *testing.T) {
 	tests := []struct {
 		name     string
diff --git a/protocols/bgp/server/update_helper.go b/protocols/bgp/server/update_helper.go
index 6873ca8db7c50ce449f23d43777fdc2d27744965..4a50f1d7ef6903c415a99108f8540fc5d0b40bcd 100644
--- a/protocols/bgp/server/update_helper.go
+++ b/protocols/bgp/server/update_helper.go
@@ -2,10 +2,12 @@ package server
 
 import (
 	"fmt"
+	"io"
 	"strings"
 
 	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
 	"github.com/bio-routing/bio-rd/route"
+	log "github.com/sirupsen/logrus"
 )
 
 func pathAttribues(p *route.Path, fsm *FSM) (*packet.PathAttribute, error) {
@@ -68,3 +70,21 @@ func addOptionalPathAttribues(p *route.Path, parent *packet.PathAttribute) error
 
 	return nil
 }
+
+type serializeAbleUpdate interface {
+	SerializeUpdate() ([]byte, error)
+}
+
+func serializeAndSendUpdate(out io.Writer, update serializeAbleUpdate) error {
+	updateBytes, err := update.SerializeUpdate()
+	if err != nil {
+		log.Errorf("Unable to serialize BGP Update: %v", err)
+		return nil
+	}
+
+	_, err = out.Write(updateBytes)
+	if err != nil {
+		return fmt.Errorf("Failed sending Update: %v", err)
+	}
+	return nil
+}
diff --git a/protocols/bgp/server/update_helper_test.go b/protocols/bgp/server/update_helper_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5752edded4aba03b66acd88950796e21c2c82620
--- /dev/null
+++ b/protocols/bgp/server/update_helper_test.go
@@ -0,0 +1,109 @@
+package server
+
+import (
+	"io"
+	"testing"
+
+	"bytes"
+
+	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
+
+	"errors"
+
+	"github.com/bio-routing/bio-rd/net"
+	"github.com/stretchr/testify/assert"
+)
+
+type failingUpdate struct{}
+
+func (f *failingUpdate) SerializeUpdate() ([]byte, error) {
+	return nil, errors.New("general error")
+}
+
+type WriterByter interface {
+	Bytes() []byte
+	io.Writer
+}
+
+type failingReadWriter struct {
+}
+
+func (f *failingReadWriter) Write(p []byte) (n int, err error) {
+	return 0, errors.New("general error")
+}
+
+func (f *failingReadWriter) Bytes() []byte {
+	return []byte{}
+}
+
+func TestSerializeAndSendUpdate(t *testing.T) {
+	tests := []struct {
+		name       string
+		buf        WriterByter
+		err        error
+		testUpdate serializeAbleUpdate
+		expected   []byte
+	}{
+		{
+			name: "normal bgp update",
+			buf:  bytes.NewBuffer(nil),
+			err:  nil,
+			testUpdate: &packet.BGPUpdate{
+				WithdrawnRoutesLen: 5,
+				WithdrawnRoutes: &packet.NLRI{
+					IP:     strAddr("10.0.0.0"),
+					Pfxlen: 8,
+					Next: &packet.NLRI{
+						IP:     strAddr("192.168.0.0"),
+						Pfxlen: 16,
+					},
+				},
+			},
+
+			expected: []byte{
+				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
+				0, 28, // Length
+				2,                               // Type = Update
+				0, 5, 8, 10, 16, 192, 168, 0, 0, // 2 withdraws
+			},
+		},
+		{
+			name:       "failed serialization",
+			buf:        bytes.NewBuffer(nil),
+			err:        nil,
+			testUpdate: &failingUpdate{},
+			expected:   nil,
+		},
+		{
+			name: "failed connection",
+			buf:  &failingReadWriter{},
+			err:  errors.New("Failed sending Update: general error"),
+			testUpdate: &packet.BGPUpdate{
+				WithdrawnRoutesLen: 5,
+				WithdrawnRoutes: &packet.NLRI{
+					IP:     strAddr("10.0.0.0"),
+					Pfxlen: 8,
+					Next: &packet.NLRI{
+						IP:     strAddr("192.168.0.0"),
+						Pfxlen: 16,
+					},
+				},
+			},
+			expected: []byte{},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			err := serializeAndSendUpdate(test.buf, test.testUpdate)
+			assert.Equal(t, test.err, err)
+
+			assert.Equal(t, test.expected, test.buf.Bytes())
+		})
+
+	}
+}
+
+func strAddr(s string) uint32 {
+	ret, _ := net.StrToAddr(s)
+	return ret
+}
diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go
index 54c1d1b0cfa28c9094015d50483af1fd12bfd2e6..6c6b7dfd152c0cf387055e8e86a5d9fc03078000 100644
--- a/protocols/bgp/server/update_sender.go
+++ b/protocols/bgp/server/update_sender.go
@@ -34,26 +34,15 @@ func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error {
 		return nil
 	}
 
-	update := &packet.BGPUpdateAddPath{
+	update := &packet.BGPUpdate{
 		PathAttributes: pathAttrs,
-		NLRI: &packet.NLRIAddPath{
-			PathIdentifier: p.BGPPath.PathIdentifier,
-			IP:             pfx.Addr(),
-			Pfxlen:         pfx.Pfxlen(),
+		NLRI: &packet.NLRI{
+			IP:     pfx.Addr(),
+			Pfxlen: pfx.Pfxlen(),
 		},
 	}
 
-	updateBytes, err := update.SerializeUpdate()
-	if err != nil {
-		log.Errorf("Unable to serialize BGP Update: %v", err)
-		return nil
-	}
-
-	_, err = u.fsm.con.Write(updateBytes)
-	if err != nil {
-		return fmt.Errorf("Failed sending Update: %v", err)
-	}
-	return nil
+	return serializeAndSendUpdate(u.fsm.con, update)
 }
 
 // RemovePath withdraws prefix `pfx` from a peer
diff --git a/protocols/bgp/server/update_sender_add_path.go b/protocols/bgp/server/update_sender_add_path.go
index 84d6796046b8b3380a6afae2f7ab1257b59a699c..5c9f545720e797309c80039a8ce466be2e72878b 100644
--- a/protocols/bgp/server/update_sender_add_path.go
+++ b/protocols/bgp/server/update_sender_add_path.go
@@ -1,8 +1,6 @@
 package server
 
 import (
-	"fmt"
-
 	log "github.com/sirupsen/logrus"
 
 	"github.com/bio-routing/bio-rd/net"
@@ -32,26 +30,15 @@ func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
 		log.Errorf("Unable to create BGP Update: %v", err)
 		return nil
 	}
-
-	update := &packet.BGPUpdate{
+	update := &packet.BGPUpdateAddPath{
 		PathAttributes: pathAttrs,
-		NLRI: &packet.NLRI{
-			IP:     pfx.Addr(),
-			Pfxlen: pfx.Pfxlen(),
+		NLRI: &packet.NLRIAddPath{
+			PathIdentifier: p.BGPPath.PathIdentifier,
+			IP:             pfx.Addr(),
+			Pfxlen:         pfx.Pfxlen(),
 		},
 	}
-
-	updateBytes, err := update.SerializeUpdate()
-	if err != nil {
-		log.Errorf("Unable to serialize BGP Update: %v", err)
-		return nil
-	}
-
-	_, err = u.fsm.con.Write(updateBytes)
-	if err != nil {
-		return fmt.Errorf("Failed sending Update: %v", err)
-	}
-	return nil
+	return serializeAndSendUpdate(u.fsm.con, update)
 }
 
 // RemovePath withdraws prefix `pfx` from a peer
diff --git a/protocols/bgp/server/withdraw.go b/protocols/bgp/server/withdraw.go
index 3769c63fa1dd5d9a59f200aadff4b945fae61d20..42e97a399cdcf8c208fc29063f7213e4d780ad96 100644
--- a/protocols/bgp/server/withdraw.go
+++ b/protocols/bgp/server/withdraw.go
@@ -35,12 +35,8 @@ func withDrawPrefixes(out io.Writer, prefixes ...net.Prefix) error {
 	update := &packet.BGPUpdate{
 		WithdrawnRoutes: rootNLRI,
 	}
-	data, err := update.SerializeUpdate()
-	if err != nil {
-		return err
-	}
-	_, err = out.Write(data)
-	return err
+	return serializeAndSendUpdate(out, update)
+
 }
 
 // withDrawPrefixesAddPath generates a BGPUpdateAddPath message and write it to the given
@@ -59,10 +55,5 @@ func withDrawPrefixesAddPath(out io.Writer, pfx net.Prefix, p *route.Path) error
 			Pfxlen:         pfx.Pfxlen(),
 		},
 	}
-	data, err := update.SerializeUpdate()
-	if err != nil {
-		return err
-	}
-	_, err = out.Write(data)
-	return err
+	return serializeAndSendUpdate(out, update)
 }
diff --git a/routingtable/table_test.go b/routingtable/table_test.go
index a2eb10f76f93046fe71e98e59998ff52e15283b5..ef18c5175533a649504f4d6ade2a43edcda102ff 100644
--- a/routingtable/table_test.go
+++ b/routingtable/table_test.go
@@ -262,6 +262,12 @@ func TestGetLonger(t *testing.T) {
 				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
 			},
 		},
+		{
+			name:     "Test 2: Empty root",
+			routes:   nil,
+			needle:   net.NewPfx(strAddr("10.0.0.0"), 8),
+			expected: []*route.Route{},
+		},
 	}
 
 	for _, test := range tests {
@@ -445,6 +451,372 @@ func TestRemovePath(t *testing.T) {
 	}
 }
 
+func TestReplacePath(t *testing.T) {
+	tests := []struct {
+		name        string
+		routes      []*route.Route
+		replacePfx  net.Prefix
+		replacePath *route.Path
+		expected    []*route.Route
+		expectedOld []*route.Path
+	}{
+		{
+			name:       "replace in empty table",
+			replacePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
+			replacePath: &route.Path{
+				Type:    route.BGPPathType,
+				BGPPath: &route.BGPPath{},
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type:    route.BGPPathType,
+					BGPPath: &route.BGPPath{},
+				}),
+			},
+			expectedOld: nil,
+		},
+		{
+			name: "replace not existing prefix with multiple paths",
+			routes: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1001,
+						NextHop:   101,
+					},
+				}),
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			replacePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
+			replacePath: &route.Path{
+				Type: route.BGPPathType,
+				BGPPath: &route.BGPPath{
+					LocalPref: 1000,
+				},
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1000,
+					},
+				}),
+				newMultiPathRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1001,
+						NextHop:   101,
+					},
+				}, &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			expectedOld: []*route.Path{},
+		},
+		{
+			name: "replace existing prefix with multiple paths",
+			routes: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 2,
+					},
+				}),
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1001,
+						NextHop:   101,
+					},
+				}),
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			replacePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
+			replacePath: &route.Path{
+				Type: route.BGPPathType,
+				BGPPath: &route.BGPPath{
+					LocalPref: 1000,
+				},
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1000,
+					},
+				}),
+				newMultiPathRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1001,
+						NextHop:   101,
+					},
+				}, &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			expectedOld: []*route.Path{
+				{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				},
+				{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 2,
+					},
+				},
+			},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			rt := NewRoutingTable()
+			for _, route := range test.routes {
+				for _, p := range route.Paths() {
+					rt.AddPath(route.Prefix(), p)
+				}
+			}
+
+			old := rt.ReplacePath(test.replacePfx, test.replacePath)
+			assert.ElementsMatch(t, test.expectedOld, old)
+			assert.ElementsMatch(t, test.expected, rt.Dump())
+		})
+
+	}
+}
+
+func TestRemovePrefix(t *testing.T) {
+	tests := []struct {
+		name        string
+		routes      []*route.Route
+		removePfx   net.Prefix
+		expected    []*route.Route
+		expectedOld []*route.Path
+	}{
+		{
+			name:        "remove in empty table",
+			removePfx:   net.NewPfx(strAddr("10.0.0.0"), 8),
+			expected:    []*route.Route{},
+			expectedOld: nil,
+		},
+		{
+			name: "remove not exist prefix",
+			routes: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			removePfx: net.NewPfx(strAddr("12.0.0.0"), 8),
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			expectedOld: nil,
+		},
+		{
+			name: "remove not existing more specific prefix",
+			routes: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			removePfx: net.NewPfx(strAddr("10.0.0.0"), 9),
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			expectedOld: nil,
+		},
+		{
+			name: "remove not existing more less prefix",
+			routes: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			removePfx: net.NewPfx(strAddr("10.0.0.0"), 7),
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			expectedOld: nil,
+		},
+		{
+			name: "remove existing prefix",
+			routes: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				}),
+				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 2,
+					},
+				}),
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			removePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1002,
+						NextHop:   100,
+					},
+				}),
+			},
+			expectedOld: []*route.Path{
+				{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 1,
+					},
+				},
+				{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						LocalPref: 2,
+					},
+				},
+			},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			rt := NewRoutingTable()
+			for _, route := range test.routes {
+				for _, p := range route.Paths() {
+					rt.AddPath(route.Prefix(), p)
+				}
+			}
+
+			old := rt.RemovePfx(test.removePfx)
+			assert.ElementsMatch(t, test.expectedOld, old)
+			assert.ElementsMatch(t, test.expected, rt.Dump())
+		})
+
+	}
+}
+
+func newMultiPathRoute(pfx net.Prefix, paths ...*route.Path) *route.Route {
+	if len(paths) == 0 {
+		return route.NewRoute(pfx, nil)
+	}
+	r := route.NewRoute(pfx, paths[0])
+	for i := 1; i < len(paths); i++ {
+		r.AddPath(paths[i])
+	}
+	return r
+
+}
+
 func strAddr(s string) uint32 {
 	ret, _ := net.StrToAddr(s)
 	return ret