diff --git a/.travis.yml b/.travis.yml
index 8285a341f00c89ae0ed0e4d8e636b2cffb9aa513..3bb9725c0aaec6fb74c58c06a540187b15b21800 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,8 +22,8 @@ script:
 - mkdir -p $HOME/gopath/src/github.com/bio-routing/
 - ln -s $TRAVIS_BUILD_DIR $HOME/gopath/src/github.com/bio-routing/bio-rd || true
 - cp .bazelrc.travis .bazelrc
-- bazel build //vendor/github.com/mattn/goveralls
 - bazel test //...
 - bazel coverage //...
-- bazel-bin/vendor/github.com/mattn/goveralls/linux_amd64_stripped/goveralls -coverprofile=$(find bazel-testlogs/ -name coverage.dat | paste -sd "," -)
+- bazel build //vendor/github.com/q3k/goveralls
+- bazel-bin/vendor/github.com/q3k/goveralls/linux_amd64_stripped/goveralls -coverprofile=$(find bazel-testlogs/ -iname coverage.dat -or -iname baseline_coverage.dat | paste -sd ',') -merge=false
 
diff --git a/Gopkg.lock b/Gopkg.lock
index 391c901dc19af67b76a331a3460327f8a0bf6fc0..81cfd2ac55537058ee897059900dccb5fedd1d50 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -46,7 +46,7 @@
     "gps/internal/pb",
     "gps/paths",
     "gps/pkgtree",
-    "internal/fs"
+    "internal/fs",
   ]
   revision = "37d9ea0ac16f0e0a05afc3b60e1ac8c364b6c329"
   version = "v0.4.1"
@@ -63,12 +63,6 @@
   revision = "8b28145dffc87104e66d074f62ea8080edfad7c8"
   version = "v0.3.0"
 
-[[projects]]
-  name = "github.com/mattn/goveralls"
-  packages = ["."]
-  revision = "b71a1e4855f87991aff01c2c833a75a07059c61c"
-  version = "v0.0.2"
-
 [[projects]]
   branch = "master"
   name = "github.com/nightlyone/lockfile"
@@ -93,6 +87,12 @@
   revision = "792786c7400a136282c1664665ae0a8db921c6c2"
   version = "v1.0.0"
 
+[[projects]]
+  name = "github.com/q3k/goveralls"
+  packages = ["."]
+  revision = "789b29cb81d4de953738cec0fbaefa8af2ff4ea2"
+  version = "v0.1.0"
+
 [[projects]]
   branch = "master"
   name = "github.com/sdboyer/constext"
@@ -140,7 +140,7 @@
   name = "golang.org/x/sys"
   packages = [
     "unix",
-    "windows"
+    "windows",
   ]
   revision = "bb9c189858d91f42db229b04d45a4c3d23a7662a"
 
@@ -153,6 +153,6 @@
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "54ddfce69bb4724edb07fa628b5a6ae7a4fb1af7ba00b2a64fe043d967d2fdff"
+  inputs-digest = "8d26786e7bd681598d376675bc030c802da70ac1e285fe39220d11970e1036c4"
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index b446095b667022895feb4c19716d134a9111aa5e..23dfe410908bc1b0c2890b82e7349ed904c184a2 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -19,7 +19,7 @@
 #  name = "github.com/x/y"
 #  version = "2.4.0"
 
-required = ["github.com/golang/dep", "github.com/mattn/goveralls", "github.com/go-yaml/yaml"]
+required = ["github.com/golang/dep", "github.com/q3k/goveralls", "github.com/go-yaml/yaml"]
 
 [prune]
   go-tests = true
diff --git a/README.md b/README.md
index a9efc980c7d4787a259e8e433153cd062211b314..418f544cb659e5e4d174be5beed66f6fb0675c05 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ Update vendor/dependencies
 After updating Gopkg.toml, run
 
     bazel build //vendor/github.com/golang/dep/cmd/dep
-    bazel-bin/vendor/github.com/golang/dep/cmd/dep/linux_amd64_stripped/dep
+    bazel-bin/vendor/github.com/golang/dep/cmd/dep/linux_amd64_stripped/dep use
     # hack: dep of dep gives us these, and it breaks gazelle
     rm -rf vendor/github.com/golang/dep/cmd/dep/testdata
     rm -rf vendor/github.com/golang/dep/internal/fs/testdata/symlinks/dir-symlink
diff --git a/main.go b/main.go
index 22cba26fdfb466f2e554538d3f81f864d8c18b79..7c5bd7f1ba15450a5679688079307d3e0428e626 100644
--- a/main.go
+++ b/main.go
@@ -40,9 +40,9 @@ func main() {
 
 	b.AddPeer(config.Peer{
 		AdminEnabled:      true,
-		LocalAS:           6695,
+		LocalAS:           65200,
 		PeerAS:            65300,
-		PeerAddress:       net.IP([]byte{169, 254, 200, 1}),
+		PeerAddress:       net.IP([]byte{172, 17, 0, 3}),
 		LocalAddress:      net.IP([]byte{169, 254, 200, 0}),
 		ReconnectInterval: time.Second * 15,
 		HoldTime:          time.Second * 90,
@@ -59,9 +59,9 @@ func main() {
 
 	b.AddPeer(config.Peer{
 		AdminEnabled:      true,
-		LocalAS:           6695,
+		LocalAS:           65200,
 		PeerAS:            65100,
-		PeerAddress:       net.IP([]byte{169, 254, 100, 0}),
+		PeerAddress:       net.IP([]byte{172, 17, 0, 2}),
 		LocalAddress:      net.IP([]byte{169, 254, 100, 1}),
 		ReconnectInterval: time.Second * 15,
 		HoldTime:          time.Second * 90,
@@ -79,7 +79,7 @@ func main() {
 
 	go func() {
 		for {
-			fmt.Print(rib.Print())
+			fmt.Printf("LocRIB count: %d\n", rib.Count())
 			time.Sleep(time.Second * 10)
 		}
 	}()
diff --git a/protocols/bgp/packet/BUILD.bazel b/protocols/bgp/packet/BUILD.bazel
index 10c8af2338d9c6ce76bb2f37d23355b04d21af69..66762a51dfcce62cd24b01dbc3d288dd7c26fbcf 100644
--- a/protocols/bgp/packet/BUILD.bazel
+++ b/protocols/bgp/packet/BUILD.bazel
@@ -9,6 +9,7 @@ go_library(
         "encoder.go",
         "large_community.go",
         "nlri.go",
+        "options.go",
         "parameters.go",
         "path_attribute_flags.go",
         "path_attributes.go",
diff --git a/protocols/bgp/packet/bgp.go b/protocols/bgp/packet/bgp.go
index 622b46f37b115dd27779a285284d177d75695230..8082f5dd8c02ae2c74a23013bcdb4c63d524d52b 100644
--- a/protocols/bgp/packet/bgp.go
+++ b/protocols/bgp/packet/bgp.go
@@ -92,9 +92,11 @@ const (
 	UnicastSAFI           = 1
 	CapabilitiesParamType = 2
 	AddPathCapabilityCode = 69
+	ASN4CapabilityCode    = 65
 	AddPathReceive        = 1
 	AddPathSend           = 2
 	AddPathSendReceive    = 3
+	ASTransASN            = 23456
 )
 
 type BGPError struct {
@@ -119,7 +121,7 @@ type BGPHeader struct {
 
 type BGPOpen struct {
 	Version       uint8
-	AS            uint16
+	ASN           uint16
 	HoldTime      uint16
 	BGPIdentifier uint32
 	OptParmLen    uint8
diff --git a/protocols/bgp/packet/decoder.go b/protocols/bgp/packet/decoder.go
index 31583bf1b68257625dfaa3d8b8e40893982d6713..c4d583f2138edfbbfb5b9be33b2a1c11764ee0bd 100644
--- a/protocols/bgp/packet/decoder.go
+++ b/protocols/bgp/packet/decoder.go
@@ -10,13 +10,13 @@ import (
 )
 
 // Decode decodes a BGP message
-func Decode(buf *bytes.Buffer) (*BGPMessage, error) {
+func Decode(buf *bytes.Buffer, opt *Options) (*BGPMessage, error) {
 	hdr, err := decodeHeader(buf)
 	if err != nil {
 		return nil, fmt.Errorf("Failed to decode header: %v", err)
 	}
 
-	body, err := decodeMsgBody(buf, hdr.Type, hdr.Length-MinLen)
+	body, err := decodeMsgBody(buf, hdr.Type, hdr.Length-MinLen, opt)
 	if err != nil {
 		return nil, fmt.Errorf("Failed to decode message: %v", err)
 	}
@@ -27,12 +27,12 @@ func Decode(buf *bytes.Buffer) (*BGPMessage, error) {
 	}, nil
 }
 
-func decodeMsgBody(buf *bytes.Buffer, msgType uint8, l uint16) (interface{}, error) {
+func decodeMsgBody(buf *bytes.Buffer, msgType uint8, l uint16, opt *Options) (interface{}, error) {
 	switch msgType {
 	case OpenMsg:
 		return decodeOpenMsg(buf)
 	case UpdateMsg:
-		return decodeUpdateMsg(buf, l)
+		return decodeUpdateMsg(buf, l, opt)
 	case KeepaliveMsg:
 		return nil, nil // Nothing to decode in Keepalive message
 	case NotificationMsg:
@@ -41,7 +41,7 @@ func decodeMsgBody(buf *bytes.Buffer, msgType uint8, l uint16) (interface{}, err
 	return nil, fmt.Errorf("Unknown message type: %d", msgType)
 }
 
-func decodeUpdateMsg(buf *bytes.Buffer, l uint16) (*BGPUpdate, error) {
+func decodeUpdateMsg(buf *bytes.Buffer, l uint16, opt *Options) (*BGPUpdate, error) {
 	msg := &BGPUpdate{}
 
 	err := decode(buf, []interface{}{&msg.WithdrawnRoutesLen})
@@ -59,7 +59,7 @@ func decodeUpdateMsg(buf *bytes.Buffer, l uint16) (*BGPUpdate, error) {
 		return msg, err
 	}
 
-	msg.PathAttributes, err = decodePathAttrs(buf, msg.TotalPathAttrLen)
+	msg.PathAttributes, err = decodePathAttrs(buf, msg.TotalPathAttrLen, opt)
 	if err != nil {
 		return msg, err
 	}
@@ -141,7 +141,7 @@ func _decodeOpenMsg(buf *bytes.Buffer) (interface{}, error) {
 
 	fields := []interface{}{
 		&msg.Version,
-		&msg.AS,
+		&msg.ASN,
 		&msg.HoldTime,
 		&msg.BGPIdentifier,
 		&msg.OptParmLen,
@@ -238,6 +238,12 @@ func decodeCapability(buf *bytes.Buffer) (Capability, error) {
 			return cap, fmt.Errorf("Unable to decode add path capability")
 		}
 		cap.Value = addPathCap
+	case ASN4CapabilityCode:
+		asn4Cap, err := decodeASN4Capability(buf)
+		if err != nil {
+			return cap, fmt.Errorf("Unable to decode 4 octet ASN capability")
+		}
+		cap.Value = asn4Cap
 	default:
 		for i := uint8(0); i < cap.Length; i++ {
 			_, err := buf.ReadByte()
@@ -266,6 +272,20 @@ func decodeAddPathCapability(buf *bytes.Buffer) (AddPathCapability, error) {
 	return addPathCap, nil
 }
 
+func decodeASN4Capability(buf *bytes.Buffer) (ASN4Capability, error) {
+	asn4Cap := ASN4Capability{}
+	fields := []interface{}{
+		&asn4Cap.ASN4,
+	}
+
+	err := decode(buf, fields)
+	if err != nil {
+		return asn4Cap, err
+	}
+
+	return asn4Cap, nil
+}
+
 func validateOpen(msg *BGPOpen) error {
 	if msg.Version != BGP4Version {
 		return BGPError{
diff --git a/protocols/bgp/packet/decoder_test.go b/protocols/bgp/packet/decoder_test.go
index a9ae237b9cb94a3e0ec6af0b988bc09f41d3f806..56416186ba1d714a13fb4f248281d3d5f48451dd 100644
--- a/protocols/bgp/packet/decoder_test.go
+++ b/protocols/bgp/packet/decoder_test.go
@@ -3,6 +3,7 @@ package packet
 import (
 	"bytes"
 	"fmt"
+	"strconv"
 	"testing"
 
 	"github.com/bio-routing/bio-rd/net"
@@ -70,7 +71,7 @@ func BenchmarkDecodeUpdateMsg(b *testing.B) {
 
 	for i := 0; i < b.N; i++ {
 		buf := bytes.NewBuffer(input)
-		_, err := decodeUpdateMsg(buf, uint16(len(input)))
+		_, err := decodeUpdateMsg(buf, uint16(len(input)), &Options{})
 		if err != nil {
 			fmt.Printf("decodeUpdateMsg failed: %v\n", err)
 		}
@@ -156,7 +157,7 @@ func TestDecode(t *testing.T) {
 				},
 				Body: &BGPOpen{
 					Version:       4,
-					AS:            200,
+					ASN:           200,
 					HoldTime:      15,
 					BGPIdentifier: uint32(169090600),
 					OptParmLen:    0,
@@ -184,7 +185,7 @@ func TestDecode(t *testing.T) {
 				},
 				Body: &BGPOpen{
 					Version:       4,
-					AS:            200,
+					ASN:           200,
 					HoldTime:      15,
 					BGPIdentifier: uint32(100),
 				},
@@ -251,7 +252,7 @@ func TestDecode(t *testing.T) {
 
 	for _, test := range tests {
 		buf := bytes.NewBuffer(test.input)
-		msg, err := Decode(buf)
+		msg, err := Decode(buf, &Options{})
 
 		if err != nil && !test.wantFail {
 			t.Errorf("Unexpected error in test %d: %v", test.testNum, err)
@@ -1369,9 +1370,9 @@ func TestDecodeUpdateMsg(t *testing.T) {
 		},
 		{
 			// 2 withdraws with four path attributes (Communities + AS4Path +AS4Aggregator + Origin), valid update
-			testNum: 19,
+			testNum: 20,
 			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 30, // Total Path Attribute Length
+				0, 32, // Total Path Attribute Length
 
 				0,          // Attribute flags
 				8,          // Attribute Type code (Community)
@@ -1379,10 +1380,12 @@ func TestDecodeUpdateMsg(t *testing.T) {
 				0, 0, 1, 0, // Arbitrary Community
 				0, 0, 1, 1, // Arbitrary Community
 
-				128,        // Attribute flags
-				17,         // Attribute Type code (AS4Path)
-				4,          // Length
-				0, 0, 2, 3, // Arbitrary Bytes
+				128,                    // Attribute flags
+				17,                     // Attribute Type code (AS4Path)
+				6,                      // Length
+				2,                      // AS_SEQUENCE
+				1,                      // Number of ASNs
+				0x00, 0x03, 0x17, 0xf3, // 202739
 
 				128,        // Attribute flags
 				18,         // Attribute Type code (AS4Aggregator)
@@ -1406,7 +1409,7 @@ func TestDecodeUpdateMsg(t *testing.T) {
 						Pfxlen: 16,
 					},
 				},
-				TotalPathAttrLen: 30,
+				TotalPathAttrLen: 32,
 				PathAttributes: &PathAttribute{
 					Optional:       false,
 					Transitive:     false,
@@ -1420,9 +1423,15 @@ func TestDecodeUpdateMsg(t *testing.T) {
 						Transitive:     false,
 						Partial:        false,
 						ExtendedLength: false,
-						Length:         4,
+						Length:         6,
 						TypeCode:       17,
-						Value:          uint32(515),
+						Value: ASPath{
+							ASPathSegment{
+								Type:  2,
+								Count: 1,
+								ASNs:  []uint32{202739},
+							},
+						},
 						Next: &PathAttribute{
 							Optional:       true,
 							Transitive:     false,
@@ -1447,29 +1456,31 @@ func TestDecodeUpdateMsg(t *testing.T) {
 		},
 	}
 
+	t.Parallel()
+
 	for _, test := range tests {
-		buf := bytes.NewBuffer(test.input)
-		l := test.explicitLength
-		if l == 0 {
-			l = uint16(len(test.input))
-		}
-		msg, err := decodeUpdateMsg(buf, l)
+		t.Run(strconv.Itoa(test.testNum), func(t *testing.T) {
+			buf := bytes.NewBuffer(test.input)
+			l := test.explicitLength
+			if l == 0 {
+				l = uint16(len(test.input))
+			}
+			msg, err := decodeUpdateMsg(buf, l, &Options{})
 
-		if err != nil && !test.wantFail {
-			t.Errorf("Unexpected error in test %d: %v", test.testNum, err)
-			continue
-		}
+			if err != nil && !test.wantFail {
+				t.Fatalf("Unexpected error in test %d: %v", test.testNum, err)
+			}
 
-		if err == nil && test.wantFail {
-			t.Errorf("Expected error did not happen in test %d", test.testNum)
-			continue
-		}
+			if err == nil && test.wantFail {
+				t.Fatalf("Expected error did not happen in test %d", test.testNum)
+			}
 
-		if err != nil && test.wantFail {
-			continue
-		}
+			if err != nil && test.wantFail {
+				return
+			}
 
-		assert.Equalf(t, test.expected, msg, "%d", test.testNum)
+			assert.Equalf(t, test.expected, msg, "%d", test.testNum)
+		})
 	}
 }
 
@@ -1490,7 +1501,7 @@ func TestDecodeMsgBody(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		res, err := decodeMsgBody(test.buffer, test.msgType, test.length)
+		res, err := decodeMsgBody(test.buffer, test.msgType, test.length, &Options{})
 		if test.wantFail && err == nil {
 			t.Errorf("Expected error dit not happen in test %q", test.name)
 		}
@@ -1512,7 +1523,7 @@ func TestDecodeOpenMsg(t *testing.T) {
 			wantFail: false,
 			expected: &BGPOpen{
 				Version:       4,
-				AS:            257,
+				ASN:           257,
 				HoldTime:      15,
 				BGPIdentifier: 169090600,
 				OptParmLen:    0,
diff --git a/protocols/bgp/packet/encoder.go b/protocols/bgp/packet/encoder.go
index ea87d1ff64cfc946688e738ae9f7ffa372cf10c7..ac9bc4483199b81f4e8ecc25c6b91e3ec8361b9c 100644
--- a/protocols/bgp/packet/encoder.go
+++ b/protocols/bgp/packet/encoder.go
@@ -35,7 +35,7 @@ func SerializeOpenMsg(msg *BGPOpen) []byte {
 	serializeHeader(buf, openLen, OpenMsg)
 
 	buf.WriteByte(msg.Version)
-	buf.Write(convert.Uint16Byte(msg.AS))
+	buf.Write(convert.Uint16Byte(msg.ASN))
 	buf.Write(convert.Uint16Byte(msg.HoldTime))
 	buf.Write(convert.Uint32Byte(msg.BGPIdentifier))
 
@@ -63,7 +63,7 @@ func serializeHeader(buf *bytes.Buffer, length uint16, typ uint8) {
 	buf.WriteByte(typ)
 }
 
-func (b *BGPUpdateAddPath) SerializeUpdate() ([]byte, error) {
+func (b *BGPUpdateAddPath) SerializeUpdate(opt *Options) ([]byte, error) {
 	budget := MaxLen - MinLen
 	buf := bytes.NewBuffer(nil)
 
@@ -78,7 +78,7 @@ func (b *BGPUpdateAddPath) SerializeUpdate() ([]byte, error) {
 
 	pathAttributesBuf := bytes.NewBuffer(nil)
 	for pa := b.PathAttributes; pa != nil; pa = pa.Next {
-		paLen := int(pa.serialize(pathAttributesBuf))
+		paLen := int(pa.serialize(pathAttributesBuf, opt))
 		budget -= paLen
 		if budget < 0 {
 			return nil, fmt.Errorf("update too long")
@@ -122,7 +122,7 @@ func (b *BGPUpdateAddPath) SerializeUpdate() ([]byte, error) {
 	return buf.Bytes(), nil
 }
 
-func (b *BGPUpdate) SerializeUpdate() ([]byte, error) {
+func (b *BGPUpdate) SerializeUpdate(opt *Options) ([]byte, error) {
 	budget := MaxLen - MinLen
 	buf := bytes.NewBuffer(nil)
 
@@ -137,7 +137,7 @@ func (b *BGPUpdate) SerializeUpdate() ([]byte, error) {
 
 	pathAttributesBuf := bytes.NewBuffer(nil)
 	for pa := b.PathAttributes; pa != nil; pa = pa.Next {
-		paLen := int(pa.serialize(pathAttributesBuf))
+		paLen := int(pa.serialize(pathAttributesBuf, opt))
 		budget -= paLen
 		if budget < 0 {
 			return nil, fmt.Errorf("update too long")
diff --git a/protocols/bgp/packet/encoder_test.go b/protocols/bgp/packet/encoder_test.go
index 0d4f70a3483dabd8f7332dd148c72b09df626dee..fd7405d735a5d11a4117d144e7086828c86f5628 100644
--- a/protocols/bgp/packet/encoder_test.go
+++ b/protocols/bgp/packet/encoder_test.go
@@ -70,7 +70,7 @@ func TestSerializeOpenMsg(t *testing.T) {
 			name: "Valid #1",
 			input: &BGPOpen{
 				Version:       4,
-				AS:            15169,
+				ASN:           15169,
 				HoldTime:      120,
 				BGPIdentifier: convert.Uint32([]byte{100, 111, 120, 130}),
 				OptParmLen:    0,
diff --git a/protocols/bgp/packet/options.go b/protocols/bgp/packet/options.go
new file mode 100644
index 0000000000000000000000000000000000000000..b2d35bc60cbe17490f94314c28da26de9a19e40a
--- /dev/null
+++ b/protocols/bgp/packet/options.go
@@ -0,0 +1,5 @@
+package packet
+
+type Options struct {
+	Supports4OctetASN bool
+}
diff --git a/protocols/bgp/packet/parameters.go b/protocols/bgp/packet/parameters.go
index 8edf42fc58e05bb3b73cacd4272012844bedcd45..0ed9af66fe01f96600c02eeb2c00b69b11edc76c 100644
--- a/protocols/bgp/packet/parameters.go
+++ b/protocols/bgp/packet/parameters.go
@@ -52,3 +52,11 @@ func (a AddPathCapability) serialize(buf *bytes.Buffer) {
 	buf.WriteByte(a.SAFI)
 	buf.WriteByte(a.SendReceive)
 }
+
+type ASN4Capability struct {
+	ASN4 uint32
+}
+
+func (a ASN4Capability) serialize(buf *bytes.Buffer) {
+	buf.Write(convert.Uint32Byte(a.ASN4))
+}
diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go
index 3b3192034590bd357b29a13833a2bcaaa632f0cf..acd5c78ab813c5b3cc6442f61067c85471366545 100644
--- a/protocols/bgp/packet/path_attributes.go
+++ b/protocols/bgp/packet/path_attributes.go
@@ -9,7 +9,7 @@ import (
 	"github.com/taktv6/tflow2/convert"
 )
 
-func decodePathAttrs(buf *bytes.Buffer, tpal uint16) (*PathAttribute, error) {
+func decodePathAttrs(buf *bytes.Buffer, tpal uint16, opt *Options) (*PathAttribute, error) {
 	var ret *PathAttribute
 	var eol *PathAttribute
 	var pa *PathAttribute
@@ -18,7 +18,7 @@ func decodePathAttrs(buf *bytes.Buffer, tpal uint16) (*PathAttribute, error) {
 
 	p := uint16(0)
 	for p < tpal {
-		pa, consumed, err = decodePathAttr(buf)
+		pa, consumed, err = decodePathAttr(buf, opt)
 		if err != nil {
 			return nil, fmt.Errorf("Unable to decode path attr: %v", err)
 		}
@@ -36,7 +36,7 @@ func decodePathAttrs(buf *bytes.Buffer, tpal uint16) (*PathAttribute, error) {
 	return ret, nil
 }
 
-func decodePathAttr(buf *bytes.Buffer) (pa *PathAttribute, consumed uint16, err error) {
+func decodePathAttr(buf *bytes.Buffer, opt *Options) (pa *PathAttribute, consumed uint16, err error) {
 	pa = &PathAttribute{}
 
 	err = decodePathAttrFlags(buf, pa)
@@ -63,9 +63,18 @@ func decodePathAttr(buf *bytes.Buffer) (pa *PathAttribute, consumed uint16, err
 			return nil, consumed, fmt.Errorf("Failed to decode Origin: %v", err)
 		}
 	case ASPathAttr:
-		if err := pa.decodeASPath(buf); err != nil {
+		asnLength := uint8(2)
+		if opt.Supports4OctetASN {
+			asnLength = 4
+		}
+
+		if err := pa.decodeASPath(buf, asnLength); err != nil {
 			return nil, consumed, fmt.Errorf("Failed to decode AS Path: %v", err)
 		}
+	case AS4PathAttr:
+		if err := pa.decodeASPath(buf, 4); err != nil {
+			return nil, consumed, fmt.Errorf("Failed to decode AS4 Path: %v", err)
+		}
 	case NextHopAttr:
 		if err := pa.decodeNextHop(buf); err != nil {
 			return nil, consumed, fmt.Errorf("Failed to decode Next-Hop: %v", err)
@@ -88,10 +97,6 @@ func decodePathAttr(buf *bytes.Buffer) (pa *PathAttribute, consumed uint16, err
 		if err := pa.decodeCommunities(buf); err != nil {
 			return nil, consumed, fmt.Errorf("Failed to decode Community: %v", err)
 		}
-	case AS4PathAttr:
-		if err := pa.decodeAS4Path(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to skip not supported AS4Path: %v", err)
-		}
 	case AS4AggregatorAttr:
 		if err := pa.decodeAS4Aggregator(buf); err != nil {
 			return nil, consumed, fmt.Errorf("Failed to skip not supported AS4Aggregator: %v", err)
@@ -139,14 +144,11 @@ func (pa *PathAttribute) decodeOrigin(buf *bytes.Buffer) error {
 	return dumpNBytes(buf, pa.Length-p)
 }
 
-func (pa *PathAttribute) decodeASPath(buf *bytes.Buffer) error {
+func (pa *PathAttribute) decodeASPath(buf *bytes.Buffer, asnLength uint8) error {
 	pa.Value = make(ASPath, 0)
-
 	p := uint16(0)
 	for p < pa.Length {
-		segment := ASPathSegment{
-			ASNs: make([]uint32, 0),
-		}
+		segment := ASPathSegment{}
 
 		err := decode(buf, []interface{}{&segment.Type, &segment.Count})
 		if err != nil {
@@ -162,23 +164,51 @@ func (pa *PathAttribute) decodeASPath(buf *bytes.Buffer) error {
 			return fmt.Errorf("Invalid AS Path segment length: %d", segment.Count)
 		}
 
+		segment.ASNs = make([]uint32, segment.Count)
 		for i := uint8(0); i < segment.Count; i++ {
-			asn := uint16(0)
-
-			err := decode(buf, []interface{}{&asn})
+			asn, err := pa.decodeASN(buf, asnLength)
 			if err != nil {
 				return err
 			}
-			p += 2
+			p += uint16(asnLength)
 
-			segment.ASNs = append(segment.ASNs, uint32(asn))
+			segment.ASNs[i] = asn
 		}
+
 		pa.Value = append(pa.Value.(ASPath), segment)
 	}
 
 	return nil
 }
 
+func (pa *PathAttribute) decodeASN(buf *bytes.Buffer, asnSize uint8) (asn uint32, err error) {
+	if asnSize == 4 {
+		return pa.decode4ByteASN(buf)
+	}
+
+	return pa.decode2ByteASN(buf)
+}
+
+func (pa *PathAttribute) decode4ByteASN(buf *bytes.Buffer) (asn uint32, err error) {
+	asn4 := uint32(0)
+	err = decode(buf, []interface{}{&asn4})
+	if err != nil {
+		return 0, err
+	}
+
+	return uint32(asn4), nil
+}
+
+func (pa *PathAttribute) decode2ByteASN(buf *bytes.Buffer) (asn uint32, err error) {
+	asn4 := uint16(0)
+	err = decode(buf, []interface{}{&asn4})
+	if err != nil {
+		return 0, err
+	}
+
+	return uint32(asn4), nil
+}
+
 func (pa *PathAttribute) decodeNextHop(buf *bytes.Buffer) error {
 	return pa.decodeUint32(buf, "next hop")
 }
@@ -273,10 +303,6 @@ func (pa *PathAttribute) decodeLargeCommunities(buf *bytes.Buffer) error {
 	return nil
 }
 
-func (pa *PathAttribute) decodeAS4Path(buf *bytes.Buffer) error {
-	return pa.decodeUint32(buf, "AS4Path")
-}
-
 func (pa *PathAttribute) decodeAS4Aggregator(buf *bytes.Buffer) error {
 	return pa.decodeUint32(buf, "AS4Aggregator")
 }
@@ -383,14 +409,14 @@ func dumpNBytes(buf *bytes.Buffer, n uint16) error {
 	return nil
 }
 
-func (pa *PathAttribute) serialize(buf *bytes.Buffer) uint8 {
+func (pa *PathAttribute) serialize(buf *bytes.Buffer, opt *Options) uint8 {
 	pathAttrLen := uint8(0)
 
 	switch pa.TypeCode {
 	case OriginAttr:
 		pathAttrLen = pa.serializeOrigin(buf)
 	case ASPathAttr:
-		pathAttrLen = pa.serializeASPath(buf)
+		pathAttrLen = pa.serializeASPath(buf, opt)
 	case NextHopAttr:
 		pathAttrLen = pa.serializeNextHop(buf)
 	case MEDAttr:
@@ -421,21 +447,32 @@ func (pa *PathAttribute) serializeOrigin(buf *bytes.Buffer) uint8 {
 	return 4
 }
 
-func (pa *PathAttribute) serializeASPath(buf *bytes.Buffer) uint8 {
+func (pa *PathAttribute) serializeASPath(buf *bytes.Buffer, opt *Options) uint8 {
 	attrFlags := uint8(0)
 	attrFlags = setTransitive(attrFlags)
 	buf.WriteByte(attrFlags)
 	buf.WriteByte(ASPathAttr)
 
+	asnLength := uint8(2)
+	if opt.Supports4OctetASN {
+		asnLength = 4
+	}
+
 	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 {
-			segmentsBuf.Write(convert.Uint16Byte(uint16(asn)))
+			if asnLength == 2 {
+				segmentsBuf.Write(convert.Uint16Byte(uint16(asn)))
+			} else {
+				segmentsBuf.Write(convert.Uint32Byte(asn))
+			}
 		}
-		length += 2 + uint8(len(segment.ASNs))*2
+		fmt.Println(segment.ASNs)
+		length += 2 + uint8(len(segment.ASNs))*asnLength
 	}
 
 	buf.WriteByte(length)
diff --git a/protocols/bgp/packet/path_attributes_test.go b/protocols/bgp/packet/path_attributes_test.go
index 248b731714389096a62e2381a548780beb8318e7..c3d5ecda2e4d484ba48809651248e4ecd1c82188 100644
--- a/protocols/bgp/packet/path_attributes_test.go
+++ b/protocols/bgp/packet/path_attributes_test.go
@@ -50,7 +50,7 @@ func TestDecodePathAttrs(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		res, err := decodePathAttrs(bytes.NewBuffer(test.input), uint16(len(test.input)))
+		res, err := decodePathAttrs(bytes.NewBuffer(test.input), uint16(len(test.input)), &Options{})
 
 		if test.wantFail && err == nil {
 			t.Errorf("Expected error did not happen for test %q", test.name)
@@ -173,7 +173,7 @@ func TestDecodePathAttr(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		res, _, err := decodePathAttr(bytes.NewBuffer(test.input))
+		res, _, err := decodePathAttr(bytes.NewBuffer(test.input), &Options{})
 
 		if test.wantFail && err == nil {
 			t.Errorf("Expected error did not happen for test %q", test.name)
@@ -264,6 +264,7 @@ func TestDecodeASPath(t *testing.T) {
 		input          []byte
 		wantFail       bool
 		explicitLength uint16
+		use4OctetASNs  bool
 		expected       *PathAttribute
 	}{
 		{
@@ -308,6 +309,28 @@ func TestDecodeASPath(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "32 bit ASNs in AS_PATH",
+			input: []byte{
+				1, // AS_SEQUENCE
+				3, // Path Length
+				0, 0, 0, 100, 0, 0, 0, 222, 0, 0, 0, 240,
+			},
+			wantFail:      false,
+			use4OctetASNs: true,
+			expected: &PathAttribute{
+				Length: 14,
+				Value: ASPath{
+					ASPathSegment{
+						Type:  1,
+						Count: 3,
+						ASNs: []uint32{
+							100, 222, 240,
+						},
+					},
+				},
+			},
+		},
 		{
 			name:           "Empty input",
 			input:          []byte{},
@@ -326,28 +349,36 @@ func TestDecodeASPath(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		l := uint16(len(test.input))
-		if test.explicitLength != 0 {
-			l = test.explicitLength
-		}
-		pa := &PathAttribute{
-			Length: l,
-		}
-		err := pa.decodeASPath(bytes.NewBuffer(test.input))
+		t.Run(test.name, func(t *testing.T) {
+			l := uint16(len(test.input))
+			if test.explicitLength != 0 {
+				l = test.explicitLength
+			}
+			pa := &PathAttribute{
+				Length: l,
+			}
 
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
+			asnLength := uint8(2)
+			if test.use4OctetASNs {
+				asnLength = 4
+			}
 
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
+			err := pa.decodeASPath(bytes.NewBuffer(test.input), asnLength)
 
-		if err != nil {
-			continue
-		}
+			if test.wantFail && err == nil {
+				t.Errorf("Expected error did not happen for test %q", test.name)
+			}
 
-		assert.Equal(t, test.expected, pa)
+			if !test.wantFail && err != nil {
+				t.Errorf("Unexpected failure for test %q: %v", test.name, err)
+			}
+
+			if err != nil {
+				return
+			}
+
+			assert.Equal(t, test.expected, pa)
+		})
 	}
 }
 
@@ -1239,6 +1270,7 @@ func TestSerializeASPath(t *testing.T) {
 		input       *PathAttribute
 		expected    []byte
 		expectedLen uint8
+		use32BitASN bool
 	}{
 		{
 			name: "Test #1",
@@ -1265,17 +1297,49 @@ func TestSerializeASPath(t *testing.T) {
 			},
 			expectedLen: 10,
 		},
+		{
+			name: "32bit ASN",
+			input: &PathAttribute{
+				TypeCode: ASPathAttr,
+				Value: ASPath{
+					{
+						Type: 2, // Sequence
+						ASNs: []uint32{
+							100, 200, 210,
+						},
+					},
+				},
+			},
+			expected: []byte{
+				64,           // Attribute flags
+				2,            // Type
+				14,           // Length
+				2,            // AS_SEQUENCE
+				3,            // ASN count
+				0, 0, 0, 100, // ASN 100
+				0, 0, 0, 200, // ASN 200
+				0, 0, 0, 210, // ASN 210
+			},
+			expectedLen: 16,
+			use32BitASN: true,
+		},
 	}
 
+	t.Parallel()
+
 	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeASPath(buf)
-		if n != test.expectedLen {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
+		t.Run(test.name, func(t *testing.T) {
+			buf := bytes.NewBuffer(nil)
+			opt := &Options{
+				Supports4OctetASN: test.use32BitASN,
+			}
+			n := test.input.serializeASPath(buf, opt)
+			if n != test.expectedLen {
+				t.Fatalf("Unexpected length for test %q: %d", test.name, n)
+			}
 
-		assert.Equal(t, test.expected, buf.Bytes())
+			assert.Equal(t, test.expected, buf.Bytes())
+		})
 	}
 }
 
@@ -1561,7 +1625,8 @@ func TestSerialize(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		res, err := test.msg.SerializeUpdate()
+		opt := &Options{}
+		res, err := test.msg.SerializeUpdate(opt)
 		if err != nil {
 			if test.wantFail {
 				continue
@@ -1767,7 +1832,8 @@ func TestSerializeAddPath(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		res, err := test.msg.SerializeUpdate()
+		opt := &Options{}
+		res, err := test.msg.SerializeUpdate(opt)
 		if err != nil {
 			if test.wantFail {
 				continue
diff --git a/protocols/bgp/server/BUILD.bazel b/protocols/bgp/server/BUILD.bazel
index 02f664a367f52241763b99d0e46bf462ff5b0f67..345c18806a64e01267a63dc585e74864867db36a 100644
--- a/protocols/bgp/server/BUILD.bazel
+++ b/protocols/bgp/server/BUILD.bazel
@@ -33,6 +33,7 @@ go_library(
         "//routingtable/adjRIBIn:go_default_library",
         "//routingtable/adjRIBOut:go_default_library",
         "//routingtable/filter:go_default_library",
+        "//routingtable/locRIB:go_default_library",
         "//vendor/github.com/sirupsen/logrus:go_default_library",
     ],
 )
@@ -40,6 +41,8 @@ go_library(
 go_test(
     name = "go_default_test",
     srcs = [
+        "fsm_open_sent_test.go",
+        "fsm_test.go",
         "server_test.go",
         "update_helper_test.go",
         "withdraw_test.go",
diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go
index 33e000d1c6010a2e3b976b13bec591a7e0e67545..cf970b40483511c2ecafc1d36597f66117de06ef 100644
--- a/protocols/bgp/server/fsm.go
+++ b/protocols/bgp/server/fsm.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
 	"github.com/bio-routing/bio-rd/routingtable"
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -56,12 +57,14 @@ type FSM struct {
 	capAddPathSend bool
 	capAddPathRecv bool
 
+	options *packet.Options
+
 	local net.IP
 
 	ribsInitialized bool
 	adjRIBIn        routingtable.RouteTableClient
 	adjRIBOut       routingtable.RouteTableClient
-	rib             routingtable.RouteTableClient
+	rib             *locRIB.LocRIB
 	updateSender    routingtable.RouteTableClient
 
 	neighborID uint32
@@ -99,6 +102,7 @@ func newFSM2(peer *peer) *FSM {
 		msgRecvFailCh:    make(chan error),
 		stopMsgRecvCh:    make(chan struct{}),
 		rib:              peer.rib,
+		options:          &packet.Options{},
 	}
 }
 
@@ -219,13 +223,7 @@ func (fsm *FSM) resetConnectRetryCounter() {
 }
 
 func (fsm *FSM) sendOpen() error {
-	msg := packet.SerializeOpenMsg(&packet.BGPOpen{
-		Version:       BGPVersion,
-		AS:            uint16(fsm.peer.localASN),
-		HoldTime:      uint16(fsm.peer.holdTime / time.Second),
-		BGPIdentifier: fsm.peer.server.routerID,
-		OptParams:     fsm.peer.optOpenParams,
-	})
+	msg := packet.SerializeOpenMsg(fsm.openMessage())
 
 	_, err := fsm.con.Write(msg)
 	if err != nil {
@@ -235,6 +233,24 @@ func (fsm *FSM) sendOpen() error {
 	return nil
 }
 
+func (fsm *FSM) openMessage() *packet.BGPOpen {
+	return &packet.BGPOpen{
+		Version:       BGPVersion,
+		ASN:           fsm.local16BitASN(),
+		HoldTime:      uint16(fsm.peer.holdTime / time.Second),
+		BGPIdentifier: fsm.peer.routerID,
+		OptParams:     fsm.peer.optOpenParams,
+	}
+}
+
+func (fsm *FSM) local16BitASN() uint16 {
+	if fsm.peer.localASN > uint32(^uint16(0)) {
+		return packet.ASTransASN
+	}
+
+	return uint16(fsm.peer.localASN)
+}
+
 func (fsm *FSM) sendNotification(errorCode uint8, errorSubCode uint8) error {
 	msg := packet.SerializeNotificationMsg(&packet.BGPNotification{})
 
diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go
index 80ff7fa7990493186924f8c35f1a90deb0c93e5b..66480407dc7e39e174b4f391017bfdc8c9f2e05f 100644
--- a/protocols/bgp/server/fsm_established.go
+++ b/protocols/bgp/server/fsm_established.go
@@ -55,7 +55,10 @@ func (s establishedState) run() (state, string) {
 }
 
 func (s *establishedState) init() error {
-	s.fsm.adjRIBIn = adjRIBIn.New(s.fsm.peer.importFilter)
+	contributingASNs := s.fsm.rib.GetContributingASNs()
+
+	s.fsm.adjRIBIn = adjRIBIn.New(s.fsm.peer.importFilter, contributingASNs)
+	contributingASNs.Add(s.fsm.peer.localASN)
 	s.fsm.adjRIBIn.Register(s.fsm.rib)
 
 	host, _, err := net.SplitHostPort(s.fsm.con.LocalAddr().String())
@@ -96,6 +99,7 @@ func (s *establishedState) init() error {
 }
 
 func (s *establishedState) uninit() {
+	s.fsm.rib.GetContributingASNs().Remove(s.fsm.peer.localASN)
 	s.fsm.adjRIBIn.Unregister(s.fsm.rib)
 	s.fsm.rib.Unregister(s.fsm.adjRIBOut)
 	s.fsm.adjRIBOut.Unregister(s.fsm.updateSender)
@@ -154,7 +158,7 @@ func (s *establishedState) keepaliveTimerExpired() (state, string) {
 }
 
 func (s *establishedState) msgReceived(data []byte) (state, string) {
-	msg, err := packet.Decode(bytes.NewBuffer(data))
+	msg, err := packet.Decode(bytes.NewBuffer(data), s.fsm.options)
 	if err != nil {
 		switch bgperr := err.(type) {
 		case packet.BGPError:
diff --git a/protocols/bgp/server/fsm_open_confirm.go b/protocols/bgp/server/fsm_open_confirm.go
index d2d25e4f533ec30d9a5d15aec25504d055c45f54..07b8a6152dd64c56055c7cbd0745980e462c3886 100644
--- a/protocols/bgp/server/fsm_open_confirm.go
+++ b/protocols/bgp/server/fsm_open_confirm.go
@@ -82,7 +82,7 @@ func (s *openConfirmState) keepaliveTimerExpired() (state, string) {
 }
 
 func (s *openConfirmState) msgReceived(data []byte) (state, string) {
-	msg, err := packet.Decode(bytes.NewBuffer(data))
+	msg, err := packet.Decode(bytes.NewBuffer(data), s.fsm.options)
 	if err != nil {
 		switch bgperr := err.(type) {
 		case packet.BGPError:
diff --git a/protocols/bgp/server/fsm_open_sent.go b/protocols/bgp/server/fsm_open_sent.go
index 63680636d8e0c65afe1dad9ec9d1280c34e9c37d..848c76697fb3a415b7e56131b67d3576d0e01722 100644
--- a/protocols/bgp/server/fsm_open_sent.go
+++ b/protocols/bgp/server/fsm_open_sent.go
@@ -10,7 +10,8 @@ import (
 )
 
 type openSentState struct {
-	fsm *FSM
+	fsm         *FSM
+	peerASNRcvd uint32
 }
 
 func newOpenSentState(fsm *FSM) *openSentState {
@@ -73,7 +74,7 @@ func (s *openSentState) holdTimerExpired() (state, string) {
 }
 
 func (s *openSentState) msgReceived(data []byte) (state, string) {
-	msg, err := packet.Decode(bytes.NewBuffer(data))
+	msg, err := packet.Decode(bytes.NewBuffer(data), s.fsm.options)
 	if err != nil {
 		switch bgperr := err.(type) {
 		case packet.BGPError:
@@ -104,6 +105,8 @@ func (s *openSentState) unexpectedMessage() (state, string) {
 
 func (s *openSentState) openMsgReceived(msg *packet.BGPMessage) (state, string) {
 	openMsg := msg.Body.(*packet.BGPOpen)
+	s.peerASNRcvd = uint32(openMsg.ASN)
+
 	s.fsm.neighborID = openMsg.BGPIdentifier
 	stopTimer(s.fsm.connectRetryTimer)
 	if s.fsm.peer.collisionHandling(s.fsm) {
@@ -114,6 +117,10 @@ func (s *openSentState) openMsgReceived(msg *packet.BGPMessage) (state, string)
 		return s.tcpFailure()
 	}
 
+	return s.handleOpenMessage(openMsg)
+}
+
+func (s *openSentState) handleOpenMessage(openMsg *packet.BGPOpen) (state, string) {
 	s.fsm.holdTime = time.Duration(math.Min(float64(s.fsm.peer.holdTime), float64(time.Duration(openMsg.HoldTime)*time.Second)))
 	if s.fsm.holdTime != 0 {
 		if !s.fsm.holdTimer.Reset(s.fsm.holdTime) {
@@ -123,7 +130,13 @@ func (s *openSentState) openMsgReceived(msg *packet.BGPMessage) (state, string)
 		s.fsm.keepaliveTimer = time.NewTimer(s.fsm.keepaliveTime)
 	}
 
+	s.peerASNRcvd = uint32(openMsg.ASN)
 	s.processOpenOptions(openMsg.OptParams)
+
+	if s.peerASNRcvd != s.fsm.peer.peerASN {
+		return newCeaseState(), fmt.Sprintf("Expected session from %d, got open message with ASN %d", s.fsm.peer.peerASN, s.peerASNRcvd)
+	}
+
 	return newOpenConfirmState(s.fsm), "Received OPEN message"
 }
 
@@ -153,7 +166,8 @@ func (s *openSentState) processCapability(cap packet.Capability) {
 	switch cap.Code {
 	case packet.AddPathCapabilityCode:
 		s.processAddPathCapability(cap.Value.(packet.AddPathCapability))
-
+	case packet.ASN4CapabilityCode:
+		s.processASN4Capability(cap.Value.(packet.ASN4Capability))
 	}
 }
 
@@ -184,6 +198,14 @@ func (s *openSentState) processAddPathCapability(addPathCap packet.AddPathCapabi
 	}
 }
 
+func (s *openSentState) processASN4Capability(cap packet.ASN4Capability) {
+	s.fsm.options.Supports4OctetASN = true
+
+	if s.peerASNRcvd == packet.ASTransASN {
+		s.peerASNRcvd = cap.ASN4
+	}
+}
+
 func (s *openSentState) notification(msg *packet.BGPMessage) (state, string) {
 	stopTimer(s.fsm.connectRetryTimer)
 	s.fsm.con.Close()
diff --git a/protocols/bgp/server/fsm_open_sent_test.go b/protocols/bgp/server/fsm_open_sent_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..39057c6480f84c21d025e335cd95b2c7b34b2b08
--- /dev/null
+++ b/protocols/bgp/server/fsm_open_sent_test.go
@@ -0,0 +1,87 @@
+package server
+
+import (
+	"testing"
+
+	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestOpenMsgReceived(t *testing.T) {
+	tests := []struct {
+		asn        uint32
+		name       string
+		msg        packet.BGPOpen
+		wantsCease bool
+	}{
+		{
+			name: "valid open message (16bit ASN)",
+			asn:  12345,
+			msg: packet.BGPOpen{
+				HoldTime:      90,
+				BGPIdentifier: 1,
+				Version:       4,
+				ASN:           12345,
+			},
+		},
+		{
+			name: "valid open message (32bit ASN)",
+			asn:  202739,
+			msg: packet.BGPOpen{
+				HoldTime:      90,
+				BGPIdentifier: 1,
+				Version:       4,
+				ASN:           23456,
+				OptParmLen:    1,
+				OptParams: []packet.OptParam{
+					{
+						Type:   packet.CapabilitiesParamType,
+						Length: 6,
+						Value: packet.Capabilities{
+							packet.Capability{
+								Code:   packet.ASN4CapabilityCode,
+								Length: 4,
+								Value: packet.ASN4Capability{
+									ASN4: 202739,
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+		{
+			name: "open message does not match configured remote ASN",
+			asn:  12345,
+			msg: packet.BGPOpen{
+				HoldTime:      90,
+				BGPIdentifier: 1,
+				Version:       4,
+				ASN:           54321,
+			},
+			wantsCease: true,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			fsm := newFSM2(&peer{
+				peerASN: test.asn,
+			})
+
+			s := &openSentState{
+				fsm: fsm,
+			}
+
+			state, _ := s.handleOpenMessage(&test.msg)
+
+			if test.wantsCease {
+				assert.IsType(t, &ceaseState{}, state, "state")
+				return
+			}
+
+			assert.IsType(t, &openConfirmState{}, state, "state")
+			assert.Equal(t, test.asn, s.peerASNRcvd, "asn")
+		})
+	}
+}
diff --git a/protocols/bgp/server/fsm_test.go b/protocols/bgp/server/fsm_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c0b293936118c345060049cfcee77a4325861741
--- /dev/null
+++ b/protocols/bgp/server/fsm_test.go
@@ -0,0 +1,98 @@
+package server
+
+import (
+	"testing"
+	"time"
+
+	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestOpenMessage(t *testing.T) {
+	tests := []struct {
+		name     string
+		localASN uint32
+		holdTime time.Duration
+		routerID uint32
+		expected packet.BGPOpen
+	}{
+		{
+			name:     "16bit ASN",
+			localASN: 12345,
+			holdTime: time.Duration(30 * time.Second),
+			routerID: 1,
+			expected: packet.BGPOpen{
+				ASN:           12345,
+				BGPIdentifier: 1,
+				HoldTime:      30,
+				OptParams: []packet.OptParam{
+					packet.OptParam{
+						Type: packet.CapabilitiesParamType,
+						Value: packet.Capabilities{
+							packet.Capability{
+								Code: 65,
+								Value: packet.ASN4Capability{
+									ASN4: 12345,
+								},
+							},
+						},
+					},
+				},
+				Version: 4,
+			},
+		},
+		{
+			name:     "32bit ASN",
+			localASN: 202739,
+			holdTime: time.Duration(30 * time.Second),
+			routerID: 1,
+			expected: packet.BGPOpen{
+				ASN:           23456,
+				BGPIdentifier: 1,
+				HoldTime:      30,
+				OptParams: []packet.OptParam{
+					packet.OptParam{
+						Type: packet.CapabilitiesParamType,
+						Value: packet.Capabilities{
+							packet.Capability{
+								Code: 65,
+								Value: packet.ASN4Capability{
+									ASN4: 202739,
+								},
+							},
+						},
+					},
+				},
+				Version: 4,
+			},
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			p := peer{
+				localASN: test.localASN,
+				holdTime: test.holdTime,
+				routerID: test.routerID,
+				optOpenParams: []packet.OptParam{
+					packet.OptParam{
+						Type: packet.CapabilitiesParamType,
+						Value: packet.Capabilities{
+							packet.Capability{
+								Code: 65,
+								Value: packet.ASN4Capability{
+									ASN4: test.localASN,
+								},
+							},
+						},
+					},
+				},
+			}
+
+			fsm := newFSM2(&p)
+			msg := fsm.openMessage()
+
+			assert.Equal(t, &test.expected, msg)
+		})
+	}
+}
diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go
index bad268285a156e5d32576af75521f42a7436a603..125393fb8fbfbfb5ed4bb626a5bc0aa352094d82 100644
--- a/protocols/bgp/server/peer.go
+++ b/protocols/bgp/server/peer.go
@@ -9,6 +9,7 @@ import (
 	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
 	"github.com/bio-routing/bio-rd/routingtable"
 	"github.com/bio-routing/bio-rd/routingtable/filter"
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
 )
 
 type PeerInfo struct {
@@ -27,7 +28,7 @@ type peer struct {
 	fsms   []*FSM
 	fsmsMu sync.Mutex
 
-	rib               routingtable.RouteTableClient
+	rib               *locRIB.LocRIB
 	routerID          uint32
 	addPathSend       routingtable.ClientOptions
 	addPathRecv       bool
@@ -100,7 +101,7 @@ func isEstablishedState(s state) bool {
 
 // 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 routingtable.RouteTableClient, server *bgpServer) (*peer, error) {
+func newPeer(c config.Peer, rib *locRIB.LocRIB, server *bgpServer) (*peer, error) {
 	if c.LocalAS == 0 {
 		c.LocalAS = server.localASN
 	}
@@ -125,24 +126,12 @@ func newPeer(c config.Peer, rib routingtable.RouteTableClient, server *bgpServer
 
 	caps := make([]packet.Capability, 0)
 
-	addPath := uint8(0)
-	if c.AddPathRecv {
-		addPath += packet.AddPathReceive
-	}
-	if !c.AddPathSend.BestOnly {
-		addPath += packet.AddPathSend
+	addPathEnabled, addPathCap := handleAddPathCapability(c)
+	if addPathEnabled {
+		caps = append(caps, addPathCap)
 	}
 
-	if addPath > 0 {
-		caps = append(caps, packet.Capability{
-			Code: packet.AddPathCapabilityCode,
-			Value: packet.AddPathCapability{
-				AFI:         packet.IPv4AFI,
-				SAFI:        packet.UnicastSAFI,
-				SendReceive: addPath,
-			},
-		})
-	}
+	caps = append(caps, asn4Capability(c))
 
 	for _, cap := range caps {
 		p.optOpenParams = append(p.optOpenParams, packet.OptParam{
@@ -154,6 +143,38 @@ func newPeer(c config.Peer, rib routingtable.RouteTableClient, server *bgpServer
 	return p, nil
 }
 
+func asn4Capability(c config.Peer) packet.Capability {
+	return packet.Capability{
+		Code: packet.ASN4CapabilityCode,
+		Value: packet.ASN4Capability{
+			ASN4: c.LocalAS,
+		},
+	}
+}
+
+func handleAddPathCapability(c config.Peer) (bool, packet.Capability) {
+	addPath := uint8(0)
+	if c.AddPathRecv {
+		addPath += packet.AddPathReceive
+	}
+	if !c.AddPathSend.BestOnly {
+		addPath += packet.AddPathSend
+	}
+
+	if addPath == 0 {
+		return false, packet.Capability{}
+	}
+
+	return true, packet.Capability{
+		Code: packet.AddPathCapabilityCode,
+		Value: packet.AddPathCapability{
+			AFI:         packet.IPv4AFI,
+			SAFI:        packet.UnicastSAFI,
+			SendReceive: addPath,
+		},
+	}
+}
+
 func filterOrDefault(f *filter.Filter) *filter.Filter {
 	if f != nil {
 		return f
diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go
index 61c79de10315e5efa65c27e7da820b3a39aee4df..db6ae24f310cf027114e5e95aee7fee3211aac8b 100644
--- a/protocols/bgp/server/server.go
+++ b/protocols/bgp/server/server.go
@@ -9,12 +9,11 @@ import (
 
 	"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"
 	log "github.com/sirupsen/logrus"
 )
 
 const (
-	uint16max  = 65535
 	BGPVersion = 4
 )
 
@@ -29,7 +28,7 @@ type bgpServer struct {
 type BGPServer interface {
 	RouterID() uint32
 	Start(*config.Global) error
-	AddPeer(config.Peer, routingtable.RouteTableClient) error
+	AddPeer(config.Peer, *locRIB.LocRIB) error
 	GetPeerInfoAll() map[string]PeerInfo
 }
 
@@ -113,11 +112,7 @@ func (b *bgpServer) incomingConnectionWorker() {
 	}
 }
 
-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")
-	}
-
+func (b *bgpServer) AddPeer(c config.Peer, rib *locRIB.LocRIB) error {
 	peer, err := newPeer(c, rib, b)
 	if err != nil {
 		return err
diff --git a/protocols/bgp/server/server_test.go b/protocols/bgp/server/server_test.go
index 86095be8e22e28168e2b66c1a70217969263fe18..baf30a19344cb12c284ec22eb364809d7dc4cd72 100644
--- a/protocols/bgp/server/server_test.go
+++ b/protocols/bgp/server/server_test.go
@@ -11,23 +11,6 @@ import (
 	"github.com/bio-routing/bio-rd/routingtable/locRIB"
 )
 
-func TestBgpServerConfigCheck(t *testing.T) {
-	s := NewBgpServer()
-
-	err := s.Start(&config.Global{})
-	if err == nil {
-		t.Fatalf("server with empty config should not start")
-	}
-
-	err = s.Start(&config.Global{
-		LocalASN: 204880,
-		RouterID: 2137,
-	})
-	if err != nil {
-		t.Fatalf("server should have started, got err: %v", err)
-	}
-}
-
 func TestBgpServerPeerSnapshot(t *testing.T) {
 	s := NewBgpServer()
 	err := s.Start(&config.Global{
diff --git a/protocols/bgp/server/update_helper.go b/protocols/bgp/server/update_helper.go
index 34f784a1de6f22cae74839dbf348865e58472c06..c45181803ee3c5c54f777cfbb66e7d3ad6831d53 100644
--- a/protocols/bgp/server/update_helper.go
+++ b/protocols/bgp/server/update_helper.go
@@ -72,17 +72,16 @@ func addOptionalPathAttribues(p *route.Path, parent *packet.PathAttribute) error
 }
 
 type serializeAbleUpdate interface {
-	SerializeUpdate() ([]byte, error)
+	SerializeUpdate(opt *packet.Options) ([]byte, error)
 }
 
-func serializeAndSendUpdate(out io.Writer, update serializeAbleUpdate) error {
-	updateBytes, err := update.SerializeUpdate()
+func serializeAndSendUpdate(out io.Writer, update serializeAbleUpdate, opt *packet.Options) error {
+	updateBytes, err := update.SerializeUpdate(opt)
 	if err != nil {
 		log.Errorf("Unable to serialize BGP Update: %v", err)
 		return nil
 	}
 
-	fmt.Printf("Sending Update: %v\n", updateBytes)
 	_, err = out.Write(updateBytes)
 	if err != nil {
 		return fmt.Errorf("Failed sending Update: %v", err)
diff --git a/protocols/bgp/server/update_helper_test.go b/protocols/bgp/server/update_helper_test.go
index 5752edded4aba03b66acd88950796e21c2c82620..d2d0a7fcf424276b6a351176cebc9a3959f9ec69 100644
--- a/protocols/bgp/server/update_helper_test.go
+++ b/protocols/bgp/server/update_helper_test.go
@@ -16,7 +16,7 @@ import (
 
 type failingUpdate struct{}
 
-func (f *failingUpdate) SerializeUpdate() ([]byte, error) {
+func (f *failingUpdate) SerializeUpdate(opt *packet.Options) ([]byte, error) {
 	return nil, errors.New("general error")
 }
 
@@ -94,12 +94,12 @@ func TestSerializeAndSendUpdate(t *testing.T) {
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			err := serializeAndSendUpdate(test.buf, test.testUpdate)
+			opt := &packet.Options{}
+			err := serializeAndSendUpdate(test.buf, test.testUpdate, opt)
 			assert.Equal(t, test.err, err)
 
 			assert.Equal(t, test.expected, test.buf.Bytes())
 		})
-
 	}
 }
 
diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go
index 67fb6662febaec64942dd48c6164ad00b0441bc4..a6ae74afeb29d7e5c3b4ec9538a6ecc18ffce32f 100644
--- a/protocols/bgp/server/update_sender.go
+++ b/protocols/bgp/server/update_sender.go
@@ -42,12 +42,12 @@ func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error {
 		},
 	}
 
-	return serializeAndSendUpdate(u.fsm.con, update)
+	return serializeAndSendUpdate(u.fsm.con, update, u.fsm.options)
 }
 
 // RemovePath withdraws prefix `pfx` from a peer
 func (u *UpdateSender) RemovePath(pfx net.Prefix, p *route.Path) bool {
-	err := withDrawPrefixes(u.fsm.con, pfx)
+	err := withDrawPrefixes(u.fsm.con, u.fsm.options, pfx)
 	return err == nil
 }
 
diff --git a/protocols/bgp/server/update_sender_add_path.go b/protocols/bgp/server/update_sender_add_path.go
index 7abef161e4f5accd6b49b423849fbbd3d4a56742..afdb71f31ba31618bed84f175478cc95f18f850f 100644
--- a/protocols/bgp/server/update_sender_add_path.go
+++ b/protocols/bgp/server/update_sender_add_path.go
@@ -39,12 +39,12 @@ func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
 			Pfxlen:         pfx.Pfxlen(),
 		},
 	}
-	return serializeAndSendUpdate(u.fsm.con, update)
+	return serializeAndSendUpdate(u.fsm.con, update, u.fsm.options)
 }
 
 // RemovePath withdraws prefix `pfx` from a peer
 func (u *UpdateSenderAddPath) RemovePath(pfx net.Prefix, p *route.Path) bool {
-	err := withDrawPrefixesAddPath(u.fsm.con, pfx, p)
+	err := withDrawPrefixesAddPath(u.fsm.con, u.fsm.options, pfx, p)
 	return err == nil
 }
 
diff --git a/protocols/bgp/server/withdraw.go b/protocols/bgp/server/withdraw.go
index 42e97a399cdcf8c208fc29063f7213e4d780ad96..089f9f2c0f7a0e25d1c5d1f2e9f292cdeec74a3c 100644
--- a/protocols/bgp/server/withdraw.go
+++ b/protocols/bgp/server/withdraw.go
@@ -11,7 +11,7 @@ import (
 
 // withDrawPrefixes generates a BGPUpdate message and write it to the given
 // io.Writer.
-func withDrawPrefixes(out io.Writer, prefixes ...net.Prefix) error {
+func withDrawPrefixes(out io.Writer, opt *packet.Options, prefixes ...net.Prefix) error {
 	if len(prefixes) < 1 {
 		return nil
 	}
@@ -35,13 +35,13 @@ func withDrawPrefixes(out io.Writer, prefixes ...net.Prefix) error {
 	update := &packet.BGPUpdate{
 		WithdrawnRoutes: rootNLRI,
 	}
-	return serializeAndSendUpdate(out, update)
+	return serializeAndSendUpdate(out, update, opt)
 
 }
 
 // withDrawPrefixesAddPath generates a BGPUpdateAddPath message and write it to the given
 // io.Writer.
-func withDrawPrefixesAddPath(out io.Writer, pfx net.Prefix, p *route.Path) error {
+func withDrawPrefixesAddPath(out io.Writer, opt *packet.Options, pfx net.Prefix, p *route.Path) error {
 	if p.Type != route.BGPPathType {
 		return errors.New("wrong path type, expected BGPPathType")
 	}
@@ -55,5 +55,5 @@ func withDrawPrefixesAddPath(out io.Writer, pfx net.Prefix, p *route.Path) error
 			Pfxlen:         pfx.Pfxlen(),
 		},
 	}
-	return serializeAndSendUpdate(out, update)
+	return serializeAndSendUpdate(out, update, opt)
 }
diff --git a/protocols/bgp/server/withdraw_test.go b/protocols/bgp/server/withdraw_test.go
index 0df94f75259aa446af0d78d1a65aa9ea7a4c67b2..d8831c3eb526d3afdaceb0a3506bf5dca39c2c41 100644
--- a/protocols/bgp/server/withdraw_test.go
+++ b/protocols/bgp/server/withdraw_test.go
@@ -3,6 +3,8 @@ package server
 import (
 	"testing"
 
+	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
+
 	"errors"
 
 	"bytes"
@@ -52,7 +54,8 @@ func TestWithDrawPrefixes(t *testing.T) {
 	}
 	for _, tc := range testcases {
 		buf := bytes.NewBuffer([]byte{})
-		err := withDrawPrefixes(buf, tc.Prefix...)
+		opt := &packet.Options{}
+		err := withDrawPrefixes(buf, opt, tc.Prefix...)
 		assert.Equal(t, tc.ExpectedError, err, "error mismatch in testcase %v", tc.Name)
 		assert.Equal(t, tc.Expected, buf.Bytes(), "expected different bytes in testcase %v", tc.Name)
 	}
@@ -108,7 +111,8 @@ func TestWithDrawPrefixesAddPath(t *testing.T) {
 	}
 	for _, tc := range testcases {
 		buf := bytes.NewBuffer([]byte{})
-		err := withDrawPrefixesAddPath(buf, tc.Prefix, tc.Path)
+		opt := &packet.Options{}
+		err := withDrawPrefixesAddPath(buf, opt, tc.Prefix, tc.Path)
 		assert.Equal(t, tc.ExpectedError, err, "error mismatch in testcase %v", tc.Name)
 		assert.Equal(t, tc.Expected, buf.Bytes(), "expected different bytes in testcase %v", tc.Name)
 	}
diff --git a/routingtable/BUILD.bazel b/routingtable/BUILD.bazel
index 1c166185a9a502a88d8442ba33f90aac43a22ee1..fdea62781ff59b143bf04d143ee5eae9385e0bc6 100644
--- a/routingtable/BUILD.bazel
+++ b/routingtable/BUILD.bazel
@@ -5,6 +5,7 @@ go_library(
     srcs = [
         "client_interface.go",
         "client_manager.go",
+        "contributing_asn_list.go",
         "neighbor.go",
         "rib_interface.go",
         "table.go",
@@ -25,6 +26,7 @@ go_test(
     name = "go_default_test",
     srcs = [
         "client_manager_test.go",
+        "contributing_asn_list_test.go",
         "table_test.go",
         "trie_test.go",
         "update_helper_test.go",
diff --git a/routingtable/adjRIBIn/BUILD.bazel b/routingtable/adjRIBIn/BUILD.bazel
index 6216861c145d1b50f23032fd42102271864449d7..3796a7a878f2fcc9cc8cfe15d39cd1bd38fdf144 100644
--- a/routingtable/adjRIBIn/BUILD.bazel
+++ b/routingtable/adjRIBIn/BUILD.bazel
@@ -7,6 +7,7 @@ go_library(
     visibility = ["//visibility:public"],
     deps = [
         "//net:go_default_library",
+        "//protocols/bgp/packet:go_default_library",
         "//route:go_default_library",
         "//routingtable:go_default_library",
         "//routingtable/filter:go_default_library",
diff --git a/routingtable/adjRIBIn/adj_rib_in.go b/routingtable/adjRIBIn/adj_rib_in.go
index ca9d0bb07570811beec3ffa3eb99ec12423f6041..2d8500240de4dcc34b571996ea5b50514c414c4a 100644
--- a/routingtable/adjRIBIn/adj_rib_in.go
+++ b/routingtable/adjRIBIn/adj_rib_in.go
@@ -3,6 +3,7 @@ package adjRIBIn
 import (
 	"sync"
 
+	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
 	"github.com/bio-routing/bio-rd/routingtable/filter"
 
 	"github.com/bio-routing/bio-rd/net"
@@ -14,16 +15,18 @@ import (
 // AdjRIBIn represents an Adjacency RIB In as described in RFC4271
 type AdjRIBIn struct {
 	routingtable.ClientManager
-	rt           *routingtable.RoutingTable
-	mu           sync.RWMutex
-	exportFilter *filter.Filter
+	rt               *routingtable.RoutingTable
+	mu               sync.RWMutex
+	exportFilter     *filter.Filter
+	contributingASNs *routingtable.ContributingASNs
 }
 
 // New creates a new Adjacency RIB In
-func New(exportFilter *filter.Filter) *AdjRIBIn {
+func New(exportFilter *filter.Filter, contributingASNs *routingtable.ContributingASNs) *AdjRIBIn {
 	a := &AdjRIBIn{
-		rt:           routingtable.NewRoutingTable(),
-		exportFilter: exportFilter,
+		rt:               routingtable.NewRoutingTable(),
+		exportFilter:     exportFilter,
+		contributingASNs: contributingASNs,
 	}
 	a.ClientManager = routingtable.NewClientManager(a)
 	return a
@@ -65,12 +68,32 @@ func (a *AdjRIBIn) AddPath(pfx net.Prefix, p *route.Path) error {
 		return nil
 	}
 
+	// Bail out - for all clients for now - if any of our ASNs is within the path
+	if a.ourASNsInPath(p) {
+		return nil
+	}
+
 	for _, client := range a.ClientManager.Clients() {
 		client.AddPath(pfx, p)
 	}
 	return nil
 }
 
+func (a *AdjRIBIn) ourASNsInPath(p *route.Path) bool {
+	// Don't accept path via iBGP which contain our ASN
+	ASPathAttr, _ := packet.ParseASPathStr(p.BGPPath.ASPath)
+
+	for _, pathSegment := range ASPathAttr.Value.(packet.ASPath) {
+		for _, asn := range pathSegment.ASNs {
+			if a.contributingASNs.IsContributingASN(asn) {
+				return true
+			}
+		}
+	}
+
+	return false
+}
+
 // RemovePath removes the path for prefix `pfx`
 func (a *AdjRIBIn) RemovePath(pfx net.Prefix, p *route.Path) bool {
 	a.mu.Lock()
diff --git a/routingtable/adjRIBIn/adj_rib_in_test.go b/routingtable/adjRIBIn/adj_rib_in_test.go
index 48ac1fdb3efbe6c4aac8c0cbbef8371f1dc691af..0eeacc3e21162d9fac3cd2461dc788083f08796e 100644
--- a/routingtable/adjRIBIn/adj_rib_in_test.go
+++ b/routingtable/adjRIBIn/adj_rib_in_test.go
@@ -115,7 +115,7 @@ func TestAddPath(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		adjRIBIn := New(filter.NewAcceptAllFilter())
+		adjRIBIn := New(filter.NewAcceptAllFilter(), routingtable.NewContributingASNs())
 		mc := NewRTMockClient()
 		adjRIBIn.ClientManager.Register(mc)
 
@@ -206,7 +206,7 @@ func TestRemovePath(t *testing.T) {
 	}
 
 	for _, test := range tests {
-		adjRIBIn := New(filter.NewAcceptAllFilter())
+		adjRIBIn := New(filter.NewAcceptAllFilter(), routingtable.NewContributingASNs())
 		for _, route := range test.routes {
 			adjRIBIn.AddPath(route.Prefix(), route.Paths()[0])
 		}
diff --git a/routingtable/adjRIBOut/adj_rib_out.go b/routingtable/adjRIBOut/adj_rib_out.go
index e5ea8e516e1c1ebd9ef3ed11cad117b6b7fbb0e0..19b44b8bd2595cc550a960ace7c9c00f1fdab21a 100644
--- a/routingtable/adjRIBOut/adj_rib_out.go
+++ b/routingtable/adjRIBOut/adj_rib_out.go
@@ -45,6 +45,11 @@ func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
 		return nil
 	}
 
+	// Don't export routes learned via iBGP to an iBGP neighbor
+	if !p.BGPPath.EBGP && a.neighbor.IBGP {
+		return nil
+	}
+
 	p = p.Copy()
 	if !a.neighbor.IBGP && !a.neighbor.RouteServerClient {
 		p.BGPPath.ASPath = fmt.Sprintf("%d %s", a.neighbor.LocalASN, p.BGPPath.ASPath)
@@ -67,12 +72,10 @@ func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
 		a.removePathsFromClients(pfx, oldPaths)
 	}
 
-	fmt.Printf("Adding path: %s\n", p.Print())
 	pathID, err := a.pathIDManager.addPath(p)
 	if err != nil {
 		return fmt.Errorf("Unable to get path ID: %v", err)
 	}
-	fmt.Printf("New path ID: %d\n", pathID)
 
 	p.BGPPath.PathIdentifier = pathID
 	a.rt.AddPath(pfx, p)
diff --git a/routingtable/contributing_asn_list.go b/routingtable/contributing_asn_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..500b79b61d66825b6f0e9c21d3508adc970c36e3
--- /dev/null
+++ b/routingtable/contributing_asn_list.go
@@ -0,0 +1,88 @@
+package routingtable
+
+import (
+	"fmt"
+	"math"
+	"sync"
+)
+
+type contributingASN struct {
+	asn   uint32
+	count uint32
+}
+
+// ContributingASNs contains a list of contributing ASN to a LocRIB to check ASPaths for possible routing loops.
+type ContributingASNs struct {
+	contributingASNs     []*contributingASN
+	contributingASNsLock sync.RWMutex
+}
+
+// NewContributingASNs creates a list of contributing ASNs to a LocRIB for routing loop prevention.
+func NewContributingASNs() *ContributingASNs {
+	c := &ContributingASNs{
+		contributingASNs: []*contributingASN{},
+	}
+
+	return c
+}
+
+// Add a new ASN to the list of contributing ASNs or add the ref count of an existing one.
+func (c *ContributingASNs) Add(asn uint32) {
+	c.contributingASNsLock.Lock()
+	defer c.contributingASNsLock.Unlock()
+
+	for _, cASN := range c.contributingASNs {
+		if cASN.asn == asn {
+			cASN.count++
+
+			if cASN.count == math.MaxUint32 {
+				panic(fmt.Sprintf("Contributing ASNs counter overflow triggered for AS %d. Dyning of shame.", asn))
+			}
+
+			return
+		}
+	}
+
+	c.contributingASNs = append(c.contributingASNs, &contributingASN{
+		asn:   asn,
+		count: 1,
+	})
+}
+
+// Remove a ASN to the list of contributing ASNs or decrement the ref count of an existing one.
+func (c *ContributingASNs) Remove(asn uint32) {
+	c.contributingASNsLock.Lock()
+	defer c.contributingASNsLock.Unlock()
+
+	asnList := c.contributingASNs
+
+	for i, cASN := range asnList {
+		if cASN.asn != asn {
+			continue
+		}
+
+		cASN.count--
+
+		if cASN.count == 0 {
+			copy(asnList[i:], asnList[i+1:])
+			asnList = asnList[:len(asnList)]
+			c.contributingASNs = asnList[:len(asnList)-1]
+		}
+
+		return
+	}
+}
+
+// IsContributingASN checks if  a given ASN is part of the contributing ASNs
+func (c *ContributingASNs) IsContributingASN(asn uint32) bool {
+	c.contributingASNsLock.RLock()
+	defer c.contributingASNsLock.RUnlock()
+
+	for _, cASN := range c.contributingASNs {
+		if asn == cASN.asn {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/routingtable/contributing_asn_list_test.go b/routingtable/contributing_asn_list_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6387b18bcca92c290bc724ed8d13032104d247fa
--- /dev/null
+++ b/routingtable/contributing_asn_list_test.go
@@ -0,0 +1,90 @@
+package routingtable
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestFancy(t *testing.T) {
+	c := NewContributingASNs()
+
+	tests := []struct {
+		runCmd func()
+		expect func() bool
+		msg    string
+	}{
+		// Empty list
+		{
+			runCmd: func() {},
+			expect: func() bool { return !c.IsContributingASN(41981) },
+			msg:    "AS41981 shouldn't be contributing yet.",
+		},
+
+		// Add and remove one ASN
+		{
+			runCmd: func() { c.Add(41981) },
+			expect: func() bool { return c.IsContributingASN(41981) },
+			msg:    "AS41981 should be contributing.",
+		},
+		{
+			runCmd: func() { c.Remove(41981) },
+			expect: func() bool { return !c.IsContributingASN(41981) },
+			msg:    "AS41981 shouldn't be contributing no more.",
+		},
+
+		// Two ASNs present
+		{
+			runCmd: func() { c.Add(41981) },
+			expect: func() bool { return c.IsContributingASN(41981) },
+			msg:    "AS41981 should be contributing.",
+		},
+		{
+			runCmd: func() { c.Add(201701) },
+			expect: func() bool { return c.IsContributingASN(41981) },
+			msg:    "AS201701 should be contributing.",
+		},
+
+		// Add AS41981 2nd time
+		{
+			runCmd: func() { c.Add(41981) },
+			expect: func() bool { return c.IsContributingASN(41981) },
+			msg:    "AS41981 should be still contributing.",
+		},
+		{
+			runCmd: func() {},
+			expect: func() bool { return c.contributingASNs[0].asn == 41981 },
+			msg:    "AS41981 is first ASN in list.",
+		},
+		{
+			runCmd: func() { fmt.Printf("%+v", c.contributingASNs) },
+			expect: func() bool { return c.contributingASNs[0].count == 2 },
+			msg:    "AS41981 should be present twice.",
+		},
+
+		// Remove 2nd AS41981
+		{
+			runCmd: func() { c.Remove(41981) },
+			expect: func() bool { return c.IsContributingASN(41981) },
+			msg:    "AS41981 should still be contributing.",
+		},
+		{
+			runCmd: func() {},
+			expect: func() bool { return c.contributingASNs[0].count == 1 },
+			msg:    "S41981 should be present once.",
+		},
+
+		// Remove AS201701
+		{
+			runCmd: func() { c.Remove(201701) },
+			expect: func() bool { return !c.IsContributingASN(201701) },
+			msg:    "AS201701 shouldn't be contributing no more.",
+		},
+	}
+
+	for i, test := range tests {
+		test.runCmd()
+		if !test.expect() {
+			t.Errorf("Test %d failed: %v", i, test.msg)
+		}
+	}
+}
diff --git a/routingtable/filter/filter_test.go b/routingtable/filter/filter_test.go
index 2f4aace7637f30095d106520495d12a2d3ad9626..273e986d29dc4e25a6788bfb8f750e54bff6beb4 100644
--- a/routingtable/filter/filter_test.go
+++ b/routingtable/filter/filter_test.go
@@ -1,85 +1,21 @@
 package filter
 
-/*func TestAddPath(t *testing.T) {
-	tests := []struct {
-		name           string
-		prefix         net.Prefix
-		path           *route.Path
-		term           *Term
-		exptectCalled  bool
-		expectModified bool
-	}{
-		{
-			name:   "accept",
-			prefix: net.NewPfx(0, 0),
-			path:   &route.Path{},
-			term: &Term{
-				then: []FilterAction{
-					&actions.AcceptAction{},
-				},
-			},
-			exptectCalled:  true,
-			expectModified: false,
-		},
-		{
-			name:   "reject",
-			prefix: net.NewPfx(0, 0),
-			path:   &route.Path{},
-			term: &Term{
-				then: []FilterAction{
-					&actions.RejectAction{},
-				},
-			},
-			exptectCalled:  false,
-			expectModified: false,
-		},
-		{
-			name:   "modified",
-			prefix: net.NewPfx(0, 0),
-			path:   &route.Path{},
-			term: &Term{
-				then: []FilterAction{
-					&mockAction{},
-					&actions.AcceptAction{},
-				},
-			},
-			exptectCalled:  true,
-			expectModified: true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(te *testing.T) {
-			m := newClientMock()
-
-			f := NewFilter([]*Term{test.term})
-			f.Register(m)
+import (
+	"testing"
 
-			f.AddPath(test.prefix, test.path)
-			assert.Equal(te, test.exptectCalled, m.addPathCalled, "called")
+	"github.com/bio-routing/bio-rd/net"
+	"github.com/bio-routing/bio-rd/route"
+	"github.com/bio-routing/bio-rd/routingtable/filter/actions"
+	"github.com/stretchr/testify/assert"
+)
 
-			if !test.exptectCalled {
-				return
-			}
-
-			if m.path != test.path && !test.expectModified {
-				te.Fatal("expected path to be not modified but was")
-			}
-
-			if m.path == test.path && test.expectModified {
-				te.Fatal("expected path to be modified but was same reference")
-			}
-		})
-	}
-}
-
-func TestRemovePath(t *testing.T) {
+func TestProcessTerms(t *testing.T) {
 	tests := []struct {
 		name           string
 		prefix         net.Prefix
 		path           *route.Path
 		term           *Term
-		exptectCalled  bool
+		exptectAccept  bool
 		expectModified bool
 	}{
 		{
@@ -91,7 +27,7 @@ func TestRemovePath(t *testing.T) {
 					&actions.AcceptAction{},
 				},
 			},
-			exptectCalled:  true,
+			exptectAccept:  true,
 			expectModified: false,
 		},
 		{
@@ -103,7 +39,7 @@ func TestRemovePath(t *testing.T) {
 					&actions.RejectAction{},
 				},
 			},
-			exptectCalled:  false,
+			exptectAccept:  false,
 			expectModified: false,
 		},
 		{
@@ -116,32 +52,21 @@ func TestRemovePath(t *testing.T) {
 					&actions.AcceptAction{},
 				},
 			},
-			exptectCalled:  true,
+			exptectAccept:  true,
 			expectModified: true,
 		},
 	}
 
 	for _, test := range tests {
 		t.Run(test.name, func(te *testing.T) {
-			m := newClientMock()
-
 			f := NewFilter([]*Term{test.term})
-			f.Register(m)
+			p, reject := f.ProcessTerms(test.prefix, test.path)
 
-			f.RemovePath(test.prefix, test.path)
-			assert.Equal(te, test.exptectCalled, m.removePathCalled, "called")
-
-			if !test.exptectCalled {
-				return
-			}
+			assert.Equal(t, test.exptectAccept, !reject)
 
-			if m.path != test.path && !test.expectModified {
-				te.Fatal("expected path to be not modified but was")
-			}
-
-			if m.path == test.path && test.expectModified {
-				te.Fatal("expected path to be modified but was same reference")
+			if test.expectModified {
+				assert.NotEqual(t, test.path, p)
 			}
 		})
 	}
-}*/
+}
diff --git a/routingtable/filter/helper_test.go b/routingtable/filter/helper_test.go
index 5d82727a9f2b5b5e0f692a980d9d7515ccd4c71d..19a444d4a5c8d656534cfb415f2b401a11ae4c57 100644
--- a/routingtable/filter/helper_test.go
+++ b/routingtable/filter/helper_test.go
@@ -1,27 +1,23 @@
 package filter
 
-/*func TestNewAcceptAllFilter(t *testing.T) {
-	f := NewAcceptAllFilter()
+import (
+	"testing"
 
-	m := &clientMock{}
-	f.Register(m)
+	"github.com/bio-routing/bio-rd/net"
+	"github.com/bio-routing/bio-rd/route"
+	"github.com/stretchr/testify/assert"
+)
 
-	f.AddPath(net.NewPfx(0, 0), &route.Path{})
+func TestNewAcceptAllFilter(t *testing.T) {
+	f := NewAcceptAllFilter()
 
-	if !m.addPathCalled {
-		t.Fatalf("expected accepted, but was filtered")
-	}
+	_, reject := f.ProcessTerms(net.NewPfx(0, 0), &route.Path{})
+	assert.Equal(t, false, reject)
 }
 
 func TestNewDrainFilter(t *testing.T) {
 	f := NewDrainFilter()
 
-	m := &clientMock{}
-	f.Register(m)
-
-	f.AddPath(net.NewPfx(0, 0), &route.Path{})
-
-	if m.addPathCalled {
-		t.Fatalf("expected filtered, but was accepted")
-	}
-}*/
+	_, reject := f.ProcessTerms(net.NewPfx(0, 0), &route.Path{})
+	assert.Equal(t, true, reject)
+}
diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go
index ff5750c34d226080bea079968becdec410d2704e..97e4b4e2d9bde0cda109b7effc26928ffcd03764 100644
--- a/routingtable/locRIB/loc_rib.go
+++ b/routingtable/locRIB/loc_rib.go
@@ -14,19 +14,34 @@ import (
 // LocRIB represents a routing information base
 type LocRIB struct {
 	routingtable.ClientManager
-	rt *routingtable.RoutingTable
-	mu sync.RWMutex
+	rt               *routingtable.RoutingTable
+	mu               sync.RWMutex
+	contributingASNs *routingtable.ContributingASNs
 }
 
 // New creates a new routing information base
 func New() *LocRIB {
 	a := &LocRIB{
-		rt: routingtable.NewRoutingTable(),
+		rt:               routingtable.NewRoutingTable(),
+		contributingASNs: routingtable.NewContributingASNs(),
 	}
 	a.ClientManager = routingtable.NewClientManager(a)
 	return a
 }
 
+// GetContributingASNs returns a pointer to the list of contributing ASNs
+func (a *LocRIB) GetContributingASNs() *routingtable.ContributingASNs {
+	return a.contributingASNs
+}
+
+//Count routes from the LocRIP
+func (a *LocRIB) Count() uint64 {
+	a.mu.RLock()
+	defer a.mu.RUnlock()
+
+	return uint64(len(a.rt.Dump()))
+}
+
 // UpdateNewClient sends current state to a new client
 func (a *LocRIB) UpdateNewClient(client routingtable.RouteTableClient) error {
 	a.mu.RLock()
diff --git a/routingtable/table.go b/routingtable/table.go
index fce8a4f1a26ac25ca5b124ec2b17810c698fe3ec..9ccb10161cde2c6f1424c0fbce851a0d1bda19dc 100644
--- a/routingtable/table.go
+++ b/routingtable/table.go
@@ -2,6 +2,7 @@ package routingtable
 
 import (
 	"sync"
+	"sync/atomic"
 
 	"github.com/bio-routing/bio-rd/net"
 	"github.com/bio-routing/bio-rd/route"
@@ -9,8 +10,9 @@ import (
 
 // RoutingTable is a binary trie that stores prefixes and their paths
 type RoutingTable struct {
-	root *node
-	mu   sync.RWMutex
+	routeCount int64
+	root       *node
+	mu         sync.RWMutex
 }
 
 // NewRoutingTable creates a new routing table
@@ -18,6 +20,11 @@ func NewRoutingTable() *RoutingTable {
 	return &RoutingTable{}
 }
 
+// GetRouteCount gets the amount of stored routes
+func (rt *RoutingTable) GetRouteCount() int64 {
+	return atomic.LoadInt64(&rt.routeCount)
+}
+
 // AddPath adds a path to the routing table
 func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
 	rt.mu.Lock()
@@ -29,6 +36,7 @@ func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
 func (rt *RoutingTable) addPath(pfx net.Prefix, p *route.Path) error {
 	if rt.root == nil {
 		rt.root = newNode(pfx, p, pfx.Pfxlen(), false)
+		atomic.AddInt64(&rt.routeCount, 1)
 		return nil
 	}
 
@@ -55,11 +63,13 @@ func (rt *RoutingTable) ReplacePath(pfx net.Prefix, p *route.Path) []*route.Path
 }
 
 // RemovePath removes a path from the trie
-func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) bool {
+func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) {
 	rt.mu.Lock()
 	defer rt.mu.Unlock()
 
-	return rt.removePath(pfx, p)
+	if rt.removePath(pfx, p) {
+		atomic.AddInt64(&rt.routeCount, -1)
+	}
 }
 
 func (rt *RoutingTable) removePath(pfx net.Prefix, p *route.Path) bool {
diff --git a/routingtable/trie.go b/routingtable/trie.go
index 730d10155284863b49c475185e34fc9db3ca0798..6fe5f4853cd4bd795c21926f6835ca5e711eeced 100644
--- a/routingtable/trie.go
+++ b/routingtable/trie.go
@@ -27,7 +27,7 @@ func newNode(pfx net.Prefix, path *route.Path, skip uint8, dummy bool) *node {
 	return n
 }
 
-func (n *node) removePath(pfx net.Prefix, p *route.Path) (success bool) {
+func (n *node) removePath(pfx net.Prefix, p *route.Path) (final bool) {
 	if n == nil {
 		return false
 	}
@@ -37,14 +37,13 @@ func (n *node) removePath(pfx net.Prefix, p *route.Path) (success bool) {
 			return
 		}
 
-		nPaths := len(n.route.Paths())
 		nPathsAfterDel := n.route.RemovePath(p)
 		if len(n.route.Paths()) == 0 {
 			// FIXME: Can this node actually be removed from the trie entirely?
 			n.dummy = true
 		}
 
-		return nPathsAfterDel < nPaths
+		return nPathsAfterDel == 0
 	}
 
 	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
diff --git a/vendor/github.com/Masterminds/semver/BUILD.bazel b/vendor/github.com/Masterminds/semver/BUILD.bazel
index bf7d35c81e3bd31ef56f80d8d2d344275048525f..501de4ec1a18ecb59402f7b162965c56eb7e8786 100644
--- a/vendor/github.com/Masterminds/semver/BUILD.bazel
+++ b/vendor/github.com/Masterminds/semver/BUILD.bazel
@@ -13,7 +13,7 @@ go_library(
         "union.go",
         "version.go",
     ],
-    importmap = "vendor/github.com/Masterminds/semver",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/Masterminds/semver",
     importpath = "github.com/Masterminds/semver",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/Masterminds/vcs/BUILD.bazel b/vendor/github.com/Masterminds/vcs/BUILD.bazel
index d5544f95e2f1331450898c29a481e06792b5d39b..25a38e72e1c0b651fd4486751f6709322a548bef 100644
--- a/vendor/github.com/Masterminds/vcs/BUILD.bazel
+++ b/vendor/github.com/Masterminds/vcs/BUILD.bazel
@@ -12,7 +12,7 @@ go_library(
         "vcs_local_lookup.go",
         "vcs_remote_lookup.go",
     ],
-    importmap = "vendor/github.com/Masterminds/vcs",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/Masterminds/vcs",
     importpath = "github.com/Masterminds/vcs",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/armon/go-radix/BUILD.bazel b/vendor/github.com/armon/go-radix/BUILD.bazel
index e9b05f2ca2c5d8946a9a3cf1c2b89da835fe36f3..7f2d8cc3e915f7a0c611751b8241b96ebe8de8b6 100644
--- a/vendor/github.com/armon/go-radix/BUILD.bazel
+++ b/vendor/github.com/armon/go-radix/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["radix.go"],
-    importmap = "vendor/github.com/armon/go-radix",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/armon/go-radix",
     importpath = "github.com/armon/go-radix",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/boltdb/bolt/BUILD.bazel b/vendor/github.com/boltdb/bolt/BUILD.bazel
index f2b6acbede3f24e2a8688c1cc4530f7f1acfca05..e44ac9afc0e1ddfc14210cb96827ed60647f39ca 100644
--- a/vendor/github.com/boltdb/bolt/BUILD.bazel
+++ b/vendor/github.com/boltdb/bolt/BUILD.bazel
@@ -26,7 +26,7 @@ go_library(
         "page.go",
         "tx.go",
     ],
-    importmap = "vendor/github.com/boltdb/bolt",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/boltdb/bolt",
     importpath = "github.com/boltdb/bolt",
     visibility = ["//visibility:public"],
     deps = select({
diff --git a/vendor/github.com/davecgh/go-spew/spew/BUILD.bazel b/vendor/github.com/davecgh/go-spew/spew/BUILD.bazel
index be40c1a667e4ae7ee4dfcdcef73efe74d18fa1d6..d2c31e00c111bd66e601740791122d71a8ee0015 100644
--- a/vendor/github.com/davecgh/go-spew/spew/BUILD.bazel
+++ b/vendor/github.com/davecgh/go-spew/spew/BUILD.bazel
@@ -11,7 +11,7 @@ go_library(
         "format.go",
         "spew.go",
     ],
-    importmap = "vendor/github.com/davecgh/go-spew/spew",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/davecgh/go-spew/spew",
     importpath = "github.com/davecgh/go-spew/spew",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/go-yaml/yaml/BUILD.bazel b/vendor/github.com/go-yaml/yaml/BUILD.bazel
index 48a837c2d7107a2e2a7b54cf16fb971361188b50..5a950bd804e1e122e011eb13cb8c4582685cde91 100644
--- a/vendor/github.com/go-yaml/yaml/BUILD.bazel
+++ b/vendor/github.com/go-yaml/yaml/BUILD.bazel
@@ -17,7 +17,7 @@ go_library(
         "yamlh.go",
         "yamlprivateh.go",
     ],
-    importmap = "vendor/github.com/go-yaml/yaml",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/go-yaml/yaml",
     importpath = "github.com/go-yaml/yaml",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/golang/dep/BUILD.bazel b/vendor/github.com/golang/dep/BUILD.bazel
index e5fa67015561b614abde2a9c800c3c5acb116bf6..890fa4720a4a2120b76bc0185988a2b6ae3a2f2d 100644
--- a/vendor/github.com/golang/dep/BUILD.bazel
+++ b/vendor/github.com/golang/dep/BUILD.bazel
@@ -11,7 +11,7 @@ go_library(
         "project.go",
         "txn_writer.go",
     ],
-    importmap = "vendor/github.com/golang/dep",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep",
     importpath = "github.com/golang/dep",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel b/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel
index 69276c90879818b0f1c81b25ce3b032c3413579c..a60622cd81dea5af0951ef405047ff4e11d337d6 100644
--- a/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel
+++ b/vendor/github.com/golang/dep/cmd/dep/BUILD.bazel
@@ -16,7 +16,7 @@ go_library(
         "status.go",
         "version.go",
     ],
-    importmap = "vendor/github.com/golang/dep/cmd/dep",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/cmd/dep",
     importpath = "github.com/golang/dep/cmd/dep",
     visibility = ["//visibility:private"],
     deps = [
diff --git a/vendor/github.com/golang/dep/gps/BUILD.bazel b/vendor/github.com/golang/dep/gps/BUILD.bazel
index a86871b51919587edbcb2c8baadfe45d60f29732..7665f62fa3acc65e4e4af1f5e7289b4fa21a1d1e 100644
--- a/vendor/github.com/golang/dep/gps/BUILD.bazel
+++ b/vendor/github.com/golang/dep/gps/BUILD.bazel
@@ -42,7 +42,7 @@ go_library(
         "version_queue.go",
         "version_unifier.go",
     ],
-    importmap = "vendor/github.com/golang/dep/gps",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/gps",
     importpath = "github.com/golang/dep/gps",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel b/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel
index fafa65ddf55f1bb7cb543eee99e6d98b0976a4fe..490ae09fcfcbb1cb4baf3c4142a924ade5dc759b 100644
--- a/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel
+++ b/vendor/github.com/golang/dep/gps/internal/pb/BUILD.bazel
@@ -6,7 +6,7 @@ go_library(
         "pb.go",
         "source_cache.pb.go",
     ],
-    importmap = "vendor/github.com/golang/dep/gps/internal/pb",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/gps/internal/pb",
     importpath = "github.com/golang/dep/gps/internal/pb",
     visibility = ["//vendor/github.com/golang/dep/gps:__subpackages__"],
     deps = ["//vendor/github.com/golang/protobuf/proto:go_default_library"],
diff --git a/vendor/github.com/golang/dep/gps/paths/BUILD.bazel b/vendor/github.com/golang/dep/gps/paths/BUILD.bazel
index 4dad14b3c38fe2737a8e1fc1f0d3f28bd00cc7db..dcac6f2b33ff5c3245996af0d01260be7705ef60 100644
--- a/vendor/github.com/golang/dep/gps/paths/BUILD.bazel
+++ b/vendor/github.com/golang/dep/gps/paths/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["paths.go"],
-    importmap = "vendor/github.com/golang/dep/gps/paths",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/gps/paths",
     importpath = "github.com/golang/dep/gps/paths",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel b/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel
index 2c64bdfad3ed5ced70decbd41a3279534b283e7d..c6e0d12728171e1fa7b93294ff5b28d1bd991131 100644
--- a/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel
+++ b/vendor/github.com/golang/dep/gps/pkgtree/BUILD.bazel
@@ -9,7 +9,7 @@ go_library(
         "pkgtree.go",
         "reachmap.go",
     ],
-    importmap = "vendor/github.com/golang/dep/gps/pkgtree",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/gps/pkgtree",
     importpath = "github.com/golang/dep/gps/pkgtree",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel b/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel
index f1194382b165c29f44dab43eb11adfeb75f28947..269168018559980ff3c2879c2ce532ba049f2ab8 100644
--- a/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel
+++ b/vendor/github.com/golang/dep/hack/licenseok/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importmap = "vendor/github.com/golang/dep/hack/licenseok",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/hack/licenseok",
     importpath = "github.com/golang/dep/hack/licenseok",
     visibility = ["//visibility:private"],
 )
diff --git a/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel b/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel
index 10a231192ad633adb6101fb572486d4749df5348..4fe3726b2ec3382412446ea04c99489498b26947 100644
--- a/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/feedback/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["feedback.go"],
-    importmap = "vendor/github.com/golang/dep/internal/feedback",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/feedback",
     importpath = "github.com/golang/dep/internal/feedback",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = ["//vendor/github.com/golang/dep/gps:go_default_library"],
diff --git a/vendor/github.com/golang/dep/internal/fs/BUILD.bazel b/vendor/github.com/golang/dep/internal/fs/BUILD.bazel
index 10e60f08a648cf669b64ce6bd9bfafe06f771ecf..418f2d3ca5a255edce129a788cbcbba3789a9afb 100644
--- a/vendor/github.com/golang/dep/internal/fs/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/fs/BUILD.bazel
@@ -7,7 +7,7 @@ go_library(
         "rename.go",
         "rename_windows.go",
     ],
-    importmap = "vendor/github.com/golang/dep/internal/fs",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/fs",
     importpath = "github.com/golang/dep/internal/fs",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = ["//vendor/github.com/pkg/errors:go_default_library"],
diff --git a/vendor/github.com/golang/dep/internal/importers/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/BUILD.bazel
index 7d4330ccf931e7f74c62cd00aa46394a11c6f2cf..153c3a59ba280c35fcd483faab8118a2920759cb 100644
--- a/vendor/github.com/golang/dep/internal/importers/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importers.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers",
     importpath = "github.com/golang/dep/internal/importers",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel
index dd342c3138c515f98e89b5d317e4c2a4392e86ee..e0689249cb4847e0938446e324e8b4034c7f0611 100644
--- a/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/base/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/base",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/base",
     importpath = "github.com/golang/dep/internal/importers/base",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel
index 68dd5efb0f014d6d76f99c6140c92415746579d1..dc945ddeff342fe9db78e8022f277fc16286a5e6 100644
--- a/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/glide/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/glide",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/glide",
     importpath = "github.com/golang/dep/internal/importers/glide",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel
index 43742756bfa5bc9dd7e67eefba01dbc4aef1b0dc..00a24a995074874944d7b62b4ed47caccde030c2 100644
--- a/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/glock/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/glock",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/glock",
     importpath = "github.com/golang/dep/internal/importers/glock",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel
index 86849a916d4e605a9553e181c7510e4f4c568323..0f244ede8c70f163eb94f70cf74596278b68efd4 100644
--- a/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/godep/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/godep",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/godep",
     importpath = "github.com/golang/dep/internal/importers/godep",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel
index dd3d3b485805eacbc3b011be4f98173da9eff411..58ed9c5b0f6bd2f79ba5efd796f6cc949b758dee 100644
--- a/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/govend/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/govend",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/govend",
     importpath = "github.com/golang/dep/internal/importers/govend",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel
index 26dc082e35140e1a1cadae8d476b2e77dfda74dc..b48ee6f19cd6dcdf60dfc0706c3e58b1c6b5338e 100644
--- a/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/govendor/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/govendor",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/govendor",
     importpath = "github.com/golang/dep/internal/importers/govendor",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel
index a22b94389803339fef8f522821396691f737b390..425445f1033972fc1e1d63708eb5bc51db560471 100644
--- a/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/gvt/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/gvt",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/gvt",
     importpath = "github.com/golang/dep/internal/importers/gvt",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel
index e11ed7d2475cc3a5a42a178e33728d2809620c92..507928a84cacb8c562bba675e646690f1736e0c0 100644
--- a/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/importertest/BUILD.bazel
@@ -6,7 +6,7 @@ go_library(
         "testcase.go",
         "testdata.go",
     ],
-    importmap = "vendor/github.com/golang/dep/internal/importers/importertest",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/importertest",
     importpath = "github.com/golang/dep/internal/importers/importertest",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel b/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel
index 72cc72322cd432346ce7b4957849265c881b1630..8e40fcceda4d29f0c7e59b2d27d0e39257ee37d3 100644
--- a/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/importers/vndr/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["importer.go"],
-    importmap = "vendor/github.com/golang/dep/internal/importers/vndr",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/importers/vndr",
     importpath = "github.com/golang/dep/internal/importers/vndr",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/dep/internal/test/BUILD.bazel b/vendor/github.com/golang/dep/internal/test/BUILD.bazel
index b0e3e57fc044d5e118565efaba0f0e073065bda9..4017b6da593c40bf1fe206c6f933e92c4868314d 100644
--- a/vendor/github.com/golang/dep/internal/test/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/test/BUILD.bazel
@@ -6,7 +6,7 @@ go_library(
         "test.go",
         "writer.go",
     ],
-    importmap = "vendor/github.com/golang/dep/internal/test",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/test",
     importpath = "github.com/golang/dep/internal/test",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = ["//vendor/github.com/pkg/errors:go_default_library"],
diff --git a/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel b/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel
index 928ded317b831494f4d9b5494efa1ef31af64be3..a2c964aa02019fd22c24c30437094faf04d77099 100644
--- a/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel
+++ b/vendor/github.com/golang/dep/internal/test/integration/BUILD.bazel
@@ -6,7 +6,7 @@ go_library(
         "testcase.go",
         "testproj.go",
     ],
-    importmap = "vendor/github.com/golang/dep/internal/test/integration",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/dep/internal/test/integration",
     importpath = "github.com/golang/dep/internal/test/integration",
     visibility = ["//vendor/github.com/golang/dep:__subpackages__"],
     deps = [
diff --git a/vendor/github.com/golang/protobuf/proto/BUILD.bazel b/vendor/github.com/golang/protobuf/proto/BUILD.bazel
index 98590c1c2793ef88a7790d37a8241c2b0d16d8e5..9d5aafd83380464a9f48c492698a8a01d0f5f8d6 100644
--- a/vendor/github.com/golang/protobuf/proto/BUILD.bazel
+++ b/vendor/github.com/golang/protobuf/proto/BUILD.bazel
@@ -19,7 +19,7 @@ go_library(
         "text.go",
         "text_parser.go",
     ],
-    importmap = "vendor/github.com/golang/protobuf/proto",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/golang/protobuf/proto",
     importpath = "github.com/golang/protobuf/proto",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/jmank88/nuts/BUILD.bazel b/vendor/github.com/jmank88/nuts/BUILD.bazel
index 920f2b554e5325aafe6d1eec46e28aa4a9f79771..72db5e47f7dcd7c8f03d5c429368e22ca71631be 100644
--- a/vendor/github.com/jmank88/nuts/BUILD.bazel
+++ b/vendor/github.com/jmank88/nuts/BUILD.bazel
@@ -8,7 +8,7 @@ go_library(
         "paths.go",
         "types.go",
     ],
-    importmap = "vendor/github.com/jmank88/nuts",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/jmank88/nuts",
     importpath = "github.com/jmank88/nuts",
     visibility = ["//visibility:public"],
     deps = ["//vendor/github.com/boltdb/bolt:go_default_library"],
diff --git a/vendor/github.com/nightlyone/lockfile/BUILD.bazel b/vendor/github.com/nightlyone/lockfile/BUILD.bazel
index 0a74fcf8fb203c8ffa147d183c97661a0f8faf92..8b1c688bca89ed5bb9caae81fdab35cd1c912209 100644
--- a/vendor/github.com/nightlyone/lockfile/BUILD.bazel
+++ b/vendor/github.com/nightlyone/lockfile/BUILD.bazel
@@ -7,7 +7,7 @@ go_library(
         "lockfile_unix.go",
         "lockfile_windows.go",
     ],
-    importmap = "vendor/github.com/nightlyone/lockfile",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/nightlyone/lockfile",
     importpath = "github.com/nightlyone/lockfile",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/pelletier/go-toml/BUILD.bazel b/vendor/github.com/pelletier/go-toml/BUILD.bazel
index 526e4aeca6d915a4f18a420ac9de331d194e34dd..8130328c049d880232a298fb7213cc55e10e50d7 100644
--- a/vendor/github.com/pelletier/go-toml/BUILD.bazel
+++ b/vendor/github.com/pelletier/go-toml/BUILD.bazel
@@ -14,7 +14,7 @@ go_library(
         "tomltree_create.go",
         "tomltree_write.go",
     ],
-    importmap = "vendor/github.com/pelletier/go-toml",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/pelletier/go-toml",
     importpath = "github.com/pelletier/go-toml",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/pkg/errors/BUILD.bazel b/vendor/github.com/pkg/errors/BUILD.bazel
index 02e03382df2b88e8d286b8ee8eccb0d9ea754a28..b1eb9941074b0da6982111f122d750abafa7b994 100644
--- a/vendor/github.com/pkg/errors/BUILD.bazel
+++ b/vendor/github.com/pkg/errors/BUILD.bazel
@@ -6,7 +6,7 @@ go_library(
         "errors.go",
         "stack.go",
     ],
-    importmap = "vendor/github.com/pkg/errors",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/pkg/errors",
     importpath = "github.com/pkg/errors",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/pmezard/go-difflib/difflib/BUILD.bazel b/vendor/github.com/pmezard/go-difflib/difflib/BUILD.bazel
index f6d4fa72e45f482c4cb676837b518e6d5be14450..8a8fca20454989179efb5cfa46a8542fc30c5845 100644
--- a/vendor/github.com/pmezard/go-difflib/difflib/BUILD.bazel
+++ b/vendor/github.com/pmezard/go-difflib/difflib/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["difflib.go"],
-    importmap = "vendor/github.com/pmezard/go-difflib/difflib",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/pmezard/go-difflib/difflib",
     importpath = "github.com/pmezard/go-difflib/difflib",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/mattn/goveralls/.gitignore b/vendor/github.com/q3k/goveralls/.gitignore
similarity index 100%
rename from vendor/github.com/mattn/goveralls/.gitignore
rename to vendor/github.com/q3k/goveralls/.gitignore
diff --git a/vendor/github.com/mattn/goveralls/.travis.yml b/vendor/github.com/q3k/goveralls/.travis.yml
similarity index 100%
rename from vendor/github.com/mattn/goveralls/.travis.yml
rename to vendor/github.com/q3k/goveralls/.travis.yml
diff --git a/vendor/github.com/mattn/goveralls/BUILD.bazel b/vendor/github.com/q3k/goveralls/BUILD.bazel
similarity index 81%
rename from vendor/github.com/mattn/goveralls/BUILD.bazel
rename to vendor/github.com/q3k/goveralls/BUILD.bazel
index 4ae53dc12ba32f3dc6de7ef90f2bc47e0837acba..04249c71ebd3067a7084271ba6fc909d316ae87b 100644
--- a/vendor/github.com/mattn/goveralls/BUILD.bazel
+++ b/vendor/github.com/q3k/goveralls/BUILD.bazel
@@ -7,8 +7,8 @@ go_library(
         "gocover.go",
         "goveralls.go",
     ],
-    importmap = "vendor/github.com/mattn/goveralls",
-    importpath = "github.com/mattn/goveralls",
+    importmap = "vendor/github.com/q3k/goveralls",
+    importpath = "github.com/q3k/goveralls",
     visibility = ["//visibility:private"],
     deps = ["//vendor/golang.org/x/tools/cover:go_default_library"],
 )
diff --git a/vendor/github.com/mattn/goveralls/README.md b/vendor/github.com/q3k/goveralls/README.md
similarity index 81%
rename from vendor/github.com/mattn/goveralls/README.md
rename to vendor/github.com/q3k/goveralls/README.md
index bc5608b57d395b3e008c52ef16758b6df482b65a..71b513d7543df0706539cfc45f3b31e92dac15b1 100644
--- a/vendor/github.com/mattn/goveralls/README.md
+++ b/vendor/github.com/q3k/goveralls/README.md
@@ -137,6 +137,40 @@ test:
 
 For more information, See https://coveralls.zendesk.com/hc/en-us/articles/201342809-Go
 
+## Semaphore
+
+Store your Coveralls API token in `Environment Variables`:
+
+```
+COVERALLS_TOKEN=your_token_goes_here
+```
+
+More instructions on how to do this can be found in the [Semaphore documentation](https://semaphoreci.com/docs/exporting-environment-variables.html).
+
+Replace the `go test` line in your `Commands` with these lines:
+
+```
+$ go get github.com/mattn/goveralls
+$ goveralls -service semaphore
+```
+
+`goveralls` automatically use the environment variable `COVERALLS_TOKEN` as the
+default value for `-repotoken`.
+
+You can use the `-v` flag to see verbose output from the test suite:
+
+```
+$ goveralls -v -service semaphore
+```
+
+## Coveralls Enterprise
+
+If you are using Coveralls Enterprise and have a self-signed certificate, you need to skip certificate verification:
+
+```shell
+$ goveralls -insecure
+```
+
 # Authors
 
 * Yasuhiro Matsumoto (a.k.a. mattn)
diff --git a/vendor/github.com/mattn/goveralls/gitinfo.go b/vendor/github.com/q3k/goveralls/gitinfo.go
similarity index 100%
rename from vendor/github.com/mattn/goveralls/gitinfo.go
rename to vendor/github.com/q3k/goveralls/gitinfo.go
diff --git a/vendor/github.com/mattn/goveralls/gocover.go b/vendor/github.com/q3k/goveralls/gocover.go
similarity index 78%
rename from vendor/github.com/mattn/goveralls/gocover.go
rename to vendor/github.com/q3k/goveralls/gocover.go
index dc3ec312c2cdca3b4c706fe2e4a47bb8217b9a0c..7e841831fe676a34bc476e443f0ccbb13d12f898 100644
--- a/vendor/github.com/mattn/goveralls/gocover.go
+++ b/vendor/github.com/q3k/goveralls/gocover.go
@@ -15,6 +15,7 @@ import (
 	"io/ioutil"
 	"log"
 	"path/filepath"
+	"sort"
 	"strings"
 
 	"golang.org/x/tools/cover"
@@ -63,6 +64,33 @@ func mergeProfs(pfss [][]*cover.Profile) []*cover.Profile {
 	return ret
 }
 
+// joinProfs merges profiles for different target packages.
+func joinProfs(pfss [][]*cover.Profile) []*cover.Profile {
+	// skip empty profiles ([no test files])
+	for i := 0; i < len(pfss); i++ {
+		if len(pfss[i]) > 0 {
+			pfss = pfss[i:]
+			break
+		}
+	}
+	if len(pfss) == 0 {
+		return nil
+	} else if len(pfss) == 1 {
+		return pfss[0]
+	}
+
+	ret := []*cover.Profile{}
+	for _, profiles := range pfss {
+		for _, profile := range profiles {
+			ret = append(ret, profile)
+		}
+	}
+	sort.Slice(ret, func(i, j int) bool {
+		return ret[i].FileName < ret[j].FileName
+	})
+	return ret
+}
+
 func mergeProfBlocks(as, bs []cover.ProfileBlock) []cover.ProfileBlock {
 	if len(as) != len(bs) {
 		log.Fatal("Two block length should be same")
@@ -122,10 +150,19 @@ func parseCover(fn string) ([]*SourceFile, error) {
 		pfss = append(pfss, profs)
 	}
 
-	sourceFiles, err := toSF(mergeProfs(pfss))
-	if err != nil {
-		return nil, err
-	}
+	if *merge {
+		sourceFiles, err := toSF(mergeProfs(pfss))
+		if err != nil {
+			return nil, err
+		}
+
+		return sourceFiles, nil
+	} else {
+		sourceFiles, err := toSF(joinProfs(pfss))
+		if err != nil {
+			return nil, err
+		}
 
-	return sourceFiles, nil
+		return sourceFiles, nil
+	}
 }
diff --git a/vendor/github.com/mattn/goveralls/goveralls.go b/vendor/github.com/q3k/goveralls/goveralls.go
similarity index 91%
rename from vendor/github.com/mattn/goveralls/goveralls.go
rename to vendor/github.com/q3k/goveralls/goveralls.go
index 3be972db997b3c4f9f34971432ecdff6474f5e8a..992d14928d2d282f3d2f8ad95eb53e363524e468 100644
--- a/vendor/github.com/mattn/goveralls/goveralls.go
+++ b/vendor/github.com/q3k/goveralls/goveralls.go
@@ -8,6 +8,7 @@ package main
 import (
 	"bytes"
 	_ "crypto/sha512"
+	"crypto/tls"
 	"encoding/json"
 	"errors"
 	"flag"
@@ -54,6 +55,9 @@ var (
 	service    = flag.String("service", "travis-ci", "The CI service or other environment in which the test suite was run. ")
 	shallow    = flag.Bool("shallow", false, "Shallow coveralls internal server errors")
 	ignore     = flag.String("ignore", "", "Comma separated files to ignore")
+	insecure   = flag.Bool("insecure", false, "Set insecure to skip verification of certificates")
+	show       = flag.Bool("show", false, "Show which package is being tested")
+	merge      = flag.Bool("merge", true, "Merge multiple coverage profiles into one")
 )
 
 // usage supplants package flag's Usage variable
@@ -149,6 +153,9 @@ func getCoverage() ([]*SourceFile, error) {
 		args = append(args, line)
 		cmd.Args = args
 
+		if *show {
+			fmt.Println("goveralls:", line)
+		}
 		err = cmd.Run()
 		if err != nil {
 			return nil, fmt.Errorf("%v: %v", err, outBuf.String())
@@ -224,6 +231,13 @@ func process() error {
 	}
 	os.Setenv("PATH", strings.Join(paths, string(filepath.ListSeparator)))
 
+	//
+	// Handle certificate verification configuration
+	//
+	if *insecure {
+		http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+	}
+
 	//
 	// Initialize Job
 	//
@@ -234,6 +248,10 @@ func process() error {
 		jobId = circleCiJobId
 	} else if appveyorJobId := os.Getenv("APPVEYOR_JOB_ID"); appveyorJobId != "" {
 		jobId = appveyorJobId
+	} else if semaphoreJobId := os.Getenv("SEMAPHORE_BUILD_NUMBER"); semaphoreJobId != "" {
+		jobId = semaphoreJobId
+	} else if jenkinsJobId := os.Getenv("BUILD_NUMBER"); jenkinsJobId != "" {
+		jobId = jenkinsJobId
 	}
 
 	if *repotoken == "" {
@@ -250,6 +268,8 @@ func process() error {
 		pullRequest = regexp.MustCompile(`[0-9]+$`).FindString(prURL)
 	} else if prNumber := os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER"); prNumber != "" {
 		pullRequest = prNumber
+	} else if prNumber := os.Getenv("PULL_REQUEST_NUMBER"); prNumber != "" {
+		pullRequest = prNumber
 	}
 
 	sourceFiles, err := getCoverage()
diff --git a/vendor/github.com/sdboyer/constext/BUILD.bazel b/vendor/github.com/sdboyer/constext/BUILD.bazel
index ee94b66945d935ba8431de6870cfd7947ffe3d84..effb8ca864561db47f40692afd71632eddebf5d5 100644
--- a/vendor/github.com/sdboyer/constext/BUILD.bazel
+++ b/vendor/github.com/sdboyer/constext/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["constext.go"],
-    importmap = "vendor/github.com/sdboyer/constext",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/sdboyer/constext",
     importpath = "github.com/sdboyer/constext",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/github.com/sirupsen/logrus/BUILD.bazel b/vendor/github.com/sirupsen/logrus/BUILD.bazel
index 8ddbd66e796eca4e59145cca34fc95cdc257feca..57ae49599a33ea71cb1c88dfbee68b1c92cde40a 100644
--- a/vendor/github.com/sirupsen/logrus/BUILD.bazel
+++ b/vendor/github.com/sirupsen/logrus/BUILD.bazel
@@ -18,7 +18,7 @@ go_library(
         "text_formatter.go",
         "writer.go",
     ],
-    importmap = "vendor/github.com/sirupsen/logrus",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/sirupsen/logrus",
     importpath = "github.com/sirupsen/logrus",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/vendor/github.com/stretchr/testify/assert/BUILD.bazel b/vendor/github.com/stretchr/testify/assert/BUILD.bazel
index 84915770c4ea7ff0b7db3bd5f755c5a8f5c7df3f..5fc04335b69097cb28abf6363cbc53e98a917aa6 100644
--- a/vendor/github.com/stretchr/testify/assert/BUILD.bazel
+++ b/vendor/github.com/stretchr/testify/assert/BUILD.bazel
@@ -11,7 +11,7 @@ go_library(
         "forward_assertions.go",
         "http_assertions.go",
     ],
-    importmap = "vendor/github.com/stretchr/testify/assert",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/stretchr/testify/assert",
     importpath = "github.com/stretchr/testify/assert",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/vendor/github.com/taktv6/tflow2/convert/BUILD.bazel b/vendor/github.com/taktv6/tflow2/convert/BUILD.bazel
index b6d8a418d173754e2d28152a5a674c26ad27a76e..5506643341e1e3a4ea891167b92208d92d0931cb 100644
--- a/vendor/github.com/taktv6/tflow2/convert/BUILD.bazel
+++ b/vendor/github.com/taktv6/tflow2/convert/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["convert.go"],
-    importmap = "vendor/github.com/taktv6/tflow2/convert",
+    importmap = "github.com/bio-routing/bio-rd/vendor/github.com/taktv6/tflow2/convert",
     importpath = "github.com/taktv6/tflow2/convert",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/BUILD.bazel b/vendor/golang.org/x/crypto/ssh/terminal/BUILD.bazel
index 593a697cd9117b5d197fa40ea741b4da68685b20..f1dbddae821cfbbdda8f70941472708f75ddf41d 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/BUILD.bazel
+++ b/vendor/golang.org/x/crypto/ssh/terminal/BUILD.bazel
@@ -11,7 +11,7 @@ go_library(
         "util_solaris.go",
         "util_windows.go",
     ],
-    importmap = "vendor/golang.org/x/crypto/ssh/terminal",
+    importmap = "github.com/bio-routing/bio-rd/vendor/golang.org/x/crypto/ssh/terminal",
     importpath = "golang.org/x/crypto/ssh/terminal",
     visibility = ["//visibility:public"],
     deps = select({
diff --git a/vendor/golang.org/x/net/context/BUILD.bazel b/vendor/golang.org/x/net/context/BUILD.bazel
index 79dde6dff60ca5ed498faadc52bc0af430537f4b..8a09a3615ea3ef3a023ed3ca7a5dc82d3b7ca79d 100644
--- a/vendor/golang.org/x/net/context/BUILD.bazel
+++ b/vendor/golang.org/x/net/context/BUILD.bazel
@@ -9,7 +9,7 @@ go_library(
         "pre_go17.go",
         "pre_go19.go",
     ],
-    importmap = "vendor/golang.org/x/net/context",
+    importmap = "github.com/bio-routing/bio-rd/vendor/golang.org/x/net/context",
     importpath = "golang.org/x/net/context",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/golang.org/x/sync/errgroup/BUILD.bazel b/vendor/golang.org/x/sync/errgroup/BUILD.bazel
index 50a4d6452a81b27bafb5accd7f061473c3175315..9090cd0a8fb216e140ee77e5f9410f28874be014 100644
--- a/vendor/golang.org/x/sync/errgroup/BUILD.bazel
+++ b/vendor/golang.org/x/sync/errgroup/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["errgroup.go"],
-    importmap = "vendor/golang.org/x/sync/errgroup",
+    importmap = "github.com/bio-routing/bio-rd/vendor/golang.org/x/sync/errgroup",
     importpath = "golang.org/x/sync/errgroup",
     visibility = ["//visibility:public"],
     deps = ["//vendor/golang.org/x/net/context:go_default_library"],
diff --git a/vendor/golang.org/x/sys/unix/BUILD.bazel b/vendor/golang.org/x/sys/unix/BUILD.bazel
index a2505682d8e61d2ebcde3fe2affc8334f0f1417d..aa6151ab66e8e90b6f8e8cc946dc94fb1bf41e1b 100644
--- a/vendor/golang.org/x/sys/unix/BUILD.bazel
+++ b/vendor/golang.org/x/sys/unix/BUILD.bazel
@@ -200,7 +200,7 @@ go_library(
         "ztypes_solaris_amd64.go",
     ],
     cgo = True,
-    importmap = "vendor/golang.org/x/sys/unix",
+    importmap = "github.com/bio-routing/bio-rd/vendor/golang.org/x/sys/unix",
     importpath = "golang.org/x/sys/unix",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/golang.org/x/sys/windows/BUILD.bazel b/vendor/golang.org/x/sys/windows/BUILD.bazel
index 8dd57def4faf7ccff521cb81875e463962b42fe9..b4ed609cba4449ca6cb18529dcb491fd705d808c 100644
--- a/vendor/golang.org/x/sys/windows/BUILD.bazel
+++ b/vendor/golang.org/x/sys/windows/BUILD.bazel
@@ -22,7 +22,7 @@ go_library(
         "types_windows_amd64.go",
         "zsyscall_windows.go",
     ],
-    importmap = "vendor/golang.org/x/sys/windows",
+    importmap = "github.com/bio-routing/bio-rd/vendor/golang.org/x/sys/windows",
     importpath = "golang.org/x/sys/windows",
     visibility = ["//visibility:public"],
 )
diff --git a/vendor/golang.org/x/tools/cover/BUILD.bazel b/vendor/golang.org/x/tools/cover/BUILD.bazel
index 599c3ebc6b9e73701e26299c299a4694e20d0ff2..85feea167867389c8dcfe6a82669ea915359276f 100644
--- a/vendor/golang.org/x/tools/cover/BUILD.bazel
+++ b/vendor/golang.org/x/tools/cover/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["profile.go"],
-    importmap = "vendor/golang.org/x/tools/cover",
+    importmap = "github.com/bio-routing/bio-rd/vendor/golang.org/x/tools/cover",
     importpath = "golang.org/x/tools/cover",
     visibility = ["//visibility:public"],
 )