diff --git a/cmd/ris/api/ris.pb.go b/cmd/ris/api/ris.pb.go
index df70cf5def5bf2378b2815e613f14a06f74a743b..8ce66b56780977b243b0aafa2c2234a5b25932cc 100644
--- a/cmd/ris/api/ris.pb.go
+++ b/cmd/ris/api/ris.pb.go
@@ -10,8 +10,6 @@ import (
 	api1 "github.com/bio-routing/bio-rd/route/api"
 	proto "github.com/golang/protobuf/proto"
 	grpc "google.golang.org/grpc"
-	codes "google.golang.org/grpc/codes"
-	status "google.golang.org/grpc/status"
 	math "math"
 )
 
@@ -79,6 +77,7 @@ func (DumpRIBRequest_AFISAFI) EnumDescriptor() ([]byte, []int) {
 type LPMRequest struct {
 	Router               string      `protobuf:"bytes,1,opt,name=router,proto3" json:"router,omitempty"`
 	VrfId                uint64      `protobuf:"varint,2,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"`
+	Vrf                  string      `protobuf:"bytes,4,opt,name=vrf,proto3" json:"vrf,omitempty"`
 	Pfx                  *api.Prefix `protobuf:"bytes,3,opt,name=pfx,proto3" json:"pfx,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
 	XXX_unrecognized     []byte      `json:"-"`
@@ -124,6 +123,13 @@ func (m *LPMRequest) GetVrfId() uint64 {
 	return 0
 }
 
+func (m *LPMRequest) GetVrf() string {
+	if m != nil {
+		return m.Vrf
+	}
+	return ""
+}
+
 func (m *LPMRequest) GetPfx() *api.Prefix {
 	if m != nil {
 		return m.Pfx
@@ -173,6 +179,7 @@ func (m *LPMResponse) GetRoutes() []*api1.Route {
 type GetRequest struct {
 	Router               string      `protobuf:"bytes,1,opt,name=router,proto3" json:"router,omitempty"`
 	VrfId                uint64      `protobuf:"varint,2,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"`
+	Vrf                  string      `protobuf:"bytes,4,opt,name=vrf,proto3" json:"vrf,omitempty"`
 	Pfx                  *api.Prefix `protobuf:"bytes,3,opt,name=pfx,proto3" json:"pfx,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
 	XXX_unrecognized     []byte      `json:"-"`
@@ -218,6 +225,13 @@ func (m *GetRequest) GetVrfId() uint64 {
 	return 0
 }
 
+func (m *GetRequest) GetVrf() string {
+	if m != nil {
+		return m.Vrf
+	}
+	return ""
+}
+
 func (m *GetRequest) GetPfx() *api.Prefix {
 	if m != nil {
 		return m.Pfx
@@ -267,6 +281,7 @@ func (m *GetResponse) GetRoutes() []*api1.Route {
 type GetLongerRequest struct {
 	Router               string      `protobuf:"bytes,1,opt,name=router,proto3" json:"router,omitempty"`
 	VrfId                uint64      `protobuf:"varint,2,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"`
+	Vrf                  string      `protobuf:"bytes,4,opt,name=vrf,proto3" json:"vrf,omitempty"`
 	Pfx                  *api.Prefix `protobuf:"bytes,3,opt,name=pfx,proto3" json:"pfx,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
 	XXX_unrecognized     []byte      `json:"-"`
@@ -312,6 +327,13 @@ func (m *GetLongerRequest) GetVrfId() uint64 {
 	return 0
 }
 
+func (m *GetLongerRequest) GetVrf() string {
+	if m != nil {
+		return m.Vrf
+	}
+	return ""
+}
+
 func (m *GetLongerRequest) GetPfx() *api.Prefix {
 	if m != nil {
 		return m.Pfx
@@ -361,6 +383,7 @@ func (m *GetLongerResponse) GetRoutes() []*api1.Route {
 type ObserveRIBRequest struct {
 	Router               string                    `protobuf:"bytes,1,opt,name=router,proto3" json:"router,omitempty"`
 	VrfId                uint64                    `protobuf:"varint,2,opt,name=vrf_id,json=vrfId,proto3" json:"vrf_id,omitempty"`
+	Vrf                  string                    `protobuf:"bytes,4,opt,name=vrf,proto3" json:"vrf,omitempty"`
 	Afisafi              ObserveRIBRequest_AFISAFI `protobuf:"varint,3,opt,name=afisafi,proto3,enum=bio.ris.ObserveRIBRequest_AFISAFI" json:"afisafi,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
 	XXX_unrecognized     []byte                    `json:"-"`
@@ -406,6 +429,13 @@ func (m *ObserveRIBRequest) GetVrfId() uint64 {
 	return 0
 }
 
+func (m *ObserveRIBRequest) GetVrf() string {
+	if m != nil {
+		return m.Vrf
+	}
+	return ""
+}
+
 func (m *ObserveRIBRequest) GetAfisafi() ObserveRIBRequest_AFISAFI {
 	if m != nil {
 		return m.Afisafi
@@ -415,6 +445,7 @@ func (m *ObserveRIBRequest) GetAfisafi() ObserveRIBRequest_AFISAFI {
 
 type RIBUpdate struct {
 	Advertisement        bool        `protobuf:"varint,1,opt,name=advertisement,proto3" json:"advertisement,omitempty"`
+	IsInitialDump        bool        `protobuf:"varint,3,opt,name=is_initial_dump,json=isInitialDump,proto3" json:"is_initial_dump,omitempty"`
 	Route                *api1.Route `protobuf:"bytes,2,opt,name=route,proto3" json:"route,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
 	XXX_unrecognized     []byte      `json:"-"`
@@ -453,6 +484,13 @@ func (m *RIBUpdate) GetAdvertisement() bool {
 	return false
 }
 
+func (m *RIBUpdate) GetIsInitialDump() bool {
+	if m != nil {
+		return m.IsInitialDump
+	}
+	return false
+}
+
 func (m *RIBUpdate) GetRoute() *api1.Route {
 	if m != nil {
 		return m.Route
@@ -702,56 +740,58 @@ func init() {
 }
 
 var fileDescriptor_ffe1202aa518913f = []byte{
-	// 633 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xdb, 0x4e, 0xdb, 0x4c,
-	0x10, 0xc6, 0x04, 0x62, 0x32, 0xf9, 0x7f, 0x0e, 0x4b, 0x29, 0xc1, 0xbd, 0x68, 0x6a, 0x55, 0x95,
-	0x11, 0xaa, 0x83, 0x42, 0x45, 0x55, 0xf5, 0x24, 0x10, 0x22, 0xb2, 0x04, 0x6d, 0xb4, 0x88, 0x4a,
-	0xed, 0x45, 0x91, 0x13, 0xaf, 0xe9, 0x4a, 0xf8, 0xd0, 0xdd, 0x8d, 0x45, 0x9e, 0xa2, 0x8f, 0xd1,
-	0xab, 0xbe, 0x63, 0xe5, 0x5d, 0xdb, 0xb1, 0x4b, 0x4a, 0x0b, 0x15, 0x37, 0x89, 0x77, 0x66, 0xbf,
-	0x99, 0x6f, 0x3e, 0xcd, 0xcc, 0xc2, 0xce, 0x39, 0x15, 0x5f, 0x46, 0x03, 0x7b, 0x18, 0x05, 0x9d,
-	0x01, 0x8d, 0x9e, 0xb2, 0x68, 0x24, 0x68, 0x78, 0xae, 0xbe, 0xbd, 0xce, 0x30, 0xf0, 0x3a, 0x8c,
-	0xf2, 0x8e, 0x1b, 0xd3, 0xf4, 0xdf, 0x8e, 0x59, 0x24, 0x22, 0xa4, 0x0f, 0x68, 0x64, 0x33, 0xca,
-	0x8d, 0xce, 0xf5, 0xe8, 0x90, 0x08, 0x89, 0x0c, 0x89, 0x50, 0x48, 0xe3, 0x0f, 0xe9, 0xd2, 0x23,
-	0x51, 0xc9, 0xd2, 0x2f, 0x05, 0x32, 0x3f, 0x03, 0x1c, 0xf5, 0x8f, 0x31, 0xf9, 0x3a, 0x22, 0x5c,
-	0xa0, 0xfb, 0x50, 0x97, 0x4e, 0xd6, 0xd2, 0xda, 0x9a, 0xd5, 0xc0, 0xd9, 0x09, 0xad, 0x41, 0x3d,
-	0x61, 0xfe, 0x19, 0xf5, 0x5a, 0xb3, 0x6d, 0xcd, 0x9a, 0xc3, 0xf3, 0x09, 0xf3, 0x1d, 0x0f, 0x3d,
-	0x82, 0x5a, 0xec, 0x5f, 0xb6, 0x6a, 0x6d, 0xcd, 0x6a, 0x76, 0x97, 0xec, 0x94, 0x79, 0x4a, 0xa7,
-	0xcf, 0x88, 0x4f, 0x2f, 0x71, 0xea, 0x33, 0x9f, 0x43, 0x53, 0xc6, 0xe7, 0x71, 0x14, 0x72, 0x82,
-	0xac, 0x2c, 0x01, 0x6f, 0x69, 0xed, 0x9a, 0xd5, 0xec, 0x2e, 0x4b, 0x90, 0x22, 0x84, 0xd3, 0xdf,
-	0x2c, 0x25, 0x4f, 0x89, 0xf5, 0x88, 0xb8, 0x53, 0x62, 0x32, 0xfe, 0x8d, 0x89, 0x79, 0xb0, 0xdc,
-	0x23, 0xe2, 0x28, 0x0a, 0xcf, 0x09, 0xbb, 0x3b, 0x7a, 0xaf, 0x61, 0xa5, 0x94, 0xe5, 0xc6, 0x24,
-	0x7f, 0x68, 0xb0, 0xf2, 0x7e, 0xc0, 0x09, 0x4b, 0x08, 0x76, 0xf6, 0x6f, 0x49, 0xf3, 0x15, 0xe8,
-	0xae, 0x4f, 0xb9, 0xeb, 0x53, 0x49, 0x75, 0xb1, 0x6b, 0xda, 0x59, 0x73, 0xda, 0x57, 0x62, 0xdb,
-	0x7b, 0x87, 0xce, 0xc9, 0xde, 0xa1, 0x83, 0x73, 0x88, 0xb9, 0x05, 0x7a, 0x66, 0x43, 0x4b, 0xd0,
-	0x74, 0xfa, 0xc9, 0xb3, 0xd3, 0x90, 0x0e, 0x5d, 0x2e, 0x96, 0x67, 0x32, 0xc3, 0x6e, 0x6e, 0xd0,
-	0xcc, 0x8f, 0xd0, 0xc0, 0xce, 0xfe, 0x69, 0xec, 0xb9, 0x82, 0xa0, 0xc7, 0xf0, 0xbf, 0xeb, 0x25,
-	0x84, 0x09, 0xca, 0x49, 0x40, 0x42, 0x21, 0xd9, 0x2e, 0xe0, 0xaa, 0x11, 0x3d, 0x81, 0x79, 0x49,
-	0x5f, 0x72, 0x9e, 0xa6, 0x85, 0x72, 0x9b, 0xdf, 0x35, 0x58, 0x3c, 0x18, 0x05, 0xf1, 0xed, 0x75,
-	0x78, 0xf1, 0xab, 0x0e, 0x0f, 0x0b, 0x1d, 0xaa, 0x81, 0xff, 0x51, 0x84, 0x5d, 0xf8, 0xaf, 0x88,
-	0x17, 0x5f, 0x8c, 0x27, 0x15, 0x6a, 0xd7, 0x57, 0xb8, 0x2a, 0x7b, 0x45, 0x9a, 0x18, 0xcf, 0xa8,
-	0x98, 0x1f, 0xa0, 0xae, 0x2c, 0x68, 0x03, 0x16, 0xf8, 0x98, 0x9f, 0x85, 0x6e, 0x40, 0xb2, 0x7a,
-	0x75, 0x3e, 0xe6, 0xef, 0xdc, 0x80, 0xa0, 0x75, 0xd0, 0x55, 0xc1, 0xbc, 0x35, 0xdb, 0xae, 0x59,
-	0x73, 0xb8, 0x2e, 0x2b, 0xe6, 0xa8, 0x05, 0xba, 0xeb, 0x79, 0x8c, 0x70, 0x2e, 0x4b, 0x6e, 0xe0,
-	0xfc, 0x68, 0xbe, 0x05, 0x54, 0x4e, 0x96, 0x75, 0xe6, 0x26, 0xe8, 0x4a, 0xc3, 0xbc, 0x35, 0x97,
-	0x0a, 0x89, 0xd4, 0x55, 0x9c, 0xfb, 0xbb, 0xdf, 0x6a, 0xb0, 0x81, 0xd5, 0x6a, 0x72, 0x42, 0x3f,
-	0x62, 0x81, 0x2b, 0x68, 0x14, 0x9e, 0x10, 0x96, 0xd0, 0x21, 0x41, 0x5d, 0xa8, 0x1d, 0xf5, 0x8f,
-	0xd1, 0x6a, 0x01, 0x9f, 0x6c, 0x27, 0xe3, 0x5e, 0xd5, 0xa8, 0x52, 0x9b, 0x33, 0x29, 0xa6, 0x47,
-	0x44, 0x09, 0x33, 0x59, 0x1c, 0x25, 0x4c, 0x69, 0xda, 0xcd, 0x19, 0xd4, 0x53, 0xeb, 0x45, 0x71,
-	0x42, 0x46, 0xe5, 0x56, 0x45, 0x48, 0xe3, 0xc1, 0x54, 0x5f, 0x11, 0xe8, 0x00, 0x1a, 0xc5, 0xa0,
-	0xa2, 0x8d, 0xf2, 0xdd, 0xca, 0x8a, 0x30, 0x8c, 0x69, 0xae, 0x22, 0xca, 0x1b, 0x80, 0xc9, 0x48,
-	0x95, 0xe8, 0x5c, 0x99, 0x33, 0x03, 0x4d, 0x84, 0xcd, 0x07, 0x66, 0x5b, 0x43, 0x2f, 0x41, 0xcf,
-	0x5a, 0x07, 0xad, 0xff, 0xa6, 0x39, 0x8d, 0xb5, 0xab, 0x8e, 0xf8, 0x62, 0xbc, 0xad, 0xed, 0x6f,
-	0x7d, 0xda, 0xfc, 0xeb, 0x97, 0x6a, 0x50, 0x97, 0xef, 0xc6, 0xce, 0xcf, 0x00, 0x00, 0x00, 0xff,
-	0xff, 0x61, 0xf9, 0x2b, 0x4e, 0xdd, 0x06, 0x00, 0x00,
+	// 670 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x5d, 0x4f, 0xdb, 0x3c,
+	0x14, 0x26, 0x04, 0x1a, 0x7a, 0xfa, 0x42, 0x8b, 0x79, 0x79, 0x09, 0x79, 0x2f, 0xd6, 0x45, 0x13,
+	0x2a, 0x42, 0x4b, 0x51, 0x99, 0x98, 0xa6, 0x7d, 0x09, 0x84, 0xa8, 0x22, 0xc1, 0x56, 0x19, 0xb1,
+	0x8b, 0xdd, 0x54, 0x69, 0xe3, 0x30, 0x4b, 0xe4, 0x63, 0xb6, 0x1b, 0xd1, 0xcb, 0xfd, 0x82, 0xfd,
+	0x8c, 0xfd, 0x8c, 0xfd, 0xb5, 0x29, 0x76, 0x9a, 0xa6, 0x83, 0xb1, 0xb1, 0x4d, 0xdc, 0xb4, 0xf6,
+	0x39, 0x7e, 0x7c, 0x9e, 0xe7, 0xd1, 0xf1, 0x09, 0xec, 0x5d, 0x50, 0xf1, 0x61, 0x34, 0x70, 0x86,
+	0x71, 0xd8, 0x1e, 0xd0, 0xf8, 0x31, 0x8b, 0x47, 0x82, 0x46, 0x17, 0x6a, 0xed, 0xb7, 0x87, 0xa1,
+	0xdf, 0x66, 0x94, 0xb7, 0xbd, 0x84, 0x66, 0xff, 0x4e, 0xc2, 0x62, 0x11, 0x23, 0x63, 0x40, 0x63,
+	0x87, 0x51, 0x6e, 0xb5, 0x6f, 0x47, 0x47, 0x44, 0x48, 0x64, 0x44, 0x84, 0x42, 0x5a, 0x3f, 0x29,
+	0x97, 0x6d, 0x89, 0x2a, 0x96, 0xad, 0x14, 0xc8, 0x4e, 0x00, 0x4e, 0x7a, 0xa7, 0x98, 0x7c, 0x1c,
+	0x11, 0x2e, 0xd0, 0x7f, 0x50, 0x91, 0x49, 0x66, 0x6a, 0x4d, 0xad, 0x55, 0xc5, 0xf9, 0x0e, 0xad,
+	0x43, 0x25, 0x65, 0x41, 0x9f, 0xfa, 0xe6, 0x7c, 0x53, 0x6b, 0x2d, 0xe0, 0xc5, 0x94, 0x05, 0xae,
+	0x8f, 0x1a, 0xa0, 0xa7, 0x2c, 0x30, 0x17, 0xe4, 0xd9, 0x6c, 0x89, 0x1e, 0x82, 0x9e, 0x04, 0x57,
+	0xa6, 0xde, 0xd4, 0x5a, 0xb5, 0x4e, 0xdd, 0xc9, 0xb4, 0x64, 0x04, 0x7b, 0x8c, 0x04, 0xf4, 0x0a,
+	0x67, 0x39, 0xfb, 0x29, 0xd4, 0x64, 0x45, 0x9e, 0xc4, 0x11, 0x27, 0xa8, 0x95, 0x97, 0xe4, 0xa6,
+	0xd6, 0xd4, 0x5b, 0xb5, 0x4e, 0x43, 0x82, 0x14, 0x45, 0x9c, 0xfd, 0xe6, 0x24, 0x78, 0x46, 0xb5,
+	0x4b, 0xc4, 0x3d, 0x53, 0x95, 0x15, 0xef, 0x4c, 0x35, 0x85, 0x46, 0x97, 0x88, 0x93, 0x38, 0xba,
+	0x20, 0xec, 0x3e, 0x09, 0xbf, 0x84, 0xd5, 0x52, 0xdd, 0x3b, 0xd3, 0xfe, 0xaa, 0xc1, 0xea, 0xdb,
+	0x01, 0x27, 0x2c, 0x25, 0xd8, 0x3d, 0xfc, 0x6b, 0xc4, 0x5f, 0x80, 0xe1, 0x05, 0x94, 0x7b, 0x01,
+	0x95, 0xe4, 0x57, 0x3a, 0xb6, 0x93, 0x37, 0xb9, 0x73, 0xad, 0x9a, 0x73, 0x70, 0xec, 0x9e, 0x1d,
+	0x1c, 0xbb, 0x78, 0x02, 0xb1, 0x77, 0xc0, 0xc8, 0x63, 0xa8, 0x0e, 0x35, 0xb7, 0x97, 0x3e, 0x39,
+	0x8f, 0xe8, 0xd0, 0xe3, 0xa2, 0x31, 0x97, 0x07, 0xf6, 0x27, 0x01, 0xcd, 0xfe, 0xa4, 0x41, 0x15,
+	0xbb, 0x87, 0xe7, 0x89, 0xef, 0x09, 0x82, 0x1e, 0xc1, 0xb2, 0xe7, 0xa7, 0x84, 0x09, 0xca, 0x49,
+	0x48, 0x22, 0x21, 0x05, 0x2c, 0xe1, 0xd9, 0x20, 0xda, 0x82, 0x3a, 0xe5, 0x7d, 0x1a, 0x51, 0x41,
+	0xbd, 0xcb, 0xbe, 0x3f, 0x0a, 0x13, 0x49, 0x73, 0x09, 0x2f, 0x53, 0xee, 0xaa, 0xe8, 0xd1, 0x28,
+	0x4c, 0xd0, 0x16, 0x2c, 0x4a, 0xe5, 0x52, 0xee, 0x4d, 0x36, 0xaa, 0xb4, 0xfd, 0x45, 0x83, 0x95,
+	0x0c, 0xf0, 0xfb, 0x16, 0x3e, 0xfb, 0xde, 0xb0, 0x07, 0x85, 0x61, 0xb3, 0x17, 0xff, 0xa1, 0x5b,
+	0xfb, 0xf0, 0x4f, 0x71, 0x5f, 0x72, 0x39, 0x9e, 0x2a, 0xd4, 0x6e, 0x57, 0xb8, 0x26, 0xdb, 0x4c,
+	0x86, 0x18, 0xcf, 0xa9, 0xd8, 0xef, 0xa0, 0xa2, 0x22, 0x68, 0x13, 0x96, 0xf8, 0x98, 0xf7, 0x23,
+	0x2f, 0x24, 0xb9, 0x5e, 0x83, 0x8f, 0xf9, 0x1b, 0x2f, 0x24, 0x68, 0x03, 0x0c, 0x25, 0x98, 0x9b,
+	0xf3, 0x4d, 0xbd, 0xb5, 0x80, 0x2b, 0x52, 0x31, 0x47, 0x26, 0x18, 0x9e, 0xef, 0x33, 0xc2, 0xb9,
+	0x94, 0x5c, 0xc5, 0x93, 0xad, 0xfd, 0x1a, 0x50, 0xb9, 0x58, 0xde, 0xd4, 0xdb, 0x60, 0x28, 0x0f,
+	0x27, 0x5d, 0x5d, 0x2f, 0x2c, 0x52, 0x47, 0xf1, 0x24, 0xdf, 0xf9, 0xac, 0xc3, 0x26, 0x56, 0xb3,
+	0xd0, 0x8d, 0x82, 0x98, 0x85, 0x9e, 0xa0, 0x71, 0x74, 0x46, 0x58, 0x4a, 0x87, 0x04, 0x75, 0x40,
+	0x3f, 0xe9, 0x9d, 0xa2, 0xb5, 0x02, 0x3e, 0x1d, 0x87, 0xd6, 0xbf, 0xb3, 0x41, 0x55, 0xda, 0x9e,
+	0xcb, 0x30, 0x5d, 0x22, 0x4a, 0x98, 0xe9, 0x5c, 0x2a, 0x61, 0x4a, 0xa3, 0xc3, 0x9e, 0x43, 0x5d,
+	0x35, 0xbd, 0x14, 0x27, 0x64, 0xcd, 0x9c, 0x9a, 0x31, 0xd2, 0xfa, 0xff, 0xc6, 0x5c, 0x71, 0xd1,
+	0x11, 0x54, 0x8b, 0x37, 0x8e, 0x36, 0xcb, 0x67, 0x67, 0xe6, 0x8d, 0x65, 0xdd, 0x94, 0x2a, 0x6e,
+	0x79, 0x05, 0x30, 0x7d, 0x7b, 0x25, 0x3a, 0xd7, 0x1e, 0xa4, 0x85, 0xa6, 0xc6, 0x4e, 0x1e, 0xd6,
+	0xae, 0x86, 0x9e, 0x83, 0x91, 0xb7, 0x0e, 0xda, 0xf8, 0x41, 0x73, 0x5a, 0xeb, 0xd7, 0x13, 0xc9,
+	0xe5, 0x78, 0x57, 0x3b, 0xdc, 0x79, 0xbf, 0xfd, 0xcb, 0x9f, 0xc6, 0x41, 0x45, 0x7e, 0xa8, 0xf6,
+	0xbe, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc5, 0xf1, 0x19, 0x78, 0x4e, 0x07, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ context.Context
-var _ grpc.ClientConnInterface
+var _ grpc.ClientConn
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion6
+const _ = grpc.SupportPackageIsVersion4
 
 // RoutingInformationServiceClient is the client API for RoutingInformationService service.
 //
@@ -766,10 +806,10 @@ type RoutingInformationServiceClient interface {
 }
 
 type routingInformationServiceClient struct {
-	cc grpc.ClientConnInterface
+	cc *grpc.ClientConn
 }
 
-func NewRoutingInformationServiceClient(cc grpc.ClientConnInterface) RoutingInformationServiceClient {
+func NewRoutingInformationServiceClient(cc *grpc.ClientConn) RoutingInformationServiceClient {
 	return &routingInformationServiceClient{cc}
 }
 
@@ -883,29 +923,6 @@ type RoutingInformationServiceServer interface {
 	DumpRIB(*DumpRIBRequest, RoutingInformationService_DumpRIBServer) error
 }
 
-// UnimplementedRoutingInformationServiceServer can be embedded to have forward compatible implementations.
-type UnimplementedRoutingInformationServiceServer struct {
-}
-
-func (*UnimplementedRoutingInformationServiceServer) LPM(ctx context.Context, req *LPMRequest) (*LPMResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method LPM not implemented")
-}
-func (*UnimplementedRoutingInformationServiceServer) Get(ctx context.Context, req *GetRequest) (*GetResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
-}
-func (*UnimplementedRoutingInformationServiceServer) GetRouters(ctx context.Context, req *GetRoutersRequest) (*GetRoutersResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetRouters not implemented")
-}
-func (*UnimplementedRoutingInformationServiceServer) GetLonger(ctx context.Context, req *GetLongerRequest) (*GetLongerResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetLonger not implemented")
-}
-func (*UnimplementedRoutingInformationServiceServer) ObserveRIB(req *ObserveRIBRequest, srv RoutingInformationService_ObserveRIBServer) error {
-	return status.Errorf(codes.Unimplemented, "method ObserveRIB not implemented")
-}
-func (*UnimplementedRoutingInformationServiceServer) DumpRIB(req *DumpRIBRequest, srv RoutingInformationService_DumpRIBServer) error {
-	return status.Errorf(codes.Unimplemented, "method DumpRIB not implemented")
-}
-
 func RegisterRoutingInformationServiceServer(s *grpc.Server, srv RoutingInformationServiceServer) {
 	s.RegisterService(&_RoutingInformationService_serviceDesc, srv)
 }
diff --git a/cmd/ris/api/ris.proto b/cmd/ris/api/ris.proto
index 92b767f89da8c148d6a1601392bd72ef14be689e..678a9fb4d9c28326218bf1cb8d7f77ef63dc8f87 100644
--- a/cmd/ris/api/ris.proto
+++ b/cmd/ris/api/ris.proto
@@ -18,6 +18,7 @@ service RoutingInformationService {
 message LPMRequest {
     string router = 1;
     uint64 vrf_id = 2;
+    string vrf = 4;
     bio.net.Prefix pfx = 3;
 }
 
@@ -28,6 +29,7 @@ message LPMResponse {
 message GetRequest {
     string router = 1;
     uint64 vrf_id = 2;
+    string vrf = 4;
     bio.net.Prefix pfx = 3;
 }
 
@@ -38,6 +40,7 @@ message GetResponse {
 message GetLongerRequest {
     string router = 1;
     uint64 vrf_id = 2;
+    string vrf = 4;
     bio.net.Prefix pfx = 3;
 }
 
@@ -48,6 +51,7 @@ message GetLongerResponse {
 message ObserveRIBRequest {
     string router = 1;
     uint64 vrf_id = 2;
+    string vrf = 4;
     enum AFISAFI {
         IPv4Unicast = 0;
         IPv6Unicast = 1;
@@ -57,6 +61,7 @@ message ObserveRIBRequest {
 
 message RIBUpdate {
     bool advertisement = 1;
+    bool is_initial_dump = 3;
     bio.route.Route route = 2;
 }
 
diff --git a/cmd/ris/risserver/server.go b/cmd/ris/risserver/server.go
index 5e9c11936066e8134db86ebcceb6d026862e9054..f9cf5e3e24cbef912ce5fd77b4537046938e071e 100644
--- a/cmd/ris/risserver/server.go
+++ b/cmd/ris/risserver/server.go
@@ -8,7 +8,6 @@ import (
 	"github.com/bio-routing/bio-rd/protocols/bgp/server"
 	"github.com/bio-routing/bio-rd/route"
 	"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/bio-routing/bio-rd/routingtable/vrf"
 	"github.com/pkg/errors"
@@ -89,9 +88,14 @@ func (s Server) getRIB(rtr string, vrfID uint64, ipVersion netapi.IP_Version) (*
 
 // LPM provides a longest prefix match service
 func (s *Server) LPM(ctx context.Context, req *pb.LPMRequest) (*pb.LPMResponse, error) {
-	rib, err := s.getRIB(req.Router, req.VrfId, req.Pfx.Address.Version)
+	vrfID, err := getVRFID(req)
 	if err != nil {
-		return nil, wrapGetRIBErr(err, req.Router, req.VrfId, req.Pfx.Address.Version)
+		return nil, err
+	}
+
+	rib, err := s.getRIB(req.Router, vrfID, req.Pfx.Address.Version)
+	if err != nil {
+		return nil, wrapGetRIBErr(err, req.Router, vrfID, req.Pfx.Address.Version)
 	}
 
 	routes := rib.LPM(bnet.NewPrefixFromProtoPrefix(req.Pfx))
@@ -107,9 +111,14 @@ func (s *Server) LPM(ctx context.Context, req *pb.LPMRequest) (*pb.LPMResponse,
 
 // Get gets a prefix (exact match)
 func (s *Server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) {
-	rib, err := s.getRIB(req.Router, req.VrfId, req.Pfx.Address.Version)
+	vrfID, err := getVRFID(req)
+	if err != nil {
+		return nil, err
+	}
+
+	rib, err := s.getRIB(req.Router, vrfID, req.Pfx.Address.Version)
 	if err != nil {
-		return nil, wrapGetRIBErr(err, req.Router, req.VrfId, req.Pfx.Address.Version)
+		return nil, wrapGetRIBErr(err, req.Router, vrfID, req.Pfx.Address.Version)
 	}
 
 	route := rib.Get(bnet.NewPrefixFromProtoPrefix(req.Pfx))
@@ -128,9 +137,14 @@ func (s *Server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse,
 
 // GetLonger gets all more specifics of a prefix
 func (s *Server) GetLonger(ctx context.Context, req *pb.GetLongerRequest) (*pb.GetLongerResponse, error) {
-	rib, err := s.getRIB(req.Router, req.VrfId, req.Pfx.Address.Version)
+	vrfID, err := getVRFID(req)
 	if err != nil {
-		return nil, wrapGetRIBErr(err, req.Router, req.VrfId, req.Pfx.Address.Version)
+		return nil, err
+	}
+
+	rib, err := s.getRIB(req.Router, vrfID, req.Pfx.Address.Version)
+	if err != nil {
+		return nil, wrapGetRIBErr(err, req.Router, vrfID, req.Pfx.Address.Version)
 	}
 
 	routes := rib.GetLonger(bnet.NewPrefixFromProtoPrefix(req.Pfx))
@@ -146,6 +160,11 @@ func (s *Server) GetLonger(ctx context.Context, req *pb.GetLongerRequest) (*pb.G
 
 // ObserveRIB implements the ObserveRIB RPC
 func (s *Server) ObserveRIB(req *pb.ObserveRIBRequest, stream pb.RoutingInformationService_ObserveRIBServer) error {
+	vrfID, err := getVRFID(req)
+	if err != nil {
+		return err
+	}
+
 	ipVersion := netapi.IP_IPv4
 	switch req.Afisafi {
 	case pb.ObserveRIBRequest_IPv4Unicast:
@@ -156,9 +175,9 @@ func (s *Server) ObserveRIB(req *pb.ObserveRIBRequest, stream pb.RoutingInformat
 		return fmt.Errorf("Unknown AFI/SAFI")
 	}
 
-	rib, err := s.getRIB(req.Router, req.VrfId, ipVersion)
+	rib, err := s.getRIB(req.Router, vrfID, ipVersion)
 	if err != nil {
-		return wrapGetRIBErr(err, req.Router, req.VrfId, ipVersion)
+		return wrapGetRIBErr(err, req.Router, vrfID, ipVersion)
 	}
 
 	risObserveFIBClients.WithLabelValues(req.Router, fmt.Sprintf("%d", req.VrfId), fmt.Sprintf("%d", req.Afisafi)).Inc()
@@ -251,6 +270,24 @@ func (s *Server) GetRouters(c context.Context, request *pb.GetRoutersRequest) (*
 	return resp, nil
 }
 
+type RequestWithVRF interface {
+	GetVrfId() uint64
+	GetVrf() string
+}
+
+func getVRFID(req RequestWithVRF) (uint64, error) {
+	if req.GetVrf() != "" {
+		vrfID, err := vrf.ParseHumanReadableRouteDistinguisher(req.GetVrf())
+		if err != nil {
+			return 0, errors.Wrap(err, "Unable to parse VRF")
+		}
+
+		return vrfID, nil
+	}
+
+	return req.GetVrfId(), nil
+}
+
 type update struct {
 	advertisement bool
 	prefix        net.Prefix
@@ -268,8 +305,17 @@ func newRIBClient(fifo *updateFIFO) *ribClient {
 }
 
 func (r *ribClient) AddPath(pfx *net.Prefix, path *route.Path) error {
+	return r.addPath(pfx, path, false)
+}
+
+func (r *ribClient) AddPathInitialDump(pfx *net.Prefix, path *route.Path) error {
+	return r.addPath(pfx, path, true)
+}
+
+func (r *ribClient) addPath(pfx *net.Prefix, path *route.Path, isInitalDump bool) error {
 	r.fifo.queue(&pb.RIBUpdate{
 		Advertisement: true,
+		IsInitialDump: isInitalDump,
 		Route: &routeapi.Route{
 			Pfx: pfx.ToProto(),
 			Paths: []*routeapi.Path{
@@ -295,36 +341,7 @@ func (r *ribClient) RemovePath(pfx *net.Prefix, path *route.Path) bool {
 	return false
 }
 
-func (r *ribClient) UpdateNewClient(routingtable.RouteTableClient) error {
-	return nil
-}
-
-func (r *ribClient) Register(routingtable.RouteTableClient) {
-}
-
-func (r *ribClient) RegisterWithOptions(routingtable.RouteTableClient, routingtable.ClientOptions) {
-}
-
-func (r *ribClient) Unregister(routingtable.RouteTableClient) {
-}
-
-func (r *ribClient) RouteCount() int64 {
-	return -1
-}
-
-func (r *ribClient) ClientCount() uint64 {
-	return 0
-}
-
-func (r *ribClient) Dump() []*route.Route {
-	return nil
-}
-
 func (r *ribClient) RefreshRoute(*net.Prefix, []*route.Path) {}
 
-func (r *ribClient) ReplaceFilterChain(filter.Chain) {}
-
 // ReplacePath is here to fulfill an interface
-func (r *ribClient) ReplacePath(*net.Prefix, *route.Path, *route.Path) {
-
-}
+func (r *ribClient) ReplacePath(*net.Prefix, *route.Path, *route.Path) {}
diff --git a/go.mod b/go.mod
index 9995a54d1046c365801a04fc27ee969afa34d3fe..e1077e5360c86f3f2c4173eb87a5a0ecde29cef2 100644
--- a/go.mod
+++ b/go.mod
@@ -15,9 +15,10 @@ require (
 	github.com/urfave/cli v1.21.0
 	github.com/vishvananda/netlink v1.0.0
 	github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
-	golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
+	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
 	golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect
 	golang.org/x/text v0.3.2 // indirect
+	golang.org/x/tools v0.0.0-20200714190737-9048b464a08d // indirect
 	google.golang.org/genproto v0.0.0-20200413115906-b5235f65be36 // indirect
 	google.golang.org/grpc v1.28.0
 	google.golang.org/protobuf v1.21.0
diff --git a/go.sum b/go.sum
index 1119a15803a7bfcf8d32b7031f2bea046cc2f5df..62be50875a720908dad645aaa4cefc60d97163e6 100644
--- a/go.sum
+++ b/go.sum
@@ -98,33 +98,48 @@ github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCO
 github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
 github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
 github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
 golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -136,7 +151,14 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200714190737-9048b464a08d h1:hYhnolbefSSt3WZp66sgmgnEOFv5PD6a5PIcnKJ8jdU=
+golang.org/x/tools v0.0.0-20200714190737-9048b464a08d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
diff --git a/protocols/bgp/api/bgp.pb.go b/protocols/bgp/api/bgp.pb.go
index a1095edf3f8c80686bd2e512900f5fc013e70eaf..65de520e03c74ebf22d3a7e129710db1d4d5134e 100644
--- a/protocols/bgp/api/bgp.pb.go
+++ b/protocols/bgp/api/bgp.pb.go
@@ -10,8 +10,6 @@ import (
 	api1 "github.com/bio-routing/bio-rd/route/api"
 	proto "github.com/golang/protobuf/proto"
 	grpc "google.golang.org/grpc"
-	codes "google.golang.org/grpc/codes"
-	status "google.golang.org/grpc/status"
 	math "math"
 )
 
@@ -247,11 +245,11 @@ var fileDescriptor_2d4ce551e16bb738 = []byte{
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ context.Context
-var _ grpc.ClientConnInterface
+var _ grpc.ClientConn
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion6
+const _ = grpc.SupportPackageIsVersion4
 
 // BgpServiceClient is the client API for BgpService service.
 //
@@ -263,10 +261,10 @@ type BgpServiceClient interface {
 }
 
 type bgpServiceClient struct {
-	cc grpc.ClientConnInterface
+	cc *grpc.ClientConn
 }
 
-func NewBgpServiceClient(cc grpc.ClientConnInterface) BgpServiceClient {
+func NewBgpServiceClient(cc *grpc.ClientConn) BgpServiceClient {
 	return &bgpServiceClient{cc}
 }
 
@@ -350,20 +348,6 @@ type BgpServiceServer interface {
 	DumpRIBOut(*DumpRIBRequest, BgpService_DumpRIBOutServer) error
 }
 
-// UnimplementedBgpServiceServer can be embedded to have forward compatible implementations.
-type UnimplementedBgpServiceServer struct {
-}
-
-func (*UnimplementedBgpServiceServer) ListSessions(ctx context.Context, req *ListSessionsRequest) (*ListSessionsResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method ListSessions not implemented")
-}
-func (*UnimplementedBgpServiceServer) DumpRIBIn(req *DumpRIBRequest, srv BgpService_DumpRIBInServer) error {
-	return status.Errorf(codes.Unimplemented, "method DumpRIBIn not implemented")
-}
-func (*UnimplementedBgpServiceServer) DumpRIBOut(req *DumpRIBRequest, srv BgpService_DumpRIBOutServer) error {
-	return status.Errorf(codes.Unimplemented, "method DumpRIBOut not implemented")
-}
-
 func RegisterBgpServiceServer(s *grpc.Server, srv BgpServiceServer) {
 	s.RegisterService(&_BgpService_serviceDesc, srv)
 }
diff --git a/protocols/bgp/server/fsm_address_family.go b/protocols/bgp/server/fsm_address_family.go
index 4ada547f9a58b643726210ff6d3158428186d3c5..102241ab93a868c7f1a89c1a68eaf43e6e829fef 100644
--- a/protocols/bgp/server/fsm_address_family.go
+++ b/protocols/bgp/server/fsm_address_family.go
@@ -20,8 +20,8 @@ type fsmAddressFamily struct {
 	safi uint8
 	fsm  *FSM
 
-	adjRIBIn  routingtable.RouteTableClient
-	adjRIBOut routingtable.RouteTableClient
+	adjRIBIn  routingtable.AdjRIBIn
+	adjRIBOut routingtable.AdjRIBOut
 	rib       *locRIB.LocRIB
 
 	importFilterChain filter.Chain
diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go
index 29f3146a012b776f8a28d2ea8e23c5084ae76db4..a113069e8a578e8f5ef1f31571b0d34b1225aedf 100644
--- a/protocols/bgp/server/update_sender.go
+++ b/protocols/bgp/server/update_sender.go
@@ -70,6 +70,10 @@ func (u *UpdateSender) Destroy() {
 	u.destroyCh <- struct{}{}
 }
 
+func (u *UpdateSender) AddPathInitialDump(pfx *bnet.Prefix, p *route.Path) error {
+	return u.AddPath(pfx, p)
+}
+
 // AddPath adds path p for pfx to toSend queue
 func (u *UpdateSender) AddPath(pfx *bnet.Prefix, p *route.Path) error {
 	u.toSendMu.Lock()
diff --git a/protocols/kernel/kernel.go b/protocols/kernel/kernel.go
index 9f59f660b7407ee7a54e709766a543e42d21daa7..ab2473d49133a431b9093c7486a59878f67eda1f 100644
--- a/protocols/kernel/kernel.go
+++ b/protocols/kernel/kernel.go
@@ -27,6 +27,10 @@ func New() (*Kernel, error) {
 	return k, nil
 }
 
+func (k *Kernel) AddPathInitialDump(pfx *net.Prefix, path *route.Path) error {
+	return k.AddPath(pfx, path)
+}
+
 func (k *Kernel) AddPath(pfx *net.Prefix, path *route.Path) error {
 	return k.osKernel.AddPath(pfx, path)
 }
diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go
index 376356ede13669cda4fdbcd852181e46924f7a55..c972dcfef7c45883648d69701c328e90764d029b 100644
--- a/routingtable/adjRIBIn/adj_rib_in.go
+++ b/routingtable/adjRIBIn/adj_rib_in.go
@@ -124,7 +124,7 @@ func (a *AdjRIBIn) UpdateNewClient(client routingtable.RouteTableClient) error {
 				continue
 			}
 
-			err := client.AddPath(route.Prefix(), path)
+			err := client.AddPathInitialDump(route.Prefix(), path)
 			if err != nil {
 				log.WithField("Sender", "AdjRIBOutAddPath").WithError(err).Error("Could not send update to client")
 			}
diff --git a/routingtable/adjRIBOut/adj_rib_out.go b/routingtable/adjRIBOut/adj_rib_out.go
index 4f470c72ca22d6c2a5de7c556fd172ee79dd3269..6387e8a8a8efef2411f4e95b0a8c2bf295c33d6e 100644
--- a/routingtable/adjRIBOut/adj_rib_out.go
+++ b/routingtable/adjRIBOut/adj_rib_out.go
@@ -116,6 +116,10 @@ func (a *AdjRIBOut) bgpChecks(pfx *bnet.Prefix, p *route.Path) (retPath *route.P
 	return p, true
 }
 
+func (a *AdjRIBOut) AddPathInitialDump(pfx *bnet.Prefix, p *route.Path) error {
+	return a.AddPath(pfx, p)
+}
+
 // AddPath adds path p to prefix `pfx`
 func (a *AdjRIBOut) AddPath(pfx *bnet.Prefix, p *route.Path) error {
 	p, propagate := a.bgpChecks(pfx, p)
diff --git a/routingtable/client_interface.go b/routingtable/client_interface.go
index f2b9885579183f8df5a73232aed5ce91f7312632..a97a3b5ad7352d7bf73ca9ab4d7be5e018aabe03 100644
--- a/routingtable/client_interface.go
+++ b/routingtable/client_interface.go
@@ -6,17 +6,35 @@ import (
 	"github.com/bio-routing/bio-rd/routingtable/filter"
 )
 
-// RouteTableClient is the interface that every type of RIB must implement
+// RouteTableClient is the interface that every route table client must implement
 type RouteTableClient interface {
-	AddPath(*net.Prefix, *route.Path) error
+	AddPath(pfx *net.Prefix, path *route.Path) error
+	AddPathInitialDump(pfx *net.Prefix, path *route.Path) error
 	RemovePath(*net.Prefix, *route.Path) bool
 	ReplacePath(*net.Prefix, *route.Path, *route.Path)
-	UpdateNewClient(RouteTableClient) error
-	Register(RouteTableClient)
-	Unregister(RouteTableClient)
+	RefreshRoute(*net.Prefix, []*route.Path)
+}
+
+type AdjRIB interface {
+	ReplaceFilterChain(filter.Chain)
+	Dump() []*route.Route
+	Register(client RouteTableClient)
+	Unregister(client RouteTableClient)
+	AddPath(pfx *net.Prefix, path *route.Path) error
+	RemovePath(*net.Prefix, *route.Path) bool
 	RouteCount() int64
 	ClientCount() uint64
-	Dump() []*route.Route
-	ReplaceFilterChain(filter.Chain)
+}
+
+// AdjRIBIn is the interface any AdjRIBIn must implement
+type AdjRIBIn interface {
+	AdjRIB
+}
+
+// AdjRIBOut is the interface any AdjRIBOut must implement
+type AdjRIBOut interface {
+	AdjRIB
+	AddPathInitialDump(pfx *net.Prefix, path *route.Path) error
+	ReplacePath(*net.Prefix, *route.Path, *route.Path)
 	RefreshRoute(*net.Prefix, []*route.Path)
 }
diff --git a/routingtable/client_manager.go b/routingtable/client_manager.go
index 5e4ac377ddeb872a606038c72d016cce35a12b95..aa4a3a7af1d7091c0096bf1a3d4bd94b86068351 100644
--- a/routingtable/client_manager.go
+++ b/routingtable/client_manager.go
@@ -4,6 +4,10 @@ import (
 	"sync"
 )
 
+type ClientManagerMaster interface {
+	UpdateNewClient(RouteTableClient) error
+}
+
 // ClientOptions represents options for a client
 type ClientOptions struct {
 	BestOnly bool
@@ -27,12 +31,12 @@ func (c *ClientOptions) GetMaxPaths(ecmpPaths uint) uint {
 // ClientManager manages clients of routing tables (observer pattern)
 type ClientManager struct {
 	clients map[RouteTableClient]ClientOptions
-	master  RouteTableClient
+	master  ClientManagerMaster
 	mu      sync.RWMutex
 }
 
 // NewClientManager creates and initializes a new client manager
-func NewClientManager(master RouteTableClient) *ClientManager {
+func NewClientManager(master ClientManagerMaster) *ClientManager {
 	return &ClientManager{
 		clients: make(map[RouteTableClient]ClientOptions, 0),
 		master:  master,
diff --git a/routingtable/client_manager_test.go b/routingtable/client_manager_test.go
index 35646a2e572645e9ad8de5afecc8221a7f7628b0..17bef2f4951f9f272d203f83931a0b1f01a42ff6 100644
--- a/routingtable/client_manager_test.go
+++ b/routingtable/client_manager_test.go
@@ -24,12 +24,19 @@ func (m MockClient) Dump() []*route.Route {
 func (m MockClient) AddPath(*net.Prefix, *route.Path) error {
 	return nil
 }
+
+func (m MockClient) AddPathInitialDump(*net.Prefix, *route.Path) error {
+	return nil
+}
+
 func (m MockClient) RemovePath(*net.Prefix, *route.Path) bool {
 	return false
 }
+
 func (m MockClient) UpdateNewClient(RouteTableClient) error {
 	return nil
 }
+
 func (m MockClient) Register(RouteTableClient) {
 	return
 }
diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go
index a97cd1d3c1f1b45c0c85285e5a8c8f66df64243e..057841e61f105ee876ce3b73a83dd24da0056b5c 100644
--- a/routingtable/locRIB/loc_rib.go
+++ b/routingtable/locRIB/loc_rib.go
@@ -110,7 +110,7 @@ func (a *LocRIB) UpdateNewClient(client routingtable.RouteTableClient) error {
 		}
 
 		for _, p := range r.Paths()[:n] {
-			client.AddPath(r.Prefix(), p)
+			client.AddPathInitialDump(r.Prefix(), p)
 		}
 	}
 
@@ -145,6 +145,10 @@ func (a *LocRIB) RouteCount() int64 {
 	return a.rt.GetRouteCount()
 }
 
+func (a *LocRIB) AddPathInitialDump(pfx *net.Prefix, p *route.Path) error {
+	return a.AddPath(pfx, p)
+}
+
 // AddPath replaces the path for prefix `pfx`. If the prefix doesn't exist it is added.
 func (a *LocRIB) AddPath(pfx *net.Prefix, p *route.Path) error {
 	a.mu.Lock()
diff --git a/routingtable/mock_client.go b/routingtable/mock_client.go
index 5696dd0b895424d1d74439ead49b2bc43e5465d5..bac4bd9709998497e94aca80d66ef3dd2e8f35f8 100644
--- a/routingtable/mock_client.go
+++ b/routingtable/mock_client.go
@@ -41,6 +41,10 @@ func (m *RTMockClient) AddPath(pfx *net.Prefix, p *route.Path) error {
 	return nil
 }
 
+func (m *RTMockClient) AddPathInitialDump(pfx *net.Prefix, p *route.Path) error {
+	return nil
+}
+
 func (m *RTMockClient) UpdateNewClient(client RouteTableClient) error {
 	return fmt.Errorf("Not implemented")
 }
diff --git a/routingtable/vrf/vrf.go b/routingtable/vrf/vrf.go
index 1162595e92cb67c3c306d3cec9442661ed09f63f..9232f5c9b85f4b682563391bc23589d197d39c17 100644
--- a/routingtable/vrf/vrf.go
+++ b/routingtable/vrf/vrf.go
@@ -2,9 +2,12 @@ package vrf
 
 import (
 	"fmt"
+	"strconv"
+	"strings"
 	"sync"
 
 	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+	"github.com/pkg/errors"
 )
 
 const (
@@ -147,3 +150,37 @@ func RouteDistinguisherHumanReadable(rdi uint64) string {
 
 	return fmt.Sprintf("%d:%d", asn, netID)
 }
+
+// ParseHumanReadableRouteDistinguisher parses a human readable route distinguisher
+func ParseHumanReadableRouteDistinguisher(x string) (uint64, error) {
+	parts := strings.Split(x, ":")
+	if len(parts) != 2 {
+		return 0, fmt.Errorf("Invalid format")
+	}
+
+	asn, err := strconv.Atoi(parts[0])
+	if err != nil {
+		return 0, errors.Wrap(err, "Unable to convert first part to int")
+	}
+
+	maxUint32 := int(^uint32(0))
+	if asn > maxUint32 {
+		return 0, fmt.Errorf("Invalid format: ASN > max uint32")
+	}
+
+	netID, err := strconv.Atoi(parts[1])
+	if err != nil {
+		return 0, errors.Wrap(err, "Unable to convert second part to int")
+	}
+
+	if netID > maxUint32 {
+		return 0, fmt.Errorf("Invalid format: Network ID > max uint32")
+	}
+
+	ret := uint64(0)
+	ret = uint64(asn)
+	ret = ret << 32
+	ret += uint64(netID)
+
+	return ret, nil
+}
diff --git a/routingtable/vrf/vrf_test.go b/routingtable/vrf/vrf_test.go
index 56466ca3ef92386a7900b4e573de6c62a3bfe4cb..d18d0993c518d93cc889f4d91a4b4ad2fe1d00f6 100644
--- a/routingtable/vrf/vrf_test.go
+++ b/routingtable/vrf/vrf_test.go
@@ -95,3 +95,39 @@ func TestRouteDistinguisherHumanReadable(t *testing.T) {
 		assert.Equal(t, test.expected, res, test.name)
 	}
 }
+
+func TestParseHumanReadableRouteDistinguisher(t *testing.T) {
+	tests := []struct {
+		name     string
+		input    string
+		expected uint64
+		wantFail bool
+	}{
+		{
+			name:     "Test #1",
+			input:    "51324:65201",
+			expected: 0x0000C87C0000FEB1,
+			wantFail: false,
+		},
+		{
+			name:     "Test #2",
+			input:    "51324",
+			wantFail: true,
+		},
+	}
+
+	for _, test := range tests {
+		res, err := ParseHumanReadableRouteDistinguisher(test.input)
+		if !test.wantFail && err != nil {
+			t.Errorf("Unexpected failure for test %q", test.name)
+			continue
+		}
+
+		if test.wantFail && err == nil {
+			t.Errorf("Unexpected success for test %q", test.name)
+			continue
+		}
+
+		assert.Equal(t, test.expected, res, test.name)
+	}
+}