diff --git a/main.go b/main.go
index 7e19a5aa8d1e0d982435fe12dd8229eecfbb1a35..3e0598bce10567ead6b30ea7f9e1caeebeafdcf3 100644
--- a/main.go
+++ b/main.go
@@ -15,7 +15,7 @@ import (
 )
 
 func main() {
-	fmt.Printf("This is a BGP speaker\n")
+	logrus.Printf("This is a BGP speaker\n")
 
 	rib := locRIB.New()
 	b := server.NewBgpServer()
diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go
index fc342e821871667f3d4fe7aab18e5d50e225674a..2a9f89dc96eba5d33ae21896452c1abca73249da 100644
--- a/protocols/bgp/server/fsm.go
+++ b/protocols/bgp/server/fsm.go
@@ -16,7 +16,6 @@ import (
 	"github.com/bio-routing/bio-rd/routingtable/adjRIBIn"
 	"github.com/bio-routing/bio-rd/routingtable/adjRIBOut"
 	"github.com/bio-routing/bio-rd/routingtable/adjRIBOutAddPath"
-	"github.com/bio-routing/bio-rd/routingtable/locRIB"
 	log "github.com/sirupsen/logrus"
 	tomb "gopkg.in/tomb.v2"
 )
@@ -92,7 +91,7 @@ type FSM struct {
 
 	adjRIBIn     *adjRIBIn.AdjRIBIn
 	adjRIBOut    routingtable.RouteTableClient
-	rib          *locRIB.LocRIB
+	rib          routingtable.RouteTableClient
 	updateSender routingtable.RouteTableClient
 
 	capAddPathSend bool
@@ -109,7 +108,7 @@ type msgRecvErr struct {
 	con *net.TCPConn
 }
 
-func NewFSM(peer *Peer, c config.Peer, rib *locRIB.LocRIB) *FSM {
+func NewFSM(peer *Peer, c config.Peer, rib routingtable.RouteTableClient) *FSM {
 	fsm := &FSM{
 		peer:              peer,
 		state:             Idle,
@@ -647,7 +646,7 @@ func (fsm *FSM) openConfirm() int {
 		case recvMsg := <-fsm.msgRecvCh:
 			msg, err := packet.Decode(bytes.NewBuffer(recvMsg.msg))
 			if err != nil {
-				fmt.Printf("Failed to decode message: %v\n", recvMsg.msg)
+				log.WithError(err).Errorf("Failed to decode BGP message %v\n", recvMsg.msg)
 				switch bgperr := err.(type) {
 				case packet.BGPError:
 					sendNotification(fsm.con, bgperr.ErrorCode, bgperr.ErrorSubCode)
@@ -790,7 +789,8 @@ func (fsm *FSM) established() int {
 		case recvMsg := <-fsm.msgRecvCh:
 			msg, err := packet.Decode(bytes.NewBuffer(recvMsg.msg))
 			if err != nil {
-				fmt.Printf("Failed to decode BGP message: %v\n", recvMsg.msg)
+				log.WithError(err).Errorf("Failed to decode BGP message %v\n", recvMsg.msg)
+
 				switch bgperr := err.(type) {
 				case packet.BGPError:
 					sendNotification(fsm.con, bgperr.ErrorCode, bgperr.ErrorSubCode)
@@ -815,14 +815,13 @@ func (fsm *FSM) established() int {
 
 				for r := u.WithdrawnRoutes; r != nil; r = r.Next {
 					pfx := tnet.NewPfx(r.IP, r.Pfxlen)
-					fmt.Printf("LPM: Removing prefix %s\n", pfx.String())
+					log.WithField("Prefix", pfx.String()).Debug("LPM: Removing prefix")
 					fsm.adjRIBIn.RemovePath(pfx, nil)
 				}
 
 				for r := u.NLRI; r != nil; r = r.Next {
 					pfx := tnet.NewPfx(r.IP, r.Pfxlen)
-					fmt.Printf("LPM: Adding prefix %s\n", pfx.String())
-
+					log.WithField("Prefix", pfx.String()).Debug("LPM: Adding prefix")
 					path := &route.Path{
 						Type: route.BGPPathType,
 						BGPPath: &route.BGPPath{
@@ -831,7 +830,6 @@ func (fsm *FSM) established() int {
 					}
 
 					for pa := u.PathAttributes; pa != nil; pa = pa.Next {
-						fmt.Printf("TypeCode: %d\n", pa.TypeCode)
 						switch pa.TypeCode {
 						case packet.OriginAttr:
 							path.BGPPath.Origin = pa.Value.(uint8)
@@ -840,7 +838,7 @@ func (fsm *FSM) established() int {
 						case packet.MEDAttr:
 							path.BGPPath.MED = pa.Value.(uint32)
 						case packet.NextHopAttr:
-							fmt.Printf("RECEIVED NEXT_HOP: %d\n", pa.Value.(uint32))
+							log.WithField("NextHop", pa.Value.(uint32)).Debug("RECEIVED NEXT_HOP")
 							path.BGPPath.NextHop = pa.Value.(uint32)
 						case packet.ASPathAttr:
 							path.BGPPath.ASPath = pa.ASPathString()
diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go
index c891b9ddcea9042980c2d71e6b1475f16018b7b0..ab1dd7467c13597bbece848f6c169b17b6cccd34 100644
--- a/protocols/bgp/server/peer.go
+++ b/protocols/bgp/server/peer.go
@@ -3,9 +3,9 @@ package server
 import (
 	"net"
 
+	"github.com/bio-routing/bio-rd/config"
 	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
 	"github.com/bio-routing/bio-rd/routingtable"
-	"github.com/bio-routing/bio-rd/routingtable/locRIB"
 
 	"time"
 
@@ -16,7 +16,7 @@ type Peer struct {
 	addr              net.IP
 	asn               uint32
 	fsm               *FSM
-	rib               *locRIB.LocRIB
+	rib               routingtable.RouteTableClient
 	routerID          uint32
 	addPathSend       routingtable.ClientOptions
 	addPathRecv       bool
@@ -26,7 +26,7 @@ type Peer struct {
 
 // NewPeer creates a new peer with the given config. If an connection is established, the adjRIBIN of the peer is connected
 // to the given rib. To actually connect the peer, call Start() on the returned peer.
-func NewPeer(c config.Peer, rib *locRIB.LocRIB) (*Peer, error) {
+func NewPeer(c config.Peer, rib routingtable.RouteTableClient) (*Peer, error) {
 	p := &Peer{
 		addr:              c.PeerAddress,
 		asn:               c.PeerAS,
diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go
index 8a11cd3a0641c6ff926ddc4459da157d7273db44..a6025140fd62f81d8fa503aeb0c31114a7589f2b 100644
--- a/protocols/bgp/server/server.go
+++ b/protocols/bgp/server/server.go
@@ -8,7 +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/routingtable/locRIB"
+	"github.com/bio-routing/bio-rd/routingtable"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -39,7 +39,7 @@ func (b *BGPServer) Start(c *config.Global) error {
 		return fmt.Errorf("Failed to load defaults: %v", err)
 	}
 
-	fmt.Printf("ROUTER ID: %d\n", c.RouterID)
+	log.Infof("ROUTER ID: %d\n", c.RouterID)
 	b.routerID = c.RouterID
 
 	if c.Listen {
@@ -62,8 +62,6 @@ func (b *BGPServer) Start(c *config.Global) error {
 func (b *BGPServer) incomingConnectionWorker() {
 	for {
 		c := <-b.acceptCh
-		fmt.Printf("Incoming connection!\n")
-		fmt.Printf("Connection from: %v\n", c.RemoteAddr())
 
 		peerAddr := strings.Split(c.RemoteAddr().String(), ":")[0]
 		if _, ok := b.peers[peerAddr]; !ok {
@@ -78,13 +76,13 @@ func (b *BGPServer) incomingConnectionWorker() {
 			"source": c.RemoteAddr(),
 		}).Info("Incoming TCP connection")
 
-		fmt.Printf("DEBUG: Sending incoming TCP connection to fsm for peer %s\n", peerAddr)
+		log.WithField("Peer", peerAddr).Debug("Sending incoming TCP connection to fsm for peer")
 		b.peers[peerAddr].fsm.conCh <- c
-		fmt.Printf("DEBUG: Sending done\n")
+		log.Debug("Sending done")
 	}
 }
 
-func (b *BGPServer) AddPeer(c config.Peer, rib *locRIB.LocRIB) error {
+func (b *BGPServer) AddPeer(c config.Peer, rib routingtable.RouteTableClient) error {
 	if c.LocalAS > uint16max || c.PeerAS > uint16max {
 		return fmt.Errorf("32bit ASNs are not supported yet")
 	}
diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go
index a5d05887f026cf336e3792e405fa7c456eae6e74..c33f2ce01882e0ba1326962fce7396c9005d9aae 100644
--- a/protocols/bgp/server/update_sender.go
+++ b/protocols/bgp/server/update_sender.go
@@ -15,18 +15,20 @@ import (
 // UpdateSender converts table changes into BGP update messages
 type UpdateSender struct {
 	routingtable.ClientManager
-	fsm *FSM
+	fsm  *FSM
+	iBGP bool
 }
 
 func newUpdateSender(fsm *FSM) *UpdateSender {
 	return &UpdateSender{
-		fsm: fsm,
+		fsm:  fsm,
+		iBGP: fsm.localASN == fsm.remoteASN,
 	}
 }
 
 // AddPath serializes a new path and sends out a BGP update message
 func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error {
-	asPathPA, err := packet.ParseASPathStr(strings.TrimRight(fmt.Sprintf("%d %s", u.fsm.localASN, p.BGPPath.ASPath), " "))
+	asPathPA, err := packet.ParseASPathStr(asPathString(u.iBGP, u.fsm.localASN, p.BGPPath.ASPath))
 	if err != nil {
 		return fmt.Errorf("Unable to parse AS path: %v", err)
 	}
@@ -41,6 +43,10 @@ func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error {
 				Next: &packet.PathAttribute{
 					TypeCode: packet.NextHopAttr,
 					Value:    p.BGPPath.NextHop,
+					Next: &packet.PathAttribute{
+						TypeCode: packet.LocalPrefAttr,
+						Value:    p.BGPPath.LocalPref,
+					},
 				},
 			},
 		},
@@ -74,3 +80,12 @@ func (u *UpdateSender) UpdateNewClient(client routingtable.RouteTableClient) err
 	log.Warningf("BGP Update Sender: UpdateNewClient() not supported")
 	return nil
 }
+
+func asPathString(iBGP bool, localASN uint16, asPath string) string {
+	ret := ""
+	if iBGP {
+		ret = ret + fmt.Sprintf("%d ", localASN)
+	}
+	ret = ret + asPath
+	return strings.TrimRight(ret, " ")
+}
diff --git a/protocols/bgp/server/update_sender_add_path.go b/protocols/bgp/server/update_sender_add_path.go
index e7b46577c594c5b5f84e115981ac560777899d11..a0fe2b3046174cfd5abd929366f631fb07c4d4fc 100644
--- a/protocols/bgp/server/update_sender_add_path.go
+++ b/protocols/bgp/server/update_sender_add_path.go
@@ -2,7 +2,6 @@ package server
 
 import (
 	"fmt"
-	"strings"
 
 	log "github.com/sirupsen/logrus"
 
@@ -15,18 +14,20 @@ import (
 // UpdateSenderAddPath converts table changes into BGP update messages with add path
 type UpdateSenderAddPath struct {
 	routingtable.ClientManager
-	fsm *FSM
+	fsm  *FSM
+	iBGP bool
 }
 
 func newUpdateSenderAddPath(fsm *FSM) *UpdateSenderAddPath {
 	return &UpdateSenderAddPath{
-		fsm: fsm,
+		fsm:  fsm,
+		iBGP: fsm.localASN == fsm.remoteASN,
 	}
 }
 
 // AddPath serializes a new path and sends out a BGP update message
 func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
-	asPathPA, err := packet.ParseASPathStr(strings.TrimRight(fmt.Sprintf("%d %s", u.fsm.localASN, p.BGPPath.ASPath), " "))
+	asPathPA, err := packet.ParseASPathStr(asPathString(u.iBGP, u.fsm.localASN, p.BGPPath.ASPath))
 	if err != nil {
 		return fmt.Errorf("Unable to parse AS path: %v", err)
 	}
@@ -41,6 +42,10 @@ func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
 				Next: &packet.PathAttribute{
 					TypeCode: packet.NextHopAttr,
 					Value:    p.BGPPath.NextHop,
+					Next: &packet.PathAttribute{
+						TypeCode: packet.LocalPrefAttr,
+						Value:    p.BGPPath.LocalPref,
+					},
 				},
 			},
 		},
diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go
index 1427278bbd5aa6c465c16bf2ac4e1462fd5a34d8..cd4dde58f17e42d9bf75433850dfa39bf2498fbf 100644
--- a/routingtable/adjRIBIn/adj_rib_in.go
+++ b/routingtable/adjRIBIn/adj_rib_in.go
@@ -6,6 +6,7 @@ import (
 	"github.com/bio-routing/bio-rd/net"
 	"github.com/bio-routing/bio-rd/route"
 	"github.com/bio-routing/bio-rd/routingtable"
+	log "github.com/sirupsen/logrus"
 )
 
 // AdjRIBIn represents an Adjacency RIB In as described in RFC4271
@@ -33,7 +34,11 @@ func (a *AdjRIBIn) UpdateNewClient(client routingtable.RouteTableClient) error {
 	for _, route := range routes {
 		paths := route.Paths()
 		for _, path := range paths {
-			client.AddPath(route.Prefix(), path)
+
+			err := client.AddPath(route.Prefix(), path)
+			if err != nil {
+				log.WithField("Sender", "AdjRIBOutAddPath").WithError(err).Error("Could not send update to client")
+			}
 		}
 	}
 	return nil
diff --git a/routingtable/adjRIBIn/adj_rib_in_test.go b/routingtable/adjRIBIn/adj_rib_in_test.go
index 5659ab805f73b3bf888a08fa8ff6a7dbe8185bdf..a994e0f5e82be4ccef141ce63463b762d055d111 100644
--- a/routingtable/adjRIBIn/adj_rib_in_test.go
+++ b/routingtable/adjRIBIn/adj_rib_in_test.go
@@ -34,6 +34,10 @@ func (m *RTMockClient) Register(routingtable.RouteTableClient) {
 	return
 }
 
+func (m *RTMockClient) RegisterWithOptions(routingtable.RouteTableClient, routingtable.ClientOptions) {
+	return
+}
+
 func (m *RTMockClient) Unregister(routingtable.RouteTableClient) {
 	return
 }
diff --git a/routingtable/adjRIBOut/adj_rib_out.go b/routingtable/adjRIBOut/adj_rib_out.go
index 1ddd93c6e05b835c9952b6e86ba5fe57545ed5e4..51347119a6b360fd2f81283edc18d9225548fdf2 100644
--- a/routingtable/adjRIBOut/adj_rib_out.go
+++ b/routingtable/adjRIBOut/adj_rib_out.go
@@ -7,6 +7,7 @@ import (
 	"github.com/bio-routing/bio-rd/net"
 	"github.com/bio-routing/bio-rd/route"
 	"github.com/bio-routing/bio-rd/routingtable"
+	log "github.com/sirupsen/logrus"
 )
 
 // AdjRIBOut represents an Adjacency RIB In as described in RFC4271
@@ -45,7 +46,10 @@ func (a *AdjRIBOut) AddPath(pfx net.Prefix, p *route.Path) error {
 	a.removePathsFromClients(pfx, oldPaths)
 
 	for _, client := range a.ClientManager.Clients() {
-		client.AddPath(pfx, p)
+		err := client.AddPath(pfx, p)
+		if err != nil {
+			log.WithField("Sender", "AdjRIBOut").WithError(err).Error("Could not send update to client")
+		}
 	}
 	return nil
 }
diff --git a/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go b/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go
index 2b4dff95575b2df72036642f40bd69cfedb4e5ab..90f76fcc873643a6d94086b0b84f5bf940b6fa9f 100644
--- a/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go
+++ b/routingtable/adjRIBOutAddPath/adj_rib_out_add_path.go
@@ -7,6 +7,7 @@ import (
 	"github.com/bio-routing/bio-rd/net"
 	"github.com/bio-routing/bio-rd/route"
 	"github.com/bio-routing/bio-rd/routingtable"
+	log "github.com/sirupsen/logrus"
 )
 
 // AdjRIBOutAddPath represents an Adjacency RIB Out with BGP add path
@@ -52,7 +53,10 @@ func (a *AdjRIBOutAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
 	a.rt.AddPath(pfx, p)
 
 	for _, client := range a.ClientManager.Clients() {
-		client.AddPath(pfx, p)
+		err := client.AddPath(pfx, p)
+		if err != nil {
+			log.WithField("Sender", "AdjRIBOutAddPath").WithError(err).Error("Could not send update to client")
+		}
 	}
 	return nil
 }
diff --git a/routingtable/client_interface.go b/routingtable/client_interface.go
index 0800ceec8db1cb3b758b74b3a1d3c8b7aef62acb..e7190c5b6c0bb1829f59cf5faadd0623ef3b395c 100644
--- a/routingtable/client_interface.go
+++ b/routingtable/client_interface.go
@@ -11,5 +11,6 @@ type RouteTableClient interface {
 	RemovePath(net.Prefix, *route.Path) bool
 	UpdateNewClient(RouteTableClient) error
 	Register(RouteTableClient)
+	RegisterWithOptions(RouteTableClient, ClientOptions)
 	Unregister(RouteTableClient)
 }
diff --git a/routingtable/client_manager.go b/routingtable/client_manager.go
index 20d848b2c090a4c311cb4a81fc8c1c4697cf5891..f29ae2dce47dc7e4a3d3ba725ff5d57fd27f74f6 100644
--- a/routingtable/client_manager.go
+++ b/routingtable/client_manager.go
@@ -55,9 +55,8 @@ func (c *ClientManager) Register(client RouteTableClient) {
 // RegisterWithOptions registers a client with options for updates
 func (c *ClientManager) RegisterWithOptions(client RouteTableClient, opt ClientOptions) {
 	c.mu.Lock()
-	defer c.mu.Unlock()
-
 	c.clients[client] = opt
+	c.mu.Unlock()
 	c.master.UpdateNewClient(client)
 }
 
diff --git a/routingtable/client_manager_test.go b/routingtable/client_manager_test.go
index af2507855bfac8a5d09551b105d7bfc4ae93dd79..78e2e58c4030a2e25a1b9ae228ef712fc1c67550 100644
--- a/routingtable/client_manager_test.go
+++ b/routingtable/client_manager_test.go
@@ -25,6 +25,11 @@ func (m MockClient) UpdateNewClient(RouteTableClient) error {
 func (m MockClient) Register(RouteTableClient) {
 	return
 }
+
+func (m MockClient) RegisterWithOptions(RouteTableClient, ClientOptions) {
+	return
+}
+
 func (m MockClient) Unregister(RouteTableClient) {
 	return
 }
diff --git a/routingtable/filter/term_condition.go b/routingtable/filter/term_condition.go
index 92c3616a8cc55f21c73696b2f87a1b2a9cfbcbd4..8bc87485d58bd9215d122e4af9792c7c0c1c2b82 100644
--- a/routingtable/filter/term_condition.go
+++ b/routingtable/filter/term_condition.go
@@ -10,6 +10,13 @@ type TermCondition struct {
 	routeFilters []*RouteFilter
 }
 
+func NewTermCondition(prefixLists []*PrefixList, routeFilters []*RouteFilter) *TermCondition {
+	return &TermCondition{
+		prefixLists:  prefixLists,
+		routeFilters: routeFilters,
+	}
+}
+
 func (f *TermCondition) Matches(p net.Prefix, pa *route.Path) bool {
 	return f.matchesAnyPrefixList(p) || f.machtchesAnyRouteFilter(p)
 }
diff --git a/routingtable/filter/term_condition_test.go b/routingtable/filter/term_condition_test.go
index 876746a240d195ee2a6612636a888a2cf41a9d25..fba97b673bea6901983e6bba509358fe8bf504f3 100644
--- a/routingtable/filter/term_condition_test.go
+++ b/routingtable/filter/term_condition_test.go
@@ -109,10 +109,10 @@ func TestMatches(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(te *testing.T) {
-			f := &TermCondition{
-				prefixLists:  test.prefixLists,
-				routeFilters: test.routeFilters,
-			}
+			f := NewTermCondition(
+				test.prefixLists,
+				test.routeFilters,
+			)
 
 			assert.Equal(te, test.expected, f.Matches(test.prefix, &route.Path{}))
 		})
diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go
index a1701743b1b5d946f958f47e1b163285427a57b0..ff5750c34d226080bea079968becdec410d2704e 100644
--- a/routingtable/locRIB/loc_rib.go
+++ b/routingtable/locRIB/loc_rib.go
@@ -8,6 +8,7 @@ import (
 	"github.com/bio-routing/bio-rd/net"
 	"github.com/bio-routing/bio-rd/route"
 	"github.com/bio-routing/bio-rd/routingtable"
+	"github.com/sirupsen/logrus"
 )
 
 // LocRIB represents a routing information base
@@ -44,6 +45,10 @@ func (a *LocRIB) AddPath(pfx net.Prefix, p *route.Path) error {
 	a.mu.Lock()
 	defer a.mu.Unlock()
 
+	logrus.WithFields(map[string]interface{}{
+		"Prefix": pfx,
+		"Route":  p,
+	}).Debug("AddPath to locRIB")
 	routeExisted := false
 	oldRoute := &route.Route{}
 	r := a.rt.Get(pfx)
@@ -70,6 +75,10 @@ func (a *LocRIB) RemovePath(pfx net.Prefix, p *route.Path) bool {
 	a.mu.Lock()
 	defer a.mu.Unlock()
 
+	logrus.WithFields(map[string]interface{}{
+		"Prefix": pfx,
+		"Route":  p,
+	}).Debug("Remove from locRIB")
 	var oldRoute *route.Route
 	r := a.rt.Get(pfx)
 	if r != nil {