diff --git a/examples/netlink/BUILD.bazel b/examples/netlink/BUILD.bazel
new file mode 100644
index 0000000000000000000000000000000000000000..c720d946780a555352121d2f6a21aa33999465b6
--- /dev/null
+++ b/examples/netlink/BUILD.bazel
@@ -0,0 +1,27 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "main.go",
+        "main_ipv4.go",
+    ],
+    importpath = "github.com/bio-routing/bio-rd/examples/netlink",
+    visibility = ["//visibility:private"],
+    deps = [
+        "//config:go_default_library",
+        "//net:go_default_library",
+        "//protocols/bgp/server:go_default_library",
+        "//protocols/netlink:go_default_library",
+        "//routingtable:go_default_library",
+        "//routingtable/filter:go_default_library",
+        "//routingtable/locRIB:go_default_library",
+        "//vendor/github.com/sirupsen/logrus:go_default_library",
+    ],
+)
+
+go_binary(
+    name = "netlink",
+    embed = [":go_default_library"],
+    visibility = ["//visibility:public"],
+)
diff --git a/examples/netlink/main.go b/examples/netlink/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..aa4e493acb4e37c1f2745f5593e39811870ecacc
--- /dev/null
+++ b/examples/netlink/main.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+	"net"
+	"os"
+	"time"
+
+	"github.com/bio-routing/bio-rd/config"
+	"github.com/bio-routing/bio-rd/protocols/bgp/server"
+	"github.com/bio-routing/bio-rd/protocols/netlink"
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+	log "github.com/sirupsen/logrus"
+
+	bnet "github.com/bio-routing/bio-rd/net"
+)
+
+func strAddr(s string) uint32 {
+	ret, _ := bnet.StrToAddr(s)
+	return ret
+}
+
+func main() {
+	log.SetLevel(log.DebugLevel)
+
+	f, err := os.OpenFile("/var/log/bio-rd.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+	if err != nil {
+		log.Fatalf("error opening file: %v", err)
+	}
+	defer f.Close()
+
+	log.SetOutput(f)
+
+	log.Info("bio-routing started...\n")
+
+	cfg := &config.Global{
+		Listen: true,
+		LocalAddressList: []net.IP{
+			net.IPv4(169, 254, 0, 2),
+		},
+	}
+
+	rib := locRIB.New()
+	b := server.NewBgpServer()
+	startBGPServer(b, rib, cfg)
+
+	// Netlink communication
+	n := protocolnetlink.NewNetlink(&config.Netlink{
+		HoldTime:       time.Second * 15,
+		UpdateInterval: time.Second * 15,
+		RoutingTable:   config.RtMain,
+	}, rib)
+	n.Start()
+
+	go func() {
+		for {
+			log.Debugf("LocRIB count: %d", rib.Count())
+			log.Debugf(rib.String())
+			time.Sleep(time.Second * 10)
+		}
+	}()
+
+	select {}
+}
diff --git a/examples/netlink/main_ipv4.go b/examples/netlink/main_ipv4.go
new file mode 100644
index 0000000000000000000000000000000000000000..12bb67ae2305208035c00d46ed634c72a2dee454
--- /dev/null
+++ b/examples/netlink/main_ipv4.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+	"time"
+
+	"github.com/bio-routing/bio-rd/routingtable"
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+
+	"github.com/bio-routing/bio-rd/config"
+	"github.com/bio-routing/bio-rd/protocols/bgp/server"
+	"github.com/bio-routing/bio-rd/routingtable/filter"
+	log "github.com/sirupsen/logrus"
+
+	bnet "github.com/bio-routing/bio-rd/net"
+)
+
+func startBGPServer(b server.BGPServer, rib *locRIB.LocRIB, cfg *config.Global) {
+	err := b.Start(cfg)
+	if err != nil {
+		log.Fatalf("Unable to start BGP server: %v", err)
+	}
+
+	b.AddPeer(config.Peer{
+		AdminEnabled:      true,
+		LocalAS:           65200,
+		PeerAS:            65100,
+		PeerAddress:       bnet.IPv4FromOctets(169, 254, 0, 1),
+		LocalAddress:      bnet.IPv4FromOctets(169, 254, 0, 2),
+		ReconnectInterval: time.Second * 20,
+		HoldTime:          time.Second * 20,
+		KeepAlive:         time.Second * 20,
+		Passive:           false,
+		RouterID:          b.RouterID(),
+
+		//AddPathSend: routingtable.ClientOptions{
+		//	MaxPaths: 10,
+		//},
+		//RouteServerClient: true,
+		IPv4: &config.AddressFamilyConfig{
+			RIB:          rib,
+			ImportFilter: filter.NewAcceptAllFilter(),
+			ExportFilter: filter.NewAcceptAllFilter(),
+			AddPathSend: routingtable.ClientOptions{
+				MaxPaths: 10,
+			},
+			AddPathRecv: true,
+		},
+	})
+}
diff --git a/examples/netlink/main_ipv6.go b/examples/netlink/main_ipv6.go
new file mode 100644
index 0000000000000000000000000000000000000000..cc26484b2e7f855eca6eeb75c6d51df436167f47
--- /dev/null
+++ b/examples/netlink/main_ipv6.go
@@ -0,0 +1,72 @@
+// +build ipv6
+
+package main
+
+import (
+	"net"
+	"time"
+
+	"github.com/bio-routing/bio-rd/config"
+	"github.com/bio-routing/bio-rd/protocols/bgp/server"
+	"github.com/bio-routing/bio-rd/routingtable"
+	"github.com/bio-routing/bio-rd/routingtable/filter"
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+	"github.com/sirupsen/logrus"
+
+	bnet "github.com/bio-routing/bio-rd/net"
+)
+
+func startServer(b server.BGPServer, rib *locRIB.LocRIB) {
+
+	err := b.Start(&config.Global{
+		Listen: true,
+		LocalAddressList: []net.IP{
+			net.IP{0x20, 0x01, 0x6, 0x78, 0x1, 0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0xca, 0xfe},
+		},
+	})
+	if err != nil {
+		logrus.Fatalf("Unable to start BGP server: %v", err)
+	}
+
+	b.AddPeer(config.Peer{
+		AdminEnabled:      true,
+		LocalAS:           65200,
+		PeerAS:            202739,
+		PeerAddress:       bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 1),
+		LocalAddress:      bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 0xcafe),
+		ReconnectInterval: time.Second * 15,
+		HoldTime:          time.Second * 90,
+		KeepAlive:         time.Second * 30,
+		Passive:           true,
+		RouterID:          b.RouterID(),
+		IPv6: &config.AddressFamilyConfig{
+			RIB:          rib,
+			ImportFilter: filter.NewAcceptAllFilter(),
+			ExportFilter: filter.NewDrainFilter(),
+			AddPathSend: routingtable.ClientOptions{
+				BestOnly: true,
+			},
+		},
+	})
+
+	b.AddPeer(config.Peer{
+		AdminEnabled:      true,
+		LocalAS:           65200,
+		PeerAS:            65400,
+		PeerAddress:       bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0xcafe, 0, 0, 0, 5),
+		LocalAddress:      bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 0xcafe),
+		ReconnectInterval: time.Second * 15,
+		HoldTime:          time.Second * 90,
+		KeepAlive:         time.Second * 30,
+		Passive:           true,
+		RouterID:          b.RouterID(),
+		IPv6: &config.AddressFamilyConfig{
+			RIB:          rib,
+			ImportFilter: filter.NewDrainFilter(),
+			ExportFilter: filter.NewAcceptAllFilter(),
+			AddPathSend: routingtable.ClientOptions{
+				BestOnly: true,
+			},
+		},
+	})
+}
diff --git a/route/BUILD.bazel b/route/BUILD.bazel
index c249b10f33d990279a7fa5cdbc2578cbdd8c639b..cefdafaefdc1e939221f8106e8318076208e5303 100644
--- a/route/BUILD.bazel
+++ b/route/BUILD.bazel
@@ -15,7 +15,6 @@ go_library(
     deps = [
         "//net:go_default_library",
         "//protocols/bgp/types:go_default_library",
-        "//vendor/github.com/sirupsen/logrus:go_default_library",
         "//vendor/github.com/taktv6/tflow2/convert:go_default_library",
         "//vendor/github.com/vishvananda/netlink:go_default_library",
     ],
diff --git a/route/netlink_path.go b/route/netlink_path.go
index c9d19b19fcfdb9621755536462c5b4a96a4e9674..cb374fe8c7672d417641b07c22187620feabea58 100644
--- a/route/netlink_path.go
+++ b/route/netlink_path.go
@@ -52,18 +52,18 @@ func NewPathsFromNlRoute(r netlink.Route, kernel bool) (bnet.Prefix, []*Path, er
 	if r.Src == nil && r.Dst != nil {
 		dst = bnet.NewPfxFromIPNet(r.Dst)
 		if dst.Addr().IsIPv4() {
-			src = bnet.IPv4FromOctets(0, 0, 0, 0)
+			src = bnet.IPv4(0)
 		} else {
-			src = bnet.IPv6FromBlocks(0, 0, 0, 0, 0, 0, 0, 0)
+			src = bnet.IPv6(0, 0)
 		}
 	}
 
 	if r.Src != nil && r.Dst == nil {
 		src, _ = bnet.IPFromBytes(r.Src)
 		if src.IsIPv4() {
-			dst = bnet.NewPfx(bnet.IPv4FromOctets(0, 0, 0, 0), 0)
+			dst = bnet.NewPfx(bnet.IPv4(0), 0)
 		} else {
-			dst = bnet.NewPfx(bnet.IPv6FromBlocks(0, 0, 0, 0, 0, 0, 0, 0), 0)
+			dst = bnet.NewPfx(bnet.IPv6(0, 0), 0)
 		}
 	}
 
@@ -111,19 +111,19 @@ func NewPathsFromNlRoute(r netlink.Route, kernel bool) (bnet.Prefix, []*Path, er
 
 // Select compares s with t and returns negative if s < t, 0 if paths are equal, positive if s > t
 func (s *NetlinkPath) Select(t *NetlinkPath) int8 {
-	if s.NextHop.Compare(t.NextHop) > 0 {
+	if s.NextHop.Compare(t.NextHop) < 0 {
 		return -1
 	}
 
-	if s.NextHop.Compare(t.NextHop) < 0 {
+	if s.NextHop.Compare(t.NextHop) > 0 {
 		return 1
 	}
 
-	if s.Src.Compare(t.Src) > 0 {
+	if s.Src.Compare(t.Src) < 0 {
 		return -1
 	}
 
-	if s.Src.Compare(t.Src) < 0 {
+	if s.Src.Compare(t.Src) > 0 {
 		return 1
 	}
 
@@ -156,28 +156,7 @@ func (s *NetlinkPath) Select(t *NetlinkPath) int8 {
 
 // ECMP determines if path s and t are equal in terms of ECMP
 func (s *NetlinkPath) ECMP(t *NetlinkPath) bool {
-
-	if s.Src != t.Src {
-		return false
-	}
-
-	if s.Priority != t.Priority {
-		return false
-	}
-
-	if s.Protocol != t.Protocol {
-		return false
-	}
-
-	if s.Type != t.Type {
-		return false
-	}
-
-	if s.Table != t.Table {
-		return false
-	}
-
-	return true
+	return s.Src == t.Src && s.Priority == t.Priority && s.Protocol == t.Protocol && s.Type == t.Type && s.Table == t.Table
 }
 
 // Copy duplicates the current object
diff --git a/route/path_test.go b/route/path_test.go
index c76cc96171591ae8af6077aac2052c97e0f52b96..84b3cde044750bcc75eb44ac89ff894c619d5cf3 100644
--- a/route/path_test.go
+++ b/route/path_test.go
@@ -451,90 +451,140 @@ func TestNewPathsFromNetlinkRoute(t *testing.T) {
 			},
 			expectError: false,
 		},
-		//	{
-		//		name: "No source but destination",
-		//		source: &netlink.Route{
-		//			Dst:      bnet.NewPfx(bnet.IPv4FromOctets(10, 0, 0, 0), 8).GetIPNet(),
-		//			Gw:       bnet.IPv4(789).Bytes(),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//		},
-		//		expected: &NetlinkPath{
-		//			Src:      bnet.IPv4FromOctets(0, 0, 0, 0),
-		//			NextHop:  bnet.IPv4(789),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//			Kernel:   true,
-		//		},
-		//		expectError: false,
-		//	},
-		//	{
-		//		name: "Source but no destination",
-		//		source: &netlink.Route{
-		//			Src:      bnet.IPv4(456).Bytes(),
-		//			Gw:       bnet.IPv4(789).Bytes(),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//		},
-		//		expected: &NetlinkPath{
-		//			Src:      bnet.IPv4(456),
-		//			NextHop:  bnet.IPv4(789),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//			Kernel:   true,
-		//		},
-		//		expectError: false,
-		//	},
-		//	{
-		//		name: "No source but destination IPv6",
-		//		source: &netlink.Route{
-		//			Dst:      bnet.NewPfx(bnet.IPv6(2001, 0), 48).GetIPNet(),
-		//			Gw:       bnet.IPv6(2001, 2).Bytes(),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//		},
-		//		expected: &NetlinkPath{
-		//			Src:      bnet.IPv6FromBlocks(0, 0, 0, 0, 0, 0, 0, 0),
-		//			NextHop:  bnet.IPv6(2001, 2),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//			Kernel:   true,
-		//		},
-		//		expectError: false,
-		//	},
-		//	{
-		//		name: "Source but no destination IPv6",
-		//		source: &netlink.Route{
-		//			Src:      bnet.IPv6(2001, 0).Bytes(),
-		//			Gw:       bnet.IPv6(2001, 2).Bytes(),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//		},
-		//		expected: &NetlinkPath{
-		//			Src:      bnet.IPv6(2001, 0),
-		//			NextHop:  bnet.IPv6(2001, 2),
-		//			Protocol: ProtoKernel,
-		//			Priority: 1,
-		//			Table:    254,
-		//			Type:     1,
-		//			Kernel:   true,
-		//		},
-		//		expectError: false,
-		//	},
+		{
+			name: "No source but destination",
+			source: netlink.Route{
+				Dst:      bnet.NewPfx(bnet.IPv4FromOctets(10, 0, 0, 0), 8).GetIPNet(),
+				Gw:       bnet.IPv4(789).Bytes(),
+				Protocol: ProtoKernel,
+				Priority: 1,
+				Table:    254,
+				Type:     1,
+			},
+			expectedPfx: bnet.NewPfx(bnet.IPv4FromOctets(10, 0, 0, 0), 8),
+			expectedPaths: []*Path{
+				{
+					Type: NetlinkPathType,
+					NetlinkPath: &NetlinkPath{
+						Src:      bnet.IPv4(0),
+						NextHop:  bnet.IPv4(789),
+						Protocol: ProtoKernel,
+						Priority: 1,
+						Table:    254,
+						Type:     1,
+						Kernel:   true,
+					},
+				},
+			},
+			expectError: false,
+		},
+		{
+			name: "Source but no destination",
+			source: netlink.Route{
+				Src:      bnet.IPv4(456).Bytes(),
+				Gw:       bnet.IPv4(789).Bytes(),
+				Protocol: ProtoKernel,
+				Priority: 1,
+				Table:    254,
+				Type:     1,
+			},
+			expectedPfx: bnet.NewPfx(bnet.IPv4FromOctets(0, 0, 0, 0), 0),
+			expectedPaths: []*Path{
+				{
+					Type: NetlinkPathType,
+					NetlinkPath: &NetlinkPath{
+						Src:      bnet.IPv4(456),
+						NextHop:  bnet.IPv4(789),
+						Protocol: ProtoKernel,
+						Priority: 1,
+						Table:    254,
+						Type:     1,
+						Kernel:   true,
+					},
+				},
+			},
+			expectError: false,
+		},
+		{
+			name: "No source but no destination",
+			source: netlink.Route{
+				Gw:       bnet.IPv4(789).Bytes(),
+				Protocol: ProtoKernel,
+				Priority: 1,
+				Table:    254,
+				Type:     1,
+			},
+			expectedPfx:   bnet.Prefix{},
+			expectedPaths: []*Path{},
+			expectError:   true,
+		},
+		{
+			name: "No source but destination IPv6",
+			source: netlink.Route{
+				Dst:      bnet.NewPfx(bnet.IPv6(2001, 0), 48).GetIPNet(),
+				Gw:       bnet.IPv6(2001, 123).Bytes(),
+				Protocol: ProtoKernel,
+				Priority: 1,
+				Table:    254,
+				Type:     1,
+			},
+			expectedPfx: bnet.NewPfx(bnet.IPv6(2001, 0), 48),
+			expectedPaths: []*Path{
+				{
+					Type: NetlinkPathType,
+					NetlinkPath: &NetlinkPath{
+						Src:      bnet.IPv6(0, 0),
+						NextHop:  bnet.IPv6(2001, 123),
+						Protocol: ProtoKernel,
+						Priority: 1,
+						Table:    254,
+						Type:     1,
+						Kernel:   true,
+					},
+				},
+			},
+			expectError: false,
+		},
+		{
+			name: "Source but no destination IPv6",
+			source: netlink.Route{
+				Src:      bnet.IPv6(2001, 456).Bytes(),
+				Gw:       bnet.IPv6(2001, 789).Bytes(),
+				Protocol: ProtoKernel,
+				Priority: 1,
+				Table:    254,
+				Type:     1,
+			},
+			expectedPfx: bnet.NewPfx(bnet.IPv6(0, 0), 0),
+			expectedPaths: []*Path{
+				{
+					Type: NetlinkPathType,
+					NetlinkPath: &NetlinkPath{
+						Src:      bnet.IPv6(2001, 456),
+						NextHop:  bnet.IPv6(2001, 789),
+						Protocol: ProtoKernel,
+						Priority: 1,
+						Table:    254,
+						Type:     1,
+						Kernel:   true,
+					},
+				},
+			},
+			expectError: false,
+		},
+		{
+			name: "no source no destination",
+			source: netlink.Route{
+				Gw:       bnet.IPv4(123).Bytes(),
+				Protocol: ProtoKernel,
+				Priority: 1,
+				Table:    254,
+				Type:     1,
+			},
+			expectedPfx:   bnet.NewPfx(bnet.IPv4(0), 0),
+			expectedPaths: []*Path{{}},
+			expectError:   true,
+		},
 	}
 
 	for _, test := range tests {
@@ -548,3 +598,272 @@ func TestNewPathsFromNetlinkRoute(t *testing.T) {
 		}
 	}
 }
+
+func TestECMP(t *testing.T) {
+	tests := []struct {
+		name  string
+		left  *Path
+		right *Path
+		ecmp  bool
+	}{
+		{
+			name: "BGP Path ecmp",
+			left: &Path{
+				Type: BGPPathType,
+				BGPPath: &BGPPath{
+					LocalPref: 100,
+					ASPathLen: 10,
+					MED:       1,
+					Origin:    123,
+				},
+			},
+			right: &Path{
+				Type: BGPPathType,
+				BGPPath: &BGPPath{
+					LocalPref: 100,
+					ASPathLen: 10,
+					MED:       1,
+					Origin:    123,
+				},
+			},
+			ecmp: true,
+		}, {
+			name: "BGP Path not ecmp",
+			left: &Path{
+				Type: BGPPathType,
+				BGPPath: &BGPPath{
+					LocalPref: 100,
+					ASPathLen: 10,
+					MED:       1,
+					Origin:    123,
+				},
+			},
+			right: &Path{
+				Type: BGPPathType,
+				BGPPath: &BGPPath{
+					LocalPref: 100,
+					ASPathLen: 5,
+					MED:       1,
+					Origin:    123,
+				},
+			},
+			ecmp: false,
+		}, {
+			name: "Netlink Path ecmp",
+			left: &Path{
+				Type: NetlinkPathType,
+				NetlinkPath: &NetlinkPath{
+					Src:      bnet.IPv4(123),
+					Priority: 1,
+					Protocol: 1,
+					Type:     1,
+					Table:    1,
+				},
+			},
+			right: &Path{
+				Type: NetlinkPathType,
+				NetlinkPath: &NetlinkPath{
+					Src:      bnet.IPv4(123),
+					Priority: 1,
+					Protocol: 1,
+					Type:     1,
+					Table:    1,
+				},
+			},
+			ecmp: true,
+		}, {
+			name: "Netlink Path not ecmp",
+			left: &Path{
+				Type: NetlinkPathType,
+				NetlinkPath: &NetlinkPath{
+					Src:      bnet.IPv4(123),
+					Priority: 1,
+					Protocol: 1,
+					Type:     1,
+					Table:    1,
+				},
+			},
+			right: &Path{
+				Type: NetlinkPathType,
+				NetlinkPath: &NetlinkPath{
+					Src:      bnet.IPv4(123),
+					Priority: 2,
+					Protocol: 1,
+					Type:     1,
+					Table:    1,
+				},
+			},
+			ecmp: false,
+		}, {
+			name: "static Path ecmp",
+			left: &Path{
+				Type: StaticPathType,
+				StaticPath: &StaticPath{
+					NextHop: bnet.IPv4(123),
+				},
+			},
+			right: &Path{
+				Type: StaticPathType,
+				StaticPath: &StaticPath{
+					NextHop: bnet.IPv4(123),
+				},
+			},
+			ecmp: true,
+		}, {
+			name: "static Path not ecmp",
+			left: &Path{
+				Type: StaticPathType,
+				StaticPath: &StaticPath{
+					NextHop: bnet.IPv4(123),
+				},
+			},
+			right: &Path{
+				Type: StaticPathType,
+				StaticPath: &StaticPath{
+					NextHop: bnet.IPv4(345),
+				},
+			},
+			// ECMP is always true for staticPath
+			ecmp: true,
+		},
+	}
+
+	for _, test := range tests {
+		ecmp := test.left.ECMP(test.right)
+		assert.Equal(t, test.ecmp, ecmp, test.name)
+	}
+}
+
+func TestNetlinkPathSelect(t *testing.T) {
+	tests := []struct {
+		name     string
+		left     *NetlinkPath
+		right    *NetlinkPath
+		expected int8
+	}{
+		{
+			name: "equal",
+			left: &NetlinkPath{
+				NextHop:  bnet.IPv4(123),
+				Src:      bnet.IPv4(234),
+				Priority: 1,
+				Protocol: 1,
+				Table:    1,
+			},
+			right: &NetlinkPath{
+				NextHop:  bnet.IPv4(123),
+				Src:      bnet.IPv4(234),
+				Priority: 1,
+				Protocol: 1,
+				Table:    1,
+			},
+			expected: 0,
+		},
+		{
+			name: "nextHop smaller",
+			left: &NetlinkPath{
+				NextHop: bnet.IPv4(1),
+			},
+			right: &NetlinkPath{
+				NextHop: bnet.IPv4(2),
+			},
+			expected: -1,
+		},
+		{
+			name: "nextHop bigger",
+			left: &NetlinkPath{
+				NextHop: bnet.IPv4(2),
+			},
+			right: &NetlinkPath{
+				NextHop: bnet.IPv4(1),
+			},
+			expected: 1,
+		},
+		{
+			name: "src smaller",
+			left: &NetlinkPath{
+				Src: bnet.IPv4(1),
+			},
+			right: &NetlinkPath{
+				Src: bnet.IPv4(2),
+			},
+			expected: -1,
+		},
+		{
+			name: "src bigger",
+			left: &NetlinkPath{
+				Src: bnet.IPv4(2),
+			},
+			right: &NetlinkPath{
+				Src: bnet.IPv4(1),
+			},
+			expected: 1,
+		},
+		{
+			name: "priority smaller",
+			left: &NetlinkPath{
+				Priority: 1,
+			},
+			right: &NetlinkPath{
+				Priority: 2,
+			},
+			expected: -1,
+		},
+		{
+			name: "priority bigger",
+			left: &NetlinkPath{
+				Priority: 2,
+			},
+			right: &NetlinkPath{
+				Priority: 1,
+			},
+			expected: 1,
+		},
+		{
+			name: "protocol smaller",
+			left: &NetlinkPath{
+				Protocol: 1,
+			},
+			right: &NetlinkPath{
+				Protocol: 2,
+			},
+			expected: -1,
+		},
+		{
+			name: "protocol bigger",
+			left: &NetlinkPath{
+				Protocol: 2,
+			},
+			right: &NetlinkPath{
+				Protocol: 1,
+			},
+			expected: 1,
+		},
+		{
+			name: "table smaller",
+			left: &NetlinkPath{
+				Table: 1,
+			},
+			right: &NetlinkPath{
+				Table: 2,
+			},
+			expected: -1,
+		},
+		{
+			name: "table bigger",
+			left: &NetlinkPath{
+				Table: 2,
+			},
+			right: &NetlinkPath{
+				Table: 1,
+			},
+			expected: 1,
+		},
+	}
+
+	for _, test := range tests {
+		result := test.left.Select(test.right)
+		assert.Equal(t, test.expected, result, test.name)
+	}
+
+}
diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go
index aa60b9243aab1846bdb6dd010f9ced6155071268..6d1f7a48d62295743280a861eb19cdcfc902e67b 100644
--- a/routingtable/locRIB/loc_rib.go
+++ b/routingtable/locRIB/loc_rib.go
@@ -175,6 +175,23 @@ func (a *LocRIB) ContainsPfxPath(pfx net.Prefix, p *route.Path) bool {
 	return false
 }
 
+func (a *LocRIB) String() string {
+	a.mu.RLock()
+	defer a.mu.RUnlock()
+
+	ret := ""
+	routes := a.rt.Dump()
+	for idx, r := range routes {
+		if idx < len(routes)-1 {
+			ret += fmt.Sprintf("%s, ", r.Prefix().String())
+		} else {
+			ret += fmt.Sprintf("%s", r.Prefix().String())
+		}
+	}
+
+	return ret
+}
+
 func (a *LocRIB) Print() string {
 	a.mu.RLock()
 	defer a.mu.RUnlock()