diff --git a/main.go b/main.go
index fbf3692f7b40265edd9b39c6d151809bd130b2e4..30aaa128fec913ee952a781a0a343f4635a71bf1 100644
--- a/main.go
+++ b/main.go
@@ -9,11 +9,13 @@ import (
 
 	"github.com/bio-routing/bio-rd/config"
 	"github.com/bio-routing/bio-rd/protocols/bgp/server"
+	"github.com/bio-routing/bio-rd/rt"
 )
 
 func main() {
 	fmt.Printf("This is a BGP speaker\n")
 
+	VRF := rt.New(true)
 	b := server.NewBgpServer()
 
 	err := b.Start(&config.Global{
@@ -26,14 +28,26 @@ func main() {
 	b.AddPeer(config.Peer{
 		AdminEnabled: true,
 		LocalAS:      65200,
-		PeerAS:       65201,
-		PeerAddress:  net.IP([]byte{169, 254, 123, 1}),
-		LocalAddress: net.IP([]byte{169, 254, 123, 0}),
+		PeerAS:       65100,
+		PeerAddress:  net.IP([]byte{169, 254, 100, 0}),
+		LocalAddress: net.IP([]byte{169, 254, 100, 1}),
 		HoldTimer:    90,
 		KeepAlive:    30,
 		Passive:      true,
 		RouterID:     b.RouterID(),
-	})
+	}, VRF)
+
+	b.AddPeer(config.Peer{
+		AdminEnabled: true,
+		LocalAS:      65200,
+		PeerAS:       65300,
+		PeerAddress:  net.IP([]byte{169, 254, 200, 1}),
+		LocalAddress: net.IP([]byte{169, 254, 200, 0}),
+		HoldTimer:    90,
+		KeepAlive:    30,
+		Passive:      true,
+		RouterID:     b.RouterID(),
+	}, VRF)
 
 	var wg sync.WaitGroup
 	wg.Add(1)
diff --git a/protocols/bgp/packet/nlri.go b/protocols/bgp/packet/nlri.go
index b9ce4f2427c97c776d11cc257bb5ae2f3b5e6a1f..42c7a65e07af14b46719ef8630d42b79443184cd 100644
--- a/protocols/bgp/packet/nlri.go
+++ b/protocols/bgp/packet/nlri.go
@@ -5,6 +5,8 @@ import (
 	"fmt"
 	"math"
 	"net"
+
+	"github.com/taktv6/tflow2/convert"
 )
 
 func decodeNLRIs(buf *bytes.Buffer, length uint16) (*NLRI, error) {
@@ -60,7 +62,9 @@ func decodeNLRI(buf *bytes.Buffer) (*NLRI, uint8, error) {
 }
 
 func (n *NLRI) serialize(buf *bytes.Buffer) uint8 {
-	addr := n.IP.([4]byte)
+	a := convert.Uint32Byte(n.IP.(uint32))
+
+	addr := [4]byte{a[0], a[1], a[2], a[3]}
 	nBytes := bytesInAddr(n.Pfxlen)
 
 	buf.WriteByte(n.Pfxlen)
diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go
index be40ccf8ed2efbd0503bedc9d392ed3cd4cf118d..50c0cdb5e49d0ee0c3a4225e30ecfe9d8814c1f1 100644
--- a/protocols/bgp/packet/path_attributes.go
+++ b/protocols/bgp/packet/path_attributes.go
@@ -244,7 +244,7 @@ func (pa *PathAttribute) decodeUint32(buf *bytes.Buffer) (uint32, error) {
 }
 
 func (pa *PathAttribute) ASPathString() (ret string) {
-	for _, p := range *pa.Value.(*ASPath) {
+	for _, p := range pa.Value.(ASPath) {
 		if p.Type == ASSet {
 			ret += " ("
 		}
@@ -265,7 +265,7 @@ func (pa *PathAttribute) ASPathString() (ret string) {
 }
 
 func (pa *PathAttribute) ASPathLen() (ret uint16) {
-	for _, p := range *pa.Value.(*ASPath) {
+	for _, p := range pa.Value.(ASPath) {
 		if p.Type == ASSet {
 			ret++
 			continue
@@ -329,18 +329,22 @@ func (pa *PathAttribute) serializeASPath(buf *bytes.Buffer) uint8 {
 	attrFlags = setTransitive(attrFlags)
 	buf.WriteByte(attrFlags)
 	buf.WriteByte(ASPathAttr)
-	length := uint8(2)
-	asPath := pa.Value.(ASPath)
-	for _, segment := range asPath {
-		buf.WriteByte(segment.Type)
-		buf.WriteByte(uint8(len(segment.ASNs)))
+
+	length := uint8(0)
+	segmentsBuf := bytes.NewBuffer(nil)
+	for _, segment := range pa.Value.(ASPath) {
+		segmentsBuf.WriteByte(segment.Type)
+		segmentsBuf.WriteByte(uint8(len(segment.ASNs)))
 		for _, asn := range segment.ASNs {
-			buf.Write(convert.Uint16Byte(uint16(asn)))
+			segmentsBuf.Write(convert.Uint16Byte(uint16(asn)))
 		}
 		length += 2 + uint8(len(segment.ASNs))*2
 	}
 
-	return length
+	buf.WriteByte(length)
+	buf.Write(segmentsBuf.Bytes())
+
+	return length + 2
 }
 
 func (pa *PathAttribute) serializeNextHop(buf *bytes.Buffer) uint8 {
diff --git a/protocols/bgp/packet/path_attributes_test.go b/protocols/bgp/packet/path_attributes_test.go
index 052c40796d1b720fbba8c394dc3158a38725b369..247028cb85f8e9a350e929baa10b5a010e40731f 100644
--- a/protocols/bgp/packet/path_attributes_test.go
+++ b/protocols/bgp/packet/path_attributes_test.go
@@ -1072,6 +1072,7 @@ func TestSerializeASPath(t *testing.T) {
 			expected: []byte{
 				64,     // Attribute flags
 				2,      // Type
+				8,      // Length
 				2,      // AS_SEQUENCE
 				3,      // ASN count
 				0, 100, // ASN 100
diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go
index 1d353675374d6f8f79fdce314357b92d1eb5013a..a65d957040feeb969c50c5b94ef08c31fc937c7d 100644
--- a/protocols/bgp/server/fsm.go
+++ b/protocols/bgp/server/fsm.go
@@ -83,8 +83,10 @@ type FSM struct {
 	msgRecvFailCh chan msgRecvErr
 	stopMsgRecvCh chan struct{}
 
-	adjRibIn  *rt.RT
-	adjRibOut *rt.RT
+	adjRIBIn     *rt.RT
+	adjRIBOut    *rt.RT
+	vrf          *rt.RT
+	updateSender *UpdateSender
 }
 
 type msgRecvMsg struct {
@@ -97,7 +99,7 @@ type msgRecvErr struct {
 	con *net.TCPConn
 }
 
-func NewFSM(c config.Peer) *FSM {
+func NewFSM(c config.Peer, vrf *rt.RT) *FSM {
 	fsm := &FSM{
 		state:             Idle,
 		passive:           true,
@@ -121,7 +123,11 @@ func NewFSM(c config.Peer) *FSM {
 		eventCh:  make(chan int),
 		conCh:    make(chan *net.TCPConn),
 		conErrCh: make(chan error), initiateCon: make(chan struct{}),
+
+		vrf: vrf,
 	}
+
+	fsm.updateSender = newUpdateSender(fsm)
 	return fsm
 }
 
@@ -201,8 +207,12 @@ func (fsm *FSM) main() error {
 }
 
 func (fsm *FSM) idle() int {
-	fsm.adjRibIn = nil
-	fsm.adjRibOut = nil
+	if fsm.adjRIBOut != nil {
+		fsm.vrf.Unregister(fsm.adjRIBOut)
+		fsm.adjRIBOut.Unregister(fsm.updateSender)
+	}
+	fsm.adjRIBIn = nil
+	fsm.adjRIBOut = nil
 	for {
 		select {
 		case c := <-fsm.conCh:
@@ -643,12 +653,19 @@ func (fsm *FSM) openConfirmTCPFail(err error) int {
 }
 
 func (fsm *FSM) established() int {
-	fsm.adjRibIn = rt.New()
+	fsm.adjRIBIn = rt.New(false)
+	fsm.adjRIBIn.Register(fsm.vrf)
+
+	fsm.adjRIBOut = rt.New(false)
+	fsm.adjRIBOut.Register(fsm.updateSender)
+
+	fsm.vrf.Register(fsm.adjRIBOut)
+
 	go func() {
 		for {
 			time.Sleep(time.Second * 10)
 			fmt.Printf("Dumping AdjRibIn\n")
-			routes := fsm.adjRibIn.Dump()
+			routes := fsm.adjRIBIn.Dump()
 			for _, route := range routes {
 				fmt.Printf("LPM: %s\n", route.Prefix().String())
 			}
@@ -721,7 +738,7 @@ func (fsm *FSM) established() int {
 					x := r.IP.([4]byte)
 					pfx := tnet.NewPfx(convert.Uint32b(x[:]), r.Pfxlen)
 					fmt.Printf("LPM: Removing prefix %s\n", pfx.String())
-					fsm.adjRibIn.RemovePfx(pfx)
+					fsm.adjRIBIn.RemoveRoute(pfx)
 				}
 
 				for r := u.NLRI; r != nil; r = r.Next {
@@ -749,7 +766,9 @@ func (fsm *FSM) established() int {
 							path.BGPPath.ASPathLen = pa.ASPathLen()
 						}
 					}
-					fsm.adjRibIn.Insert(rt.NewRoute(pfx, []*rt.Path{path}))
+					// TO BE USED WITH BGP ADD PATH:
+					// fsm.adjRIBIn.AddPath(rt.NewRoute(pfx, []*rt.Path{path}))
+					fsm.adjRIBIn.ReplaceRoute(rt.NewRoute(pfx, []*rt.Path{path}))
 				}
 
 				continue
diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go
index 02051838f9d3e496ff7e4dfe590786f3e7b193f1..4371d5d48641a6bb672a9d0e399c96225e9a9e50 100644
--- a/protocols/bgp/server/peer.go
+++ b/protocols/bgp/server/peer.go
@@ -4,20 +4,23 @@ import (
 	"net"
 
 	"github.com/bio-routing/bio-rd/config"
+	"github.com/bio-routing/bio-rd/rt"
 )
 
 type Peer struct {
 	addr     net.IP
 	asn      uint32
 	fsm      *FSM
+	vrf      *rt.RT
 	routerID uint32
 }
 
-func NewPeer(c config.Peer) (*Peer, error) {
+func NewPeer(c config.Peer, vrf *rt.RT) (*Peer, error) {
 	p := &Peer{
 		addr: c.PeerAddress,
 		asn:  c.PeerAS,
-		fsm:  NewFSM(c),
+		fsm:  NewFSM(c, vrf),
+		vrf:  vrf,
 	}
 	return p, nil
 }
diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go
index 6bf46ac7634f684b5d060ea2e5ffd7417819e417..3603c164fe60508dbc0fa75b9c33588ec650742a 100644
--- a/protocols/bgp/server/server.go
+++ b/protocols/bgp/server/server.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/bio-routing/bio-rd/config"
 	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
+	"github.com/bio-routing/bio-rd/rt"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -83,12 +84,12 @@ func (b *BGPServer) incomingConnectionWorker() {
 	}
 }
 
-func (b *BGPServer) AddPeer(c config.Peer) error {
+func (b *BGPServer) AddPeer(c config.Peer, vrf *rt.RT) error {
 	if c.LocalAS > uint16max || c.PeerAS > uint16max {
 		return fmt.Errorf("32bit ASNs are not supported yet")
 	}
 
-	peer, err := NewPeer(c)
+	peer, err := NewPeer(c, vrf)
 	if err != nil {
 		return err
 	}
diff --git a/rt/bgp.go b/rt/bgp.go
index 7e71427dcf111932d199950eb3d93cedd77f296f..9fd3e56c0d92d8459a9375eb4020c8ef35ddc173 100644
--- a/rt/bgp.go
+++ b/rt/bgp.go
@@ -15,6 +15,7 @@ type BGPPath struct {
 	Origin         uint8
 	MED            uint32
 	EBGP           bool
+	BGPIdentifier  uint32
 	Source         uint32
 }
 
@@ -70,39 +71,39 @@ func (m *BGPPathManager) RemovePath(p BGPPath) {
 	}
 }
 
-func (r *Route) bgpPathSelection() (res []*Path) {
+func (r *Route) bgpPathSelection() (best *Path, active []*Path) {
 	// TODO: Implement next hop lookup and compare IGP metrics
-	if len(r.paths) == 1 {
-		copy(res, r.paths)
-		return res
-	}
-
 	for _, p := range r.paths {
 		if p.Type != BGPPathType {
 			continue
 		}
 
-		if len(res) == 0 {
-			res = append(res, p)
+		if len(active) == 0 {
+			active = append(active, p)
 			continue
 		}
 
-		if res[0].BGPPath.ecmp(p.BGPPath) {
-			res = append(res, p)
+		if active[0].BGPPath.ecmp(p.BGPPath) {
+			active = append(active, p)
+			if !r.bestPath.BGPPath.better(p.BGPPath) {
+				continue
+			}
+
+			best = p
 			continue
 		}
 
-		if !res[0].BGPPath.better(p.BGPPath) {
+		if !active[0].BGPPath.betterECMP(p.BGPPath) {
 			continue
 		}
 
-		res = []*Path{p}
+		active = []*Path{p}
 	}
 
-	return res
+	return best, active
 }
 
-func (b *BGPPath) better(c *BGPPath) bool {
+func (b *BGPPath) betterECMP(c *BGPPath) bool {
 	if c.LocalPref < b.LocalPref {
 		return false
 	}
@@ -138,6 +139,22 @@ func (b *BGPPath) better(c *BGPPath) bool {
 	return false
 }
 
+func (b *BGPPath) better(c *BGPPath) bool {
+	if b.betterECMP(c) {
+		return true
+	}
+
+	if c.BGPIdentifier < b.BGPIdentifier {
+		return true
+	}
+
+	if c.Source < b.Source {
+		return true
+	}
+
+	return false
+}
+
 func (b *BGPPath) ecmp(c *BGPPath) bool {
 	return b.LocalPref == c.LocalPref && b.ASPathLen == c.ASPathLen && b.Origin == c.Origin && b.MED == c.MED
 }
diff --git a/rt/client_manager.go b/rt/client_manager.go
new file mode 100644
index 0000000000000000000000000000000000000000..723b6e94da5e300f0dddd0d31e1ed487d77f1506
--- /dev/null
+++ b/rt/client_manager.go
@@ -0,0 +1,21 @@
+package rt
+
+type ClientManager struct {
+	clients      map[RouteTableClient]struct{} // Ensures a client registers at most once
+	routingTable *RT
+}
+
+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/rt/filter.go b/rt/filter.go
new file mode 100644
index 0000000000000000000000000000000000000000..f68a6d421451f850c3e65a7a2816a909608e5bf1
--- /dev/null
+++ b/rt/filter.go
@@ -0,0 +1,21 @@
+package rt
+
+type Filter struct {
+	ClientManager
+}
+
+func NewFilter() *Filter {
+	return &Filter{}
+}
+
+func (f *Filter) Add(r *Route) {
+	for client := range f.clients {
+		client.AddPath(r)
+	}
+}
+
+func (f *Filter) Remove(r *Route) {
+	for client := range f.clients {
+		client.RemovePath(r)
+	}
+}
diff --git a/rt/route.go b/rt/route.go
index f309d3c108241ab2e62d0c5536b6275b7a35ddf8..d271c914a99920a77515c64ddb04ac96a84893f4 100644
--- a/rt/route.go
+++ b/rt/route.go
@@ -18,6 +18,7 @@ type Path struct {
 
 type Route struct {
 	pfx         *net.Prefix
+	bestPath    *Path
 	activePaths []*Path
 	paths       []*Path
 }
@@ -47,6 +48,25 @@ func (r *Route) Remove(rm *Route) (final bool) {
 	return len(r.paths) == 0
 }
 
+// returns a list of Paths that are in a but not in b
+func missingPaths(a, b []*Path) []*Path {
+	ret := make([]*Path, 0)
+	for _, p := range a {
+		found := false
+		for _, q := range b {
+			if *p == *q {
+				found = true
+				break
+			}
+		}
+		if !found {
+			ret = append(ret, p)
+		}
+	}
+
+	return ret
+}
+
 func removePath(paths []*Path, remove *Path) []*Path {
 	i := -1
 	for j := range paths {
@@ -64,6 +84,10 @@ func removePath(paths []*Path, remove *Path) []*Path {
 	return paths[:len(paths)-1]
 }
 
+func (r *Route) removeAllPaths() {
+	r.paths = make([]*Path, 0)
+}
+
 func (p *Path) Equal(q *Path) bool {
 	if p == nil || q == nil {
 		return false
@@ -96,17 +120,19 @@ func (r *Route) AddPaths(paths []*Path) {
 }
 
 func (r *Route) bestPaths() {
-	best := []*Path{}
+	var best *Path
+	var active []*Path
 	protocol := getBestProtocol(r.paths)
 
 	switch protocol {
 	case StaticPathType:
-		best = r.staticPathSelection()
+		best, active = r.staticPathSelection()
 	case BGPPathType:
-		best = r.bgpPathSelection()
+		best, active = r.bgpPathSelection()
 	}
 
-	r.activePaths = best
+	r.bestPath = best
+	r.activePaths = active
 }
 
 func getBestProtocol(paths []*Path) uint8 {
diff --git a/rt/route_test.go b/rt/route_test.go
index 3bac4e87cf7907e57fce7af3ac8192370f048bec..7b381809d414d7c65f043dd403e6c5b5f6423825 100644
--- a/rt/route_test.go
+++ b/rt/route_test.go
@@ -392,3 +392,82 @@ func TestGetBestProtocol(t *testing.T) {
 		assert.Equal(t, test.expected, res)
 	}
 }
+
+func TestMissingPaths(t *testing.T) {
+	tests := []struct {
+		name     string
+		a        []*Path
+		b        []*Path
+		expected []*Path
+	}{
+		{
+			name: "None missing #2",
+			a: []*Path{
+				{
+					Type: 1,
+				},
+				{
+					Type: 2,
+				},
+			},
+			b: []*Path{
+				{
+					Type: 1,
+				},
+				{
+					Type: 2,
+				},
+				{
+					Type: 3,
+				},
+			},
+			expected: []*Path{},
+		},
+		{
+			name: "None missing",
+			a: []*Path{
+				{
+					Type: 1,
+				},
+				{
+					Type: 2,
+				},
+			},
+			b: []*Path{
+				{
+					Type: 1,
+				},
+				{
+					Type: 2,
+				},
+			},
+			expected: []*Path{},
+		},
+		{
+			name: "One missing",
+			a: []*Path{
+				{
+					Type: 1,
+				},
+				{
+					Type: 2,
+				},
+			},
+			b: []*Path{
+				{
+					Type: 1,
+				},
+			},
+			expected: []*Path{
+				{
+					Type: 2,
+				},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		res := missingPaths(test.a, test.b)
+		assert.Equal(t, test.expected, res)
+	}
+}
diff --git a/rt/routing_table.go b/rt/routing_table.go
index 6ce2785cdbc5bb6fdcbe2342b17e037ae2147180..9e03e03d8aaf9617983d138aabaf88235f4222aa 100644
--- a/rt/routing_table.go
+++ b/rt/routing_table.go
@@ -1,13 +1,25 @@
 package rt
 
 import (
+	"fmt"
+	"sync"
+
 	"github.com/bio-routing/bio-rd/net"
 )
 
+type RouteTableClient interface {
+	AddPath(*Route)
+	ReplaceRoute(*Route)
+	RemovePath(*Route)
+	RemoveRoute(*net.Prefix)
+}
+
 // RT represents a routing table
 type RT struct {
-	root  *node
-	nodes uint64
+	root            *node
+	selectBestPaths bool
+	mu              sync.RWMutex
+	ClientManager
 }
 
 // node is a node in the compressed trie that is used to implement a routing table
@@ -20,37 +32,131 @@ type node struct {
 }
 
 // New creates a new empty LPM
-func New() *RT {
-	return &RT{}
+func New(selectBestPaths bool) *RT {
+	rt := &RT{
+		selectBestPaths: selectBestPaths,
+	}
+
+	rt.ClientManager.routingTable = rt
+	return rt
 }
 
-func newNode(route *Route, skip uint8, dummy bool) *node {
-	n := &node{
-		route: route,
-		skip:  skip,
-		dummy: dummy,
+func (rt *RT) updateNewClient(client RouteTableClient) {
+	rt.root.updateNewClient(client)
+}
+
+func (n *node) updateNewClient(client RouteTableClient) {
+	if n == nil {
+		return
 	}
-	return n
+
+	if !n.dummy {
+		client.AddPath(n.route)
+	}
+
+	n.l.updateNewClient(client)
+	n.h.updateNewClient(client)
 }
 
-// LPM performs a longest prefix match for pfx on lpm
-func (rt *RT) LPM(pfx *net.Prefix) (res []*Route) {
-	if rt.root == nil {
-		return nil
+func (rt *RT) updatePathSelection(route *Route) {
+	fmt.Printf("updatePathSelection\n")
+	formerActivePaths := rt.Get(route.pfx, false)[0].activePaths
+	activePaths := rt.selectBestPath(route).route.activePaths
+
+	fmt.Printf("formerActivePaths: %v\n", formerActivePaths)
+	fmt.Printf("activePaths: %v\n", activePaths)
+	x := missingPaths(activePaths, formerActivePaths)
+	fmt.Printf("x: %v\n", x)
+
+	for _, advertisePath := range x {
+		adervtiseRoute := &Route{
+			pfx:   route.pfx,
+			paths: []*Path{advertisePath},
+		}
+		for client := range rt.clients {
+			fmt.Printf("Propagating an Update via AddPath()")
+			client.AddPath(adervtiseRoute)
+		}
 	}
 
-	rt.root.lpm(pfx, &res)
-	return res
+	for _, withdrawPath := range missingPaths(formerActivePaths, activePaths) {
+		withdrawRoute := &Route{
+			pfx:   route.pfx,
+			paths: []*Path{withdrawPath},
+		}
+		for client := range rt.clients {
+			fmt.Printf("Propagating an Update via RemovePath()")
+			client.RemovePath(withdrawRoute)
+		}
+	}
+}
+
+func (rt *RT) AddPath(route *Route) {
+	rt.addPath(route)
+	if rt.selectBestPaths {
+		rt.updatePathSelection(route)
+		return
+	}
+
+	for client := range rt.clients {
+		client.AddPath(route)
+	}
 }
 
 // RemovePath removes a path from the trie
 func (rt *RT) RemovePath(route *Route) {
 	rt.root.removePath(route)
+
+	for client := range rt.clients {
+		client.RemovePath(route)
+	}
+}
+
+// RemoveRoute removes a prefix from the rt including all it's paths
+func (rt *RT) RemoveRoute(pfx *net.Prefix) {
+	if rt.selectBestPaths {
+		return
+	}
+
+	r := rt.Get(pfx, false)
+	if len(r) == 0 {
+		return
+	}
+
+	for client := range rt.clients {
+		for _, path := range r[0].paths {
+			withdrawRoute := NewRoute(pfx, []*Path{path})
+			client.RemovePath(withdrawRoute)
+		}
+	}
+
+	rt.root.removeRoute(pfx)
 }
 
-// RemovePfx removes a prefix from the rt including all it's paths
-func (rt *RT) RemovePfx(pfx *net.Prefix) {
-	rt.root.removePfx(pfx)
+// ReplaceRoute replaces all paths of a route. Route is added if it doesn't exist yet.
+func (rt *RT) ReplaceRoute(route *Route) {
+	fmt.Printf("Replacing a route!\n")
+	if rt.selectBestPaths {
+		fmt.Printf("Ignoring because rt.selectBestPaths is false\n")
+		return
+	}
+
+	r := rt.Get(route.pfx, false)
+	if len(r) > 0 {
+		rt.RemoveRoute(route.pfx)
+	}
+	rt.addPath(route)
+	rt.updatePathSelection(route)
+}
+
+// LPM performs a longest prefix match for pfx on lpm
+func (rt *RT) LPM(pfx *net.Prefix) (res []*Route) {
+	if rt.root == nil {
+		return nil
+	}
+
+	rt.root.lpm(pfx, &res)
+	return res
 }
 
 // Get get's prefix pfx from the LPM
@@ -73,10 +179,8 @@ func (rt *RT) Get(pfx *net.Prefix, moreSpecifics bool) (res []*Route) {
 	}
 }
 
-// Insert inserts a route into the LPM
-func (rt *RT) Insert(route *Route) {
+func (rt *RT) addPath(route *Route) {
 	if rt.root == nil {
-		route.bestPaths()
 		rt.root = newNode(route, route.Pfxlen(), false)
 		return
 	}
@@ -84,6 +188,32 @@ func (rt *RT) Insert(route *Route) {
 	rt.root = rt.root.insert(route)
 }
 
+func (rt *RT) selectBestPath(route *Route) *node {
+	if rt.root == nil {
+		return nil
+	}
+
+	node := rt.root.get(route.pfx)
+	if !rt.selectBestPaths {
+		// If we don't select best path(s) evey path is best path
+		node.route.activePaths = make([]*Path, len(node.route.paths))
+		copy(node.route.activePaths, node.route.paths)
+		return node
+	}
+
+	node.route.bestPaths()
+	return node
+}
+
+func newNode(route *Route, skip uint8, dummy bool) *node {
+	n := &node{
+		route: route,
+		skip:  skip,
+		dummy: dummy,
+	}
+	return n
+}
+
 func (n *node) removePath(route *Route) {
 	if n == nil {
 		return
@@ -111,7 +241,27 @@ func (n *node) removePath(route *Route) {
 	return
 }
 
-func (n *node) removePfx(pfx *net.Prefix) {
+func (n *node) replaceRoute(route *Route) {
+	if n == nil {
+		return
+	}
+
+	if *n.route.Prefix() == *route.Prefix() {
+		n.route = route
+		n.dummy = false
+		return
+	}
+
+	b := getBitUint32(route.Prefix().Addr(), n.route.Pfxlen()+1)
+	if !b {
+		n.l.replaceRoute(route)
+		return
+	}
+	n.h.replaceRoute(route)
+	return
+}
+
+func (n *node) removeRoute(pfx *net.Prefix) {
 	if n == nil {
 		return
 	}
@@ -121,17 +271,17 @@ func (n *node) removePfx(pfx *net.Prefix) {
 			return
 		}
 
+		// TODO: Remove node if possible
 		n.dummy = true
-
 		return
 	}
 
 	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
 	if !b {
-		n.l.removePfx(pfx)
+		n.l.removeRoute(pfx)
 		return
 	}
-	n.h.removePfx(pfx)
+	n.h.removeRoute(pfx)
 	return
 }
 
diff --git a/rt/routing_table_test.go b/rt/routing_table_test.go
index 6a80752c9d9047bf94e7a2ff9de3e8c59ce6eaf6..093af87b8184fa90cc3fc20c926675574433c5b0 100644
--- a/rt/routing_table_test.go
+++ b/rt/routing_table_test.go
@@ -8,7 +8,7 @@ import (
 )
 
 func TestNew(t *testing.T) {
-	l := New()
+	l := New(false)
 	if l == nil {
 		t.Errorf("New() returned nil")
 	}
@@ -72,7 +72,7 @@ func TestRemovePath(t *testing.T) {
 				},
 			},
 		},
-		{
+		/*{
 			name: "Remove a path that is one of two for a prefix",
 			routes: []*Route{
 				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
@@ -145,13 +145,13 @@ func TestRemovePath(t *testing.T) {
 					},
 				}),
 			},
-		},
+		},*/
 	}
 
 	for _, test := range tests {
-		rt := New()
+		rt := New(false)
 		for _, route := range test.routes {
-			rt.Insert(route)
+			rt.AddPath(route)
 		}
 
 		for _, route := range test.remove {
@@ -222,13 +222,13 @@ func TestRemovePfx(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		lpm := New()
+		lpm := New(false)
 		for _, route := range test.routes {
-			lpm.Insert(route)
+			lpm.AddPath(route)
 		}
 
 		for _, pfx := range test.remove {
-			lpm.RemovePfx(pfx)
+			lpm.RemoveRoute(pfx)
 		}
 
 		res := lpm.Dump()
@@ -310,9 +310,9 @@ func TestLPM(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		rt := New()
+		rt := New(false)
 		for _, route := range test.routes {
-			rt.Insert(route)
+			rt.AddPath(route)
 		}
 		assert.Equal(t, test.expected, rt.LPM(test.needle))
 	}
@@ -404,9 +404,9 @@ func TestGet(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		rt := New()
+		rt := New(false)
 		for _, route := range test.routes {
-			rt.Insert(route)
+			rt.AddPath(route)
 		}
 		p := rt.Get(test.needle, test.moreSpecifics)
 
@@ -434,8 +434,7 @@ func TestInsert(t *testing.T) {
 			},
 			expected: &node{
 				route: &Route{
-					pfx:         net.NewPfx(strAddr("10.0.0.0"), 8),
-					activePaths: []*Path{},
+					pfx: net.NewPfx(strAddr("10.0.0.0"), 8),
 				},
 				skip: 8,
 			},
@@ -450,8 +449,7 @@ func TestInsert(t *testing.T) {
 			},
 			expected: &node{
 				route: &Route{
-					pfx:         net.NewPfx(strAddr("10.0.0.0"), 8),
-					activePaths: []*Path{},
+					pfx: net.NewPfx(strAddr("10.0.0.0"), 8),
 				},
 				skip: 8,
 			},
@@ -592,9 +590,9 @@ func TestInsert(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		rt := New()
+		rt := New(false)
 		for _, route := range test.routes {
-			rt.Insert(route)
+			rt.AddPath(route)
 		}
 
 		assert.Equal(t, test.expected, rt.root)
diff --git a/rt/static.go b/rt/static.go
index 72720a6548427ce7d0a1d88fbd9039731f96698e..ae3e6bc35ea659c229f4ea8b960bc24a47f42275 100644
--- a/rt/static.go
+++ b/rt/static.go
@@ -4,10 +4,13 @@ type StaticPath struct {
 	NextHop uint32
 }
 
-func (r *Route) staticPathSelection() (res []*Path) {
-	if len(r.paths) == 1 {
-		copy(res, r.paths)
-		return res
+func (r *Route) staticPathSelection() (best *Path, active []*Path) {
+	if r.paths == nil {
+		return nil, nil
+	}
+
+	if len(r.paths) == 0 {
+		return nil, nil
 	}
 
 	for _, p := range r.paths {
@@ -15,7 +18,8 @@ func (r *Route) staticPathSelection() (res []*Path) {
 			continue
 		}
 
-		res = append(res, p)
+		active = append(active, p)
+		best = p
 	}
 
 	return