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_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)
+		}
+	}
+}