diff --git a/routingtable/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/routingtable/adjRIBIn/adj_rib_in.go
deleted file mode 100644
index 2657f22334fac285fcf952d2bc996ce0a69a1094..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/adjRIBIn/adj_rib_in.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package adjRIBIn
-
-import (
-	"github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/routingtable"
-)
-
-// AdjRIBIn implements an Adjacency RIB In (for use with BGP)
-type AdjRIBIn struct {
-	rt *routingtable.RoutingTable
-}
-
-// New creates a new Adjacency RIB In
-func New() *AdjRIBIn {
-	return &AdjRIBIn{
-		rt: routingtable.New(),
-	}
-}
-
-// AddPath adds a route to the AdjRIBIn. If prefix exists already it is replaced.
-func (a *AdjRIBIn) AddPath(pfx *net.Prefix, p *routingtable.Path) {
-
-}
-
-// RemovePath removes prefix pfx from the AdjRIBIn
-func (a *AdjRIBIn) RemovePath(pfx *net.Prefix, p *routingtable.Path) {
-
-}
diff --git a/routingtable/routingtable/client_interface.go b/routingtable/routingtable/client_interface.go
deleted file mode 100644
index 648bf40ae29738a7c9f85bf068183d2317d66120..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/client_interface.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package routingtable
-
-import (
-	"github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/route"
-)
-
-// RouteTableClient is the interface that every type of RIB must implement
-type RouteTableClient interface {
-	AddPath(*net.Prefix, *route.Path) error
-	RemovePath(*net.Prefix, *route.Path) error
-}
diff --git a/routingtable/routingtable/client_manager.go b/routingtable/routingtable/client_manager.go
deleted file mode 100644
index 08e2587aa0d9f50bcf59054765754cfe84166af0..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/client_manager.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package routingtable
-
-type ClientManager struct {
-	clients      map[RouteTableClient]struct{} // Ensures a client registers at most once
-	routingTable *RoutingTable
-}
-
-func (c *ClientManager) Register(client RouteTableClient) {
-	if c.clients == nil {
-		c.clients = make(map[RouteTableClient]struct{}, 0)
-	}
-	c.clients[client] = struct{}{}
-	//c.routingTable.updateNewClient(client)
-}
-
-func (c *ClientManager) Unregister(client RouteTableClient) {
-	if _, ok := c.clients[client]; !ok {
-		return
-	}
-	delete(c.clients, client)
-}
diff --git a/routingtable/routingtable/rib_interface.go b/routingtable/routingtable/rib_interface.go
deleted file mode 100644
index 45afeb2605a13a3ca65bfb885950d0a3b2fc8692..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/rib_interface.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package routingtable
-
-import (
-	"github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/route"
-)
-
-type RIB interface {
-	AddPath(*net.Prefix, *route.Path)
-	RemovePath(*net.Prefix, *route.Path)
-}
diff --git a/routingtable/routingtable/table.go b/routingtable/routingtable/table.go
deleted file mode 100644
index 6b8bcb6b39200b0710aa3de0899ce12c248ed846..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/table.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package routingtable
-
-import (
-	"sync"
-
-	"github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/route"
-)
-
-// RoutingTable is a binary trie that stores prefixes and their paths
-type RoutingTable struct {
-	root *node
-	mu   sync.RWMutex
-}
-
-// NewRoutingTable creates a new routing table
-func NewRoutingTable() *RoutingTable {
-	return &RoutingTable{}
-}
-
-// AddPath adds a path to the routing table
-func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
-	rt.mu.Lock()
-	defer rt.mu.Unlock()
-
-	if rt.root == nil {
-		rt.root = newNode(pfx, p, pfx.Pfxlen(), false)
-		return nil
-	}
-
-	rt.root = rt.root.addPath(pfx, p)
-	return nil
-}
-
-// RemovePath removes a path from the trie
-func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) error {
-	rt.mu.Lock()
-	defer rt.mu.Unlock()
-
-	rt.root.removePath(pfx, p)
-	return nil
-}
-
-// LPM performs a longest prefix match for pfx on lpm
-func (rt *RoutingTable) LPM(pfx net.Prefix) (res []*route.Route) {
-	rt.mu.RLock()
-	defer rt.mu.RUnlock()
-
-	if rt.root == nil {
-		return nil
-	}
-
-	rt.root.lpm(pfx, &res)
-	return res
-}
-
-// Get get's the route for pfx from the LPM
-func (rt *RoutingTable) Get(pfx net.Prefix) *route.Route {
-	rt.mu.RLock()
-	defer rt.mu.RUnlock()
-
-	if rt.root == nil {
-		return nil
-	}
-
-	res := rt.root.get(pfx)
-	if res == nil {
-		return nil
-	}
-	return res.route
-}
-
-// GetLonger get's prefix pfx and all it's more specifics from the LPM
-func (rt *RoutingTable) GetLonger(pfx net.Prefix) (res []*route.Route) {
-	rt.mu.RLock()
-	defer rt.mu.RUnlock()
-
-	if rt.root == nil {
-		return []*route.Route{}
-	}
-
-	return rt.root.get(pfx).dumpPfxs(res)
-}
-
-// Dump dumps all routes in table rt into a slice
-func (rt *RoutingTable) Dump() []*route.Route {
-	rt.mu.RLock()
-	defer rt.mu.RUnlock()
-
-	res := make([]*route.Route, 0)
-	return rt.root.dump(res)
-}
diff --git a/routingtable/routingtable/table_test.go b/routingtable/routingtable/table_test.go
deleted file mode 100644
index a2eb10f76f93046fe71e98e59998ff52e15283b5..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/table_test.go
+++ /dev/null
@@ -1,451 +0,0 @@
-package routingtable
-
-import (
-	"testing"
-
-	"github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/route"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestAddPath(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*route.Route
-		expected *node
-	}{
-		{
-			name: "Insert first node",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-			},
-			expected: &node{
-				route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				skip:  8,
-			},
-		},
-		{
-			name: "Insert duplicate node",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-			},
-			expected: &node{
-				route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				skip:  8,
-			},
-		},
-		{
-			name: "Insert triangle",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), nil),
-			},
-			expected: &node{
-				route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				skip:  8,
-				l: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), nil),
-				},
-				h: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), nil),
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-			},
-			expected: &node{
-				route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 7), nil),
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				},
-				h: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-					skip:  16,
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes plus one child low",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			expected: &node{
-				route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 7), nil),
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-					l: &node{
-						skip:  1,
-						route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-						l: &node{
-							skip:  1,
-							route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-						},
-					},
-				},
-				h: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-					skip:  16,
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes plus one child high",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.128"), 25), nil),
-			},
-			expected: &node{
-				route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 7), nil),
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-					l: &node{
-						skip:  1,
-						route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-						l: &node{
-							skip:  1,
-							route: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-						},
-					},
-				},
-				h: &node{
-					route: route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-					skip:  16,
-					h: &node{
-						route: route.NewRoute(net.NewPfx(strAddr("11.100.123.128"), 25), nil),
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		rt := NewRoutingTable()
-		for _, route := range test.routes {
-			rt.AddPath(route.Prefix(), nil)
-		}
-
-		assert.Equal(t, test.expected, rt.root)
-	}
-}
-
-func TestGet(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*route.Route
-		needle   net.Prefix
-		expected *route.Route
-	}{
-		{
-			name: "Test 1: Search pfx and dump route + more specifics",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 8),
-			expected: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-		},
-		{
-			name: "Test 2: Search pfx and don't dump more specifics",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 8),
-			expected: route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-		},
-		{
-			name:     "Test 3: Empty table",
-			routes:   []*route.Route{},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 32),
-			expected: nil,
-		},
-		{
-			name: "Test 4: Get Dummy",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 7),
-			expected: nil,
-		},
-		{
-			name: "Test 5",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle:   net.NewPfx(strAddr("11.100.123.0"), 24),
-			expected: route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-		},
-		{
-			name: "Test 4: Get nonexistent #1",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 10),
-			expected: nil,
-		},
-		{
-			name: "Test 4: Get nonexistent #2",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 10),
-			expected: nil,
-		},
-	}
-
-	for _, test := range tests {
-		rt := NewRoutingTable()
-		for _, route := range test.routes {
-			rt.AddPath(route.Prefix(), nil)
-		}
-		p := rt.Get(test.needle)
-
-		if p == nil {
-			if test.expected != nil {
-				t.Errorf("Unexpected nil result for test %q", test.name)
-			}
-			continue
-		}
-
-		assert.Equal(t, test.expected, p)
-	}
-}
-func TestGetLonger(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*route.Route
-		needle   net.Prefix
-		expected []*route.Route
-	}{
-		{
-			name: "Test 1: Search pfx and dump route + more specifics",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(strAddr("10.0.0.0"), 8),
-			expected: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-			},
-		},
-	}
-
-	for _, test := range tests {
-		rt := NewRoutingTable()
-		for _, route := range test.routes {
-			rt.AddPath(route.Prefix(), nil)
-		}
-		p := rt.GetLonger(test.needle)
-
-		if p == nil {
-			if test.expected != nil {
-				t.Errorf("Unexpected nil result for test %q", test.name)
-			}
-			continue
-		}
-
-		assert.Equal(t, test.expected, p)
-	}
-}
-func TestLPM(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*route.Route
-		needle   net.Prefix
-		expected []*route.Route
-	}{
-		{
-			name:     "LPM for non-existent route",
-			routes:   []*route.Route{},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 32),
-			expected: nil,
-		},
-		{
-			name: "Positive LPM test",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(167772160, 32), // 10.0.0.0/32
-			expected: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-			},
-		},
-		{
-			name: "Exact match",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(strAddr("10.0.0.0"), 10),
-			expected: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-		},
-	}
-
-	for _, test := range tests {
-		rt := NewRoutingTable()
-		for _, route := range test.routes {
-			rt.AddPath(route.Prefix(), nil)
-		}
-		assert.Equal(t, test.expected, rt.LPM(test.needle))
-	}
-}
-
-func TestRemovePath(t *testing.T) {
-	tests := []struct {
-		name       string
-		routes     []*route.Route
-		removePfx  net.Prefix
-		removePath *route.Path
-		expected   []*route.Route
-	}{
-		{
-			name: "Remove a path that is the only one for a prefix",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-			},
-			removePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
-			removePath: &route.Path{
-				Type:    route.BGPPathType,
-				BGPPath: &route.BGPPath{},
-			},
-			expected: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-			},
-		},
-		{
-			name: "Remove a path that is one of two for a prefix",
-			routes: []*route.Route{
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
-					Type: route.BGPPathType,
-					BGPPath: &route.BGPPath{
-						LocalPref: 1000,
-					},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
-					Type: route.BGPPathType,
-					BGPPath: &route.BGPPath{
-						LocalPref: 2000,
-					},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-			},
-			removePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
-			removePath: &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: 2000,
-					},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-				route.NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), &route.Path{
-					Type:    route.BGPPathType,
-					BGPPath: &route.BGPPath{},
-				}),
-			},
-		},
-	}
-
-	for _, test := range tests {
-		rt := NewRoutingTable()
-		for _, route := range test.routes {
-			for _, p := range route.Paths() {
-				rt.AddPath(route.Prefix(), p)
-			}
-		}
-
-		rt.RemovePath(test.removePfx, test.removePath)
-
-		rtExpected := NewRoutingTable()
-		for _, route := range test.expected {
-			for _, p := range route.Paths() {
-				rtExpected.AddPath(route.Prefix(), p)
-			}
-		}
-
-		assert.Equal(t, rtExpected.Dump(), rt.Dump())
-	}
-}
-
-func strAddr(s string) uint32 {
-	ret, _ := net.StrToAddr(s)
-	return ret
-}
diff --git a/routingtable/routingtable/trie.go b/routingtable/routingtable/trie.go
deleted file mode 100644
index 21e840df990a2798a290e36e9ac5c26233a4a894..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/trie.go
+++ /dev/null
@@ -1,228 +0,0 @@
-package routingtable
-
-import (
-	"github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/route"
-)
-
-// node is a node in the compressed trie that is used to implement a routing table
-type node struct {
-	skip  uint8
-	dummy bool
-	route *route.Route
-	l     *node
-	h     *node
-}
-
-func getBitUint32(x uint32, pos uint8) bool {
-	return ((x) & (1 << (32 - pos))) != 0
-}
-
-func newNode(pfx net.Prefix, path *route.Path, skip uint8, dummy bool) *node {
-	n := &node{
-		route: route.NewRoute(pfx, path),
-		skip:  skip,
-		dummy: dummy,
-	}
-	return n
-}
-
-func (n *node) removePath(pfx net.Prefix, p *route.Path) {
-	if n == nil {
-		return
-	}
-
-	if n.route.Prefix() == pfx {
-		if n.dummy {
-			return
-		}
-
-		if n.route.RemovePath(p) {
-			// FIXME: Can this node actually be removed from the trie entirely?
-			n.dummy = true
-		}
-
-		return
-	}
-
-	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l.removePath(pfx, p)
-		return
-	}
-	n.h.removePath(pfx, p)
-	return
-}
-
-func (n *node) lpm(needle net.Prefix, res *[]*route.Route) {
-	if n == nil {
-		return
-	}
-
-	currentPfx := n.route.Prefix()
-	if currentPfx == needle && !n.dummy {
-		*res = append(*res, n.route)
-		return
-	}
-
-	if !currentPfx.Contains(needle) {
-		return
-	}
-
-	if !n.dummy {
-		*res = append(*res, n.route)
-	}
-	n.l.lpm(needle, res)
-	n.h.lpm(needle, res)
-}
-
-func (n *node) dumpPfxs(res []*route.Route) []*route.Route {
-	if n == nil {
-		return nil
-	}
-
-	if !n.dummy {
-		res = append(res, n.route)
-	}
-
-	if n.l != nil {
-		res = n.l.dumpPfxs(res)
-	}
-
-	if n.h != nil {
-		res = n.h.dumpPfxs(res)
-	}
-
-	return res
-}
-
-func (n *node) get(pfx net.Prefix) *node {
-	if n == nil {
-		return nil
-	}
-
-	if n.route.Prefix() == pfx {
-		if n.dummy {
-			return nil
-		}
-		return n
-	}
-
-	if n.route.Pfxlen() > pfx.Pfxlen() {
-		return nil
-	}
-
-	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
-	if !b {
-		return n.l.get(pfx)
-	}
-	return n.h.get(pfx)
-}
-
-func (n *node) addPath(pfx net.Prefix, p *route.Path) *node {
-	currentPfx := n.route.Prefix()
-	if currentPfx == pfx {
-		n.route.AddPath(p)
-		n.dummy = false
-		return n
-	}
-
-	// is pfx NOT a subnet of this node?
-	if !currentPfx.Contains(pfx) {
-		if pfx.Contains(currentPfx) {
-			return n.insertBefore(pfx, p, n.route.Pfxlen()-n.skip-1)
-		}
-
-		return n.newSuperNode(pfx, p)
-	}
-
-	// pfx is a subnet of this node
-	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
-	if !b {
-		return n.insertLow(pfx, p, currentPfx.Pfxlen())
-	}
-	return n.insertHigh(pfx, p, n.route.Pfxlen())
-}
-
-func (n *node) insertLow(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *node {
-	if n.l == nil {
-		n.l = newNode(pfx, p, pfx.Pfxlen()-parentPfxLen-1, false)
-		return n
-	}
-	n.l = n.l.addPath(pfx, p)
-	return n
-}
-
-func (n *node) insertHigh(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *node {
-	if n.h == nil {
-		n.h = newNode(pfx, p, pfx.Pfxlen()-parentPfxLen-1, false)
-		return n
-	}
-	n.h = n.h.addPath(pfx, p)
-	return n
-}
-
-func (n *node) newSuperNode(pfx net.Prefix, p *route.Path) *node {
-	superNet := pfx.GetSupernet(n.route.Prefix())
-
-	pfxLenDiff := n.route.Pfxlen() - superNet.Pfxlen()
-	skip := n.skip - pfxLenDiff
-
-	pseudoNode := newNode(superNet, nil, skip, true)
-	pseudoNode.insertChildren(n, pfx, p)
-	return pseudoNode
-}
-
-func (n *node) insertChildren(old *node, newPfx net.Prefix, newPath *route.Path) {
-	// Place the old node
-	b := getBitUint32(old.route.Prefix().Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l = old
-		n.l.skip = old.route.Pfxlen() - n.route.Pfxlen() - 1
-	} else {
-		n.h = old
-		n.h.skip = old.route.Pfxlen() - n.route.Pfxlen() - 1
-	}
-
-	// Place the new Prefix
-	newNode := newNode(newPfx, newPath, newPfx.Pfxlen()-n.route.Pfxlen()-1, false)
-	b = getBitUint32(newPfx.Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l = newNode
-	} else {
-		n.h = newNode
-	}
-}
-
-func (n *node) insertBefore(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *node {
-	tmp := n
-
-	pfxLenDiff := n.route.Pfxlen() - pfx.Pfxlen()
-	skip := n.skip - pfxLenDiff
-	new := newNode(pfx, p, skip, false)
-
-	b := getBitUint32(pfx.Addr(), parentPfxLen)
-	if !b {
-		new.l = tmp
-		new.l.skip = tmp.route.Pfxlen() - pfx.Pfxlen() - 1
-	} else {
-		new.h = tmp
-		new.h.skip = tmp.route.Pfxlen() - pfx.Pfxlen() - 1
-	}
-
-	return new
-}
-
-func (n *node) dump(res []*route.Route) []*route.Route {
-	if n == nil {
-		return res
-	}
-
-	if !n.dummy {
-		res = append(res, n.route)
-	}
-
-	res = n.l.dump(res)
-	res = n.h.dump(res)
-	return res
-}
diff --git a/routingtable/routingtable/trie_test.go b/routingtable/routingtable/trie_test.go
deleted file mode 100644
index 7bbf46e11dcc2a19e3af36a012e81b65be326cad..0000000000000000000000000000000000000000
--- a/routingtable/routingtable/trie_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package routingtable
-
-import (
-	"testing"
-)
-
-func TestGetBitUint32(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint32
-		offset   uint8
-		expected bool
-	}{
-		{
-			name:     "test 1",
-			input:    167772160, // 10.0.0.0
-			offset:   8,
-			expected: false,
-		},
-		{
-			name:     "test 2",
-			input:    184549376, // 11.0.0.0
-			offset:   8,
-			expected: true,
-		},
-	}
-
-	for _, test := range tests {
-		b := getBitUint32(test.input, test.offset)
-		if b != test.expected {
-			t.Errorf("%s: Unexpected failure: Bit %d of %d is %v. Expected %v", test.name, test.offset, test.input, b, test.expected)
-		}
-	}
-}
diff --git a/routingtable/table.go b/routingtable/table.go
index a75ba5cc78d297280ac782524e15041e952c9e41..6b8bcb6b39200b0710aa3de0899ce12c248ed846 100644
--- a/routingtable/table.go
+++ b/routingtable/table.go
@@ -20,6 +20,9 @@ func NewRoutingTable() *RoutingTable {
 
 // AddPath adds a path to the routing table
 func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
+	rt.mu.Lock()
+	defer rt.mu.Unlock()
+
 	if rt.root == nil {
 		rt.root = newNode(pfx, p, pfx.Pfxlen(), false)
 		return nil
@@ -31,12 +34,18 @@ func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
 
 // RemovePath removes a path from the trie
 func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) error {
+	rt.mu.Lock()
+	defer rt.mu.Unlock()
+
 	rt.root.removePath(pfx, p)
 	return nil
 }
 
 // LPM performs a longest prefix match for pfx on lpm
 func (rt *RoutingTable) LPM(pfx net.Prefix) (res []*route.Route) {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	if rt.root == nil {
 		return nil
 	}
@@ -47,6 +56,9 @@ func (rt *RoutingTable) LPM(pfx net.Prefix) (res []*route.Route) {
 
 // Get get's the route for pfx from the LPM
 func (rt *RoutingTable) Get(pfx net.Prefix) *route.Route {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	if rt.root == nil {
 		return nil
 	}
@@ -60,6 +72,9 @@ func (rt *RoutingTable) Get(pfx net.Prefix) *route.Route {
 
 // GetLonger get's prefix pfx and all it's more specifics from the LPM
 func (rt *RoutingTable) GetLonger(pfx net.Prefix) (res []*route.Route) {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	if rt.root == nil {
 		return []*route.Route{}
 	}
@@ -69,6 +84,9 @@ func (rt *RoutingTable) GetLonger(pfx net.Prefix) (res []*route.Route) {
 
 // Dump dumps all routes in table rt into a slice
 func (rt *RoutingTable) Dump() []*route.Route {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	res := make([]*route.Route, 0)
 	return rt.root.dump(res)
 }
diff --git a/routingtable/trie.go b/routingtable/trie.go
index 73e208d339086cc2dcdf04b2cb9fef4f7a087935..21e840df990a2798a290e36e9ac5c26233a4a894 100644
--- a/routingtable/trie.go
+++ b/routingtable/trie.go
@@ -1,8 +1,6 @@
 package routingtable
 
 import (
-	"fmt"
-
 	"github.com/bio-routing/bio-rd/net"
 	"github.com/bio-routing/bio-rd/route"
 )
@@ -131,9 +129,7 @@ func (n *node) addPath(pfx net.Prefix, p *route.Path) *node {
 
 	// is pfx NOT a subnet of this node?
 	if !currentPfx.Contains(pfx) {
-		fmt.Printf("The new Prefix is not a sub pfx of this node!\n")
 		if pfx.Contains(currentPfx) {
-			fmt.Printf("The current nodes pfx is a subnet of the new one!\n")
 			return n.insertBefore(pfx, p, n.route.Pfxlen()-n.skip-1)
 		}
 
@@ -148,31 +144,6 @@ func (n *node) addPath(pfx net.Prefix, p *route.Path) *node {
 	return n.insertHigh(pfx, p, n.route.Pfxlen())
 }
 
-/*func (n *node) insert(route *route.Route) *node {
-	if n.route.Prefix() == route.Prefix() {
-		n.route.AddPaths(route.paths)
-		n.dummy = false
-		return n
-	}
-
-	// is pfx NOT a subnet of this node?
-	if !n.route.Prefix().Contains(route.Prefix()) {
-		route.bestPaths()
-		if route.Prefix().Contains(n.route.Prefix()) {
-			return n.insertBefore(route, n.route.Pfxlen()-n.skip-1)
-		}
-
-		return n.newSuperNode(route)
-	}
-
-	// pfx is a subnet of this node
-	b := getBitUint32(route.Prefix().Addr(), n.route.Pfxlen()+1)
-	if !b {
-		return n.insertLow(route, n.route.Prefix().Pfxlen())
-	}
-	return n.insertHigh(route, n.route.Pfxlen())
-}*/
-
 func (n *node) insertLow(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *node {
 	if n.l == nil {
 		n.l = newNode(pfx, p, pfx.Pfxlen()-parentPfxLen-1, false)
@@ -193,7 +164,6 @@ func (n *node) insertHigh(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *no
 
 func (n *node) newSuperNode(pfx net.Prefix, p *route.Path) *node {
 	superNet := pfx.GetSupernet(n.route.Prefix())
-	fmt.Printf("New supernet: %s\n", superNet.String())
 
 	pfxLenDiff := n.route.Pfxlen() - superNet.Pfxlen()
 	skip := n.skip - pfxLenDiff