diff --git a/route/route.go b/route/route.go
index f9251bbcef51371005215b99b1efa58fae17d26a..e6b46ee6bd3e4bd69927f9cb97ec386dae0aaa56 100644
--- a/route/route.go
+++ b/route/route.go
@@ -28,7 +28,7 @@ type Route struct {
 	ecmpPaths uint
 }
 
-// NewRoute generates a new route with paths p
+// NewRoute generates a new route with path p
 func NewRoute(pfx net.Prefix, p *Path) *Route {
 	r := &Route{
 		pfx: pfx,
@@ -43,6 +43,23 @@ func NewRoute(pfx net.Prefix, p *Path) *Route {
 	return r
 }
 
+// NewRouteAddPath generates a new route with paths p
+func NewRouteAddPath(pfx net.Prefix, p []*Path) *Route {
+	r := &Route{
+		pfx: pfx,
+	}
+
+	if p == nil {
+		r.paths = make([]*Path, 0)
+		return r
+	}
+
+	for _, path := range p {
+		r.paths = append(r.paths, path)
+	}
+	return r
+}
+
 // Copy returns a copy of route r
 func (r *Route) Copy() *Route {
 	if r == nil {
diff --git a/routingtable/adjRIBOut/BUILD.bazel b/routingtable/adjRIBOut/BUILD.bazel
index b7077150d43164d6ce1dcfee524452c0f1c47232..f4c213395b35ca5b183522605f0e130f54140be9 100644
--- a/routingtable/adjRIBOut/BUILD.bazel
+++ b/routingtable/adjRIBOut/BUILD.bazel
@@ -19,10 +19,17 @@ go_library(
 
 go_test(
     name = "go_default_test",
-    srcs = ["path_id_manager_test.go"],
+    srcs = [
+        "adj_rib_out_test.go",
+        "path_id_manager_test.go",
+    ],
     embed = [":go_default_library"],
     deps = [
+        "//net:go_default_library",
+        "//protocols/bgp/types:go_default_library",
         "//route:go_default_library",
+        "//routingtable:go_default_library",
+        "//routingtable/filter:go_default_library",
         "//vendor/github.com/stretchr/testify/assert:go_default_library",
     ],
 )
diff --git a/routingtable/adjRIBOut/adj_rib_out.go b/routingtable/adjRIBOut/adj_rib_out.go
index a2179fc02d3d9cff82bc67f95ba1e86fa2a293bd..2685ce37e45bd40fb91f891190a82e2054fee472 100644
--- a/routingtable/adjRIBOut/adj_rib_out.go
+++ b/routingtable/adjRIBOut/adj_rib_out.go
@@ -47,6 +47,9 @@ func (a *AdjRIBOut) RouteCount() int64 {
 // AddPath adds path p to prefix `pfx`
 func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
 	if !routingtable.ShouldPropagateUpdate(pfx, p, a.neighbor) {
+		if a.neighbor.CapAddPathRX {
+			a.removePathsForPrefix(pfx)
+		}
 		return nil
 	}
 
@@ -55,6 +58,7 @@ func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
 		return nil
 	}
 
+	// If the neighbor is an eBGP peer and not a Route Server client modify ASPath and Next Hop
 	p = p.Copy()
 	if !a.neighbor.IBGP && !a.neighbor.RouteServerClient {
 		p.BGPPath.Prepend(a.neighbor.LocalASN, 1)
@@ -130,6 +134,25 @@ func (a *AdjRIBOut) RemovePath(pfx bnet.Prefix, p *route.Path) bool {
 	return true
 }
 
+func (a *AdjRIBOut) removePathsForPrefix(pfx bnet.Prefix) bool {
+	// We were called before a.AddPath() had a lock, so we need to lock here and release it
+	// after the get to prevent a dead lock as RemovePath() will acquire a lock itself!
+	a.mu.Lock()
+	r := a.rt.Get(pfx)
+	a.mu.Unlock()
+
+	// If no path with this prefix is present, we're done
+	if r == nil {
+		return false
+	}
+
+	for _, path := range r.Paths() {
+		a.RemovePath(pfx, path)
+	}
+
+	return true
+}
+
 func (a *AdjRIBOut) isOwnPath(p *route.Path) bool {
 	if p.Type != a.neighbor.Type {
 		return false
diff --git a/routingtable/adjRIBOut/adj_rib_out_test.go b/routingtable/adjRIBOut/adj_rib_out_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..0d01dd0890f06f1c518101205755162b10081c3e
--- /dev/null
+++ b/routingtable/adjRIBOut/adj_rib_out_test.go
@@ -0,0 +1,1121 @@
+package adjRIBOut
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/bio-routing/bio-rd/net"
+	"github.com/bio-routing/bio-rd/protocols/bgp/types"
+	"github.com/bio-routing/bio-rd/routingtable/filter"
+
+	"github.com/bio-routing/bio-rd/route"
+	"github.com/bio-routing/bio-rd/routingtable"
+)
+
+func TestBestPathOnlyEBGP(t *testing.T) {
+	neighborBestOnlyEBGP := &routingtable.Neighbor{
+		Type:              route.BGPPathType,
+		LocalAddress:      net.IPv4FromOctets(127, 0, 0, 1),
+		Address:           net.IPv4FromOctets(127, 0, 0, 2),
+		IBGP:              false,
+		LocalASN:          41981,
+		RouteServerClient: false,
+		CapAddPathRX:      false,
+	}
+
+	adjRIBOut := New(neighborBestOnlyEBGP, filter.NewAcceptAllFilter())
+
+	tests := []struct {
+		name          string
+		routesAdd     []*route.Route
+		routesRemove  []*route.Route
+		expected      []*route.Route
+		expectedCount int64
+	}{
+		{
+			name: "Add a valid route",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type:    route.BGPPathType,
+					BGPPath: &route.BGPPath{},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Try to remove unpresent route",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               1,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Remove route added in first step",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Try to add route with NO_EXPORT community set",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						Communities: []uint32{
+							types.WellKnownCommunityNoExport,
+						},
+					},
+				}),
+			},
+			expected: []*route.Route{},
+		},
+		{
+			name: "Try to add route with NO_ADVERTISE community set",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						Communities: []uint32{
+							types.WellKnownCommunityNoAdvertise,
+						},
+					},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Re-add valid route again",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type:    route.BGPPathType,
+					BGPPath: &route.BGPPath{},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Try to remove route with NO_EXPORT community set",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen: 1,
+						Origin:    0,
+						MED:       0,
+						EBGP:      false,
+						Communities: []uint32{
+							types.WellKnownCommunityNoExport,
+						},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Try to remove non-existent prefix",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 23, 42, 0), 24), &route.Path{
+					Type:    route.BGPPathType,
+					BGPPath: &route.BGPPath{},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									neighborBestOnlyEBGP.LocalASN,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              false,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+	}
+
+	for i, test := range tests {
+		fmt.Printf("Running eBGP best only test #%d: %s\n", i+1, test.name)
+		for _, route := range test.routesAdd {
+			adjRIBOut.AddPath(route.Prefix(), route.Paths()[0])
+		}
+
+		for _, route := range test.routesRemove {
+			adjRIBOut.RemovePath(route.Prefix(), route.Paths()[0])
+		}
+
+		assert.Equal(t, test.expected, adjRIBOut.rt.Dump())
+
+		actualCount := adjRIBOut.RouteCount()
+		if test.expectedCount != actualCount {
+			t.Errorf("Expected route count %d differs from actual route count %d!\n", test.expectedCount, actualCount)
+		}
+	}
+}
+
+func TestBestPathOnlyIBGP(t *testing.T) {
+	neighborBestOnlyEBGP := &routingtable.Neighbor{
+		Type:              route.BGPPathType,
+		LocalAddress:      net.IPv4FromOctets(127, 0, 0, 1),
+		Address:           net.IPv4FromOctets(127, 0, 0, 2),
+		IBGP:              true,
+		LocalASN:          41981,
+		RouteServerClient: false,
+		CapAddPathRX:      false,
+	}
+
+	adjRIBOut := New(neighborBestOnlyEBGP, filter.NewAcceptAllFilter())
+
+	tests := []struct {
+		name          string
+		routesAdd     []*route.Route
+		routesRemove  []*route.Route
+		expected      []*route.Route
+		expectedCount int64
+	}{
+		{
+			name: "Add an iBGP route (without success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type:    route.BGPPathType,
+					BGPPath: &route.BGPPath{},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Add an eBGP route (with success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(1, 2, 3, 4),
+					},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Try to remove slightly different route",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               1,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Remove route added in 2nd step",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Try to add route with NO_EXPORT community set (without success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						Communities: []uint32{
+							types.WellKnownCommunityNoExport,
+						},
+					},
+				}),
+			},
+			expected: []*route.Route{},
+		},
+		{
+			name: "Try to add route with NO_EXPORT community set (without success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						Communities: []uint32{
+							types.WellKnownCommunityNoAdvertise,
+						},
+					},
+				}),
+			},
+			expected: []*route.Route{},
+		},
+	}
+
+	for i, test := range tests {
+		fmt.Printf("Running iBGP best only test #%d: %s\n", i+1, test.name)
+		for _, route := range test.routesAdd {
+			adjRIBOut.AddPath(route.Prefix(), route.Paths()[0])
+		}
+
+		for _, route := range test.routesRemove {
+			adjRIBOut.RemovePath(route.Prefix(), route.Paths()[0])
+		}
+
+		assert.Equal(t, test.expected, adjRIBOut.rt.Dump())
+
+		actualCount := adjRIBOut.RouteCount()
+		if test.expectedCount != actualCount {
+			t.Errorf("Expected route count %d differs from actual route count %d!\n", test.expectedCount, actualCount)
+		}
+	}
+}
+
+/*
+ * Test for AddPath capabale peer / AdjRIBOut
+ */
+
+func TestAddPathIBGP(t *testing.T) {
+	neighborBestOnlyEBGP := &routingtable.Neighbor{
+		Type:              route.BGPPathType,
+		LocalAddress:      net.IPv4FromOctets(127, 0, 0, 1),
+		Address:           net.IPv4FromOctets(127, 0, 0, 2),
+		IBGP:              true,
+		LocalASN:          41981,
+		RouteServerClient: false,
+		CapAddPathRX:      true,
+	}
+
+	adjRIBOut := New(neighborBestOnlyEBGP, filter.NewAcceptAllFilter())
+
+	tests := []struct {
+		name          string
+		routesAdd     []*route.Route
+		routesRemove  []*route.Route
+		expected      []*route.Route
+		expectedCount int64
+	}{
+		{
+			name: "Add an iBGP route (without success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type:    route.BGPPathType,
+					BGPPath: &route.BGPPath{},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Add an eBGP route (with success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(1, 2, 3, 4),
+					},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    1,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Try to remove slightly different route",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               1, // MED of route present in table is 0
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    1,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Remove route added in 2nd step",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0, // We calculate PathID in RIBOut so none is present when removing from RIBOut
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Try to add route with NO_EXPORT community set (without success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						Communities: []uint32{
+							types.WellKnownCommunityNoExport,
+						},
+					},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+		{
+			name: "Try to add route with NO_EXPORT community set (without success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						Communities: []uint32{
+							types.WellKnownCommunityNoAdvertise,
+						},
+					},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+
+		// Ok table is empty, re add previous route
+		{
+			name: "Readd an eBGP route (with success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(1, 2, 3, 4),
+					},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    2,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Add 2nd path to existing one with different NH (with success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(2, 3, 4, 5),
+					},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRouteAddPath(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), []*route.Path{
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen:         1,
+							Origin:            0,
+							MED:               0,
+							EBGP:              true,
+							Communities:       []uint32{},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    2,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					},
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(2, 3, 4, 5),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen:         1,
+							Origin:            0,
+							MED:               0,
+							EBGP:              true,
+							Communities:       []uint32{},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    3,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					}}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Remove 2nd path added above",
+			routesRemove: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(2, 3, 4, 5),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    0,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen:         1,
+						Origin:            0,
+						MED:               0,
+						EBGP:              true,
+						Communities:       []uint32{},
+						LargeCommunities:  []types.LargeCommunity{},
+						UnknownAttributes: nil,
+						PathIdentifier:    2,
+						LocalPref:         0,
+						Source:            net.IP{}},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Re-add 2nd path to existing one with different NH (with success)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(3, 4, 5, 6),
+					},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRouteAddPath(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), []*route.Path{
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen:         1,
+							Origin:            0,
+							MED:               0,
+							EBGP:              true,
+							Communities:       []uint32{},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    2,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					},
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(3, 4, 5, 6),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen:         1,
+							Origin:            0,
+							MED:               0,
+							EBGP:              true,
+							Communities:       []uint32{},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    4,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					}}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Add 3rd path to existing ones, containing NO_EXPORT community (successful)",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(4, 5, 6, 7),
+						Communities: []uint32{
+							types.WellKnownCommunityNoExport,
+						},
+					},
+				}),
+			},
+			expected: []*route.Route{
+				route.NewRouteAddPath(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), []*route.Path{
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(1, 2, 3, 4),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen:         1,
+							Origin:            0,
+							MED:               0,
+							EBGP:              true,
+							Communities:       []uint32{},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    2,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					},
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(3, 4, 5, 6),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen:         1,
+							Origin:            0,
+							MED:               0,
+							EBGP:              true,
+							Communities:       []uint32{},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    4,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					},
+					&route.Path{
+						Type: route.BGPPathType,
+						BGPPath: &route.BGPPath{
+							NextHop: net.IPv4FromOctets(4, 5, 6, 7),
+							ASPath: types.ASPath{
+								types.ASPathSegment{
+									Type: types.ASSequence,
+									ASNs: []uint32{
+										201701,
+									},
+								},
+							},
+							ASPathLen: 1,
+							Origin:    0,
+							MED:       0,
+							EBGP:      true,
+							Communities: []uint32{
+								types.WellKnownCommunityNoExport,
+							},
+							LargeCommunities:  []types.LargeCommunity{},
+							UnknownAttributes: nil,
+							PathIdentifier:    5,
+							LocalPref:         0,
+							Source:            net.IP{}},
+					},
+				}),
+			},
+			expectedCount: 1,
+		},
+		{
+			name: "Add 4th path to existing ones, containing NO_ADVERTISE community",
+			routesAdd: []*route.Route{
+				route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
+					Type: route.BGPPathType,
+					BGPPath: &route.BGPPath{
+						EBGP: true,
+						ASPath: types.ASPath{
+							types.ASPathSegment{
+								Type: types.ASSequence,
+								ASNs: []uint32{
+									201701,
+								},
+							},
+						},
+						ASPathLen: 1,
+						NextHop:   net.IPv4FromOctets(5, 6, 7, 8),
+						Communities: []uint32{
+							types.WellKnownCommunityNoAdvertise,
+						},
+					},
+				}),
+			},
+			expected:      []*route.Route{},
+			expectedCount: 0,
+		},
+	}
+
+	for i, test := range tests {
+		fmt.Printf("Running iBGP AddPath test #%d: %s\n", i+1, test.name)
+		for _, route := range test.routesAdd {
+			adjRIBOut.AddPath(route.Prefix(), route.Paths()[0])
+		}
+
+		for _, route := range test.routesRemove {
+			adjRIBOut.RemovePath(route.Prefix(), route.Paths()[0])
+		}
+
+		assert.Equal(t, test.expected, adjRIBOut.rt.Dump())
+
+		actualCount := adjRIBOut.RouteCount()
+		if test.expectedCount != actualCount {
+			t.Errorf("Expected route count %d differs from actual route count %d!\n", test.expectedCount, actualCount)
+		}
+	}
+}