diff --git a/Gopkg.lock b/Gopkg.lock
index b31d98511243125698789697c27347039eb15909..d08b1b29212e5f9a5091ea8e776e530a12ccce7b 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -64,6 +64,6 @@
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "efc3f49bbc94070f3d7cc4e513804cd72455c937dc67f3692e5c880a78c1700e"
+  inputs-digest = "57d99764685b75e316ae1a1245ae53ad0f5ca7d60f1eee63102c3759e188d0fd"
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index 83f8fd423918fcc873aec20c5d94d7709b992ad9..b6b3c4ef2110bd6159a9dac398ded19fbda8c624 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -20,11 +20,6 @@
 #  name = "github.com/x/y"
 #  version = "2.4.0"
 
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/bio-routing/bio-rd"
-
 [[constraint]]
   name = "github.com/sirupsen/logrus"
   version = "1.0.5"
diff --git a/vendor/github.com/bio-routing/bio-rd/AUTHORS b/vendor/github.com/bio-routing/bio-rd/AUTHORS
deleted file mode 100644
index 61a22aa1d3350a0948fbf7b2c3bb199dfb90780e..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/AUTHORS
+++ /dev/null
@@ -1,13 +0,0 @@
-# This is the official list of bio-routing‚ authors for copyright purposes.
-# This file is distinct from the CONTRIBUTORS files.
-# See the latter for an explanation.
-
-# Names should be added to this file as one of
-#     Organization's name
-#     Individual's name <submission email address>
-#     Individual's name <submission email address> <email2> <emailN>
-# See CONTRIBUTORS for the meaning of multiple email addresses.
-
-# Please keep the list sorted.
-
-Oliver Herms
diff --git a/vendor/github.com/bio-routing/bio-rd/CONTRIBUTING.md b/vendor/github.com/bio-routing/bio-rd/CONTRIBUTING.md
deleted file mode 100644
index 1b082ebe3e41967336a9155e59ec61e0a7da9eae..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/CONTRIBUTING.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Want to contribute? Great! First, read this page.
-
-### Code guidelines
-We expect all submissions to be properly formatted using gofmt.
-Golint and govet shall not complain about your code. Gocyclo shall not report 
-complexity above 15. And your code should not lower the testcoverage of our
-codebase.
-
-### Code reviews
-All submissions, including submissions by project members, require review. We
-use Github pull requests for this purpose.
-
-### License
-By sending us your code you agree to release your contribution under the projects
-chosen license: Apche License 2.0 (see LICENSE file).
\ No newline at end of file
diff --git a/vendor/github.com/bio-routing/bio-rd/CONTRIBUTORS b/vendor/github.com/bio-routing/bio-rd/CONTRIBUTORS
deleted file mode 100644
index d9d12494cd0f5762e2c382d33079df3f18722271..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/CONTRIBUTORS
+++ /dev/null
@@ -1,7 +0,0 @@
-# This is the official list of people who can contribute
-# (and typically have contributed) code to the bio-rd repository.
-# The AUTHORS file lists the copyright holders; this file
-# lists people.  For example, Google employees are listed here
-# but not in AUTHORS, because Google holds the copyright.
-
-Oliver Herms
diff --git a/vendor/github.com/bio-routing/bio-rd/LICENSE b/vendor/github.com/bio-routing/bio-rd/LICENSE
deleted file mode 100644
index 261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/bio-routing/bio-rd/config/peer.go b/vendor/github.com/bio-routing/bio-rd/config/peer.go
deleted file mode 100644
index 8f7692b085e39fae5b1ec998233bf2d174a84581..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/config/peer.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package config
-
-import (
-	"net"
-)
-
-type Peer struct {
-	AdminEnabled bool
-	KeepAlive    uint16
-	HoldTimer    uint16
-	LocalAddress net.IP
-	PeerAddress  net.IP
-	LocalAS      uint32
-	PeerAS       uint32
-	Passive      bool
-	RouterID     uint32
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/config/server.go b/vendor/github.com/bio-routing/bio-rd/config/server.go
deleted file mode 100644
index fed6f908365319418abb5b5dee1290ec666d418e..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/config/server.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package config
-
-import (
-	"fmt"
-	"net"
-	"strings"
-
-	"github.com/taktv6/tflow2/convert"
-)
-
-type Global struct {
-	LocalAS          uint32
-	RouterID         uint32
-	Port             uint16
-	LocalAddressList []net.IP
-	Listen           bool
-}
-
-const BGPPORT = uint16(179)
-
-func (g *Global) SetDefaultGlobalConfigValues() error {
-	if g.LocalAddressList == nil {
-		g.LocalAddressList = make([]net.IP, 0)
-		g.LocalAddressList = append(g.LocalAddressList, net.ParseIP("0.0.0.0"))
-		g.LocalAddressList = append(g.LocalAddressList, net.ParseIP("::"))
-	}
-
-	if g.RouterID == 0 {
-		rtrid, err := generateRouterID()
-		if err != nil {
-			return fmt.Errorf("Unable to determine router ID: %v", err)
-		}
-		g.RouterID = rtrid
-	}
-
-	if g.Port == 0 {
-		g.Port = BGPPORT
-	}
-
-	return nil
-}
-
-func generateRouterID() (uint32, error) {
-	addr, err := getLoopbackIP()
-	if err == nil {
-		return convert.Uint32b([]byte(addr)[12:16]), nil
-	}
-
-	return 0, fmt.Errorf("Unable to determine router id")
-}
-
-func getHighestIP() (net.IP, error) {
-	ifs, err := net.Interfaces()
-	if err != nil {
-		return nil, fmt.Errorf("Unable to ")
-	}
-
-	return _getHighestIP(ifs)
-}
-
-func _getHighestIP(ifs []net.Interface) (net.IP, error) {
-	candidates := make([]net.IP, 0)
-	for _, iface := range ifs {
-		addrs, err := iface.Addrs()
-		if err != nil {
-			return nil, fmt.Errorf("Unable to get interface addrs for %s: %v", iface.Name, err)
-		}
-
-		for _, addr := range addrs {
-			a := net.ParseIP(addr.String())
-			if addr.String() != "127.0.0.1" && a.To4() != nil {
-				candidates = append(candidates, a)
-			}
-		}
-	}
-
-	if len(candidates) == 0 {
-		return nil, fmt.Errorf("No IPv4 address found on any interface")
-	}
-
-	max := candidates[0]
-	for _, c := range candidates[1:] {
-		if addrIsGreater(c, max) {
-			max = c
-		}
-	}
-
-	return nil, fmt.Errorf("No non localhost IPv4 address found on interface lo")
-}
-
-func getLoopbackIP() (net.IP, error) {
-	iface, err := net.InterfaceByName("lo")
-	if err != nil {
-		return nil, fmt.Errorf("Unable to get interface lo: %v", err)
-	}
-
-	return _getLoopbackIP(iface)
-}
-
-func _getLoopbackIP(iface *net.Interface) (net.IP, error) {
-	addrs, err := iface.Addrs()
-	if err != nil {
-		return nil, fmt.Errorf("Unable to get interface addresses: %v", err)
-	}
-
-	candidates := make([]net.IP, 0)
-	for _, addr := range addrs {
-		a := net.ParseIP(strings.Split(addr.String(), "/")[0])
-		if a.String() != "127.0.0.1" && a.To4() != nil {
-			candidates = append(candidates, a)
-		}
-	}
-
-	if len(candidates) == 0 {
-		return nil, fmt.Errorf("No non localhost IPv4 address found on interface lo")
-	}
-
-	max := candidates[0]
-	for _, c := range candidates {
-		if addrIsGreater(c, max) {
-			max = c
-		}
-	}
-
-	return max, nil
-}
-
-func addrIsGreater(a net.IP, b net.IP) bool {
-	/*
-	 * FIXME: Implement proper comparison
-	 */
-	if a.String() > b.String() {
-		return true
-	}
-	return false
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/config/server_test.go b/vendor/github.com/bio-routing/bio-rd/config/server_test.go
deleted file mode 100644
index d44821f8fa1ed70bd101e0a07cbb8a114d610778..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/config/server_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package config
-
-import (
-	"net"
-	"reflect"
-	"testing"
-)
-
-func TestGetLoopbackIP(t *testing.T) {
-	type args struct {
-		iface *net.Interface
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    net.IP
-		wantErr bool
-	}{
-	// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := _getLoopbackIP(tt.args.iface)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("_getLoopbackIP() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("_getLoopbackIP() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestGetHighestIP(t *testing.T) {
-	type args struct {
-		ifs []net.Interface
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    net.IP
-		wantErr bool
-	}{
-	// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := _getHighestIP(tt.args.ifs)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("_getHighestIP() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("_getHighestIP() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestAddrIsGreater(t *testing.T) {
-	type args struct {
-		a net.IP
-		b net.IP
-	}
-	tests := []struct {
-		name string
-		args args
-		want bool
-	}{
-	// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := addrIsGreater(tt.args.a, tt.args.b); got != tt.want {
-				t.Errorf("addrIsGreater() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/logo/bio-rd-logo.svg b/vendor/github.com/bio-routing/bio-rd/logo/bio-rd-logo.svg
deleted file mode 100644
index 971535547c55a948bd6445d85be5828786b18214..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/logo/bio-rd-logo.svg
+++ /dev/null
@@ -1,254 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.0"
-   width="744.09448"
-   height="623.2677"
-   id="svg2693"
-   sodipodi:version="0.32"
-   inkscape:version="0.92.2 2405546, 2018-03-11"
-   sodipodi:docname="bio-rd-logo.svg"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <metadata
-     id="metadata39">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <sodipodi:namedview
-     inkscape:window-height="1061"
-     inkscape:window-width="1920"
-     inkscape:pageshadow="2"
-     inkscape:pageopacity="0.0"
-     guidetolerance="10.0"
-     gridtolerance="10.0"
-     objecttolerance="10.0"
-     borderopacity="1.0"
-     bordercolor="#666666"
-     pagecolor="#ffffff"
-     id="base"
-     inkscape:zoom="1.209753"
-     inkscape:cx="403.74347"
-     inkscape:cy="247.39431"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:current-layer="g5903"
-     showgrid="false"
-     inkscape:window-maximized="0" />
-  <defs
-     id="defs2695">
-    <linearGradient
-       x1="362.32599"
-       y1="5.8388"
-       x2="379.63699"
-       y2="5.8388"
-       id="id1"
-       gradientUnits="userSpaceOnUse">
-      <stop
-         style="stop-color:#71bf44;stop-opacity:1"
-         offset="0"
-         id="stop2504" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1"
-         offset="1"
-         id="stop2506" />
-    </linearGradient>
-    <linearGradient
-       x1="362.32599"
-       y1="5.8388"
-       x2="379.63699"
-       y2="5.8388"
-       id="linearGradient2686"
-       xlink:href="#id1"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(17.570118,0,0,17.570118,-1735.4368,-2488.6967)" />
-    <linearGradient
-       x1="362.32599"
-       y1="5.8388"
-       x2="379.63699"
-       y2="5.8388"
-       id="linearGradient2761"
-       xlink:href="#id1"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(17.570118,0,0,17.570118,-1735.4368,-2488.6967)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#id1"
-       id="linearGradient2219"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(17.570118,0,0,17.570118,-1735.4368,-2488.6967)"
-       x1="362.32599"
-       y1="5.8388"
-       x2="379.63699"
-       y2="5.8388" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#id1"
-       id="linearGradient2243"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(19.522353,0,0,19.522353,-2227.9788,-2810.4687)"
-       x1="135.63422"
-       y1="154.97049"
-       x2="142.07021"
-       y2="154.97049" />
-  </defs>
-  <polygon
-     points="124.173,144.87 115.032,159.883 124.203,174.979 142.171,174.979 151.332,159.898 151.332,159.898 142.207,144.87 124.173,144.87 "
-     transform="matrix(19.522353,0,0,19.522353,-2227.9788,-2810.4687)"
-     style="fill:#ffffff;fill-rule:nonzero"
-     id="polygon2583" />
-  <rect
-     style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.20234585;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47637796"
-     id="rect5993"
-     width="44.853615"
-     height="217.52908"
-     x="194.49643"
-     y="143.14575" />
-  <path
-     d="M 212.29578,46.198101 L 52.973852,309.53904 L 212.30553,574.8888 L 529.5106,574.8888 L 688.34251,309.53904 L 529.52228,46.198101 L 212.29578,46.198101 L 212.29578,46.198101 z M 513.11375,75.253202 C 520.86801,88.11259 646.20933,295.94367 654.44581,309.59761 C 646.25033,323.28472 520.78213,532.89816 513.04151,545.8337 C 497.89606,545.8337 243.87319,545.8337 228.75115,545.8337 C 221.00079,532.92549 95.136274,323.31595 86.901729,309.59761 C 95.181174,295.91243 220.91881,88.079424 228.67892,75.253202 C 243.74631,75.253202 498.023,75.253202 513.11375,75.253202 z "
-     style="fill:#71bf44;fill-rule:nonzero"
-     id="path2585" />
-  <path
-     d="M 381.10554,209.6197 C 381.10554,222.17061 370.92074,232.35739 358.36983,232.35739 C 345.81893,232.35739 335.63407,222.17061 335.63407,209.6197 C 335.63407,197.07072 345.81893,186.884 358.36983,186.884 C 370.92074,186.884 381.10554,197.07072 381.10554,209.6197 z "
-     style="fill:#231f20;fill-rule:evenodd"
-     id="path2591" />
-  <g
-     id="g5911"
-     transform="matrix(7.4637512,0,0,7.4637512,3654.4502,2135.9905)">
-    <g
-       transform="translate(43.83788,-5.9911769)"
-       id="flowRoot5812"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:'MUTT ClearlyU Alternate Glyphs Wide';-inkscape-font-specification:'MUTT ClearlyU Alternate Glyphs Wide';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-       aria-label="o">
-      <path
-         inkscape:connector-curvature="0"
-         id="path5850"
-         d="m -465.53711,-251.78906 q -2.89062,0 -4.57031,2.26562 -1.67969,2.2461 -1.67969,6.17188 0,3.92578 1.66016,6.1914 1.67968,2.2461 4.58984,2.2461 2.87109,0 4.55078,-2.26563 1.67969,-2.26562 1.67969,-6.17187 0,-3.88672 -1.67969,-6.15235 -1.67969,-2.28515 -4.55078,-2.28515 z m 0,-3.04688 q 4.6875,0 7.36328,3.04688 2.67578,3.04687 2.67578,8.4375 0,5.37109 -2.67578,8.4375 -2.67578,3.04687 -7.36328,3.04687 -4.70703,0 -7.38281,-3.04687 -2.65625,-3.06641 -2.65625,-8.4375 0,-5.39063 2.65625,-8.4375 2.67578,-3.04688 7.38281,-3.04688 z" />
-    </g>
-    <g
-       style="stroke:none"
-       transform="matrix(1.1063192,0,0,1.1063192,-833.30223,0.28717909)"
-       id="g5848">
-      <g
-         transform="translate(-1.7044944,-1.3542613)"
-         id="g5880">
-        <path
-           sodipodi:nodetypes="cccccc"
-           style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.15866427;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47637796"
-           d="m 368.14212,-218.67608 c 3.09813,3.09809 8.12116,3.09805 11.21926,-8e-5 3.09812,-3.09809 3.09815,-8.12112 6e-5,-11.21925 -3.09812,-3.09818 -8.12123,-3.09818 -11.21935,0 -3.09817,3.09812 -3.09816,8.12122 1e-5,11.21934 z"
-           id="path5844"
-           inkscape:connector-curvature="0" />
-        <path
-           inkscape:connector-curvature="0"
-           id="path5164"
-           d="m 367.67983,-218.21379 a 8.5869898,8.5869898 0 0 0 12.14384,-8e-5 8.5869898,8.5869898 0 0 0 7e-5,-12.14383 8.5869898,8.5869898 0 0 0 -12.14394,0 8.5869898,8.5869898 0 0 0 10e-6,12.14393 z m 1.125,-1.125 0.18031,-2.70097 0.5717,0.5717 0.003,0.003 2.7379,-2.73789 1.3739,1.37392 -2.73788,2.7379 0.57169,0.5717 z m 5.91017,-1.46334 -0.18043,-2.70086 2.70088,0.18042 -0.5717,0.57169 2.73789,2.7379 -1.37392,1.37391 -2.73789,-2.73789 -0.003,0.003 z m -4.44694,-4.44691 0.57171,-0.57171 0.003,-0.003 -2.73778,-2.73778 1.37391,-1.37393 2.7378,2.7378 0.57169,-0.5717 0.18042,2.70087 z m 4.94071,0.88337 -1.37392,-1.37393 2.7379,-2.73788 -0.003,-0.003 -0.57169,-0.5717 2.70098,-0.18032 -0.18043,2.70087 -0.5717,-0.5717 z"
-           style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17173979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47637796" />
-      </g>
-    </g>
-  </g>
-  <g
-     id="g5903"
-     transform="matrix(6.9235089,0,0,6.9235089,3153.6149,1719.6471)">
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.77741718px;line-height:1.25;font-family:'URW Gothic';-inkscape-font-specification:'URW Gothic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.14443544"
-       x="-411.65942"
-       y="-191.28912"
-       id="text5923"><tspan
-         sodipodi:role="line"
-         id="tspan5921"
-         x="-411.65942"
-         y="-191.28912"
-         style="stroke-width:0.14443544">routing</tspan></text>
-    <g
-       transform="matrix(0.04984713,0,0,0.04984713,-376.80251,-223.39298)"
-       id="g5934">
-      <circle
-         r="18.575233"
-         cy="84.387085"
-         cx="70.425522"
-         id="path5925"
-         style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5929"
-         y="92.263435"
-         x="56.593464"
-         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.31624031px;line-height:1.25;font-family:'URW Gothic';-inkscape-font-specification:'URW Gothic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.532906"
-         xml:space="preserve"><tspan
-           style="stroke-width:0.532906"
-           y="92.263435"
-           x="56.593464"
-           id="tspan5927"
-           sodipodi:role="line">RD</tspan></text>
-    </g>
-  </g>
-  <g
-     transform="matrix(6.7799663,0,0,6.7799663,3135.2341,1973.3465)"
-     id="g5991">
-    <g
-       aria-label="o"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:'MUTT ClearlyU Alternate Glyphs Wide';-inkscape-font-specification:'MUTT ClearlyU Alternate Glyphs Wide';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-       id="g5981"
-       transform="translate(43.83788,-5.9911769)">
-      <path
-         d="m -465.53711,-251.78906 q -2.89062,0 -4.57031,2.26562 -1.67969,2.2461 -1.67969,6.17188 0,3.92578 1.66016,6.1914 1.67968,2.2461 4.58984,2.2461 2.87109,0 4.55078,-2.26563 1.67969,-2.26562 1.67969,-6.17187 0,-3.88672 -1.67969,-6.15235 -1.67969,-2.28515 -4.55078,-2.28515 z m 0,-3.04688 q 4.6875,0 7.36328,3.04688 2.67578,3.04687 2.67578,8.4375 0,5.37109 -2.67578,8.4375 -2.67578,3.04687 -7.36328,3.04687 -4.70703,0 -7.38281,-3.04687 -2.65625,-3.06641 -2.65625,-8.4375 0,-5.39063 2.65625,-8.4375 2.67578,-3.04688 7.38281,-3.04688 z"
-         id="path5979"
-         inkscape:connector-curvature="0" />
-    </g>
-    <g
-       id="g5989"
-       transform="matrix(1.1063192,0,0,1.1063192,-833.30223,0.28717909)"
-       style="stroke:none">
-      <g
-         id="g5987"
-         transform="translate(-1.7044944,-1.3542613)">
-        <path
-           inkscape:connector-curvature="0"
-           id="path5983"
-           d="m 368.14212,-218.67608 c 3.09813,3.09809 8.12116,3.09805 11.21926,-8e-5 3.09812,-3.09809 3.09815,-8.12112 6e-5,-11.21925 -3.09812,-3.09818 -8.12123,-3.09818 -11.21935,0 -3.09817,3.09812 -3.09816,8.12122 1e-5,11.21934 z"
-           style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.15866427;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47637796"
-           sodipodi:nodetypes="cccccc" />
-        <path
-           style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17173979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47637796"
-           d="m 367.67983,-218.21379 a 8.5869898,8.5869898 0 0 0 12.14384,-8e-5 8.5869898,8.5869898 0 0 0 7e-5,-12.14383 8.5869898,8.5869898 0 0 0 -12.14394,0 8.5869898,8.5869898 0 0 0 10e-6,12.14393 z m 1.125,-1.125 0.18031,-2.70097 0.5717,0.5717 0.003,0.003 2.7379,-2.73789 1.3739,1.37392 -2.73788,2.7379 0.57169,0.5717 z m 5.91017,-1.46334 -0.18043,-2.70086 2.70088,0.18042 -0.5717,0.57169 2.73789,2.7379 -1.37392,1.37391 -2.73789,-2.73789 -0.003,0.003 z m -4.44694,-4.44691 0.57171,-0.57171 0.003,-0.003 -2.73778,-2.73778 1.37391,-1.37393 2.7378,2.7378 0.57169,-0.5717 0.18042,2.70087 z m 4.94071,0.88337 -1.37392,-1.37393 2.7379,-2.73788 -0.003,-0.003 -0.57169,-0.5717 2.70098,-0.18032 -0.18043,2.70087 -0.5717,-0.5717 z"
-           id="path5985"
-           inkscape:connector-curvature="0" />
-      </g>
-    </g>
-  </g>
-  <path
-     d="M 336.20416,230.25486 L 336.20416,358.70411 L 381.32228,358.70411 L 381.32228,358.70411 C 383.44042,352.62681 409.49887,278.93188 439.27243,243.07711 C 466.06686,210.81646 507.64945,171.96306 559.249,205.96709 C 559.249,205.96709 510.46261,159.84946 446.8998,196.81893 C 406.23666,220.47221 385.48636,262.22268 381.48234,273.1591 L 381.48234,229.14009 C 376.0766,235.95733 367.74057,240.34592 358.37176,240.34592 C 349.53204,240.34592 341.61182,236.4278 336.20416,230.25486 L 336.20416,230.25486 z "
-     style="fill:url(#linearGradient2243);fill-rule:evenodd;fill-opacity:1.0"
-     id="path2593" />
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:'URW Gothic';-inkscape-font-specification:'URW Gothic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
-     x="371.06567"
-     y="442.10641"
-     id="text5915"><tspan
-       sodipodi:role="line"
-       id="tspan5913"
-       x="371.06567"
-       y="442.10641"
-       style="text-align:center;text-anchor:middle">aus kontrollierten</tspan><tspan
-       sodipodi:role="line"
-       x="371.06567"
-       y="492.10641"
-       id="tspan5919"
-       style="text-align:center;text-anchor:middle">RFCs</tspan></text>
-</svg>
diff --git a/vendor/github.com/bio-routing/bio-rd/main.go b/vendor/github.com/bio-routing/bio-rd/main.go
deleted file mode 100644
index fbf3692f7b40265edd9b39c6d151809bd130b2e4..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/main.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"net"
-	"sync"
-
-	"github.com/sirupsen/logrus"
-
-	"github.com/bio-routing/bio-rd/config"
-	"github.com/bio-routing/bio-rd/protocols/bgp/server"
-)
-
-func main() {
-	fmt.Printf("This is a BGP speaker\n")
-
-	b := server.NewBgpServer()
-
-	err := b.Start(&config.Global{
-		Listen: true,
-	})
-	if err != nil {
-		logrus.Fatalf("Unable to start BGP server: %v", err)
-	}
-
-	b.AddPeer(config.Peer{
-		AdminEnabled: true,
-		LocalAS:      65200,
-		PeerAS:       65201,
-		PeerAddress:  net.IP([]byte{169, 254, 123, 1}),
-		LocalAddress: net.IP([]byte{169, 254, 123, 0}),
-		HoldTimer:    90,
-		KeepAlive:    30,
-		Passive:      true,
-		RouterID:     b.RouterID(),
-	})
-
-	var wg sync.WaitGroup
-	wg.Add(1)
-	wg.Wait()
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/net/prefix.go b/vendor/github.com/bio-routing/bio-rd/net/prefix.go
deleted file mode 100644
index 72ece5d6409521547d39586e4592355cebe9a8af..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/net/prefix.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package net
-
-import (
-	"fmt"
-	"math"
-	"net"
-	"strconv"
-	"strings"
-
-	"github.com/taktv6/tflow2/convert"
-)
-
-// Prefix represents an IPv4 prefix
-type Prefix struct {
-	addr   uint32
-	pfxlen uint8
-}
-
-// NewPfx creates a new Prefix
-func NewPfx(addr uint32, pfxlen uint8) *Prefix {
-	return &Prefix{
-		addr:   addr,
-		pfxlen: pfxlen,
-	}
-}
-
-// StrToAddr converts an IP address string to it's uint32 representation
-func StrToAddr(x string) (uint32, error) {
-	parts := strings.Split(x, ".")
-	if len(parts) != 4 {
-		return 0, fmt.Errorf("Invalid format")
-	}
-
-	ret := uint32(0)
-	for i := 0; i < 4; i++ {
-		y, err := strconv.Atoi(parts[i])
-		if err != nil {
-			return 0, fmt.Errorf("Unable to convert %q to int: %v", parts[i], err)
-		}
-
-		if y > 255 {
-			return 0, fmt.Errorf("%d is too big for a uint8", y)
-		}
-
-		ret += uint32(math.Pow(256, float64(3-i))) * uint32(y)
-	}
-
-	return ret, nil
-}
-
-// Addr returns the address of the prefix
-func (pfx *Prefix) Addr() uint32 {
-	return pfx.addr
-}
-
-// Pfxlen returns the length of the prefix
-func (pfx *Prefix) Pfxlen() uint8 {
-	return pfx.pfxlen
-}
-
-// String returns a string representation of pfx
-func (pfx *Prefix) String() string {
-	return fmt.Sprintf("%s/%d", net.IP(convert.Uint32Byte(pfx.addr)), pfx.pfxlen)
-}
-
-// Contains checks if x is a subnet of or equal to pfx
-func (pfx *Prefix) Contains(x *Prefix) bool {
-	if x.pfxlen <= pfx.pfxlen {
-		return false
-	}
-
-	mask := (uint32(1) << (32 - pfx.pfxlen))
-	return (pfx.addr & mask) == (x.addr & mask)
-}
-
-// Equal checks if pfx and x are equal
-func (pfx *Prefix) Equal(x *Prefix) bool {
-	return *pfx == *x
-}
-
-// GetSupernet gets the next common supernet of pfx and x
-func (pfx *Prefix) GetSupernet(x *Prefix) *Prefix {
-	maxPfxLen := min(pfx.pfxlen, x.pfxlen) - 1
-	a := pfx.addr >> (32 - maxPfxLen)
-	b := x.addr >> (32 - maxPfxLen)
-
-	for i := 0; a != b; i++ {
-		a = a >> 1
-		b = b >> 1
-		maxPfxLen--
-	}
-
-	return &Prefix{
-		addr:   a << (32 - maxPfxLen),
-		pfxlen: maxPfxLen,
-	}
-}
-
-func min(a uint8, b uint8) uint8 {
-	if a < b {
-		return a
-	}
-	return b
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/net/prefix_test.go b/vendor/github.com/bio-routing/bio-rd/net/prefix_test.go
deleted file mode 100644
index 45fb90287a22483b6a49eeda1870b48b791790de..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/net/prefix_test.go
+++ /dev/null
@@ -1,334 +0,0 @@
-package net
-
-import (
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestNewPfx(t *testing.T) {
-	p := NewPfx(123, 11)
-	if p.addr != 123 || p.pfxlen != 11 {
-		t.Errorf("NewPfx() failed: Unexpected values")
-	}
-}
-
-func TestAddr(t *testing.T) {
-	tests := []struct {
-		name     string
-		pfx      *Prefix
-		expected uint32
-	}{
-		{
-			name:     "Test 1",
-			pfx:      NewPfx(100, 5),
-			expected: 100,
-		},
-	}
-
-	for _, test := range tests {
-		res := test.pfx.Addr()
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %s: Got %d Expected %d", test.name, res, test.expected)
-		}
-	}
-}
-
-func TestPfxlen(t *testing.T) {
-	tests := []struct {
-		name     string
-		pfx      *Prefix
-		expected uint8
-	}{
-		{
-			name:     "Test 1",
-			pfx:      NewPfx(100, 5),
-			expected: 5,
-		},
-	}
-
-	for _, test := range tests {
-		res := test.pfx.Pfxlen()
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %s: Got %d Expected %d", test.name, res, test.expected)
-		}
-	}
-}
-
-func TestGetSupernet(t *testing.T) {
-	tests := []struct {
-		name     string
-		a        *Prefix
-		b        *Prefix
-		expected *Prefix
-	}{
-		{
-			name: "Test 1",
-			a: &Prefix{
-				addr:   167772160, // 10.0.0.0/8
-				pfxlen: 8,
-			},
-			b: &Prefix{
-				addr:   191134464, // 11.100.123.0/24
-				pfxlen: 24,
-			},
-			expected: &Prefix{
-				addr:   167772160, // 10.0.0.0/7
-				pfxlen: 7,
-			},
-		},
-		{
-			name: "Test 2",
-			a: &Prefix{
-				addr:   167772160, // 10.0.0.0/8
-				pfxlen: 8,
-			},
-			b: &Prefix{
-				addr:   3232235520, // 192.168.0.0/24
-				pfxlen: 24,
-			},
-			expected: &Prefix{
-				addr:   0, // 0.0.0.0/0
-				pfxlen: 0,
-			},
-		},
-	}
-
-	for _, test := range tests {
-		s := test.a.GetSupernet(test.b)
-		assert.Equal(t, s, test.expected)
-	}
-}
-
-func TestContains(t *testing.T) {
-	tests := []struct {
-		name     string
-		a        *Prefix
-		b        *Prefix
-		expected bool
-	}{
-		{
-			name: "Test 1",
-			a: &Prefix{
-				addr:   0,
-				pfxlen: 0,
-			},
-			b: &Prefix{
-				addr:   100,
-				pfxlen: 24,
-			},
-			expected: true,
-		},
-		{
-			name: "Test 2",
-			a: &Prefix{
-				addr:   100,
-				pfxlen: 24,
-			},
-			b: &Prefix{
-				addr:   0,
-				pfxlen: 0,
-			},
-			expected: false,
-		},
-		{
-			name: "Test 3",
-			a: &Prefix{
-				addr:   167772160,
-				pfxlen: 8,
-			},
-			b: &Prefix{
-				addr:   167772160,
-				pfxlen: 9,
-			},
-			expected: true,
-		},
-		{
-			name: "Test 4",
-			a: &Prefix{
-				addr:   167772160,
-				pfxlen: 8,
-			},
-			b: &Prefix{
-				addr:   174391040,
-				pfxlen: 24,
-			},
-			expected: true,
-		},
-		{
-			name: "Test 5",
-			a: &Prefix{
-				addr:   167772160,
-				pfxlen: 8,
-			},
-			b: &Prefix{
-				addr:   184549377,
-				pfxlen: 24,
-			},
-			expected: false,
-		},
-		{
-			name: "Test 6",
-			a: &Prefix{
-				addr:   167772160,
-				pfxlen: 8,
-			},
-			b: &Prefix{
-				addr:   191134464,
-				pfxlen: 24,
-			},
-			expected: false,
-		},
-	}
-
-	for _, test := range tests {
-		res := test.a.Contains(test.b)
-		if res != test.expected {
-			t.Errorf("Unexpected result %v for test %s: %s contains %s\n", res, test.name, test.a.String(), test.b.String())
-		}
-	}
-}
-
-func TestMin(t *testing.T) {
-	tests := []struct {
-		name     string
-		a        uint8
-		b        uint8
-		expected uint8
-	}{
-		{
-			name:     "Min 100 200",
-			a:        100,
-			b:        200,
-			expected: 100,
-		},
-		{
-			name:     "Min 200 100",
-			a:        200,
-			b:        100,
-			expected: 100,
-		},
-		{
-			name:     "Min 111 112",
-			a:        111,
-			b:        112,
-			expected: 111,
-		},
-	}
-
-	for _, test := range tests {
-		res := min(test.a, test.b)
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %s: Got %d Expected %d", test.name, res, test.expected)
-		}
-	}
-}
-
-func TestEqual(t *testing.T) {
-	tests := []struct {
-		name     string
-		a        *Prefix
-		b        *Prefix
-		expected bool
-	}{
-		{
-			name:     "Equal PFXs",
-			a:        NewPfx(100, 8),
-			b:        NewPfx(100, 8),
-			expected: true,
-		},
-		{
-			name:     "Unequal PFXs",
-			a:        NewPfx(100, 8),
-			b:        NewPfx(200, 8),
-			expected: false,
-		},
-	}
-
-	for _, test := range tests {
-		res := test.a.Equal(test.b)
-		if res != test.expected {
-			t.Errorf("Unexpected result for %q: Got %v Expected %v", test.name, res, test.expected)
-		}
-	}
-}
-
-func TestString(t *testing.T) {
-	tests := []struct {
-		name     string
-		pfx      *Prefix
-		expected string
-	}{
-		{
-			name:     "Test 1",
-			pfx:      NewPfx(167772160, 8), // 10.0.0.0/8
-			expected: "10.0.0.0/8",
-		},
-		{
-			name:     "Test 2",
-			pfx:      NewPfx(167772160, 16), // 10.0.0.0/8
-			expected: "10.0.0.0/16",
-		},
-	}
-
-	for _, test := range tests {
-		res := test.pfx.String()
-		if res != test.expected {
-			t.Errorf("Unexpected result for %q: Got %q Expected %q", test.name, res, test.expected)
-		}
-	}
-}
-
-func TestStrToAddr(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    string
-		wantFail bool
-		expected uint32
-	}{
-		{
-			name:     "Invalid address #1",
-			input:    "10.10.10",
-			wantFail: true,
-		},
-		{
-			name:     "Invalid address #2",
-			input:    "",
-			wantFail: true,
-		},
-		{
-			name:     "Invalid address #3",
-			input:    "10.10.10.10.10",
-			wantFail: true,
-		},
-		{
-			name:     "Invalid address #4",
-			input:    "10.256.0.0",
-			wantFail: true,
-		},
-		{
-			name:     "Valid address",
-			input:    "10.0.0.0",
-			wantFail: false,
-			expected: 167772160,
-		},
-	}
-
-	for _, test := range tests {
-		res, err := StrToAddr(test.input)
-		if err != nil {
-			if test.wantFail {
-				continue
-			}
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		if test.wantFail {
-			t.Errorf("Unexpected success for test %q", test.name)
-			continue
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/bgp.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/bgp.go
deleted file mode 100644
index be4f30dc5890e9abca69a4822a3e7d6187a30a0c..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/bgp.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package packet
-
-const (
-	OctetLen    = 8
-	BGP4Version = 4
-
-	MarkerLen  = 16
-	HeaderLen  = 19
-	MinLen     = 19
-	MaxLen     = 4096
-	NLRIMaxLen = 5
-
-	OpenMsg         = 1
-	UpdateMsg       = 2
-	NotificationMsg = 3
-	KeepaliveMsg    = 4
-
-	MessageHeaderError      = 1
-	OpenMessageError        = 2
-	UpdateMessageError      = 3
-	HoldTimeExpired         = 4
-	FiniteStateMachineError = 5
-	Cease                   = 6
-
-	// Msg Header Errors
-	ConnectionNotSync = 1
-	BadMessageLength  = 2
-	BadMessageType    = 3
-
-	// Open Msg Errors
-	UnsupportedVersionNumber     = 1
-	BadPeerAS                    = 2
-	BadBGPIdentifier             = 3
-	UnsupportedOptionalParameter = 4
-	DeprecatedOpenMsgError5      = 5
-	UnacceptableHoldTime         = 6
-
-	// Update Msg Errors
-	MalformedAttributeList    = 1
-	UnrecognizedWellKnownAttr = 2
-	MissingWellKnonAttr       = 3
-	AttrFlagsError            = 4
-	AttrLengthError           = 5
-	InvalidOriginAttr         = 6
-	DeprecatedUpdateMsgError7 = 7
-	InvalidNextHopAttr        = 8
-	OptionalAttrError         = 9
-	InvalidNetworkField       = 10
-	MalformedASPath           = 11
-
-	// Attribute Type Codes
-	OriginAttr     = 1
-	ASPathAttr     = 2
-	NextHopAttr    = 3
-	MEDAttr        = 4
-	LocalPrefAttr  = 5
-	AtomicAggrAttr = 6
-	AggregatorAttr = 7
-
-	// ORIGIN values
-	IGP        = 0
-	EGP        = 1
-	INCOMPLETE = 2
-
-	// ASPath Segment Types
-	ASSet      = 1
-	ASSequence = 2
-
-	// NOTIFICATION Cease error SubCodes (RFC4486)
-	MaxPrefReached                = 1
-	AdminShut                     = 2
-	PeerDeconfigured              = 3
-	AdminReset                    = 4
-	ConnectionRejected            = 5
-	OtherConfigChange             = 8
-	ConnectionCollisionResolution = 7
-	OutOfResoutces                = 8
-)
-
-type BGPError struct {
-	ErrorCode    uint8
-	ErrorSubCode uint8
-	ErrorStr     string
-}
-
-func (b BGPError) Error() string {
-	return b.ErrorStr
-}
-
-type BGPMessage struct {
-	Header *BGPHeader
-	Body   interface{}
-}
-
-type BGPHeader struct {
-	Length uint16
-	Type   uint8
-}
-
-type BGPOpen struct {
-	Version       uint8
-	AS            uint16
-	HoldTime      uint16
-	BGPIdentifier uint32
-	OptParmLen    uint8
-}
-
-type BGPNotification struct {
-	ErrorCode    uint8
-	ErrorSubcode uint8
-}
-
-type BGPUpdate struct {
-	WithdrawnRoutesLen uint16
-	WithdrawnRoutes    *NLRI
-	TotalPathAttrLen   uint16
-	PathAttributes     *PathAttribute
-	NLRI               *NLRI
-}
-
-type PathAttribute struct {
-	Length         uint16
-	Optional       bool
-	Transitive     bool
-	Partial        bool
-	ExtendedLength bool
-	TypeCode       uint8
-	Value          interface{}
-	Next           *PathAttribute
-}
-
-type NLRI struct {
-	IP     interface{}
-	Pfxlen uint8
-	Next   *NLRI
-}
-
-type ASPath []ASPathSegment
-type ASPathSegment struct {
-	Type  uint8
-	Count uint8
-	ASNs  []uint32
-}
-
-type Aggretator struct {
-	Addr [4]byte
-	ASN  uint16
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/decoder.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/decoder.go
deleted file mode 100644
index 8ba824ec9fd0620a32416bc0c66c8fd3b8d4c0ef..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/decoder.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"net"
-
-	"github.com/taktv6/tflow2/convert"
-)
-
-// Decode decodes a BGP message
-func Decode(buf *bytes.Buffer) (*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)
-	if err != nil {
-		return nil, fmt.Errorf("Failed to decode message: %v", err)
-	}
-
-	return &BGPMessage{
-		Header: hdr,
-		Body:   body,
-	}, nil
-}
-
-func decodeMsgBody(buf *bytes.Buffer, msgType uint8, l uint16) (interface{}, error) {
-	switch msgType {
-	case OpenMsg:
-		return decodeOpenMsg(buf)
-	case UpdateMsg:
-		return decodeUpdateMsg(buf, l)
-	case KeepaliveMsg:
-		return nil, nil // Nothing to decode in Keepalive message
-	case NotificationMsg:
-		return decodeNotificationMsg(buf)
-	}
-	return nil, fmt.Errorf("Unknown message type: %d", msgType)
-}
-
-func decodeUpdateMsg(buf *bytes.Buffer, l uint16) (*BGPUpdate, error) {
-	msg := &BGPUpdate{}
-
-	err := decode(buf, []interface{}{&msg.WithdrawnRoutesLen})
-	if err != nil {
-		return msg, err
-	}
-
-	msg.WithdrawnRoutes, err = decodeNLRIs(buf, uint16(msg.WithdrawnRoutesLen))
-	if err != nil {
-		return msg, err
-	}
-
-	err = decode(buf, []interface{}{&msg.TotalPathAttrLen})
-	if err != nil {
-		return msg, err
-	}
-
-	msg.PathAttributes, err = decodePathAttrs(buf, msg.TotalPathAttrLen)
-	if err != nil {
-		return msg, err
-	}
-
-	nlriLen := uint16(l) - 4 - uint16(msg.TotalPathAttrLen) - uint16(msg.WithdrawnRoutesLen)
-	if nlriLen > 0 {
-		msg.NLRI, err = decodeNLRIs(buf, nlriLen)
-		if err != nil {
-			return msg, err
-		}
-	}
-
-	return msg, nil
-}
-
-func decodeNotificationMsg(buf *bytes.Buffer) (*BGPNotification, error) {
-	msg := &BGPNotification{}
-
-	fields := []interface{}{
-		&msg.ErrorCode,
-		&msg.ErrorSubcode,
-	}
-
-	err := decode(buf, fields)
-	if err != nil {
-		return msg, err
-	}
-
-	if msg.ErrorCode > Cease {
-		return msg, fmt.Errorf("Invalid error code: %d", msg.ErrorSubcode)
-	}
-
-	switch msg.ErrorCode {
-	case MessageHeaderError:
-		if msg.ErrorSubcode > BadMessageType || msg.ErrorSubcode == 0 {
-			return invalidErrCode(msg)
-		}
-	case OpenMessageError:
-		if msg.ErrorSubcode > UnacceptableHoldTime || msg.ErrorSubcode == 0 || msg.ErrorSubcode == DeprecatedOpenMsgError5 {
-			return invalidErrCode(msg)
-		}
-	case UpdateMessageError:
-		if msg.ErrorSubcode > MalformedASPath || msg.ErrorSubcode == 0 || msg.ErrorSubcode == DeprecatedUpdateMsgError7 {
-			return invalidErrCode(msg)
-		}
-	case HoldTimeExpired:
-		if msg.ErrorSubcode != 0 {
-			return invalidErrCode(msg)
-		}
-	case FiniteStateMachineError:
-		if msg.ErrorSubcode != 0 {
-			return invalidErrCode(msg)
-		}
-	case Cease:
-		if msg.ErrorSubcode != 0 {
-			return invalidErrCode(msg)
-		}
-	default:
-		return invalidErrCode(msg)
-	}
-
-	return msg, nil
-}
-
-func invalidErrCode(n *BGPNotification) (*BGPNotification, error) {
-	return n, fmt.Errorf("Invalid error sub code: %d/%d", n.ErrorCode, n.ErrorSubcode)
-}
-
-func decodeOpenMsg(buf *bytes.Buffer) (*BGPOpen, error) {
-	msg, err := _decodeOpenMsg(buf)
-	return msg.(*BGPOpen), err
-}
-
-func _decodeOpenMsg(buf *bytes.Buffer) (interface{}, error) {
-	msg := &BGPOpen{}
-
-	fields := []interface{}{
-		&msg.Version,
-		&msg.AS,
-		&msg.HoldTime,
-		&msg.BGPIdentifier,
-		&msg.OptParmLen,
-	}
-
-	err := decode(buf, fields)
-	if err != nil {
-		return msg, err
-	}
-
-	err = validateOpen(msg)
-	if err != nil {
-		return nil, err
-	}
-
-	return msg, nil
-}
-
-func validateOpen(msg *BGPOpen) error {
-	if msg.Version != BGP4Version {
-		return BGPError{
-			ErrorCode:    OpenMessageError,
-			ErrorSubCode: UnsupportedVersionNumber,
-			ErrorStr:     fmt.Sprintf("Unsupported version number"),
-		}
-	}
-	if !isValidIdentifier(msg.BGPIdentifier) {
-		return BGPError{
-			ErrorCode:    OpenMessageError,
-			ErrorSubCode: BadBGPIdentifier,
-			ErrorStr:     fmt.Sprintf("Invalid BGP identifier"),
-		}
-	}
-
-	return nil
-}
-
-func isValidIdentifier(id uint32) bool {
-	addr := net.IP(convert.Uint32Byte(id))
-	if addr.IsLoopback() {
-		return false
-	}
-
-	if addr.IsMulticast() {
-		return false
-	}
-
-	if addr[0] == 0 {
-		return false
-	}
-
-	if addr[0] == 255 && addr[1] == 255 && addr[2] == 255 && addr[3] == 255 {
-		return false
-	}
-
-	return true
-}
-
-func decodeHeader(buf *bytes.Buffer) (*BGPHeader, error) {
-	hdr := &BGPHeader{}
-
-	marker := make([]byte, MarkerLen)
-	n, err := buf.Read(marker)
-	if err != nil {
-		return hdr, BGPError{
-			ErrorCode:    Cease,
-			ErrorSubCode: 0,
-			ErrorStr:     fmt.Sprintf("Failed to read from buffer: %v", err.Error()),
-		}
-	}
-
-	if n != MarkerLen {
-		return hdr, BGPError{
-			ErrorCode:    Cease,
-			ErrorSubCode: 0,
-			ErrorStr:     fmt.Sprintf("Unable to read marker"),
-		}
-	}
-
-	for i := range marker {
-		if marker[i] != 255 {
-			return nil, BGPError{
-				ErrorCode:    MessageHeaderError,
-				ErrorSubCode: ConnectionNotSync,
-				ErrorStr:     fmt.Sprintf("Invalid marker: %v", marker),
-			}
-		}
-	}
-
-	fields := []interface{}{
-		&hdr.Length,
-		&hdr.Type,
-	}
-
-	err = decode(buf, fields)
-	if err != nil {
-		return hdr, BGPError{
-			ErrorCode:    Cease,
-			ErrorSubCode: 0,
-			ErrorStr:     fmt.Sprintf("%v", err.Error()),
-		}
-	}
-
-	if hdr.Length < MinLen || hdr.Length > MaxLen {
-		return hdr, BGPError{
-			ErrorCode:    MessageHeaderError,
-			ErrorSubCode: BadMessageLength,
-			ErrorStr:     fmt.Sprintf("Invalid length in BGP header: %v", hdr.Length),
-		}
-	}
-
-	if hdr.Type > KeepaliveMsg || hdr.Type == 0 {
-		return hdr, BGPError{
-			ErrorCode:    MessageHeaderError,
-			ErrorSubCode: BadMessageType,
-			ErrorStr:     fmt.Sprintf("Invalid message type: %d", hdr.Type),
-		}
-	}
-
-	return hdr, nil
-}
-
-func decode(buf *bytes.Buffer, fields []interface{}) error {
-	var err error
-	for _, field := range fields {
-		err = binary.Read(buf, binary.BigEndian, field)
-		if err != nil {
-			return fmt.Errorf("Unable to read from buffer: %v", err)
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/decoder_test.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/decoder_test.go
deleted file mode 100644
index ddb20a2e8beee9f1b6a8ff8d3b3a7fc3b3be5a2b..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/decoder_test.go
+++ /dev/null
@@ -1,1536 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/taktv6/tflow2/convert"
-)
-
-type test struct {
-	testNum  int
-	input    []byte
-	wantFail bool
-	expected interface{}
-}
-
-type decodeFunc func(*bytes.Buffer) (interface{}, error)
-
-func BenchmarkDecodeUpdateMsg(b *testing.B) {
-	input := []byte{0, 5, 8, 10, 16, 192, 168,
-		0, 53, // Total Path Attribute Length
-
-		255,  // Attribute flags
-		1,    // Attribute Type code (ORIGIN)
-		0, 1, // Length
-		2, // INCOMPLETE
-
-		0,      // Attribute flags
-		2,      // Attribute Type code (AS Path)
-		12,     // Length
-		2,      // Type = AS_SEQUENCE
-		2,      // Path Segement Length
-		59, 65, // AS15169
-		12, 248, // AS3320
-		1,      // Type = AS_SET
-		2,      // Path Segement Length
-		59, 65, // AS15169
-		12, 248, // AS3320
-
-		0,              // Attribute flags
-		3,              // Attribute Type code (Next Hop)
-		4,              // Length
-		10, 11, 12, 13, // Next Hop
-
-		0,          // Attribute flags
-		4,          // Attribute Type code (MED)
-		4,          // Length
-		0, 0, 1, 0, // MED 256
-
-		0,          // Attribute flags
-		5,          // Attribute Type code (Local Pref)
-		4,          // Length
-		0, 0, 1, 0, // Local Pref 256
-
-		0, // Attribute flags
-		6, // Attribute Type code (Atomic Aggregate)
-		0, // Length
-
-		0,    // Attribute flags
-		7,    // Attribute Type code (Atomic Aggregate)
-		6,    // Length
-		1, 2, // ASN
-		10, 11, 12, 13, // Address
-
-		8, 11, // 11.0.0.0/8
-	}
-
-	for i := 0; i < b.N; i++ {
-		buf := bytes.NewBuffer(input)
-		_, err := decodeUpdateMsg(buf, uint16(len(input)))
-		if err != nil {
-			fmt.Printf("decodeUpdateMsg failed: %v\n", err)
-		}
-		//buf.Next(1)
-	}
-}
-
-func TestDecode(t *testing.T) {
-	tests := []test{
-		{
-			// Proper packet
-			testNum: 1,
-			input: []byte{
-				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
-				0, 19, // Length
-				4, // Type = Keepalive
-
-			},
-			wantFail: false,
-			expected: &BGPMessage{
-				Header: &BGPHeader{
-					Length: 19,
-					Type:   4,
-				},
-			},
-		},
-		{
-			// Invalid marker
-			testNum: 2,
-			input: []byte{
-				1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, // Marker
-				0, 19, // Length
-				4, // Type = Keepalive
-
-			},
-			wantFail: true,
-			expected: &BGPMessage{
-				Header: &BGPHeader{
-					Length: 19,
-					Type:   4,
-				},
-			},
-		},
-		{
-			// Proper NOTIFICATION packet
-			testNum: 3,
-			input: []byte{
-				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
-				0, 21, // Length
-				3,    // Type = Notification
-				1, 1, // Message Header Error, Connection Not Synchronized.
-			},
-			wantFail: false,
-			expected: &BGPMessage{
-				Header: &BGPHeader{
-					Length: 21,
-					Type:   3,
-				},
-				Body: &BGPNotification{
-					ErrorCode:    1,
-					ErrorSubcode: 1,
-				},
-			},
-		},
-		{
-			// Proper OPEN packet
-			testNum: 4,
-			input: []byte{
-				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
-				0, 29, // Length
-				1,      // Type = Open
-				4,      // Version
-				0, 200, //ASN,
-				0, 15, // Holdtime
-				10, 20, 30, 40, // BGP Identifier
-				0, // Opt Parm Len
-			},
-			wantFail: false,
-			expected: &BGPMessage{
-				Header: &BGPHeader{
-					Length: 29,
-					Type:   1,
-				},
-				Body: &BGPOpen{
-					Version:       4,
-					AS:            200,
-					HoldTime:      15,
-					BGPIdentifier: uint32(169090600),
-					OptParmLen:    0,
-				},
-			},
-		},
-		{
-			// Incomplete OPEN packet
-			testNum: 5,
-			input: []byte{
-				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
-				0, 28, // Length
-				1,      // Type = Open
-				4,      // Version
-				0, 200, //ASN,
-				0, 15, // Holdtime
-				0, 0, 0, 100, // BGP Identifier
-			},
-			wantFail: true,
-			expected: &BGPMessage{
-				Header: &BGPHeader{
-					Length: 28,
-					Type:   1,
-				},
-				Body: &BGPOpen{
-					Version:       4,
-					AS:            200,
-					HoldTime:      15,
-					BGPIdentifier: uint32(100),
-				},
-			},
-		},
-		{
-			testNum: 6,
-			input: []byte{
-				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
-				0, 28, // Length
-				2,                               // Type = Update
-				0, 5, 8, 10, 16, 192, 168, 0, 0, // 2 withdraws
-			},
-			wantFail: false,
-			expected: &BGPMessage{
-				Header: &BGPHeader{
-					Length: 28,
-					Type:   2,
-				},
-				Body: &BGPUpdate{
-					WithdrawnRoutesLen: 5,
-					WithdrawnRoutes: &NLRI{
-						IP:     [4]byte{10, 0, 0, 0},
-						Pfxlen: 8,
-						Next: &NLRI{
-							IP:     [4]byte{192, 168, 0, 0},
-							Pfxlen: 16,
-						},
-					},
-				},
-			},
-		},
-		{
-			testNum: 7,
-			input: []byte{
-				255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
-				0, 28, // Length
-				5,                               // Type = Invalid
-				0, 5, 8, 10, 16, 192, 168, 0, 0, // Some more stuff
-			},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(test.input)
-		msg, err := Decode(buf)
-
-		if err != nil && !test.wantFail {
-			t.Errorf("Unexpected error in test %d: %v", test.testNum, err)
-			continue
-		}
-
-		if err == nil && test.wantFail {
-			t.Errorf("Expected error did not happen in test %d", test.testNum)
-			continue
-		}
-
-		if err != nil && test.wantFail {
-			continue
-		}
-
-		if msg == nil {
-			t.Errorf("Unexpected nil result in test %d. Expected: %v", test.testNum, test.expected)
-			continue
-		}
-
-		assert.Equal(t, test.expected, msg)
-	}
-}
-
-func TestDecodeNotificationMsg(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []byte
-		wantFail bool
-		expected interface{}
-	}{
-		{
-			name:     "Invalid error code",
-			input:    []byte{0, 0},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid error code #2",
-			input:    []byte{7, 0},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Header)",
-			input:    []byte{1, 0},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Header) #2",
-			input:    []byte{1, 4},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Open)",
-			input:    []byte{2, 0},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Open) #2",
-			input:    []byte{2, 7},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Open) #3",
-			input:    []byte{2, 5},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Update)",
-			input:    []byte{3, 0},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Update) #2",
-			input:    []byte{3, 12},
-			wantFail: true,
-		},
-		{
-			name:     "Invalid ErrSubCode (Update) #3",
-			input:    []byte{3, 7},
-			wantFail: true,
-		},
-		{
-			name:     "Valid Notification",
-			input:    []byte{2, 2},
-			wantFail: false,
-			expected: &BGPNotification{
-				ErrorCode:    2,
-				ErrorSubcode: 2,
-			},
-		},
-		{
-			name:     "Empty input",
-			input:    []byte{},
-			wantFail: true,
-		},
-		{
-			name:     "Hold Timer Expired",
-			input:    []byte{4, 0},
-			wantFail: false,
-			expected: &BGPNotification{
-				ErrorCode:    4,
-				ErrorSubcode: 0,
-			},
-		},
-		{
-			name:     "Hold Timer Expired (invalid subcode)",
-			input:    []byte{4, 1},
-			wantFail: true,
-		},
-		{
-			name:     "FSM Error",
-			input:    []byte{5, 0},
-			wantFail: false,
-			expected: &BGPNotification{
-				ErrorCode:    5,
-				ErrorSubcode: 0,
-			},
-		},
-		{
-			name:     "FSM Error (invalid subcode)",
-			input:    []byte{5, 1},
-			wantFail: true,
-		},
-		{
-			name:     "Cease",
-			input:    []byte{6, 0},
-			wantFail: false,
-			expected: &BGPNotification{
-				ErrorCode:    6,
-				ErrorSubcode: 0,
-			},
-		},
-		{
-			name:     "Cease (invalid subcode)",
-			input:    []byte{6, 1},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		res, err := decodeNotificationMsg(bytes.NewBuffer(test.input))
-
-		if test.wantFail {
-			if err != nil {
-				continue
-			}
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestDecodeUpdateMsg(t *testing.T) {
-	tests := []struct {
-		testNum        int
-		input          []byte
-		explicitLength uint16
-		wantFail       bool
-		expected       interface{}
-	}{
-		{
-			// 2 withdraws only, valid update
-			testNum:  1,
-			input:    []byte{0, 5, 8, 10, 16, 192, 168, 0, 0},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with one path attribute (ORIGIN), valid update
-			testNum: 2,
-			input: []byte{
-				0, 5, // Withdrawn Routes Length
-				8, 10, // 10.0.0.0/8
-				16, 192, 168, // 192.168.0.0/16
-				0, 5, // Total Path Attribute Length
-				255,  // Attribute flags
-				1,    // Attribute Type code
-				0, 1, // Length
-				2, // INCOMPLETE
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 5,
-				PathAttributes: &PathAttribute{
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-				},
-			},
-		},
-		{
-			// 2 withdraws with two path attributes (ORIGIN + ASPath), valid update
-			testNum: 3,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 14, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				6,      // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 14,
-				PathAttributes: &PathAttribute{
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         6,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with two path attributes (ORIGIN + ASPath), invalid AS Path segment type
-			testNum: 4,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 13, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0, // Attribute flags
-				2, // Attribute Type code (AS Path)
-				6, // Length
-				1, // Type = AS_SET
-				0, // Path Segement Length
-			},
-			wantFail: true,
-		},
-		{
-			// 2 withdraws with two path attributes (ORIGIN + ASPath), invalid AS Path segment member count
-			testNum: 5,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 13, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				6,      // Length
-				3,      // Type = INVALID
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-			},
-			wantFail: true,
-		},
-		{
-			// 2 withdraws with two path attributes (ORIGIN + ASPath), valid update
-			testNum: 6,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 20, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				12,     // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-				1,      // Type = AS_SET
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 20,
-				PathAttributes: &PathAttribute{
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         12,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-							{
-								Type:  1,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with 3 path attributes (ORIGIN + ASPath, NH), valid update
-			testNum: 7,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 27, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				12,     // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-				1,      // Type = AS_SET
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-
-				0,              // Attribute flags
-				3,              // Attribute Type code (Next Hop)
-				4,              // Length
-				10, 11, 12, 13, // Next Hop
-
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 27,
-				PathAttributes: &PathAttribute{
-
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         12,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-							{
-								Type:  1,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-						Next: &PathAttribute{
-							Optional:       false,
-							Transitive:     false,
-							Partial:        false,
-							ExtendedLength: false,
-							Length:         4,
-							TypeCode:       3,
-							Value:          [4]byte{10, 11, 12, 13},
-						},
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with 4 path attributes (ORIGIN + ASPath, NH, MED), valid update
-			testNum: 8,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 34, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				12,     // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-				1,      // Type = AS_SET
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-
-				0,              // Attribute flags
-				3,              // Attribute Type code (Next Hop)
-				4,              // Length
-				10, 11, 12, 13, // Next Hop
-
-				0,          // Attribute flags
-				4,          // Attribute Type code (Next Hop)
-				4,          // Length
-				0, 0, 1, 0, // MED 256
-
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 34,
-				PathAttributes: &PathAttribute{
-
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         12,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-							{
-								Type:  1,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-						Next: &PathAttribute{
-							Optional:       false,
-							Transitive:     false,
-							Partial:        false,
-							ExtendedLength: false,
-							Length:         4,
-							TypeCode:       3,
-							Value:          [4]byte{10, 11, 12, 13},
-							Next: &PathAttribute{
-								Optional:       false,
-								Transitive:     false,
-								Partial:        false,
-								ExtendedLength: false,
-								Length:         4,
-								TypeCode:       4,
-								Value:          uint32(256),
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with 4 path attributes (ORIGIN + ASPath, NH, MED, Local Pref), valid update
-			testNum: 9,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 41, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				12,     // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-				1,      // Type = AS_SET
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-
-				0,              // Attribute flags
-				3,              // Attribute Type code (Next Hop)
-				4,              // Length
-				10, 11, 12, 13, // Next Hop
-
-				0,          // Attribute flags
-				4,          // Attribute Type code (MED)
-				4,          // Length
-				0, 0, 1, 0, // MED 256
-
-				0,          // Attribute flags
-				5,          // Attribute Type code (Local Pref)
-				4,          // Length
-				0, 0, 1, 0, // Local Pref 256
-
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 41,
-				PathAttributes: &PathAttribute{
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         12,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-							{
-								Type:  1,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-						Next: &PathAttribute{
-							Optional:       false,
-							Transitive:     false,
-							Partial:        false,
-							ExtendedLength: false,
-							Length:         4,
-							TypeCode:       3,
-							Value:          [4]byte{10, 11, 12, 13},
-							Next: &PathAttribute{
-								Optional:       false,
-								Transitive:     false,
-								Partial:        false,
-								ExtendedLength: false,
-								Length:         4,
-								TypeCode:       4,
-								Value:          uint32(256),
-								Next: &PathAttribute{
-									Optional:       false,
-									Transitive:     false,
-									Partial:        false,
-									ExtendedLength: false,
-									Length:         4,
-									TypeCode:       5,
-									Value:          uint32(256),
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with 6 path attributes (ORIGIN, ASPath, NH, MED, Local Pref, Atomi Aggregate), valid update
-			testNum: 9,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 44, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				12,     // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-				1,      // Type = AS_SET
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-
-				0,              // Attribute flags
-				3,              // Attribute Type code (Next Hop)
-				4,              // Length
-				10, 11, 12, 13, // Next Hop
-
-				0,          // Attribute flags
-				4,          // Attribute Type code (MED)
-				4,          // Length
-				0, 0, 1, 0, // MED 256
-
-				0,          // Attribute flags
-				5,          // Attribute Type code (Local Pref)
-				4,          // Length
-				0, 0, 1, 0, // Local Pref 256
-
-				0, // Attribute flags
-				6, // Attribute Type code (Atomic Aggregate)
-				0, // Length
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 44,
-				PathAttributes: &PathAttribute{
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         12,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-							{
-								Type:  1,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-						Next: &PathAttribute{
-							Optional:       false,
-							Transitive:     false,
-							Partial:        false,
-							ExtendedLength: false,
-							Length:         4,
-							TypeCode:       3,
-							Value:          [4]byte{10, 11, 12, 13},
-							Next: &PathAttribute{
-								Optional:       false,
-								Transitive:     false,
-								Partial:        false,
-								ExtendedLength: false,
-								Length:         4,
-								TypeCode:       4,
-								Value:          uint32(256),
-								Next: &PathAttribute{
-									Optional:       false,
-									Transitive:     false,
-									Partial:        false,
-									ExtendedLength: false,
-									Length:         4,
-									TypeCode:       5,
-									Value:          uint32(256),
-									Next: &PathAttribute{
-										Optional:       false,
-										Transitive:     false,
-										Partial:        false,
-										ExtendedLength: false,
-										Length:         0,
-										TypeCode:       6,
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			// 2 withdraws with 7 path attributes (ORIGIN, ASPath, NH, MED, Local Pref, Atomic Aggregate), valid update
-			testNum: 10,
-			input: []byte{0, 5, 8, 10, 16, 192, 168,
-				0, 53, // Total Path Attribute Length
-
-				255,  // Attribute flags
-				1,    // Attribute Type code (ORIGIN)
-				0, 1, // Length
-				2, // INCOMPLETE
-
-				0,      // Attribute flags
-				2,      // Attribute Type code (AS Path)
-				12,     // Length
-				2,      // Type = AS_SEQUENCE
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-				1,      // Type = AS_SET
-				2,      // Path Segement Length
-				59, 65, // AS15169
-				12, 248, // AS3320
-
-				0,              // Attribute flags
-				3,              // Attribute Type code (Next Hop)
-				4,              // Length
-				10, 11, 12, 13, // Next Hop
-
-				0,          // Attribute flags
-				4,          // Attribute Type code (MED)
-				4,          // Length
-				0, 0, 1, 0, // MED 256
-
-				0,          // Attribute flags
-				5,          // Attribute Type code (Local Pref)
-				4,          // Length
-				0, 0, 1, 0, // Local Pref 256
-
-				0, // Attribute flags
-				6, // Attribute Type code (Atomic Aggregate)
-				0, // Length
-
-				0,    // Attribute flags
-				7,    // Attribute Type code (Atomic Aggregate)
-				6,    // Length
-				1, 2, // ASN
-				10, 11, 12, 13, // Address
-
-				8, 11, // 11.0.0.0/8
-			},
-			wantFail: false,
-			expected: &BGPUpdate{
-				WithdrawnRoutesLen: 5,
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				TotalPathAttrLen: 53,
-				PathAttributes: &PathAttribute{
-					Optional:       true,
-					Transitive:     true,
-					Partial:        true,
-					ExtendedLength: true,
-					Length:         1,
-					TypeCode:       1,
-					Value:          uint8(2),
-					Next: &PathAttribute{
-						Optional:       false,
-						Transitive:     false,
-						Partial:        false,
-						ExtendedLength: false,
-						Length:         12,
-						TypeCode:       2,
-						Value: ASPath{
-							{
-								Type:  2,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-							{
-								Type:  1,
-								Count: 2,
-								ASNs: []uint32{
-									15169,
-									3320,
-								},
-							},
-						},
-						Next: &PathAttribute{
-							Optional:       false,
-							Transitive:     false,
-							Partial:        false,
-							ExtendedLength: false,
-							Length:         4,
-							TypeCode:       3,
-							Value:          [4]byte{10, 11, 12, 13},
-							Next: &PathAttribute{
-								Optional:       false,
-								Transitive:     false,
-								Partial:        false,
-								ExtendedLength: false,
-								Length:         4,
-								TypeCode:       4,
-								Value:          uint32(256),
-								Next: &PathAttribute{
-									Optional:       false,
-									Transitive:     false,
-									Partial:        false,
-									ExtendedLength: false,
-									Length:         4,
-									TypeCode:       5,
-									Value:          uint32(256),
-									Next: &PathAttribute{
-										Optional:       false,
-										Transitive:     false,
-										Partial:        false,
-										ExtendedLength: false,
-										Length:         0,
-										TypeCode:       6,
-										Next: &PathAttribute{
-											Optional:       false,
-											Transitive:     false,
-											Partial:        false,
-											ExtendedLength: false,
-											Length:         6,
-											TypeCode:       7,
-											Value: Aggretator{
-												ASN:  uint16(258),
-												Addr: [4]byte{10, 11, 12, 13},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-				NLRI: &NLRI{
-					Pfxlen: 8,
-					IP:     [4]byte{11, 0, 0, 0},
-				},
-			},
-		},
-		{
-			testNum: 11, // Incomplete Withdraw
-			input: []byte{
-				0, 5, // Length
-			},
-			wantFail: true,
-		},
-		{
-			testNum:  12, // Empty buffer
-			input:    []byte{},
-			wantFail: true,
-		},
-		{
-			testNum: 13,
-			input: []byte{
-				0, 0, // No Withdraws
-				0, 5, // Total Path Attributes Length
-			},
-			wantFail: true,
-		},
-		{
-			testNum: 14,
-			input: []byte{
-				0, 0, // No Withdraws
-				0, 0, // Total Path Attributes Length
-				24, // Incomplete NLRI
-			},
-			wantFail: true,
-		},
-		{
-			testNum: 15, // Cut at Total Path Attributes Length
-			input: []byte{
-				0, 0, // No Withdraws
-			},
-			explicitLength: 5,
-			wantFail:       true,
-		},
-	}
-
-	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)
-
-		if err != nil && !test.wantFail {
-			t.Errorf("Unexpected error in test %d: %v", test.testNum, err)
-			continue
-		}
-
-		if err == nil && test.wantFail {
-			t.Errorf("Expected error did not happen in test %d", test.testNum)
-			continue
-		}
-
-		if err != nil && test.wantFail {
-			continue
-		}
-
-		assert.Equal(t, test.expected, msg)
-	}
-}
-
-func TestDecodeMsgBody(t *testing.T) {
-	tests := []struct {
-		name     string
-		buffer   *bytes.Buffer
-		msgType  uint8
-		length   uint16
-		wantFail bool
-		expected interface{}
-	}{
-		{
-			name:     "Unknown msgType",
-			msgType:  5,
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		res, err := decodeMsgBody(test.buffer, test.msgType, test.length)
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error dit not happen in test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected error in test %q: %v", test.name, err)
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestDecodeOpenMsg(t *testing.T) {
-	tests := []test{
-		{
-			// Valid message
-			testNum:  1,
-			input:    []byte{4, 1, 1, 0, 15, 10, 20, 30, 40, 0},
-			wantFail: false,
-			expected: &BGPOpen{
-				Version:       4,
-				AS:            257,
-				HoldTime:      15,
-				BGPIdentifier: 169090600,
-				OptParmLen:    0,
-			},
-		},
-		{
-			// Invalid Version
-			testNum:  2,
-			input:    []byte{3, 1, 1, 0, 15, 10, 10, 10, 11, 0},
-			wantFail: true,
-		},
-	}
-
-	genericTest(_decodeOpenMsg, tests, t)
-}
-
-func TestDecodeHeader(t *testing.T) {
-	tests := []test{
-		{
-			// Valid header
-			testNum:  1,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 19, KeepaliveMsg},
-			wantFail: false,
-			expected: &BGPHeader{
-				Length: 19,
-				Type:   KeepaliveMsg,
-			},
-		},
-		{
-			// Invalid length too short
-			testNum:  2,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 18, KeepaliveMsg},
-			wantFail: true,
-			expected: &BGPHeader{
-				Length: 18,
-				Type:   KeepaliveMsg,
-			},
-		},
-		{
-			// Invalid length too long
-			testNum:  3,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 16, 1, KeepaliveMsg},
-			wantFail: true,
-			expected: &BGPHeader{
-				Length: 18,
-				Type:   KeepaliveMsg,
-			},
-		},
-		{
-			// Invalid message type 5
-			testNum:  4,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 19, 5},
-			wantFail: true,
-			expected: &BGPHeader{
-				Length: 19,
-				Type:   KeepaliveMsg,
-			},
-		},
-		{
-			// Invalid message type 0
-			testNum:  5,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 19, 0},
-			wantFail: true,
-			expected: &BGPHeader{
-				Length: 19,
-				Type:   KeepaliveMsg,
-			},
-		},
-		{
-			// Invalid marker
-			testNum:  6,
-			input:    []byte{1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 19, KeepaliveMsg},
-			wantFail: true,
-			expected: &BGPHeader{
-				Length: 19,
-				Type:   KeepaliveMsg,
-			},
-		},
-		{
-			// Incomplete Marker
-			testNum:  7,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255},
-			wantFail: true,
-		},
-		{
-			// Incomplete Header
-			testNum:  8,
-			input:    []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 19},
-			wantFail: true,
-		},
-		{
-			// Empty input
-			testNum:  9,
-			input:    []byte{},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(test.input)
-		res, err := decodeHeader(buf)
-
-		if err != nil {
-			if test.wantFail {
-				continue
-			}
-			t.Errorf("Unexpected failure for test %d: %v", test.testNum, err)
-			continue
-		}
-
-		if test.wantFail {
-			t.Errorf("Unexpected success fo test %d", test.testNum)
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func genericTest(f decodeFunc, tests []test, t *testing.T) {
-	for _, test := range tests {
-		buf := bytes.NewBuffer(test.input)
-		msg, err := f(buf)
-
-		if err != nil && !test.wantFail {
-			t.Errorf("Unexpected error in test %d: %v", test.testNum, err)
-			continue
-		}
-
-		if err == nil && test.wantFail {
-			t.Errorf("Expected error did not happen in test %d", test.testNum)
-			continue
-		}
-
-		if err != nil && test.wantFail {
-			continue
-		}
-
-		if msg == nil {
-			t.Errorf("Unexpected nil result in test %d. Expected: %v", test.testNum, test.expected)
-			continue
-		}
-
-		assert.Equal(t, test.expected, msg)
-	}
-}
-
-func TestIsValidIdentifier(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint32
-		expected bool
-	}{
-		{
-			name:     "Valid #1",
-			input:    convert.Uint32b([]byte{8, 8, 8, 8}),
-			expected: true,
-		},
-		{
-			name:     "Multicast",
-			input:    convert.Uint32b([]byte{239, 8, 8, 8}),
-			expected: false,
-		},
-		{
-			name:     "Loopback",
-			input:    convert.Uint32b([]byte{127, 8, 8, 8}),
-			expected: false,
-		},
-		{
-			name:     "First byte 0",
-			input:    convert.Uint32b([]byte{0, 8, 8, 8}),
-			expected: false,
-		},
-		{
-			name:     "All bytes 255",
-			input:    convert.Uint32b([]byte{255, 255, 255, 255}),
-			expected: false,
-		},
-	}
-
-	for _, test := range tests {
-		res := isValidIdentifier(test.input)
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestValidateOpenMessage(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    *BGPOpen
-		wantFail bool
-	}{
-		{
-			name: "Valid #1",
-			input: &BGPOpen{
-				Version:       4,
-				BGPIdentifier: convert.Uint32b([]byte{8, 8, 8, 8}),
-			},
-			wantFail: false,
-		},
-		{
-			name: "Invalid Identifier",
-			input: &BGPOpen{
-				Version:       4,
-				BGPIdentifier: convert.Uint32b([]byte{0, 8, 8, 8}),
-			},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		res := validateOpen(test.input)
-
-		if res != nil {
-			if test.wantFail {
-				continue
-			}
-			t.Errorf("Unexpected failure for test %q: %v", test.name, res)
-			continue
-		}
-
-		if test.wantFail {
-			t.Errorf("Unexpected success for test %q", test.name)
-		}
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/encoder.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/encoder.go
deleted file mode 100644
index 3cfe702d14ffb66605919fe60839d98a8308b761..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/encoder.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"fmt"
-
-	"github.com/taktv6/tflow2/convert"
-)
-
-func SerializeKeepaliveMsg() []byte {
-	keepaliveLen := uint16(19)
-	buf := bytes.NewBuffer(make([]byte, 0, keepaliveLen))
-	serializeHeader(buf, keepaliveLen, KeepaliveMsg)
-
-	return buf.Bytes()
-}
-
-func SerializeNotificationMsg(msg *BGPNotification) []byte {
-	notificationLen := uint16(21)
-	buf := bytes.NewBuffer(make([]byte, 0, notificationLen))
-	serializeHeader(buf, notificationLen, NotificationMsg)
-	buf.WriteByte(msg.ErrorCode)
-	buf.WriteByte(msg.ErrorSubcode)
-
-	return buf.Bytes()
-}
-
-func SerializeOpenMsg(msg *BGPOpen) []byte {
-	openLen := uint16(29)
-	buf := bytes.NewBuffer(make([]byte, 0, openLen))
-	serializeHeader(buf, openLen, OpenMsg)
-
-	buf.WriteByte(msg.Version)
-	buf.Write(convert.Uint16Byte(msg.AS))
-	buf.Write(convert.Uint16Byte(msg.HoldTime))
-	buf.Write(convert.Uint32Byte(msg.BGPIdentifier))
-	buf.WriteByte(uint8(0))
-
-	return buf.Bytes()
-}
-
-func serializeHeader(buf *bytes.Buffer, length uint16, typ uint8) {
-	buf.Write([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})
-	buf.Write(convert.Uint16Byte(length))
-	buf.WriteByte(typ)
-}
-
-func (b *BGPUpdate) SerializeUpdate() ([]byte, error) {
-	budget := MaxLen - MinLen
-	buf := bytes.NewBuffer(nil)
-
-	withdrawBuf := bytes.NewBuffer(nil)
-	for withdraw := b.WithdrawnRoutes; withdraw != nil; withdraw = withdraw.Next {
-		nlriLen := int(withdraw.serialize(withdrawBuf))
-		budget -= nlriLen
-		if budget < 0 {
-			return nil, fmt.Errorf("update too long")
-		}
-	}
-
-	pathAttributesBuf := bytes.NewBuffer(nil)
-	for pa := b.PathAttributes; pa != nil; pa = pa.Next {
-		paLen := int(pa.serialize(pathAttributesBuf))
-		budget -= paLen
-		if budget < 0 {
-			return nil, fmt.Errorf("update too long")
-		}
-	}
-
-	nlriBuf := bytes.NewBuffer(nil)
-	for nlri := b.NLRI; nlri != nil; nlri = nlri.Next {
-		nlriLen := int(nlri.serialize(nlriBuf))
-		budget -= nlriLen
-		if budget < 0 {
-			return nil, fmt.Errorf("update too long")
-		}
-	}
-
-	withdrawnRoutesLen := withdrawBuf.Len()
-	if withdrawnRoutesLen > 65535 {
-		return nil, fmt.Errorf("Invalid Withdrawn Routes Length: %d", withdrawnRoutesLen)
-	}
-
-	totalPathAttributesLen := pathAttributesBuf.Len()
-	if totalPathAttributesLen > 65535 {
-		return nil, fmt.Errorf("Invalid Total Path Attribute Length: %d", totalPathAttributesLen)
-	}
-
-	totalLength := 2 + withdrawnRoutesLen + totalPathAttributesLen + 2 + nlriBuf.Len() + 19
-	if totalLength > 4096 {
-		return nil, fmt.Errorf("Update too long: %d bytes", totalLength)
-	}
-
-	serializeHeader(buf, uint16(totalLength), UpdateMsg)
-
-	buf.Write(convert.Uint16Byte(uint16(withdrawnRoutesLen)))
-	buf.Write(withdrawBuf.Bytes())
-
-	buf.Write(convert.Uint16Byte(uint16(totalPathAttributesLen)))
-	buf.Write(pathAttributesBuf.Bytes())
-
-	buf.Write(nlriBuf.Bytes())
-
-	return buf.Bytes(), nil
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/encoder_test.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/encoder_test.go
deleted file mode 100644
index eccfdfdcace6be4eeac998bdbcaa29749d0a2581..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/encoder_test.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/taktv6/tflow2/convert"
-)
-
-func TestSerializeKeepaliveMsg(t *testing.T) {
-	expected := []byte{
-		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-		0x00, 0x13, 0x04,
-	}
-	res := SerializeKeepaliveMsg()
-
-	assert.Equal(t, expected, res)
-}
-
-func TestSerializeNotificationMsg(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    *BGPNotification
-		expected []byte
-	}{
-		{
-			name: "Valid #1",
-			input: &BGPNotification{
-				ErrorCode:    10,
-				ErrorSubcode: 5,
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0x00, 0x15, // Length
-				0x03, // Type
-				0x0a, // Error Code
-				0x05, // Error Subcode
-			},
-		},
-		{
-			name: "Valid #2",
-			input: &BGPNotification{
-				ErrorCode:    11,
-				ErrorSubcode: 6,
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0x00, 0x15, // Length
-				0x03, // Type
-				0x0b, // Error Code
-				0x06, // Error Subcode
-			},
-		},
-	}
-
-	for _, test := range tests {
-		res := SerializeNotificationMsg(test.input)
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestSerializeOpenMsg(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    *BGPOpen
-		expected []byte
-	}{
-		{
-			name: "Valid #1",
-			input: &BGPOpen{
-				Version:       4,
-				AS:            15169,
-				HoldTime:      120,
-				BGPIdentifier: convert.Uint32([]byte{100, 111, 120, 130}),
-				OptParmLen:    0,
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0x00, 0x1d, // Length
-				0x01,       // Type
-				0x04,       // Version
-				0x3b, 0x41, // ASN
-				0x00, 0x78, // Holdtime
-				130, 120, 111, 100, // BGP Identifier
-				0x00, // Opt. Param Length
-			},
-		},
-	}
-
-	for _, test := range tests {
-		res := SerializeOpenMsg(test.input)
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestSerializeHeader(t *testing.T) {
-	tests := []struct {
-		name     string
-		length   uint16
-		typ      uint8
-		expected []byte
-	}{
-		{
-			name:   "Valid #1",
-			length: 10,
-			typ:    5,
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0x00, 0x0a, 0x05,
-			},
-		},
-		{
-			name:   "Valid #12",
-			length: 256,
-			typ:    255,
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0x01, 0x00, 0xff,
-			},
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer([]byte{})
-		serializeHeader(buf, test.length, test.typ)
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/nlri.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/nlri.go
deleted file mode 100644
index b9ce4f2427c97c776d11cc257bb5ae2f3b5e6a1f..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/nlri.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"fmt"
-	"math"
-	"net"
-)
-
-func decodeNLRIs(buf *bytes.Buffer, length uint16) (*NLRI, error) {
-	var ret *NLRI
-	var eol *NLRI
-	var nlri *NLRI
-	var err error
-	var consumed uint8
-	p := uint16(0)
-
-	for p < length {
-		nlri, consumed, err = decodeNLRI(buf)
-		if err != nil {
-			return nil, fmt.Errorf("Unable to decode NLRI: %v", err)
-		}
-		p += uint16(consumed)
-
-		if ret == nil {
-			ret = nlri
-			eol = nlri
-			continue
-		}
-
-		eol.Next = nlri
-		eol = nlri
-	}
-
-	return ret, nil
-}
-
-func decodeNLRI(buf *bytes.Buffer) (*NLRI, uint8, error) {
-	var addr [4]byte
-	nlri := &NLRI{}
-
-	err := decode(buf, []interface{}{&nlri.Pfxlen})
-	if err != nil {
-		return nil, 0, err
-	}
-
-	toCopy := uint8(math.Ceil(float64(nlri.Pfxlen) / float64(OctetLen)))
-	for i := uint8(0); i < net.IPv4len%OctetLen; i++ {
-		if i < toCopy {
-			err := decode(buf, []interface{}{&addr[i]})
-			if err != nil {
-				return nil, 0, err
-			}
-		} else {
-			addr[i] = 0
-		}
-	}
-	nlri.IP = addr
-	return nlri, toCopy + 1, nil
-}
-
-func (n *NLRI) serialize(buf *bytes.Buffer) uint8 {
-	addr := n.IP.([4]byte)
-	nBytes := bytesInAddr(n.Pfxlen)
-
-	buf.WriteByte(n.Pfxlen)
-	buf.Write(addr[:nBytes])
-
-	return nBytes + 1
-}
-
-func bytesInAddr(pfxlen uint8) uint8 {
-	return uint8(math.Ceil(float64(pfxlen) / 8))
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/nlri_test.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/nlri_test.go
deleted file mode 100644
index c9299e2c2dff1e42953f527837276cb193f19577..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/nlri_test.go
+++ /dev/null
@@ -1,210 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestDecodeNLRIs(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []byte
-		wantFail bool
-		expected *NLRI
-	}{
-		{
-			name: "Valid NRLI #1",
-			input: []byte{
-				24, 192, 168, 0,
-				8, 10,
-				17, 172, 16, 0,
-			},
-			wantFail: false,
-			expected: &NLRI{
-				IP:     [4]byte{192, 168, 0, 0},
-				Pfxlen: 24,
-				Next: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{172, 16, 0, 0},
-						Pfxlen: 17,
-					},
-				},
-			},
-		},
-		{
-			name: "Invalid NRLI #1",
-			input: []byte{
-				24, 192, 168, 0,
-				8, 10,
-				17, 172, 16,
-			},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(test.input)
-		res, err := decodeNLRIs(buf, uint16(len(test.input)))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestDecodeNLRI(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []byte
-		wantFail bool
-		expected *NLRI
-	}{
-		{
-			name: "Valid NRLI #1",
-			input: []byte{
-				24, 192, 168, 0,
-			},
-			wantFail: false,
-			expected: &NLRI{
-				IP:     [4]byte{192, 168, 0, 0},
-				Pfxlen: 24,
-			},
-		},
-		{
-			name: "Valid NRLI #2",
-			input: []byte{
-				25, 192, 168, 0, 128,
-			},
-			wantFail: false,
-			expected: &NLRI{
-				IP:     [4]byte{192, 168, 0, 128},
-				Pfxlen: 25,
-			},
-		},
-		{
-			name: "Incomplete NLRI #1",
-			input: []byte{
-				25, 192, 168, 0,
-			},
-			wantFail: true,
-		},
-		{
-			name: "Incomplete NLRI #2",
-			input: []byte{
-				25,
-			},
-			wantFail: true,
-		},
-		{
-			name:     "Empty input",
-			input:    []byte{},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(test.input)
-		res, _, err := decodeNLRI(buf)
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestBytesInAddr(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint8
-		expected uint8
-	}{
-		{
-			name:     "Test #1",
-			input:    24,
-			expected: 3,
-		},
-		{
-			name:     "Test #2",
-			input:    25,
-			expected: 4,
-		},
-		{
-			name:     "Test #3",
-			input:    32,
-			expected: 4,
-		},
-		{
-			name:     "Test #4",
-			input:    0,
-			expected: 0,
-		},
-		{
-			name:     "Test #5",
-			input:    9,
-			expected: 2,
-		},
-	}
-
-	for _, test := range tests {
-		res := bytesInAddr(test.input)
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %q: %d", test.name, res)
-		}
-	}
-}
-
-func TestNLRISerialize(t *testing.T) {
-	tests := []struct {
-		name     string
-		nlri     *NLRI
-		expected []byte
-	}{
-		{
-			name: "Test #1",
-			nlri: &NLRI{
-				IP:     [4]byte{1, 2, 3, 0},
-				Pfxlen: 25,
-			},
-			expected: []byte{25, 1, 2, 3, 0},
-		},
-		{
-			name: "Test #2",
-			nlri: &NLRI{
-				IP:     [4]byte{1, 2, 3, 0},
-				Pfxlen: 24,
-			},
-			expected: []byte{24, 1, 2, 3},
-		},
-		{
-			name: "Test #3",
-			nlri: &NLRI{
-				IP:     [4]byte{100, 200, 128, 0},
-				Pfxlen: 17,
-			},
-			expected: []byte{17, 100, 200, 128},
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		test.nlri.serialize(buf)
-		res := buf.Bytes()
-		assert.Equal(t, test.expected, res)
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attribute_flags.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attribute_flags.go
deleted file mode 100644
index 8c4b09f916dff0aa619c61c33bec0b66e1398922..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attribute_flags.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package packet
-
-import "bytes"
-
-func decodePathAttrFlags(buf *bytes.Buffer, pa *PathAttribute) error {
-	flags := uint8(0)
-	err := decode(buf, []interface{}{&flags})
-	if err != nil {
-		return err
-	}
-
-	pa.Optional = isOptional(flags)
-	pa.Transitive = isTransitive(flags)
-	pa.Partial = isPartial(flags)
-	pa.ExtendedLength = isExtendedLength(flags)
-
-	return nil
-}
-
-func isOptional(x uint8) bool {
-	if x&128 == 128 {
-		return true
-	}
-	return false
-}
-
-func isTransitive(x uint8) bool {
-	if x&64 == 64 {
-		return true
-	}
-	return false
-}
-
-func isPartial(x uint8) bool {
-	if x&32 == 32 {
-		return true
-	}
-	return false
-}
-
-func isExtendedLength(x uint8) bool {
-	if x&16 == 16 {
-		return true
-	}
-	return false
-}
-
-func setOptional(x uint8) uint8 {
-	return x | 128
-}
-
-func setTransitive(x uint8) uint8 {
-	return x | 64
-}
-
-func setPartial(x uint8) uint8 {
-	return x | 32
-}
-
-func setExtendedLength(x uint8) uint8 {
-	return x | 16
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attributes.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attributes.go
deleted file mode 100644
index be40ccf8ed2efbd0503bedc9d392ed3cd4cf118d..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attributes.go
+++ /dev/null
@@ -1,400 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"fmt"
-
-	"github.com/taktv6/tflow2/convert"
-)
-
-func decodePathAttrs(buf *bytes.Buffer, tpal uint16) (*PathAttribute, error) {
-	var ret *PathAttribute
-	var eol *PathAttribute
-	var pa *PathAttribute
-	var err error
-	var consumed uint16
-
-	p := uint16(0)
-	for p < tpal {
-		pa, consumed, err = decodePathAttr(buf)
-		if err != nil {
-			return nil, fmt.Errorf("Unable to decode path attr: %v", err)
-		}
-		p += consumed
-
-		if ret == nil {
-			ret = pa
-			eol = pa
-		} else {
-			eol.Next = pa
-			eol = pa
-		}
-	}
-
-	return ret, nil
-}
-
-func decodePathAttr(buf *bytes.Buffer) (pa *PathAttribute, consumed uint16, err error) {
-	pa = &PathAttribute{}
-
-	err = decodePathAttrFlags(buf, pa)
-	if err != nil {
-		return nil, consumed, fmt.Errorf("Unable to get path attribute flags: %v", err)
-	}
-	consumed++
-
-	err = decode(buf, []interface{}{&pa.TypeCode})
-	if err != nil {
-		return nil, consumed, err
-	}
-	consumed++
-
-	n, err := pa.setLength(buf)
-	if err != nil {
-		return nil, consumed, err
-	}
-	consumed += uint16(n)
-
-	switch pa.TypeCode {
-	case OriginAttr:
-		if err := pa.decodeOrigin(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to decode Origin: %v", err)
-		}
-	case ASPathAttr:
-		if err := pa.decodeASPath(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to decode AS Path: %v", err)
-		}
-	case NextHopAttr:
-		if err := pa.decodeNextHop(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to decode Next-Hop: %v", err)
-		}
-	case MEDAttr:
-		if err := pa.decodeMED(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to decode MED: %v", err)
-		}
-	case LocalPrefAttr:
-		if err := pa.decodeLocalPref(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to decode local pref: %v", err)
-		}
-	case AggregatorAttr:
-		if err := pa.decodeAggregator(buf); err != nil {
-			return nil, consumed, fmt.Errorf("Failed to decode Aggregator: %v", err)
-		}
-	case AtomicAggrAttr:
-		// Nothing to do for 0 octet long attribute
-	default:
-		return nil, consumed, fmt.Errorf("Invalid Attribute Type Code: %v", pa.TypeCode)
-	}
-
-	return pa, consumed + pa.Length, nil
-}
-
-func (pa *PathAttribute) decodeOrigin(buf *bytes.Buffer) error {
-	origin := uint8(0)
-
-	p := uint16(0)
-	err := decode(buf, []interface{}{&origin})
-	if err != nil {
-		return fmt.Errorf("Unable to decode: %v", err)
-	}
-
-	pa.Value = origin
-	p++
-
-	return dumpNBytes(buf, pa.Length-p)
-}
-
-func (pa *PathAttribute) decodeASPath(buf *bytes.Buffer) error {
-	pa.Value = make(ASPath, 0)
-
-	p := uint16(0)
-	for p < pa.Length {
-		segment := ASPathSegment{
-			ASNs: make([]uint32, 0),
-		}
-
-		err := decode(buf, []interface{}{&segment.Type, &segment.Count})
-		if err != nil {
-			return err
-		}
-		p += 2
-
-		if segment.Type != ASSet && segment.Type != ASSequence {
-			return fmt.Errorf("Invalid AS Path segment type: %d", segment.Type)
-		}
-
-		if segment.Count == 0 {
-			return fmt.Errorf("Invalid AS Path segment length: %d", segment.Count)
-		}
-
-		for i := uint8(0); i < segment.Count; i++ {
-			asn := uint16(0)
-
-			err := decode(buf, []interface{}{&asn})
-			if err != nil {
-				return err
-			}
-			p += 2
-
-			segment.ASNs = append(segment.ASNs, uint32(asn))
-		}
-		pa.Value = append(pa.Value.(ASPath), segment)
-	}
-
-	return nil
-}
-
-func (pa *PathAttribute) decodeNextHop(buf *bytes.Buffer) error {
-	addr := [4]byte{}
-
-	p := uint16(0)
-	n, err := buf.Read(addr[:])
-	if err != nil {
-		return err
-	}
-	if n != 4 {
-		return fmt.Errorf("Unable to read next hop: buf.Read read %d bytes", n)
-	}
-
-	pa.Value = addr
-	p += 4
-
-	return dumpNBytes(buf, pa.Length-p)
-}
-
-func (pa *PathAttribute) decodeMED(buf *bytes.Buffer) error {
-	med, err := pa.decodeUint32(buf)
-	if err != nil {
-		return fmt.Errorf("Unable to recode local pref: %v", err)
-	}
-
-	pa.Value = uint32(med)
-	return nil
-}
-
-func (pa *PathAttribute) decodeLocalPref(buf *bytes.Buffer) error {
-	lpref, err := pa.decodeUint32(buf)
-	if err != nil {
-		return fmt.Errorf("Unable to recode local pref: %v", err)
-	}
-
-	pa.Value = uint32(lpref)
-	return nil
-}
-
-func (pa *PathAttribute) decodeAggregator(buf *bytes.Buffer) error {
-	aggr := Aggretator{}
-
-	p := uint16(0)
-	err := decode(buf, []interface{}{&aggr.ASN})
-	if err != nil {
-		return err
-	}
-	p += 2
-
-	n, err := buf.Read(aggr.Addr[:])
-	if err != nil {
-		return err
-	}
-	if n != 4 {
-		return fmt.Errorf("Unable to read aggregator IP: buf.Read read %d bytes", n)
-	}
-	p += 4
-
-	pa.Value = aggr
-	return dumpNBytes(buf, pa.Length-p)
-}
-
-func (pa *PathAttribute) setLength(buf *bytes.Buffer) (int, error) {
-	bytesRead := 0
-	if pa.ExtendedLength {
-		err := decode(buf, []interface{}{&pa.Length})
-		if err != nil {
-			return 0, err
-		}
-		bytesRead = 2
-	} else {
-		x := uint8(0)
-		err := decode(buf, []interface{}{&x})
-		if err != nil {
-			return 0, err
-		}
-		pa.Length = uint16(x)
-		bytesRead = 1
-	}
-	return bytesRead, nil
-}
-
-func (pa *PathAttribute) decodeUint32(buf *bytes.Buffer) (uint32, error) {
-	var v uint32
-
-	p := uint16(0)
-	err := decode(buf, []interface{}{&v})
-	if err != nil {
-		return 0, err
-	}
-
-	p += 4
-	err = dumpNBytes(buf, pa.Length-p)
-	if err != nil {
-		return 0, fmt.Errorf("dumpNBytes failed: %v", err)
-	}
-
-	return v, nil
-}
-
-func (pa *PathAttribute) ASPathString() (ret string) {
-	for _, p := range *pa.Value.(*ASPath) {
-		if p.Type == ASSet {
-			ret += " ("
-		}
-		n := len(p.ASNs)
-		for i, asn := range p.ASNs {
-			if i < n-1 {
-				ret += fmt.Sprintf("%d ", asn)
-				continue
-			}
-			ret += fmt.Sprintf("%d", asn)
-		}
-		if p.Type == ASSet {
-			ret += ")"
-		}
-	}
-
-	return
-}
-
-func (pa *PathAttribute) ASPathLen() (ret uint16) {
-	for _, p := range *pa.Value.(*ASPath) {
-		if p.Type == ASSet {
-			ret++
-			continue
-		}
-		ret += uint16(len(p.ASNs))
-	}
-
-	return
-}
-
-// dumpNBytes is used to dump n bytes of buf. This is useful in case an path attributes
-// length doesn't match a fixed length's attributes length (e.g. ORIGIN is always an octet)
-func dumpNBytes(buf *bytes.Buffer, n uint16) error {
-	if n <= 0 {
-		return nil
-	}
-	dump := make([]byte, n)
-	err := decode(buf, []interface{}{&dump})
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (pa *PathAttribute) serialize(buf *bytes.Buffer) uint8 {
-	pathAttrLen := uint8(0)
-
-	switch pa.TypeCode {
-	case OriginAttr:
-		pathAttrLen = pa.serializeOrigin(buf)
-	case ASPathAttr:
-		pathAttrLen = pa.serializeASPath(buf)
-	case NextHopAttr:
-		pathAttrLen = pa.serializeNextHop(buf)
-	case MEDAttr:
-		pathAttrLen = pa.serializeMED(buf)
-	case LocalPrefAttr:
-		pathAttrLen = pa.serializeLocalpref(buf)
-	case AtomicAggrAttr:
-		pathAttrLen = pa.serializeAtomicAggregate(buf)
-	case AggregatorAttr:
-		pathAttrLen = pa.serializeAggregator(buf)
-	}
-
-	return pathAttrLen
-}
-
-func (pa *PathAttribute) serializeOrigin(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setTransitive(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(OriginAttr)
-	length := uint8(1)
-	buf.WriteByte(length)
-	buf.WriteByte(pa.Value.(uint8))
-	return 4
-}
-
-func (pa *PathAttribute) serializeASPath(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setTransitive(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(ASPathAttr)
-	length := uint8(2)
-	asPath := pa.Value.(ASPath)
-	for _, segment := range asPath {
-		buf.WriteByte(segment.Type)
-		buf.WriteByte(uint8(len(segment.ASNs)))
-		for _, asn := range segment.ASNs {
-			buf.Write(convert.Uint16Byte(uint16(asn)))
-		}
-		length += 2 + uint8(len(segment.ASNs))*2
-	}
-
-	return length
-}
-
-func (pa *PathAttribute) serializeNextHop(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setTransitive(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(NextHopAttr)
-	length := uint8(4)
-	buf.WriteByte(length)
-	addr := pa.Value.([4]byte)
-	buf.Write(addr[:])
-	return 7
-}
-
-func (pa *PathAttribute) serializeMED(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setOptional(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(MEDAttr)
-	length := uint8(4)
-	buf.WriteByte(length)
-	buf.Write(convert.Uint32Byte(pa.Value.(uint32)))
-	return 7
-}
-
-func (pa *PathAttribute) serializeLocalpref(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setTransitive(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(LocalPrefAttr)
-	length := uint8(4)
-	buf.WriteByte(length)
-	buf.Write(convert.Uint32Byte(pa.Value.(uint32)))
-	return 7
-}
-
-func (pa *PathAttribute) serializeAtomicAggregate(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setTransitive(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(AtomicAggrAttr)
-	length := uint8(0)
-	buf.WriteByte(length)
-	return 3
-}
-
-func (pa *PathAttribute) serializeAggregator(buf *bytes.Buffer) uint8 {
-	attrFlags := uint8(0)
-	attrFlags = setOptional(attrFlags)
-	attrFlags = setTransitive(attrFlags)
-	buf.WriteByte(attrFlags)
-	buf.WriteByte(AggregatorAttr)
-	length := uint8(2)
-	buf.WriteByte(length)
-	buf.Write(convert.Uint16Byte(pa.Value.(uint16)))
-	return 5
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attributes_test.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attributes_test.go
deleted file mode 100644
index 052c40796d1b720fbba8c394dc3158a38725b369..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/packet/path_attributes_test.go
+++ /dev/null
@@ -1,1292 +0,0 @@
-package packet
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestDecodePathAttrs(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []byte
-		wantFail bool
-		expected *PathAttribute
-	}{
-		{
-			name: "Valid attribute set",
-			input: []byte{
-				0,              // Attr. Flags
-				1,              // Attr. Type Code
-				1,              // Attr. Length
-				1,              // EGP
-				0,              // Attr. Flags
-				3,              // Next Hop
-				4,              // Attr. Length
-				10, 20, 30, 40, // IP-Address
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				TypeCode: 1,
-				Length:   1,
-				Value:    uint8(1),
-				Next: &PathAttribute{
-					TypeCode: 3,
-					Length:   4,
-					Value:    [4]byte{10, 20, 30, 40},
-				},
-			},
-		},
-		{
-			name: "Incomplete data",
-			input: []byte{
-				0, // Attr. Flags
-				1, // Attr. Type Code
-				1, // Attr. Length
-			},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		res, err := decodePathAttrs(bytes.NewBuffer(test.input), uint16(len(test.input)))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestDecodePathAttr(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []byte
-		wantFail bool
-		expected *PathAttribute
-	}{
-		{
-			name: "Valid origin",
-			input: []byte{
-				0, // Attr. Flags
-				1, // Attr. Type Code
-				1, // Attr. Length
-				1, // EGP
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length:         1,
-				Optional:       false,
-				Transitive:     false,
-				Partial:        false,
-				ExtendedLength: false,
-				TypeCode:       OriginAttr,
-				Value:          uint8(1),
-			},
-		},
-		{
-			name: "Missing TypeCode",
-			input: []byte{
-				0, // Attr. Flags
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing Length",
-			input: []byte{
-				0, // Attr. Flags
-				1, // Attr. Type Code
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing Value ORIGIN",
-			input: []byte{
-				0, // Attr. Flags
-				1, // Attr. Type Code
-				1, // Attr. Length
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing value AS_PATH",
-			input: []byte{
-				0, // Attr. Flags
-				2, // Attr. Type Code
-				8, // Attr. Length
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing value NextHop",
-			input: []byte{
-				0, // Attr. Flags
-				3, // Attr. Type Code
-				4, // Attr. Length
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing value MED",
-			input: []byte{
-				0, // Attr. Flags
-				4, // Attr. Type Code
-				4, // Attr. Length
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing value LocalPref",
-			input: []byte{
-				0, // Attr. Flags
-				5, // Attr. Type Code
-				4, // Attr. Length
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing value AGGREGATOR",
-			input: []byte{
-				0, // Attr. Flags
-				7, // Attr. Type Code
-				4, // Attr. Length
-			},
-			wantFail: true,
-		},
-		{
-			name: "Not supported attribute",
-			input: []byte{
-				0,   // Attr. Flags
-				111, // Attr. Type Code
-				4,   // Attr. Length
-			},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		res, _, err := decodePathAttr(bytes.NewBuffer(test.input))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestDecodeOrigin(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []byte
-		wantFail bool
-		expected *PathAttribute
-	}{
-		{
-			name: "Test #1",
-			input: []byte{
-				0, // Origin: IGP
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Value:  uint8(IGP),
-				Length: 1,
-			},
-		},
-		{
-			name: "Test #2",
-			input: []byte{
-				1, // Origin: EGP
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Value:  uint8(EGP),
-				Length: 1,
-			},
-		},
-		{
-			name: "Test #3",
-			input: []byte{
-				2, // Origin: INCOMPLETE
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Value:  uint8(INCOMPLETE),
-				Length: 1,
-			},
-		},
-		{
-			name:     "Test #4",
-			input:    []byte{},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		pa := &PathAttribute{
-			Length: uint16(len(test.input)),
-		}
-		err := pa.decodeOrigin(bytes.NewBuffer(test.input))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
-
-		if err != nil {
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-	}
-}
-
-func TestDecodeASPath(t *testing.T) {
-	tests := []struct {
-		name           string
-		input          []byte
-		wantFail       bool
-		explicitLength uint16
-		expected       *PathAttribute
-	}{
-		{
-			name: "Test #1",
-			input: []byte{
-				2, // AS_SEQUENCE
-				4, // Path Length
-				0, 100, 0, 200, 0, 222, 0, 240,
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length: 10,
-				Value: ASPath{
-					ASPathSegment{
-						Type:  2,
-						Count: 4,
-						ASNs: []uint32{
-							100, 200, 222, 240,
-						},
-					},
-				},
-			},
-		},
-		{
-			name: "Test #2",
-			input: []byte{
-				1, // AS_SEQUENCE
-				3, // Path Length
-				0, 100, 0, 222, 0, 240,
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length: 8,
-				Value: ASPath{
-					ASPathSegment{
-						Type:  1,
-						Count: 3,
-						ASNs: []uint32{
-							100, 222, 240,
-						},
-					},
-				},
-			},
-		},
-		{
-			name:           "Empty input",
-			input:          []byte{},
-			explicitLength: 5,
-			wantFail:       true,
-		},
-		{
-			name: "Incomplete AS_PATH",
-			input: []byte{
-				1, // AS_SEQUENCE
-				3, // Path Length
-				0, 100, 0, 222,
-			},
-			wantFail: true,
-		},
-	}
-
-	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))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
-
-		if err != nil {
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-	}
-}
-
-func TestDecodeNextHop(t *testing.T) {
-	tests := []struct {
-		name           string
-		input          []byte
-		wantFail       bool
-		explicitLength uint16
-		expected       *PathAttribute
-	}{
-		{
-			name: "Test #1",
-			input: []byte{
-				10, 20, 30, 40,
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length: 4,
-				Value: [4]byte{
-					10, 20, 30, 40,
-				},
-			},
-		},
-		{
-			name:           "Test #2",
-			input:          []byte{},
-			explicitLength: 5,
-			wantFail:       true,
-		},
-		{
-			name:           "Incomplete IP-Address",
-			input:          []byte{10, 20, 30},
-			explicitLength: 5,
-			wantFail:       true,
-		},
-	}
-
-	for _, test := range tests {
-		l := uint16(len(test.input))
-		if test.explicitLength != 0 {
-			l = test.explicitLength
-		}
-		pa := &PathAttribute{
-			Length: l,
-		}
-		err := pa.decodeNextHop(bytes.NewBuffer(test.input))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
-
-		if err != nil {
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-	}
-}
-
-func TestDecodeMED(t *testing.T) {
-	tests := []struct {
-		name           string
-		input          []byte
-		wantFail       bool
-		explicitLength uint16
-		expected       *PathAttribute
-	}{
-		{
-			name: "Test #1",
-			input: []byte{
-				0, 0, 3, 232,
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length: 4,
-				Value:  uint32(1000),
-			},
-		},
-		{
-			name:           "Test #2",
-			input:          []byte{},
-			explicitLength: 5,
-			wantFail:       true,
-		},
-	}
-
-	for _, test := range tests {
-		l := uint16(len(test.input))
-		if test.explicitLength != 0 {
-			l = test.explicitLength
-		}
-		pa := &PathAttribute{
-			Length: l,
-		}
-		err := pa.decodeMED(bytes.NewBuffer(test.input))
-
-		if test.wantFail && err == nil {
-			t.Errorf("Expected error did not happen for test %q", test.name)
-		}
-
-		if !test.wantFail && err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-		}
-
-		if err != nil {
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-	}
-}
-
-func TestDecodeLocalPref(t *testing.T) {
-	tests := []struct {
-		name           string
-		input          []byte
-		wantFail       bool
-		explicitLength uint16
-		expected       *PathAttribute
-	}{
-		{
-			name: "Test #1",
-			input: []byte{
-				0, 0, 3, 232,
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length: 4,
-				Value:  uint32(1000),
-			},
-		},
-		{
-			name:           "Test #2",
-			input:          []byte{},
-			explicitLength: 5,
-			wantFail:       true,
-		},
-	}
-
-	for _, test := range tests {
-		l := uint16(len(test.input))
-		if test.explicitLength != 0 {
-			l = test.explicitLength
-		}
-		pa := &PathAttribute{
-			Length: l,
-		}
-		err := pa.decodeLocalPref(bytes.NewBuffer(test.input))
-
-		if test.wantFail {
-			if err != nil {
-				continue
-			}
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-	}
-}
-
-func TestDecodeAggregator(t *testing.T) {
-	tests := []struct {
-		name           string
-		input          []byte
-		wantFail       bool
-		explicitLength uint16
-		expected       *PathAttribute
-	}{
-		{
-			name: "Valid aggregator",
-			input: []byte{
-				0, 222, // ASN
-				10, 20, 30, 40, // Aggregator IP
-			},
-			wantFail: false,
-			expected: &PathAttribute{
-				Length: 6,
-				Value: Aggretator{
-					ASN:  222,
-					Addr: [4]byte{10, 20, 30, 40},
-				},
-			},
-		},
-		{
-			name: "Incomplete Address",
-			input: []byte{
-				0, 222, // ASN
-				10, 20, // Aggregator IP
-			},
-			wantFail: true,
-		},
-		{
-			name: "Missing Address",
-			input: []byte{
-				0, 222, // ASN
-			},
-			wantFail: true,
-		},
-		{
-			name:     "Empty input",
-			input:    []byte{},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		l := uint16(len(test.input))
-		if test.explicitLength != 0 {
-			l = test.explicitLength
-		}
-		pa := &PathAttribute{
-			Length: l,
-		}
-		err := pa.decodeAggregator(bytes.NewBuffer(test.input))
-
-		if test.wantFail {
-			if err != nil {
-				continue
-			}
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-	}
-}
-
-func TestSetLength(t *testing.T) {
-	tests := []struct {
-		name             string
-		input            []byte
-		ExtendedLength   bool
-		wantFail         bool
-		expected         *PathAttribute
-		expectedConsumed int
-	}{
-		{
-			name:           "Valid input",
-			ExtendedLength: false,
-			input:          []byte{22},
-			expected: &PathAttribute{
-				ExtendedLength: false,
-				Length:         22,
-			},
-			expectedConsumed: 1,
-		},
-		{
-			name:           "Valid input (extended)",
-			ExtendedLength: true,
-			input:          []byte{1, 1},
-			expected: &PathAttribute{
-				ExtendedLength: true,
-				Length:         257,
-			},
-			expectedConsumed: 2,
-		},
-		{
-			name:           "Invalid input",
-			ExtendedLength: true,
-			input:          []byte{},
-			wantFail:       true,
-		},
-		{
-			name:           "Invalid input (extended)",
-			ExtendedLength: true,
-			input:          []byte{1},
-			wantFail:       true,
-		},
-	}
-
-	for _, test := range tests {
-		pa := &PathAttribute{
-			ExtendedLength: test.ExtendedLength,
-		}
-		consumed, err := pa.setLength(bytes.NewBuffer(test.input))
-
-		if test.wantFail {
-			if err != nil {
-				continue
-			}
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, pa)
-		assert.Equal(t, test.expectedConsumed, consumed)
-	}
-}
-
-func TestDecodeUint32(t *testing.T) {
-	tests := []struct {
-		name           string
-		input          []byte
-		wantFail       bool
-		explicitLength uint16
-		expected       uint32
-	}{
-		{
-			name:     "Valid input",
-			input:    []byte{0, 0, 1, 1},
-			expected: 257,
-		},
-		{
-			name:     "Valid input with additional crap",
-			input:    []byte{0, 0, 1, 1, 200},
-			expected: 257,
-		},
-		{
-			name:           "Valid input with additional crap and invalid length",
-			input:          []byte{0, 0, 1, 1, 200},
-			explicitLength: 8,
-			wantFail:       true,
-		},
-		{
-			name:     "Invalid input",
-			input:    []byte{0, 0, 1},
-			wantFail: true,
-		},
-	}
-
-	for _, test := range tests {
-		l := uint16(len(test.input))
-		if test.explicitLength > 0 {
-			l = test.explicitLength
-		}
-		pa := &PathAttribute{
-			Length: l,
-		}
-		res, err := pa.decodeUint32(bytes.NewBuffer(test.input))
-
-		if test.wantFail {
-			if err != nil {
-				continue
-			}
-			t.Errorf("Expected error did not happen for test %q", test.name)
-			continue
-		}
-
-		if err != nil {
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestASPathString(t *testing.T) {
-	tests := []struct {
-		name     string
-		pa       *PathAttribute
-		expected string
-	}{
-		{
-			name: "Test #1",
-			pa: &PathAttribute{
-				Value: &ASPath{
-					{
-						Type: ASSequence,
-						ASNs: []uint32{10, 20, 30},
-					},
-				},
-			},
-			expected: "10 20 30",
-		},
-		{
-			name: "Test #2",
-			pa: &PathAttribute{
-				Value: &ASPath{
-					{
-						Type: ASSequence,
-						ASNs: []uint32{10, 20, 30},
-					},
-					{
-						Type: ASSet,
-						ASNs: []uint32{200, 300},
-					},
-				},
-			},
-			expected: "10 20 30 (200 300)",
-		},
-	}
-
-	for _, test := range tests {
-		res := test.pa.ASPathString()
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestSetOptional(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint8
-		expected uint8
-	}{
-		{
-			name:     "Test #1",
-			input:    0,
-			expected: 128,
-		},
-	}
-
-	for _, test := range tests {
-		res := setOptional(test.input)
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %q: %d", test.name, res)
-		}
-	}
-}
-
-func TestSetTransitive(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint8
-		expected uint8
-	}{
-		{
-			name:     "Test #1",
-			input:    0,
-			expected: 64,
-		},
-	}
-
-	for _, test := range tests {
-		res := setTransitive(test.input)
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %q: %d", test.name, res)
-		}
-	}
-}
-
-func TestSetPartial(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint8
-		expected uint8
-	}{
-		{
-			name:     "Test #1",
-			input:    0,
-			expected: 32,
-		},
-	}
-
-	for _, test := range tests {
-		res := setPartial(test.input)
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %q: %d", test.name, res)
-		}
-	}
-}
-
-func TestSetExtendedLength(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint8
-		expected uint8
-	}{
-		{
-			name:     "Test #1",
-			input:    0,
-			expected: 16,
-		},
-	}
-
-	for _, test := range tests {
-		res := setExtendedLength(test.input)
-		if res != test.expected {
-			t.Errorf("Unexpected result for test %q: %d", test.name, res)
-		}
-	}
-}
-
-func TestSerializeOrigin(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: OriginAttr,
-				Value:    uint8(0), // IGP
-			},
-			expectedLen: 4,
-			expected:    []byte{64, 1, 1, 0},
-		},
-		{
-			name: "Test #2",
-			input: &PathAttribute{
-				TypeCode: OriginAttr,
-				Value:    uint8(2), // INCOMPLETE
-			},
-			expectedLen: 4,
-			expected:    []byte{64, 1, 1, 2},
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeOrigin(buf)
-		if test.expectedLen != n {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerializeNextHop(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: NextHopAttr,
-				Value:    [4]byte{100, 110, 120, 130},
-			},
-			expected:    []byte{0, 3, 4, 100, 110, 120, 130},
-			expectedLen: 7,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeNextHop(buf)
-		if n != test.expectedLen {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerializeMED(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: MEDAttr,
-				Value:    uint32(1000),
-			},
-			expected: []byte{
-				128,          // Attribute flags
-				4,            // Type
-				4,            // Length
-				0, 0, 3, 232, // Value = 1000
-			},
-			expectedLen: 7,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeMED(buf)
-		if n != test.expectedLen {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerializeLocalPref(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: LocalPrefAttr,
-				Value:    uint32(1000),
-			},
-			expected: []byte{
-				64,           // Attribute flags
-				5,            // Type
-				4,            // Length
-				0, 0, 3, 232, // Value = 1000
-			},
-			expectedLen: 7,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeLocalpref(buf)
-		if n != test.expectedLen {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerializeAtomicAggregate(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: AtomicAggrAttr,
-			},
-			expected: []byte{
-				64, // Attribute flags
-				6,  // Type
-				0,  // Length
-			},
-			expectedLen: 3,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeAtomicAggregate(buf)
-		if n != test.expectedLen {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerializeAggregator(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: AggregatorAttr,
-				Value:    uint16(174),
-			},
-			expected: []byte{
-				192,    // Attribute flags
-				7,      // Type
-				2,      // Length
-				0, 174, // Value = 174
-			},
-			expectedLen: 5,
-		},
-	}
-
-	for _, test := range tests {
-		buf := bytes.NewBuffer(nil)
-		n := test.input.serializeAggregator(buf)
-		if n != test.expectedLen {
-			t.Errorf("Unexpected length for test %q: %d", test.name, n)
-			continue
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerializeASPath(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       *PathAttribute
-		expected    []byte
-		expectedLen uint8
-	}{
-		{
-			name: "Test #1",
-			input: &PathAttribute{
-				TypeCode: ASPathAttr,
-				Value: ASPath{
-					{
-						Type: 2, // Sequence
-						ASNs: []uint32{
-							100, 200, 210,
-						},
-					},
-				},
-			},
-			expected: []byte{
-				64,     // Attribute flags
-				2,      // Type
-				2,      // AS_SEQUENCE
-				3,      // ASN count
-				0, 100, // ASN 100
-				0, 200, // ASN 200
-				0, 210, // ASN 210
-			},
-			expectedLen: 10,
-		},
-	}
-
-	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
-		}
-
-		assert.Equal(t, test.expected, buf.Bytes())
-	}
-}
-
-func TestSerialize(t *testing.T) {
-	tests := []struct {
-		name     string
-		msg      *BGPUpdate
-		expected []byte
-		wantFail bool
-	}{
-		{
-			name: "Withdraw only",
-			msg: &BGPUpdate{
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{100, 110, 120, 0},
-					Pfxlen: 24,
-				},
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0, 27, // Length
-				2,    // Msg Type
-				0, 4, // Withdrawn Routes Length
-				24, 100, 110, 120, // NLRI
-				0, 0, // Total Path Attribute Length
-			},
-		},
-		{
-			name: "NLRI only",
-			msg: &BGPUpdate{
-				NLRI: &NLRI{
-					IP:     [4]byte{100, 110, 128, 0},
-					Pfxlen: 17,
-				},
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0, 27, // Length
-				2,    // Msg Type
-				0, 0, // Withdrawn Routes Length
-				0, 0, // Total Path Attribute Length
-				17, 100, 110, 128, // NLRI
-			},
-		},
-		{
-			name: "Path Attributes only",
-			msg: &BGPUpdate{
-				PathAttributes: &PathAttribute{
-					Optional:   true,
-					Transitive: true,
-					TypeCode:   OriginAttr,
-					Value:      uint8(0), // IGP
-				},
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0, 27, // Length
-				2,    // Msg Type
-				0, 0, // Withdrawn Routes Length
-				0, 4, // Total Path Attribute Length
-				64, // Attr. Flags
-				1,  // Attr. Type Code
-				1,  // Length
-				0,  // Value
-			},
-		},
-		{
-			name: "Full test",
-			msg: &BGPUpdate{
-				WithdrawnRoutes: &NLRI{
-					IP:     [4]byte{10, 0, 0, 0},
-					Pfxlen: 8,
-					Next: &NLRI{
-						IP:     [4]byte{192, 168, 0, 0},
-						Pfxlen: 16,
-					},
-				},
-				PathAttributes: &PathAttribute{
-					TypeCode: OriginAttr,
-					Value:    uint8(0),
-					Next: &PathAttribute{
-						TypeCode: ASPathAttr,
-						Value: ASPath{
-							{
-								Type: 2,
-								ASNs: []uint32{100, 155, 200},
-							},
-							{
-								Type: 1,
-								ASNs: []uint32{10, 20},
-							},
-						},
-						Next: &PathAttribute{
-							TypeCode: NextHopAttr,
-							Value:    [4]byte{10, 20, 30, 40},
-							Next: &PathAttribute{
-								TypeCode: MEDAttr,
-								Value:    uint32(100),
-								Next: &PathAttribute{
-									TypeCode: LocalPrefAttr,
-									Value:    uint32(500),
-									Next: &PathAttribute{
-										TypeCode: AtomicAggrAttr,
-										Next: &PathAttribute{
-											TypeCode: AggregatorAttr,
-											Value:    uint16(200),
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-				NLRI: &NLRI{
-					IP:     [4]byte{8, 8, 8, 0},
-					Pfxlen: 24,
-					Next: &NLRI{
-						IP:     [4]byte{185, 65, 240, 0},
-						Pfxlen: 22,
-					},
-				},
-			},
-			expected: []byte{
-				0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-				0, 85, // Length
-				2, // Msg Type
-
-				// Withdraws
-				0, 5, // Withdrawn Routes Length
-				8, 10, // Withdraw 10/8
-				16, 192, 168, // Withdraw 192.168/16
-
-				0, 49, // Total Path Attribute Length
-
-				// ORIGIN
-				64, // Attr. Flags
-				1,  // Attr. Type Code
-				1,  // Length
-				0,  // Value
-				// ASPath
-				64,                     // Attr. Flags
-				2,                      // Attr. Type Code
-				2,                      // Path Segment Type = AS_SEQUENCE
-				3,                      // Path Segment Length
-				0, 100, 0, 155, 0, 200, // ASNs
-				1,            // Path Segment Type = AS_SET
-				2,            // Path Segment Type = AS_SET
-				0, 10, 0, 20, // ASNs
-				// Next Hop
-				64,             // Attr. Flags
-				3,              // Attr. Type Code
-				4,              // Length
-				10, 20, 30, 40, // Next Hop Address
-				// MED
-				128,          // Attr. Flags
-				4,            // Attr Type Code
-				4,            // Length
-				0, 0, 0, 100, // MED = 100
-				// LocalPref
-				64,           // Attr. Flags
-				5,            // Attr. Type Code
-				4,            // Length
-				0, 0, 1, 244, // Localpref
-				// Atomic Aggregate
-				64, // Attr. Flags
-				6,  // Attr. Type Code
-				0,  // Length
-				// Aggregator
-				192,    // Attr. Flags
-				7,      // Attr. Type Code
-				2,      // Length
-				0, 200, // Aggregator ASN = 200
-
-				// NLRI
-				24, 8, 8, 8, // 8.8.8.0/24
-				22, 185, 65, 240, // 185.65.240.0/22
-			},
-		},
-	}
-
-	for _, test := range tests {
-		res, err := test.msg.SerializeUpdate()
-		if err != nil {
-			if test.wantFail {
-				continue
-			}
-
-			t.Errorf("Unexpected failure for test %q: %v", test.name, err)
-			continue
-		}
-
-		if test.wantFail {
-			t.Errorf("Unexpected success for test %q", test.name)
-			continue
-		}
-
-		assert.Equal(t, test.expected, res)
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/fsm.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/fsm.go
deleted file mode 100644
index 1d353675374d6f8f79fdce314357b92d1eb5013a..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/fsm.go
+++ /dev/null
@@ -1,864 +0,0 @@
-package server
-
-import (
-	"bytes"
-	"fmt"
-	"math"
-	"net"
-	"time"
-
-	"github.com/bio-routing/bio-rd/config"
-	tnet "github.com/bio-routing/bio-rd/net"
-	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
-	"github.com/bio-routing/bio-rd/rt"
-	log "github.com/sirupsen/logrus"
-	"github.com/taktv6/tflow2/convert"
-	tomb "gopkg.in/tomb.v2"
-)
-
-const (
-	// Administrative events
-	ManualStart                               = 1
-	ManualStop                                = 2
-	AutomaticStart                            = 3
-	ManualStartWithPassiveTcpEstablishment    = 4
-	AutomaticStartWithPassiveTcpEstablishment = 5
-	AutomaticStop                             = 8
-
-	// Timer events
-	ConnectRetryTimerExpires = 9
-	HoldTimerExpires         = 10
-	KeepaliveTimerExpires    = 11
-)
-
-const (
-	Cease       = 0
-	Idle        = 1
-	Connect     = 2
-	Active      = 3
-	OpenSent    = 4
-	OpenConfirm = 5
-	Established = 6
-)
-
-type FSM struct {
-	t           tomb.Tomb
-	stateReason string
-	state       int
-	lastState   int
-	eventCh     chan int
-
-	con         *net.TCPConn
-	con2        *net.TCPConn
-	conCh       chan *net.TCPConn
-	conErrCh    chan error
-	initiateCon chan struct{}
-	passive     bool
-
-	local  net.IP
-	remote net.IP
-
-	localASN  uint16
-	remoteASN uint16
-
-	neighborID uint32
-	routerID   uint32
-
-	delayOpen      bool
-	delayOpenTime  time.Duration
-	delayOpenTimer *time.Timer
-
-	connectRetryTime    time.Duration
-	connectRetryTimer   *time.Timer
-	connectRetryCounter int
-
-	holdTimeConfigured time.Duration
-	holdTime           time.Duration
-	holdTimer          *time.Timer
-
-	keepaliveTime  time.Duration
-	keepaliveTimer *time.Timer
-
-	msgRecvCh     chan msgRecvMsg
-	msgRecvFailCh chan msgRecvErr
-	stopMsgRecvCh chan struct{}
-
-	adjRibIn  *rt.RT
-	adjRibOut *rt.RT
-}
-
-type msgRecvMsg struct {
-	msg []byte
-	con *net.TCPConn
-}
-
-type msgRecvErr struct {
-	err error
-	con *net.TCPConn
-}
-
-func NewFSM(c config.Peer) *FSM {
-	fsm := &FSM{
-		state:             Idle,
-		passive:           true,
-		connectRetryTime:  5,
-		connectRetryTimer: time.NewTimer(time.Second * time.Duration(20)),
-
-		msgRecvCh:     make(chan msgRecvMsg),
-		msgRecvFailCh: make(chan msgRecvErr),
-		stopMsgRecvCh: make(chan struct{}),
-
-		holdTimeConfigured: time.Duration(c.HoldTimer),
-		holdTimer:          time.NewTimer(0),
-
-		keepaliveTime:  time.Duration(c.KeepAlive),
-		keepaliveTimer: time.NewTimer(0),
-
-		routerID: c.RouterID,
-		remote:   c.PeerAddress,
-		local:    c.LocalAddress,
-		localASN: uint16(c.LocalAS),
-		eventCh:  make(chan int),
-		conCh:    make(chan *net.TCPConn),
-		conErrCh: make(chan error), initiateCon: make(chan struct{}),
-	}
-	return fsm
-}
-
-func (fsm *FSM) disconnect() {
-	if fsm.con != nil {
-		fsm.con.Close()
-		fsm.con = nil
-	}
-	if fsm.con2 != nil {
-		fsm.con2.Close()
-		fsm.con2 = nil
-	}
-}
-
-func (fsm *FSM) changeState(new int, reason string) int {
-	state := map[int]string{
-		Cease:       "Cease",
-		Idle:        "Idle",
-		Connect:     "Connect",
-		Active:      "Active",
-		OpenSent:    "OpenSent",
-		OpenConfirm: "OpenConfirm",
-		Established: "Established",
-	}
-
-	log.WithFields(log.Fields{
-		"peer":       fsm.remote.String(),
-		"last_state": state[fsm.state],
-		"new_state":  state[new],
-		"reason":     reason,
-	}).Info("FSM: Neighbor state change")
-
-	fsm.lastState = fsm.state
-	fsm.state = new
-	fsm.stateReason = reason
-
-	return fsm.state
-}
-
-func (fsm *FSM) activate() {
-	fsm.eventCh <- ManualStart
-}
-
-func (fsm *FSM) Stop() error {
-	fsm.eventCh <- ManualStop
-	fsm.t.Kill(nil)
-	return fsm.t.Wait()
-}
-
-func (fsm *FSM) start() {
-	fsm.t.Go(fsm.main)
-	fsm.t.Go(fsm.tcpConnector)
-	return
-}
-
-func (fsm *FSM) main() error {
-	next := fsm.idle()
-	for {
-		switch next {
-		case Cease:
-			fsm.t.Kill(fmt.Errorf("FSM is being stopped"))
-			return nil
-		case Idle:
-			next = fsm.idle()
-		case Connect:
-			next = fsm.connect()
-		case Active:
-			next = fsm.active()
-		case OpenSent:
-			next = fsm.openSent()
-		case OpenConfirm:
-			next = fsm.openConfirm()
-		case Established:
-			next = fsm.established()
-		}
-	}
-}
-
-func (fsm *FSM) idle() int {
-	fsm.adjRibIn = nil
-	fsm.adjRibOut = nil
-	for {
-		select {
-		case c := <-fsm.conCh:
-			c.Close()
-			continue
-		case e := <-fsm.eventCh:
-			reason := ""
-			switch e {
-			case ManualStart:
-				reason = "Received ManualStart event %d for %s peer"
-			case AutomaticStart:
-				reason = "Received AutomaticStart event %d for %s peer"
-			default:
-				continue
-			}
-
-			fsm.connectRetryCounter = 0
-			fsm.startConnectRetryTimer()
-			if fsm.passive {
-				return fsm.changeState(Active, fmt.Sprintf(reason, "passive"))
-			}
-			fsm.tcpConnect()
-			return fsm.changeState(Connect, fmt.Sprintf(reason, "active"))
-		}
-
-	}
-}
-
-func (fsm *FSM) tcpConnector() error {
-	for {
-		select {
-		case <-fsm.initiateCon:
-			c, err := net.DialTCP("tcp", &net.TCPAddr{IP: fsm.local}, &net.TCPAddr{IP: fsm.remote, Port: BGPPORT})
-			if err != nil {
-				select {
-				case fsm.conErrCh <- err:
-					continue
-				case <-time.NewTimer(time.Second * 30).C:
-					continue
-				}
-			}
-
-			select {
-			case fsm.conCh <- c:
-				continue
-			case <-time.NewTimer(time.Second * 30).C:
-				c.Close()
-				continue
-			}
-		case <-fsm.t.Dying():
-			return nil
-		}
-	}
-}
-
-func (fsm *FSM) tcpConnect() {
-	fsm.initiateCon <- struct{}{}
-}
-
-// connect state waits for a TCP connection to be fully established. Either the active or passive one.
-func (fsm *FSM) connect() int {
-	for {
-		select {
-		case e := <-fsm.eventCh:
-			if e == ManualStop {
-				fsm.connectRetryCounter = 0
-				stopTimer(fsm.connectRetryTimer)
-				return fsm.changeState(Idle, "Manual stop event")
-			}
-			continue
-		case <-fsm.connectRetryTimer.C:
-			fsm.resetConnectRetryTimer()
-			fsm.tcpConnect()
-			continue
-		case c := <-fsm.conCh:
-			fsm.con = c
-			stopTimer(fsm.connectRetryTimer)
-			return fsm.connectSendOpen()
-		}
-	}
-}
-
-func (fsm *FSM) connectSendOpen() int {
-	err := fsm.sendOpen(fsm.con)
-	if err != nil {
-		stopTimer(fsm.connectRetryTimer)
-		return fsm.changeState(Idle, fmt.Sprintf("Sending OPEN message failed: %v", err))
-	}
-	fsm.holdTimer = time.NewTimer(time.Minute * 4)
-	return fsm.changeState(OpenSent, "Sent OPEN message")
-}
-
-// in the active state we wait for a passive TCP connection to be established
-func (fsm *FSM) active() int {
-	for {
-		select {
-		case e := <-fsm.eventCh:
-			if e == ManualStop {
-				fsm.disconnect()
-				fsm.connectRetryCounter = 0
-				stopTimer(fsm.connectRetryTimer)
-				return fsm.changeState(Active, "Manual stop event")
-			}
-			continue
-		case <-fsm.connectRetryTimer.C:
-			fsm.resetConnectRetryTimer()
-			fsm.tcpConnect()
-			return fsm.changeState(Connect, "Connect retry timer expired")
-		case c := <-fsm.conCh:
-			fsm.con = c
-			stopTimer(fsm.connectRetryTimer)
-			return fsm.activeSendOpen()
-		}
-	}
-}
-
-func (fsm *FSM) activeSendOpen() int {
-	err := fsm.sendOpen(fsm.con)
-	if err != nil {
-		fsm.resetConnectRetryTimer()
-		fsm.connectRetryCounter++
-		return fsm.changeState(Idle, fmt.Sprintf("Sending OPEN message failed: %v", err))
-	}
-	fsm.holdTimer = time.NewTimer(time.Minute * 4)
-	return fsm.changeState(OpenSent, "Sent OPEN message")
-}
-
-func (fsm *FSM) msgReceiver(c *net.TCPConn) error {
-	for {
-		msg, err := recvMsg(c)
-		if err != nil {
-			fsm.msgRecvFailCh <- msgRecvErr{err: err, con: c}
-			return nil
-
-			/*select {
-			case fsm.msgRecvFailCh <- msgRecvErr{err: err, con: c}:
-				continue
-			case <-time.NewTimer(time.Second * 60).C:
-				return nil
-			}*/
-		}
-		fsm.msgRecvCh <- msgRecvMsg{msg: msg, con: c}
-
-		select {
-		case <-fsm.stopMsgRecvCh:
-			return nil
-		default:
-			continue
-		}
-	}
-}
-
-func (fsm *FSM) openSent() int {
-	go fsm.msgReceiver(fsm.con)
-
-	for {
-		select {
-		case e := <-fsm.eventCh:
-			if e == ManualStop {
-				sendNotification(fsm.con, packet.Cease, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.disconnect()
-				fsm.connectRetryCounter = 0
-				return fsm.changeState(Idle, "Manual stop event")
-			}
-			continue
-		case <-fsm.holdTimer.C:
-			sendNotification(fsm.con, packet.HoldTimeExpired, 0)
-			stopTimer(fsm.connectRetryTimer)
-			fsm.disconnect()
-			fsm.connectRetryCounter++
-			return fsm.changeState(Idle, "Holdtimer expired")
-		case c := <-fsm.conCh: // 2nd connection coming in. Collision!
-			if fsm.con2 != nil {
-				log.WithFields(log.Fields{
-					"peer":  fsm.remote.String(),
-					"local": fsm.local.String(),
-				}).Warningf("Received third connection from peer. Dropping new connection")
-				c.Close()
-				continue
-			}
-
-			err := fsm.sendOpen(c) // FIXME: Not sure if this is standard compliant
-			if err != nil {
-				c.Close()
-				continue
-			}
-			fsm.con2 = c
-			go fsm.msgReceiver(c)
-			continue
-		case recvMsg := <-fsm.msgRecvCh:
-			msg, err := packet.Decode(bytes.NewBuffer(recvMsg.msg))
-			if err != nil {
-				switch bgperr := err.(type) {
-				case packet.BGPError:
-					sendNotification(fsm.con, bgperr.ErrorCode, bgperr.ErrorSubCode)
-					sendNotification(fsm.con2, bgperr.ErrorCode, bgperr.ErrorSubCode)
-				}
-				stopTimer(fsm.connectRetryTimer)
-				fsm.disconnect()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, fmt.Sprintf("Failed to decode BGP message: %v", err))
-			}
-			switch msg.Header.Type {
-			case packet.NotificationMsg:
-				nMsg := msg.Body.(*packet.BGPNotification)
-				if nMsg.ErrorCode == packet.UnsupportedVersionNumber {
-					stopTimer(fsm.connectRetryTimer)
-					fsm.disconnect()
-					return fsm.changeState(Idle, "Received NOTIFICATION")
-				}
-
-				if nMsg.ErrorCode == packet.Cease {
-					// Was this connection to be closed anyways?
-					if fsm.dumpCon(recvMsg.con) {
-						continue
-					}
-				}
-				stopTimer(fsm.connectRetryTimer)
-				fsm.disconnect()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "Received NOTIFICATION")
-			case packet.OpenMsg:
-				openMsg := msg.Body.(*packet.BGPOpen)
-				fsm.neighborID = openMsg.BGPIdentifier
-				fsm.resolveCollision()
-				stopTimer(fsm.connectRetryTimer)
-				err := fsm.sendKeepalive()
-				if err != nil {
-					return fsm.openSentTCPFail(err)
-				}
-				fsm.holdTime = time.Duration(math.Min(float64(fsm.holdTimeConfigured), float64(openMsg.HoldTime)))
-				if fsm.holdTime != 0 {
-					fsm.holdTimer.Reset(time.Second * fsm.holdTime)
-					fsm.keepaliveTime = fsm.holdTime / 3
-					fsm.keepaliveTimer.Reset(time.Second * fsm.keepaliveTime)
-				}
-				return fsm.changeState(OpenConfirm, "Received OPEN message")
-			default:
-				sendNotification(fsm.con, packet.FiniteStateMachineError, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "FSM Error")
-			}
-		case err := <-fsm.msgRecvFailCh:
-			if err.con == fsm.con && fsm.con2 != nil {
-				fsm.con.Close()
-				fsm.con = fsm.con2
-				fsm.con2 = nil
-				continue
-			}
-
-			if err.con == fsm.con2 {
-				fsm.con2.Close()
-				fsm.con2 = nil
-				continue
-			}
-			return fsm.openSentTCPFail(err.err)
-		}
-	}
-}
-
-func (fsm *FSM) openSentTCPFail(err error) int {
-	fsm.con.Close()
-	fsm.resetConnectRetryTimer()
-	return fsm.changeState(Active, fmt.Sprintf("TCP failure: %v", err))
-}
-
-func (fsm *FSM) dumpCon(c *net.TCPConn) bool {
-	p := fsm.isPassive(c)
-	if fsm.routerID > fsm.neighborID {
-		return p
-	}
-	return !p
-}
-
-func (fsm *FSM) resolveCollision() {
-	if fsm.con2 == nil {
-		return
-	}
-
-	if fsm.routerID > fsm.neighborID {
-		// Terminate passive connection
-		if fsm.isPassive(fsm.con) {
-			dumpCon(fsm.con)
-			fsm.con = fsm.con2
-			return
-		}
-		if fsm.isPassive(fsm.con2) {
-			dumpCon(fsm.con2)
-			return
-		}
-		return
-	}
-
-	// Terminate active connection
-	if !fsm.isPassive(fsm.con) {
-		dumpCon(fsm.con)
-		fsm.con = fsm.con2
-		return
-	}
-	if !fsm.isPassive(fsm.con2) {
-		dumpCon(fsm.con2)
-		fsm.con2.Close()
-		fsm.con2 = nil
-		return
-	}
-}
-
-func dumpCon(c *net.TCPConn) {
-	sendNotification(c, packet.Cease, packet.ConnectionCollisionResolution)
-	c.Close()
-}
-
-func (fsm *FSM) isPassive(c *net.TCPConn) bool {
-	if c.LocalAddr().String() == fmt.Sprintf("%s:179", fsm.local.String()) {
-		return true
-	}
-	return false
-}
-
-func (fsm *FSM) openConfirm() int {
-	for {
-		select {
-		case e := <-fsm.eventCh:
-			if e == ManualStop { // Event 2
-				sendNotification(fsm.con, packet.Cease, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.disconnect()
-				fsm.connectRetryCounter = 0
-				return fsm.changeState(Idle, "Manual stop event")
-			}
-			continue
-		case <-fsm.holdTimer.C:
-			sendNotification(fsm.con, packet.HoldTimeExpired, 0)
-			stopTimer(fsm.connectRetryTimer)
-			fsm.disconnect()
-			fsm.connectRetryCounter++
-			return fsm.changeState(Idle, "Holdtimer expired")
-		case <-fsm.keepaliveTimer.C:
-			err := fsm.sendKeepalive()
-			if err != nil {
-				stopTimer(fsm.connectRetryTimer)
-				fsm.disconnect()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, fmt.Sprintf("Failed to send keepalive: %v", err))
-			}
-			fsm.keepaliveTimer.Reset(time.Second * fsm.keepaliveTime)
-			continue
-		case c := <-fsm.conCh:
-			if fsm.con2 != nil {
-				log.WithFields(log.Fields{
-					"peer":  fsm.remote.String(),
-					"local": fsm.local.String(),
-				}).Warningf("Received third connection from peer. Dropping new connection")
-				c.Close()
-				continue
-			}
-
-			err := fsm.sendOpen(c) // FIXME: Not sure if this is standard compliant
-			if err != nil {
-				c.Close()
-				continue
-			}
-			fsm.con2 = c
-			go fsm.msgReceiver(c)
-			continue
-		case recvMsg := <-fsm.msgRecvCh:
-			msg, err := packet.Decode(bytes.NewBuffer(recvMsg.msg))
-			if err != nil {
-				fmt.Printf("Failed to decode message: %v\n", recvMsg.msg)
-				switch bgperr := err.(type) {
-				case packet.BGPError:
-					sendNotification(fsm.con, bgperr.ErrorCode, bgperr.ErrorSubCode)
-					sendNotification(fsm.con2, bgperr.ErrorCode, bgperr.ErrorSubCode)
-				}
-				stopTimer(fsm.connectRetryTimer)
-				fsm.disconnect()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "Failed to decode BGP message")
-			}
-
-			switch msg.Header.Type {
-			case packet.NotificationMsg:
-				nMsg := msg.Body.(packet.BGPNotification)
-				if nMsg.ErrorCode == packet.UnsupportedVersionNumber {
-					stopTimer(fsm.connectRetryTimer)
-					fsm.con.Close()
-					return fsm.changeState(Idle, "Received NOTIFICATION")
-				}
-
-				if nMsg.ErrorCode == packet.Cease {
-					// Was this connection to be closed anyways?
-					if fsm.dumpCon(recvMsg.con) {
-						continue
-					}
-				}
-
-				return fsm.openConfirmTCPFail(fmt.Errorf("NOTIFICATION received"))
-			case packet.KeepaliveMsg:
-				fsm.holdTimer.Reset(time.Second * fsm.holdTime)
-				return fsm.changeState(Established, "Received KEEPALIVE")
-			case packet.OpenMsg:
-				openMsg := msg.Body.(*packet.BGPOpen)
-				fsm.neighborID = openMsg.BGPIdentifier
-				fsm.resolveCollision()
-			default:
-				sendNotification(fsm.con, packet.FiniteStateMachineError, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "FSM Error")
-			}
-		case err := <-fsm.msgRecvFailCh:
-			if err.con == fsm.con && fsm.con2 != nil {
-				fsm.con.Close()
-				fsm.con = fsm.con2
-				fsm.con2 = nil
-				continue
-			}
-
-			if err.con == fsm.con2 {
-				fsm.con2.Close()
-				fsm.con2 = nil
-				continue
-			}
-			return fsm.openConfirmTCPFail(err.err)
-		}
-	}
-}
-
-func (fsm *FSM) openConfirmTCPFail(err error) int {
-	fsm.con.Close()
-	fsm.resetConnectRetryTimer()
-	fsm.connectRetryCounter++
-	return fsm.changeState(Idle, fmt.Sprintf("Failure: %v", err))
-}
-
-func (fsm *FSM) established() int {
-	fsm.adjRibIn = rt.New()
-	go func() {
-		for {
-			time.Sleep(time.Second * 10)
-			fmt.Printf("Dumping AdjRibIn\n")
-			routes := fsm.adjRibIn.Dump()
-			for _, route := range routes {
-				fmt.Printf("LPM: %s\n", route.Prefix().String())
-			}
-		}
-	}()
-
-	for {
-		select {
-		case e := <-fsm.eventCh:
-			if e == ManualStop { // Event 2
-				sendNotification(fsm.con, packet.Cease, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter = 0
-				return fsm.changeState(Idle, "Manual stop event")
-			}
-			if e == AutomaticStop { // Event 8
-				sendNotification(fsm.con, packet.Cease, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "Automatic stop event")
-			}
-			continue
-		case <-fsm.holdTimer.C:
-			sendNotification(fsm.con, packet.HoldTimeExpired, 0)
-			stopTimer(fsm.connectRetryTimer)
-			fsm.con.Close()
-			fsm.connectRetryCounter++
-			return fsm.changeState(Idle, "Holdtimer expired")
-		case <-fsm.keepaliveTimer.C:
-			err := fsm.sendKeepalive()
-			if err != nil {
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, fmt.Sprintf("Failed to send keepalive: %v", err))
-			}
-			fsm.keepaliveTimer.Reset(time.Second * fsm.keepaliveTime)
-			continue
-		case c := <-fsm.conCh:
-			c.Close()
-			continue
-		case recvMsg := <-fsm.msgRecvCh:
-			msg, err := packet.Decode(bytes.NewBuffer(recvMsg.msg))
-			if err != nil {
-				switch bgperr := err.(type) {
-				case packet.BGPError:
-					sendNotification(fsm.con, bgperr.ErrorCode, bgperr.ErrorSubCode)
-				}
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "Failed to decode BGP message")
-			}
-			switch msg.Header.Type {
-			case packet.NotificationMsg:
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "Received NOTIFICATION")
-			case packet.UpdateMsg:
-				if fsm.holdTime != 0 {
-					fsm.holdTimer.Reset(time.Second * fsm.holdTime)
-				}
-
-				u := msg.Body.(*packet.BGPUpdate)
-
-				for r := u.WithdrawnRoutes; r != nil; r = r.Next {
-					x := r.IP.([4]byte)
-					pfx := tnet.NewPfx(convert.Uint32b(x[:]), r.Pfxlen)
-					fmt.Printf("LPM: Removing prefix %s\n", pfx.String())
-					fsm.adjRibIn.RemovePfx(pfx)
-				}
-
-				for r := u.NLRI; r != nil; r = r.Next {
-					x := r.IP.([4]byte)
-					pfx := tnet.NewPfx(convert.Uint32b(x[:]), r.Pfxlen)
-					fmt.Printf("LPM: Adding prefix %s\n", pfx.String())
-
-					path := &rt.Path{
-						Type:    rt.BGPPathType,
-						BGPPath: &rt.BGPPath{},
-					}
-
-					for pa := u.PathAttributes; pa.Next != nil; pa = pa.Next {
-						switch pa.TypeCode {
-						case packet.OriginAttr:
-							path.BGPPath.Origin = pa.Value.(uint8)
-						case packet.LocalPrefAttr:
-							path.BGPPath.LocalPref = pa.Value.(uint32)
-						case packet.MEDAttr:
-							path.BGPPath.MED = pa.Value.(uint32)
-						case packet.NextHopAttr:
-							path.BGPPath.NextHop = pa.Value.(uint32)
-						case packet.ASPathAttr:
-							path.BGPPath.ASPath = pa.ASPathString()
-							path.BGPPath.ASPathLen = pa.ASPathLen()
-						}
-					}
-					fsm.adjRibIn.Insert(rt.NewRoute(pfx, []*rt.Path{path}))
-				}
-
-				continue
-			case packet.KeepaliveMsg:
-				if fsm.holdTime != 0 {
-					fsm.holdTimer.Reset(time.Second * fsm.holdTime)
-				}
-				continue
-			case packet.OpenMsg:
-				if fsm.con2 != nil {
-					sendNotification(fsm.con2, packet.Cease, packet.ConnectionCollisionResolution)
-					fsm.con2.Close()
-					fsm.con2 = nil
-					continue
-				}
-				sendNotification(fsm.con, packet.FiniteStateMachineError, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "FSM Error")
-			default:
-				sendNotification(fsm.con, packet.FiniteStateMachineError, 0)
-				stopTimer(fsm.connectRetryTimer)
-				fsm.con.Close()
-				fsm.connectRetryCounter++
-				return fsm.changeState(Idle, "FSM Error")
-			}
-		case err := <-fsm.msgRecvFailCh:
-			if err.con == fsm.con && fsm.con2 != nil {
-				fsm.con.Close()
-				fsm.con = fsm.con2
-				fsm.con2 = nil
-				continue
-			}
-
-			if err.con == fsm.con2 {
-				fsm.con2.Close()
-				fsm.con2 = nil
-				continue
-			}
-			return fsm.openConfirmTCPFail(err.err)
-		}
-	}
-}
-
-func stopTimer(t *time.Timer) {
-	if !t.Stop() {
-		select {
-		case <-t.C:
-		default:
-		}
-	}
-}
-
-func (fsm *FSM) startConnectRetryTimer() {
-	fsm.connectRetryTimer = time.NewTimer(time.Second * fsm.connectRetryTime)
-}
-
-func (fsm *FSM) resetConnectRetryTimer() {
-	if !fsm.connectRetryTimer.Reset(time.Second * fsm.connectRetryTime) {
-		<-fsm.connectRetryTimer.C
-	}
-}
-
-func (fsm *FSM) resetDelayOpenTimer() {
-	if !fsm.delayOpenTimer.Reset(time.Second * fsm.delayOpenTime) {
-		<-fsm.delayOpenTimer.C
-	}
-}
-
-func (fsm *FSM) sendKeepalive() error {
-	msg := packet.SerializeKeepaliveMsg()
-
-	_, err := fsm.con.Write(msg)
-	if err != nil {
-		return fmt.Errorf("Unable to send KEEPALIVE message: %v", err)
-	}
-
-	return nil
-}
-
-func (fsm *FSM) sendOpen(c *net.TCPConn) error {
-	msg := packet.SerializeOpenMsg(&packet.BGPOpen{
-		Version:       BGPVersion,
-		AS:            fsm.localASN,
-		HoldTime:      uint16(fsm.holdTimeConfigured),
-		BGPIdentifier: fsm.routerID,
-		OptParmLen:    0,
-	})
-
-	_, err := c.Write(msg)
-	if err != nil {
-		return fmt.Errorf("Unable to send OPEN message: %v", err)
-	}
-
-	return nil
-}
-
-func sendNotification(c *net.TCPConn, errorCode uint8, errorSubCode uint8) error {
-	if c == nil {
-		return fmt.Errorf("connection is nil")
-	}
-
-	msg := packet.SerializeNotificationMsg(&packet.BGPNotification{})
-
-	_, err := c.Write(msg)
-	if err != nil {
-		return fmt.Errorf("Unable to send NOTIFICATION message: %v", err)
-	}
-
-	return nil
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/peer.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/peer.go
deleted file mode 100644
index 02051838f9d3e496ff7e4dfe590786f3e7b193f1..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/peer.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package server
-
-import (
-	"net"
-
-	"github.com/bio-routing/bio-rd/config"
-)
-
-type Peer struct {
-	addr     net.IP
-	asn      uint32
-	fsm      *FSM
-	routerID uint32
-}
-
-func NewPeer(c config.Peer) (*Peer, error) {
-	p := &Peer{
-		addr: c.PeerAddress,
-		asn:  c.PeerAS,
-		fsm:  NewFSM(c),
-	}
-	return p, nil
-}
-
-func (p *Peer) GetAddr() net.IP {
-	return p.addr
-}
-
-func (p *Peer) GetASN() uint32 {
-	return p.asn
-}
-
-func (p *Peer) Start() {
-	p.fsm.start()
-	p.fsm.activate()
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/server.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/server.go
deleted file mode 100644
index 6bf46ac7634f684b5d060ea2e5ffd7417819e417..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/server.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package server
-
-import (
-	"fmt"
-	"io"
-	"net"
-	"strings"
-
-	"github.com/bio-routing/bio-rd/config"
-	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
-	log "github.com/sirupsen/logrus"
-)
-
-const (
-	uint16max  = 65535
-	BGPVersion = 4
-)
-
-type BGPServer struct {
-	listeners []*TCPListener
-	acceptCh  chan *net.TCPConn
-	peers     map[string]*Peer
-	routerID  uint32
-}
-
-func NewBgpServer() *BGPServer {
-	return &BGPServer{
-		peers: make(map[string]*Peer),
-	}
-}
-
-func (b *BGPServer) RouterID() uint32 {
-	return b.routerID
-}
-
-func (b *BGPServer) Start(c *config.Global) error {
-	if err := c.SetDefaultGlobalConfigValues(); err != nil {
-		return fmt.Errorf("Failed to load defaults: %v", err)
-	}
-
-	fmt.Printf("ROUTER ID: %d\n", c.RouterID)
-	b.routerID = c.RouterID
-
-	if c.Listen {
-		acceptCh := make(chan *net.TCPConn, 4096)
-		for _, addr := range c.LocalAddressList {
-			l, err := NewTCPListener(addr, c.Port, acceptCh)
-			if err != nil {
-				return fmt.Errorf("Failed to start TCPListener for %s: %v", addr.String(), err)
-			}
-			b.listeners = append(b.listeners, l)
-		}
-		b.acceptCh = acceptCh
-
-		go b.incomingConnectionWorker()
-	}
-
-	return nil
-}
-
-func (b *BGPServer) incomingConnectionWorker() {
-	for {
-		c := <-b.acceptCh
-		fmt.Printf("Incoming connection!\n")
-		fmt.Printf("Connection from: %v\n", c.RemoteAddr())
-
-		peerAddr := strings.Split(c.RemoteAddr().String(), ":")[0]
-		if _, ok := b.peers[peerAddr]; !ok {
-			c.Close()
-			log.WithFields(log.Fields{
-				"source": c.RemoteAddr(),
-			}).Warning("TCP connection from unknown source")
-			continue
-		}
-
-		log.WithFields(log.Fields{
-			"source": c.RemoteAddr(),
-		}).Info("Incoming TCP connection")
-
-		fmt.Printf("DEBUG: Sending incoming TCP connection to fsm for peer %s\n", peerAddr)
-		b.peers[peerAddr].fsm.conCh <- c
-		fmt.Printf("DEBUG: Sending done\n")
-	}
-}
-
-func (b *BGPServer) AddPeer(c config.Peer) error {
-	if c.LocalAS > uint16max || c.PeerAS > uint16max {
-		return fmt.Errorf("32bit ASNs are not supported yet")
-	}
-
-	peer, err := NewPeer(c)
-	if err != nil {
-		return err
-	}
-
-	peer.routerID = c.RouterID
-	peerAddr := peer.GetAddr().String()
-	b.peers[peerAddr] = peer
-	b.peers[peerAddr].Start()
-
-	return nil
-}
-
-func recvMsg(c *net.TCPConn) (msg []byte, err error) {
-	buffer := make([]byte, packet.MaxLen)
-	_, err = io.ReadFull(c, buffer[0:packet.MinLen])
-	if err != nil {
-		return nil, fmt.Errorf("Read failed: %v", err)
-	}
-
-	l := int(buffer[16])*256 + int(buffer[17])
-	toRead := l
-	_, err = io.ReadFull(c, buffer[packet.MinLen:toRead])
-	if err != nil {
-		return nil, fmt.Errorf("Read failed: %v", err)
-	}
-
-	return buffer, nil
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/sockopt.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/sockopt.go
deleted file mode 100644
index 2984216a6217ac05cf7dc7439dad3f7cb3dee72d..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/sockopt.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package server
-
-import (
-	"net"
-	"os"
-	"syscall"
-)
-
-const (
-	TCP_MD5SIG       = 14 // TCP MD5 Signature (RFC2385)
-	IPV6_MINHOPCOUNT = 73 // Generalized TTL Security Mechanism (RFC5082)
-)
-
-func SetListenTCPTTLSockopt(l *net.TCPListener, ttl int) error {
-	fi, family, err := extractFileAndFamilyFromTCPListener(l)
-	defer fi.Close()
-	if err != nil {
-		return err
-	}
-	return setsockoptIPTTL(int(fi.Fd()), family, ttl)
-}
-
-func setsockoptIPTTL(fd int, family int, value int) error {
-	level := syscall.IPPROTO_IP
-	name := syscall.IP_TTL
-	if family == syscall.AF_INET6 {
-		level = syscall.IPPROTO_IPV6
-		name = syscall.IPV6_UNICAST_HOPS
-	}
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, level, name, value))
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/tcplistener.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/tcplistener.go
deleted file mode 100644
index 04607c74259f7a9392cb71757d082644c1aba079..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/tcplistener.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package server
-
-import (
-	"net"
-	"strconv"
-
-	log "github.com/sirupsen/logrus"
-)
-
-const (
-	BGPPORT = 179
-)
-
-type TCPListener struct {
-	l       *net.TCPListener
-	closeCh chan struct{}
-}
-
-func NewTCPListener(address net.IP, port uint16, ch chan *net.TCPConn) (*TCPListener, error) {
-	proto := "tcp4"
-	if address.To4() == nil {
-		proto = "tcp6"
-	}
-
-	addr, err := net.ResolveTCPAddr(proto, net.JoinHostPort(address.String(), strconv.Itoa(int(port))))
-	if err != nil {
-		return nil, err
-	}
-
-	l, err := net.ListenTCP(proto, addr)
-	if err != nil {
-		return nil, err
-	}
-
-	// Note: Set TTL=255 for incoming connection listener in order to accept
-	// connection in case for the neighbor has TTL Security settings.
-	if err := SetListenTCPTTLSockopt(l, 255); err != nil {
-		log.WithFields(log.Fields{
-			"Topic": "Peer",
-			"Key":   addr,
-		}).Warnf("cannot set TTL(=%d) for TCPLisnter: %s", 255, err)
-	}
-
-	tl := &TCPListener{
-		l:       l,
-		closeCh: make(chan struct{}),
-	}
-
-	go func(tl *TCPListener) error {
-		for {
-			conn, err := tl.l.AcceptTCP()
-			if err != nil {
-				close(tl.closeCh)
-				log.WithFields(log.Fields{
-					"Topic": "Peer",
-					"Error": err,
-				}).Warn("Failed to AcceptTCP")
-				return err
-			}
-			ch <- conn
-		}
-	}(tl)
-
-	return tl, nil
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/util.go b/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/util.go
deleted file mode 100644
index 871f6a580eb57d3c0f42d8592b260b75e3ea17d2..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/protocols/bgp/server/util.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package server
-
-import (
-	"net"
-	"os"
-	"strings"
-	"syscall"
-)
-
-func extractFileAndFamilyFromTCPListener(l *net.TCPListener) (*os.File, int, error) {
-	// Note #1: TCPListener.File() has the unexpected side-effect of putting
-	// the original socket into blocking mode. See Note #2.
-	fi, err := l.File()
-	if err != nil {
-		return nil, 0, err
-	}
-
-	// Note #2: Call net.FileListener() to put the original socket back into
-	// non-blocking mode.
-	fl, err := net.FileListener(fi)
-	if err != nil {
-		fi.Close()
-		return nil, 0, err
-	}
-	fl.Close()
-
-	family := syscall.AF_INET
-	if strings.Contains(l.Addr().String(), "[") {
-		family = syscall.AF_INET6
-	}
-
-	return fi, family, nil
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/bgp.go b/vendor/github.com/bio-routing/bio-rd/rt/bgp.go
deleted file mode 100644
index 7e71427dcf111932d199950eb3d93cedd77f296f..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/bgp.go
+++ /dev/null
@@ -1,143 +0,0 @@
-package rt
-
-import (
-	"sync"
-
-	log "github.com/sirupsen/logrus"
-)
-
-type BGPPath struct {
-	PathIdentifier uint32
-	NextHop        uint32
-	LocalPref      uint32
-	ASPath         string
-	ASPathLen      uint16
-	Origin         uint8
-	MED            uint32
-	EBGP           bool
-	Source         uint32
-}
-
-type BGPPathManager struct {
-	paths map[BGPPath]*BGPPathCounter
-	mu    sync.Mutex
-}
-
-type BGPPathCounter struct {
-	usageCount uint64
-	path       *BGPPath
-}
-
-func NewBGPPathManager() *BGPPathManager {
-	m := &BGPPathManager{}
-	return m
-}
-
-func (m *BGPPathManager) pathExists(p BGPPath) bool {
-	if _, ok := m.paths[p]; !ok {
-		return false
-	}
-
-	return true
-}
-
-func (m *BGPPathManager) AddPath(p BGPPath) *BGPPath {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-
-	if !m.pathExists(p) {
-		m.paths[p] = &BGPPathCounter{
-			path: &p,
-		}
-	}
-
-	m.paths[p].usageCount++
-	return m.paths[p].path
-}
-
-func (m *BGPPathManager) RemovePath(p BGPPath) {
-	m.mu.Lock()
-	defer m.mu.Unlock()
-
-	if !m.pathExists(p) {
-		log.Fatalf("Tried to remove non-existent BGPPath: %v", p)
-		return
-	}
-
-	m.paths[p].usageCount--
-	if m.paths[p].usageCount == 0 {
-		delete(m.paths, p)
-	}
-}
-
-func (r *Route) bgpPathSelection() (res []*Path) {
-	// TODO: Implement next hop lookup and compare IGP metrics
-	if len(r.paths) == 1 {
-		copy(res, r.paths)
-		return res
-	}
-
-	for _, p := range r.paths {
-		if p.Type != BGPPathType {
-			continue
-		}
-
-		if len(res) == 0 {
-			res = append(res, p)
-			continue
-		}
-
-		if res[0].BGPPath.ecmp(p.BGPPath) {
-			res = append(res, p)
-			continue
-		}
-
-		if !res[0].BGPPath.better(p.BGPPath) {
-			continue
-		}
-
-		res = []*Path{p}
-	}
-
-	return res
-}
-
-func (b *BGPPath) better(c *BGPPath) bool {
-	if c.LocalPref < b.LocalPref {
-		return false
-	}
-
-	if c.LocalPref > b.LocalPref {
-		return true
-	}
-
-	if c.ASPathLen > b.ASPathLen {
-		return false
-	}
-
-	if c.ASPathLen < b.ASPathLen {
-		return true
-	}
-
-	if c.Origin > b.Origin {
-		return false
-	}
-
-	if c.Origin < b.Origin {
-		return true
-	}
-
-	if c.MED > b.MED {
-		return false
-	}
-
-	if c.MED < b.MED {
-		return true
-	}
-
-	return false
-}
-
-func (b *BGPPath) ecmp(c *BGPPath) bool {
-	return b.LocalPref == c.LocalPref && b.ASPathLen == c.ASPathLen && b.Origin == c.Origin && b.MED == c.MED
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/lpm_test.go.dis b/vendor/github.com/bio-routing/bio-rd/rt/lpm_test.go.dis
deleted file mode 100644
index 90f9e450ba42b376a81b239f90285aca497902e7..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/lpm_test.go.dis
+++ /dev/null
@@ -1,673 +0,0 @@
-package rt
-
-import (
-	"testing"
-
-	"github.com/taktv6/tbgp/net"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestNew(t *testing.T) {
-	l := New()
-	if l == nil {
-		t.Errorf("New() returned nil")
-	}
-}
-
-func TestRemove(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*Route
-		remove   []*net.Prefix
-		expected []*Route
-	}{
-		{
-			name: "Test 1",
-			routes: []*Route{
-				NewRoute(net.NewPfx(167772160, 8)), // 10.0.0.0
-				NewRoute(net.NewPfx(167772160, 9)), // 10.0.0.0
-				NewRoute(net.NewPfx(176160768, 9)), // 10.128.0.0
-			},
-			remove: []*net.Prefix{
-				net.NewPfx(167772160, 8), // 10.0.0.0
-			},
-			expected: []*Route{
-				NewRoute(net.NewPfx(167772160, 9)), // 10.0.0.0
-				NewRoute(net.NewPfx(176160768, 9)), // 10.128.0.0
-			},
-		},
-		{
-			name: "Test 2",
-			routes: []*Route{
-				NewRoute(net.NewPfx(167772160, 8)),  // 10.0.0.0/8
-				NewRoute(net.NewPfx(191134464, 24)), // 11.100.123.0/24
-				NewRoute(net.NewPfx(167772160, 12)), // 10.0.0.0/12
-				NewRoute(net.NewPfx(167772160, 10)), // 10.0.0.0/10
-			},
-			remove: []*net.Prefix{
-				net.NewPfx(167772160, 7), // 10.0.0.0/7
-			},
-			expected: []*Route{
-				NewRoute(net.NewPfx(167772160, 8)),  // 10.0.0.0/8
-				NewRoute(net.NewPfx(167772160, 10)), // 10.0.0.0/10
-				NewRoute(net.NewPfx(167772160, 12)), // 10.0.0.0/12
-				NewRoute(net.NewPfx(191134464, 24)), // 11.100.123.0/24
-			},
-		},
-		{
-			name: "Test 3",
-			remove: []*net.Prefix{
-				NewRoute(net.NewPfx(167772160, 7)), // 10.0.0.0/7
-			},
-			expected: []*Route{},
-		},
-		{
-			name: "Test 4",
-			prefixes: []*net.Prefix{
-				NewRoute(net.NewPfx(167772160, 8)),  // 10.0.0.0
-				NewRoute(net.NewPfx(191134464, 24)), // 11.100.123.0/24
-				NewRoute(net.NewPfx(167772160, 12)), // 10.0.0.0
-				NewRoute(net.NewPfx(167772160, 10)), // 10.0.0.0
-				NewRoute(net.NewPfx(191134592, 25)), // 11.100.123.128/25
-			},
-			remove: []*net.Prefix{
-				NewRoute(net.NewPfx(191134464, 24)), // 11.100.123.0/24
-			},
-			expected: []*Route{
-				NewRoute(net.NewPfx(167772160, 8)),  // 10.0.0.0
-				NewRoute(net.NewPfx(167772160, 10)), // 10.0.0.0
-				NewRoute(net.NewPfx(167772160, 12)), // 10.0.0.0
-				NewRoute(net.NewPfx(191134592, 25)), // 11.100.123.128/25
-			},
-		},
-		{
-			name: "Test 5",
-			prefixes: []*net.Prefix{
-				NewRoute(net.NewPfx(167772160, 8)),  // 10.0.0.0
-				NewRoute(net.NewPfx(191134464, 24)), // 11.100.123.0/24
-				NewRoute(net.NewPfx(167772160, 12)), // 10.0.0.0
-				NewRoute(net.NewPfx(167772160, 10)), // 10.0.0.0
-				NewRoute(net.NewPfx(191134592, 25)), // 11.100.123.128/25
-			},
-			remove: []*net.Prefix{
-				NewRoute(net.NewPfx(167772160, 12)), // 10.0.0.0/12
-			},
-			expected: []*Route{
-				NewRoute(net.NewPfx(167772160, 8)),  // 10.0.0.0
-				NewRoute(net.NewPfx(167772160, 10)), // 10.0.0.0
-				NewRoute(net.NewPfx(191134464, 24)), // 11.100.123.0/24
-				NewRoute(net.NewPfx(191134592, 25)), // 11.100.123.128/25
-			},
-		},
-	}
-
-	for _, test := range tests {
-		lpm := New()
-		for _, route := range test.routes {
-			lpm.Insert(route)
-		}
-
-		for _, pfx := range test.remove {
-			lpm.Remove(pfx)
-		}
-
-		res := lpm.Dump()
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestInsert(t *testing.T) {
-	tests := []struct {
-		name     string
-		prefixes []*net.Prefix
-		expected *node
-	}{
-		{
-			name: "Insert first node",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8), // 10.0.0.0/8
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8)}, // 10.0.0.0/8
-				skip: 8,
-			},
-		},
-		{
-			name: "Insert double node",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8), // 10.0.0.0/8
-				net.NewPfx(167772160, 8), // 10.0.0.0/8
-				net.NewPfx(167772160, 8), // 10.0.0.0/8
-				net.NewPfx(167772160, 8), // 10.0.0.0/8
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-				},
-				skip: 8,
-			},
-		},
-		{
-			name: "Insert triangle",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8), // 10.0.0.0
-				net.NewPfx(167772160, 9), // 10.0.0.0
-				net.NewPfx(176160768, 9), // 10.128.0.0
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-				},
-				skip: 8,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 9), // 10.0.0.0
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(176160768, 9), // 10.128.0.0
-					},
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), // 10.0.0.0/8
-					},
-					skip: 16,
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes plus one child low",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-					l: &node{
-						skip: 1,
-						route: &Route{
-							pfx: net.NewPfx(167772160, 10), // 10.0.0.0/10
-						},
-						l: &node{
-							skip: 1,
-							route: &Route{
-								pfx: net.NewPfx(167772160, 12), // 10.0.0.0
-							},
-						},
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), // 10.0.0.0/8
-					},
-					skip: 16,
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes plus one child high",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-				net.NewPfx(191134592, 25), // 11.100.123.128/25
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-					l: &node{
-						skip: 1,
-						route: &Route{
-							pfx: net.NewPfx(167772160, 10), // 10.0.0.0/10
-						},
-						l: &node{
-							skip: 1,
-							route: &Route{
-								pfx: net.NewPfx(167772160, 12), // 10.0.0.0
-							},
-						},
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), //11.100.123.0/24
-					},
-					skip: 16,
-					h: &node{
-						route: &Route{
-							pfx: net.NewPfx(191134592, 25), //11.100.123.128/25
-						},
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		l := New()
-		for _, pfx := range test.prefixes {
-			l.Insert(&Route{pfx: pfx})
-		}
-
-		assert.Equal(t, test.expected, l.root)
-	}
-}
-
-func TestLPM(t *testing.T) {
-	tests := []struct {
-		name     string
-		prefixes []*net.Prefix
-		needle   *net.Prefix
-		expected []*net.Prefix
-	}{
-		{
-			name: "Test 1",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-			needle: net.NewPfx(167772160, 32), // 10.0.0.0/32
-			expected: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-				net.NewPfx(167772160, 12), // 10.0.0.0
-			},
-		},
-		{
-			name:     "Test 2",
-			prefixes: []*net.Prefix{},
-			needle:   net.NewPfx(167772160, 32), // 10.0.0.0/32
-			expected: nil,
-		},
-		{
-			name: "Test 3",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-			needle: net.NewPfx(167772160, 10), // 10.0.0.0/10
-			expected: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-		},
-	}
-
-	for _, test := range tests {
-		lpm := New()
-		for _, pfx := range test.prefixes {
-			lpm.Insert(&Route{pfx: pfx})
-		}
-		assert.Equal(t, test.expected, lpm.LPM(test.needle))
-	}
-}
-
-func TestGet(t *testing.T) {
-	tests := []struct {
-		name          string
-		moreSpecifics bool
-		prefixes      []*net.Prefix
-		needle        *net.Prefix
-		expected      []*net.Prefix
-	}{
-		{
-			name:          "Test 1: Search pfx and dump more specifics",
-			moreSpecifics: true,
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0/8
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0/12
-				net.NewPfx(167772160, 10), // 10.0.0.0/10
-			},
-			needle: net.NewPfx(167772160, 8), // 10.0.0.0/8
-			expected: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0/8
-				net.NewPfx(167772160, 10), // 10.0.0.0
-				net.NewPfx(167772160, 12), // 10.0.0.0
-			},
-		},
-		{
-			name: "Test 2: Search pfx and don't dump more specifics",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0/8
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-			needle: net.NewPfx(167772160, 8), // 10.0.0.0/8
-			expected: []*net.Prefix{
-				net.NewPfx(167772160, 8), // 10.0.0.0/8
-			},
-		},
-		{
-			name:     "Test 3",
-			prefixes: []*net.Prefix{},
-			needle:   net.NewPfx(167772160, 32), // 10.0.0.0/32
-			expected: nil,
-		},
-		{
-			name: "Test 4: Get Dummy",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-			},
-			needle:   net.NewPfx(167772160, 7), // 10.0.0.0/7
-			expected: nil,
-		},
-		{
-			name: "Test 5",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-			needle: net.NewPfx(191134464, 24), // 10.0.0.0/8
-			expected: []*net.Prefix{
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-			},
-		},
-		{
-			name: "Test 4: Get nonexistent #1",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-			},
-			needle:   net.NewPfx(167772160, 10), // 10.0.0.0/10
-			expected: nil,
-		},
-		{
-			name: "Test 4: Get nonexistent #2",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0/8
-				net.NewPfx(167772160, 12), // 10.0.0.0/12
-			},
-			needle:   net.NewPfx(167772160, 10), // 10.0.0.0/10
-			expected: nil,
-		},
-	}
-
-	for _, test := range tests {
-		lpm := New()
-		for _, pfx := range test.prefixes {
-			lpm.Insert(&Route{pfx: pfx})
-		}
-		p := lpm.Get(test.needle, test.moreSpecifics)
-
-		if p == nil {
-			if test.expected != nil {
-				t.Errorf("Unexpected nil result for test %q", test.name)
-			}
-			continue
-		}
-
-		assert.Equal(t, test.expected, p)
-	}
-}
-
-func TestNewSuperNode(t *testing.T) {
-	tests := []struct {
-		name     string
-		a        *net.Prefix
-		b        *net.Prefix
-		expected *node
-	}{
-		{
-			name: "Test 1",
-			a:    net.NewPfx(167772160, 8),  // 10.0.0.0/8
-			b:    net.NewPfx(191134464, 24), // 11.100.123.0/24
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), //11.100.123.0/24
-					},
-					skip: 16,
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		n := newNode(&Route{pfx: test.a}, test.a.Pfxlen(), false)
-		n = n.newSuperNode(&Route{pfx: test.b})
-		assert.Equal(t, test.expected, n)
-	}
-}
-
-func TestDumpPfxs(t *testing.T) {
-	tests := []struct {
-		name     string
-		prefixes []*net.Prefix
-		expected []*net.Prefix
-	}{
-
-		{
-			name:     "Test 1: Empty node",
-			expected: nil,
-		},
-		{
-			name: "Test 2: ",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0/8
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0/12
-				net.NewPfx(167772160, 10), // 10.0.0.0/10
-			},
-			expected: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0/8
-				net.NewPfx(167772160, 10), // 10.0.0.0/10
-				net.NewPfx(167772160, 12), // 10.0.0.0/12
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-			},
-		},
-	}
-
-	for _, test := range tests {
-		lpm := New()
-		for _, pfx := range test.prefixes {
-			lpm.Insert(&Route{pfx: pfx})
-		}
-
-		res := make([]*Route, 0)
-		r := lpm.root.dumpPfxs(res)
-		assert.Equal(t, test.expected, r)
-	}
-}
-
-func TestGetBitUint32(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint32
-		offset   uint8
-		expected bool
-	}{
-		{
-			name:     "test 1",
-			input:    167772160, // 10.0.0.0
-			offset:   8,
-			expected: false,
-		},
-		{
-			name:     "test 2",
-			input:    184549376, // 11.0.0.0
-			offset:   8,
-			expected: true,
-		},
-	}
-
-	for _, test := range tests {
-		b := getBitUint32(test.input, test.offset)
-		if b != test.expected {
-			t.Errorf("%s: Unexpected failure: Bit %d of %d is %v. Expected %v", test.name, test.offset, test.input, b, test.expected)
-		}
-	}
-}
-
-func TestInsertChildren(t *testing.T) {
-	tests := []struct {
-		name     string
-		base     *net.Prefix
-		old      *net.Prefix
-		new      *net.Prefix
-		expected *node
-	}{
-		{
-			name: "Test 1",
-			base: net.NewPfx(167772160, 8), //10.0.0.0/8
-			old:  net.NewPfx(167772160, 9), //10.0.0.0/9
-			new:  net.NewPfx(176160768, 9), //10.128.0.0/9
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8),
-				},
-				skip:  8,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 9),
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(176160768, 9),
-					},
-				},
-			},
-		},
-		{
-			name: "Test 2",
-			base: net.NewPfx(167772160, 8), //10.0.0.0/8
-			old:  net.NewPfx(176160768, 9), //10.128.0.0/9
-			new:  net.NewPfx(167772160, 9), //10.0.0.0/9
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8),
-				},
-				skip:  8,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 9),
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(176160768, 9),
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		n := newNode(&Route{pfx: test.base}, test.base.Pfxlen(), true)
-		old := newNode(&Route{pfx: test.old}, test.old.Pfxlen(), false)
-		n.insertChildren(old, &Route{pfx: test.new})
-		assert.Equal(t, test.expected, n)
-	}
-}
-
-func TestInsertBefore(t *testing.T) {
-	tests := []struct {
-		name     string
-		a        *net.Prefix
-		b        *net.Prefix
-		expected *node
-	}{
-		{
-			name: "Test 1",
-			a:    net.NewPfx(167772160, 10), // 10.0.0.0
-			b:    net.NewPfx(167772160, 8),  // 10.0.0.0
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8), // 10.0.0.0,
-				},
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 10), // 10.0.0.0
-					},
-					skip: 1,
-				},
-				skip: 8,
-			},
-		},
-		{
-			name: "Test 2",
-			a:    net.NewPfx(184549376, 8), // 11.0.0.0/8
-			b:    net.NewPfx(167772160, 7), // 10.0.0.0/7
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0,
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(184549376, 8), // 10.0.0.0
-					},
-					skip: 0,
-				},
-				skip: 7,
-			},
-		},
-	}
-
-	for _, test := range tests {
-		n := newNode(&Route{pfx: test.a}, test.a.Pfxlen(), false)
-		n = n.insertBefore(&Route{pfx: test.b}, test.b.Pfxlen())
-		assert.Equal(t, test.expected, n)
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/route.go b/vendor/github.com/bio-routing/bio-rd/rt/route.go
deleted file mode 100644
index f309d3c108241ab2e62d0c5536b6275b7a35ddf8..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/route.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package rt
-
-import (
-	net "github.com/bio-routing/bio-rd/net"
-)
-
-// Path Types
-const StaticPathType = 1
-const BGPPathType = 2
-const OSPFPathType = 3
-const ISISPathType = 4
-
-type Path struct {
-	Type       uint8
-	StaticPath *StaticPath
-	BGPPath    *BGPPath
-}
-
-type Route struct {
-	pfx         *net.Prefix
-	activePaths []*Path
-	paths       []*Path
-}
-
-func NewRoute(pfx *net.Prefix, paths []*Path) *Route {
-	r := &Route{
-		pfx:   pfx,
-		paths: paths,
-	}
-
-	return r
-}
-
-func (r *Route) Pfxlen() uint8 {
-	return r.pfx.Pfxlen()
-}
-
-func (r *Route) Prefix() *net.Prefix {
-	return r.pfx
-}
-
-func (r *Route) Remove(rm *Route) (final bool) {
-	for _, del := range rm.paths {
-		r.paths = removePath(r.paths, del)
-	}
-
-	return len(r.paths) == 0
-}
-
-func removePath(paths []*Path, remove *Path) []*Path {
-	i := -1
-	for j := range paths {
-		if paths[j].Equal(remove) {
-			i = j
-			break
-		}
-	}
-
-	if i < 0 {
-		return paths
-	}
-
-	copy(paths[i:], paths[i+1:])
-	return paths[:len(paths)-1]
-}
-
-func (p *Path) Equal(q *Path) bool {
-	if p == nil || q == nil {
-		return false
-	}
-
-	if p.Type != q.Type {
-		return false
-	}
-
-	switch p.Type {
-	case BGPPathType:
-		if *p.BGPPath != *q.BGPPath {
-			return false
-		}
-	}
-
-	return true
-}
-
-func (r *Route) AddPath(p *Path) {
-	r.paths = append(r.paths, p)
-	r.bestPaths()
-}
-
-func (r *Route) AddPaths(paths []*Path) {
-	for _, p := range paths {
-		r.paths = append(r.paths, p)
-	}
-	r.bestPaths()
-}
-
-func (r *Route) bestPaths() {
-	best := []*Path{}
-	protocol := getBestProtocol(r.paths)
-
-	switch protocol {
-	case StaticPathType:
-		best = r.staticPathSelection()
-	case BGPPathType:
-		best = r.bgpPathSelection()
-	}
-
-	r.activePaths = best
-}
-
-func getBestProtocol(paths []*Path) uint8 {
-	best := uint8(0)
-	for _, p := range paths {
-		if best == 0 {
-			best = p.Type
-			continue
-		}
-
-		if p.Type < best {
-			best = p.Type
-		}
-	}
-
-	return best
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/route_test.go b/vendor/github.com/bio-routing/bio-rd/rt/route_test.go
deleted file mode 100644
index 3bac4e87cf7907e57fce7af3ac8192370f048bec..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/route_test.go
+++ /dev/null
@@ -1,394 +0,0 @@
-package rt
-
-import (
-	"testing"
-
-	net "github.com/bio-routing/bio-rd/net"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestNewRoute(t *testing.T) {
-	tests := []struct {
-		name     string
-		pfx      *net.Prefix
-		paths    []*Path
-		expected *Route
-	}{
-		{
-			name: "Test #1",
-			pfx:  net.NewPfx(158798889, 24),
-			paths: []*Path{
-				{
-					Type: 2,
-					StaticPath: &StaticPath{
-						NextHop: 56963289,
-					},
-				},
-			},
-			expected: &Route{
-				pfx: net.NewPfx(158798889, 24),
-				paths: []*Path{
-					{
-						Type: 2,
-						StaticPath: &StaticPath{
-							NextHop: 56963289,
-						},
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		res := NewRoute(test.pfx, test.paths)
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestPfxlen(t *testing.T) {
-	tests := []struct {
-		name     string
-		pfx      *net.Prefix
-		expected uint8
-	}{
-		{
-			name:     "Test #1",
-			pfx:      net.NewPfx(158798889, 24),
-			expected: 24,
-		},
-	}
-
-	for _, test := range tests {
-		r := NewRoute(test.pfx, nil)
-		res := r.Pfxlen()
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestPrefix(t *testing.T) {
-	tests := []struct {
-		name     string
-		pfx      *net.Prefix
-		expected *net.Prefix
-	}{
-		{
-			name:     "Test #1",
-			pfx:      net.NewPfx(158798889, 24),
-			expected: net.NewPfx(158798889, 24),
-		},
-	}
-
-	for _, test := range tests {
-		r := NewRoute(test.pfx, nil)
-		res := r.Prefix()
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestRouteRemovePath(t *testing.T) {
-	tests := []struct {
-		name     string
-		paths    []*Path
-		remove   *Path
-		expected []*Path
-	}{
-		{
-			name: "Remove middle",
-			paths: []*Path{
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 100,
-					},
-				},
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 200,
-					},
-				},
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 300,
-					},
-				},
-			},
-			remove: &Path{
-				Type: BGPPathType,
-				BGPPath: &BGPPath{
-					LocalPref: 200,
-				},
-			},
-			expected: []*Path{
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 100,
-					},
-				},
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 300,
-					},
-				},
-			},
-		},
-		{
-			name: "Remove non-existent",
-			paths: []*Path{
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 10,
-					},
-				},
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 20,
-					},
-				},
-			},
-			remove: &Path{
-				Type: BGPPathType,
-				BGPPath: &BGPPath{
-					LocalPref: 50,
-				},
-			},
-			expected: []*Path{
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 10,
-					},
-				},
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 20,
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		res := removePath(test.paths, test.remove)
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestEqual(t *testing.T) {
-	tests := []struct {
-		name     string
-		pathA    *Path
-		pathB    *Path
-		expected bool
-	}{
-		{
-			name: "Unequal types",
-			pathA: &Path{
-				Type: 1,
-			},
-			pathB: &Path{
-				Type: 2,
-			},
-			expected: false,
-		},
-		{
-			name: "Unequal attributes",
-			pathA: &Path{
-				Type: 2,
-				BGPPath: &BGPPath{
-					LocalPref: 100,
-				},
-			},
-			pathB: &Path{
-				Type: 2,
-				BGPPath: &BGPPath{
-					LocalPref: 200,
-				},
-			},
-			expected: false,
-		},
-		{
-			name: "Equal",
-			pathA: &Path{
-				Type: 2,
-				BGPPath: &BGPPath{
-					LocalPref: 100,
-				},
-			},
-			pathB: &Path{
-				Type: 2,
-				BGPPath: &BGPPath{
-					LocalPref: 100,
-				},
-			},
-			expected: true,
-		},
-	}
-
-	for _, test := range tests {
-		res := test.pathA.Equal(test.pathB)
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestAddPath(t *testing.T) {
-	tests := []struct {
-		name     string
-		route    *Route
-		new      *Path
-		expected *Route
-	}{
-		{
-			name: "Add a new best path",
-			route: &Route{
-				paths: []*Path{
-					{
-						Type: 2,
-						BGPPath: &BGPPath{
-							LocalPref: 100,
-						},
-					},
-				},
-			},
-			new: &Path{
-				Type: 2,
-				BGPPath: &BGPPath{
-					LocalPref: 200,
-				},
-			},
-			expected: &Route{
-				activePaths: []*Path{
-					{
-						Type: 2,
-						BGPPath: &BGPPath{
-							LocalPref: 200,
-						},
-					},
-				},
-				paths: []*Path{
-					{
-						Type: 2,
-						BGPPath: &BGPPath{
-							LocalPref: 100,
-						},
-					},
-					{
-						Type: 2,
-						BGPPath: &BGPPath{
-							LocalPref: 200,
-						},
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		test.route.AddPath(test.new)
-		assert.Equal(t, test.expected, test.route)
-	}
-}
-
-func TestAddPaths(t *testing.T) {
-	tests := []struct {
-		name     string
-		route    *Route
-		new      []*Path
-		expected *Route
-	}{
-		{
-			name: "Add 2 new paths including a new best path",
-			route: &Route{
-				paths: []*Path{
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 100,
-						},
-					},
-				},
-			},
-			new: []*Path{
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 200,
-					},
-				},
-				{
-					Type: BGPPathType,
-					BGPPath: &BGPPath{
-						LocalPref: 50,
-					},
-				},
-			},
-			expected: &Route{
-				activePaths: []*Path{
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 200,
-						},
-					},
-				},
-				paths: []*Path{
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 100,
-						},
-					},
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 200,
-						},
-					},
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 50,
-						},
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		test.route.AddPaths(test.new)
-		assert.Equal(t, test.expected, test.route)
-	}
-}
-
-func TestGetBestProtocol(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    []*Path
-		expected uint8
-	}{
-		{
-			name: "Foo",
-			input: []*Path{
-				{
-					Type: BGPPathType,
-				},
-				{
-					Type: StaticPathType,
-				},
-			},
-			expected: StaticPathType,
-		},
-	}
-
-	for _, test := range tests {
-		res := getBestProtocol(test.input)
-		assert.Equal(t, test.expected, res)
-	}
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/routing_table.go b/vendor/github.com/bio-routing/bio-rd/rt/routing_table.go
deleted file mode 100644
index 6ce2785cdbc5bb6fdcbe2342b17e037ae2147180..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/routing_table.go
+++ /dev/null
@@ -1,320 +0,0 @@
-package rt
-
-import (
-	"github.com/bio-routing/bio-rd/net"
-)
-
-// RT represents a routing table
-type RT struct {
-	root  *node
-	nodes uint64
-}
-
-// node is a node in the compressed trie that is used to implement a routing table
-type node struct {
-	skip  uint8
-	dummy bool
-	route *Route
-	l     *node
-	h     *node
-}
-
-// New creates a new empty LPM
-func New() *RT {
-	return &RT{}
-}
-
-func newNode(route *Route, skip uint8, dummy bool) *node {
-	n := &node{
-		route: route,
-		skip:  skip,
-		dummy: dummy,
-	}
-	return n
-}
-
-// LPM performs a longest prefix match for pfx on lpm
-func (rt *RT) LPM(pfx *net.Prefix) (res []*Route) {
-	if rt.root == nil {
-		return nil
-	}
-
-	rt.root.lpm(pfx, &res)
-	return res
-}
-
-// RemovePath removes a path from the trie
-func (rt *RT) RemovePath(route *Route) {
-	rt.root.removePath(route)
-}
-
-// RemovePfx removes a prefix from the rt including all it's paths
-func (rt *RT) RemovePfx(pfx *net.Prefix) {
-	rt.root.removePfx(pfx)
-}
-
-// Get get's prefix pfx from the LPM
-func (rt *RT) Get(pfx *net.Prefix, moreSpecifics bool) (res []*Route) {
-	if rt.root == nil {
-		return nil
-	}
-
-	node := rt.root.get(pfx)
-	if moreSpecifics {
-		return node.dumpPfxs(res)
-	}
-
-	if node == nil {
-		return nil
-	}
-
-	return []*Route{
-		node.route,
-	}
-}
-
-// Insert inserts a route into the LPM
-func (rt *RT) Insert(route *Route) {
-	if rt.root == nil {
-		route.bestPaths()
-		rt.root = newNode(route, route.Pfxlen(), false)
-		return
-	}
-
-	rt.root = rt.root.insert(route)
-}
-
-func (n *node) removePath(route *Route) {
-	if n == nil {
-		return
-	}
-
-	if *n.route.Prefix() == *route.Prefix() {
-		if n.dummy {
-			return
-		}
-
-		if n.route.Remove(route) {
-			// FIXME: Can this node actually be removed from the trie entirely?
-			n.dummy = true
-		}
-
-		return
-	}
-
-	b := getBitUint32(route.Prefix().Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l.removePath(route)
-		return
-	}
-	n.h.removePath(route)
-	return
-}
-
-func (n *node) removePfx(pfx *net.Prefix) {
-	if n == nil {
-		return
-	}
-
-	if *n.route.Prefix() == *pfx {
-		if n.dummy {
-			return
-		}
-
-		n.dummy = true
-
-		return
-	}
-
-	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l.removePfx(pfx)
-		return
-	}
-	n.h.removePfx(pfx)
-	return
-}
-
-func (n *node) lpm(needle *net.Prefix, res *[]*Route) {
-	if n == nil {
-		return
-	}
-
-	if *n.route.Prefix() == *needle && !n.dummy {
-		*res = append(*res, n.route)
-		return
-	}
-
-	if !n.route.Prefix().Contains(needle) {
-		return
-	}
-
-	if !n.dummy {
-		*res = append(*res, n.route)
-	}
-	n.l.lpm(needle, res)
-	n.h.lpm(needle, res)
-}
-
-func (n *node) dumpPfxs(res []*Route) []*Route {
-	if n == nil {
-		return nil
-	}
-
-	if !n.dummy {
-		res = append(res, n.route)
-	}
-
-	if n.l != nil {
-		res = n.l.dumpPfxs(res)
-	}
-
-	if n.h != nil {
-		res = n.h.dumpPfxs(res)
-	}
-
-	return res
-}
-
-func (n *node) get(pfx *net.Prefix) *node {
-	if n == nil {
-		return nil
-	}
-
-	if *n.route.Prefix() == *pfx {
-		if n.dummy {
-			return nil
-		}
-		return n
-	}
-
-	if n.route.Pfxlen() > pfx.Pfxlen() {
-		return nil
-	}
-
-	b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
-	if !b {
-		return n.l.get(pfx)
-	}
-	return n.h.get(pfx)
-}
-
-func (n *node) insert(route *Route) *node {
-	if *n.route.Prefix() == *route.Prefix() {
-		n.route.AddPaths(route.paths)
-		n.dummy = false
-		return n
-	}
-
-	// is pfx NOT a subnet of this node?
-	if !n.route.Prefix().Contains(route.Prefix()) {
-		route.bestPaths()
-		if route.Prefix().Contains(n.route.Prefix()) {
-			return n.insertBefore(route, n.route.Pfxlen()-n.skip-1)
-		}
-
-		return n.newSuperNode(route)
-	}
-
-	// pfx is a subnet of this node
-	b := getBitUint32(route.Prefix().Addr(), n.route.Pfxlen()+1)
-	if !b {
-		return n.insertLow(route, n.route.Prefix().Pfxlen())
-	}
-	return n.insertHigh(route, n.route.Pfxlen())
-}
-
-func (n *node) insertLow(route *Route, parentPfxLen uint8) *node {
-	if n.l == nil {
-		route.bestPaths()
-		n.l = newNode(route, route.Pfxlen()-parentPfxLen-1, false)
-		return n
-	}
-	n.l = n.l.insert(route)
-	return n
-}
-
-func (n *node) insertHigh(route *Route, parentPfxLen uint8) *node {
-	if n.h == nil {
-		route.bestPaths()
-		n.h = newNode(route, route.Pfxlen()-parentPfxLen-1, false)
-		return n
-	}
-	n.h = n.h.insert(route)
-	return n
-}
-
-func (n *node) newSuperNode(route *Route) *node {
-	superNet := route.Prefix().GetSupernet(n.route.Prefix())
-
-	pfxLenDiff := n.route.Pfxlen() - superNet.Pfxlen()
-	skip := n.skip - pfxLenDiff
-
-	pseudoNode := newNode(NewRoute(superNet, nil), skip, true)
-	pseudoNode.insertChildren(n, route)
-	return pseudoNode
-}
-
-func (n *node) insertChildren(old *node, new *Route) {
-	// Place the old node
-	b := getBitUint32(old.route.Prefix().Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l = old
-		n.l.skip = old.route.Pfxlen() - n.route.Pfxlen() - 1
-	} else {
-		n.h = old
-		n.h.skip = old.route.Pfxlen() - n.route.Pfxlen() - 1
-	}
-
-	// Place the new Prefix
-	newNode := newNode(new, new.Pfxlen()-n.route.Pfxlen()-1, false)
-	b = getBitUint32(new.Prefix().Addr(), n.route.Pfxlen()+1)
-	if !b {
-		n.l = newNode
-	} else {
-		n.h = newNode
-	}
-}
-
-func (n *node) insertBefore(route *Route, parentPfxLen uint8) *node {
-	tmp := n
-
-	pfxLenDiff := n.route.Pfxlen() - route.Pfxlen()
-	skip := n.skip - pfxLenDiff
-	new := newNode(route, skip, false)
-
-	b := getBitUint32(route.Prefix().Addr(), parentPfxLen)
-	if !b {
-		new.l = tmp
-		new.l.skip = tmp.route.Pfxlen() - route.Pfxlen() - 1
-	} else {
-		new.h = tmp
-		new.h.skip = tmp.route.Pfxlen() - route.Pfxlen() - 1
-	}
-
-	return new
-}
-
-// Dump dumps all routes in table rt into a slice
-func (rt *RT) Dump() []*Route {
-	res := make([]*Route, 0)
-	return rt.root.dump(res)
-}
-
-func (n *node) dump(res []*Route) []*Route {
-	if n == nil {
-		return res
-	}
-
-	if !n.dummy {
-		res = append(res, n.route)
-	}
-
-	res = n.l.dump(res)
-	res = n.h.dump(res)
-	return res
-}
-
-func getBitUint32(x uint32, pos uint8) bool {
-	return ((x) & (1 << (32 - pos))) != 0
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/routing_table_test.go b/vendor/github.com/bio-routing/bio-rd/rt/routing_table_test.go
deleted file mode 100644
index 6a80752c9d9047bf94e7a2ff9de3e8c59ce6eaf6..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/routing_table_test.go
+++ /dev/null
@@ -1,607 +0,0 @@
-package rt
-
-import (
-	"testing"
-
-	net "github.com/bio-routing/bio-rd/net"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestNew(t *testing.T) {
-	l := New()
-	if l == nil {
-		t.Errorf("New() returned nil")
-	}
-}
-
-func TestRemovePath(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*Route
-		remove   []*Route
-		expected []*Route
-	}{
-		{
-			name: "Remove a path that is the only one for a prefix",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-			remove: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-			expected: []*Route{
-				{
-					pfx: net.NewPfx(strAddr("10.0.0.0"), 9),
-					paths: []*Path{
-						{
-							Type:    BGPPathType,
-							BGPPath: &BGPPath{},
-						},
-					},
-				},
-				{
-					pfx: net.NewPfx(strAddr("10.128.0.0"), 9),
-					paths: []*Path{
-						{
-							Type:    BGPPathType,
-							BGPPath: &BGPPath{},
-						},
-					},
-				},
-			},
-		},
-		{
-			name: "Remove a path that is one of two for a prefix",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 1000,
-						},
-					},
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 2000,
-						},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-			remove: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type: BGPPathType,
-						BGPPath: &BGPPath{
-							LocalPref: 1000,
-						},
-					},
-				}),
-			},
-			expected: []*Route{
-				{
-					pfx: net.NewPfx(strAddr("10.0.0.0"), 8),
-					paths: []*Path{
-						{
-							Type: BGPPathType,
-							BGPPath: &BGPPath{
-								LocalPref: 2000,
-							},
-						},
-					},
-					activePaths: []*Path{
-						{
-							Type: BGPPathType,
-							BGPPath: &BGPPath{
-								LocalPref: 2000,
-							},
-						},
-					},
-				},
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-		},
-	}
-
-	for _, test := range tests {
-		rt := New()
-		for _, route := range test.routes {
-			rt.Insert(route)
-		}
-
-		for _, route := range test.remove {
-			rt.RemovePath(route)
-		}
-
-		res := rt.Dump()
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestRemovePfx(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*Route
-		remove   []*net.Prefix
-		expected []*Route
-	}{
-		{
-			name: "Remove non-existent prefix",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("100.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-			remove: []*net.Prefix{
-				net.NewPfx(0, 0),
-			},
-			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-				NewRoute(net.NewPfx(strAddr("100.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-		},
-		{
-			name: "Remove final prefix",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{
-					{
-						Type:    BGPPathType,
-						BGPPath: &BGPPath{},
-					},
-				}),
-			},
-			remove: []*net.Prefix{
-				net.NewPfx(strAddr("10.0.0.0"), 8),
-			},
-			expected: []*Route{},
-		},
-	}
-
-	for _, test := range tests {
-		lpm := New()
-		for _, route := range test.routes {
-			lpm.Insert(route)
-		}
-
-		for _, pfx := range test.remove {
-			lpm.RemovePfx(pfx)
-		}
-
-		res := lpm.Dump()
-		assert.Equal(t, test.expected, res)
-	}
-}
-
-func TestGetBitUint32(t *testing.T) {
-	tests := []struct {
-		name     string
-		input    uint32
-		offset   uint8
-		expected bool
-	}{
-		{
-			name:     "test 1",
-			input:    167772160, // 10.0.0.0
-			offset:   8,
-			expected: false,
-		},
-		{
-			name:     "test 2",
-			input:    184549376, // 11.0.0.0
-			offset:   8,
-			expected: true,
-		},
-	}
-
-	for _, test := range tests {
-		b := getBitUint32(test.input, test.offset)
-		if b != test.expected {
-			t.Errorf("%s: Unexpected failure: Bit %d of %d is %v. Expected %v", test.name, test.offset, test.input, b, test.expected)
-		}
-	}
-}
-
-func TestLPM(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*Route
-		needle   *net.Prefix
-		expected []*Route
-	}{
-		{
-			name:     "LPM for non-existent route",
-			routes:   []*Route{},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 32),
-			expected: nil,
-		},
-		{
-			name: "Positive LPM test",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(167772160, 32), // 10.0.0.0/32
-			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-			},
-		},
-		/*{
-			name: "Exact match",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(strAddr("10.0.0.0"), 10),
-			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-		},*/
-	}
-
-	for _, test := range tests {
-		rt := New()
-		for _, route := range test.routes {
-			rt.Insert(route)
-		}
-		assert.Equal(t, test.expected, rt.LPM(test.needle))
-	}
-}
-
-func TestGet(t *testing.T) {
-	tests := []struct {
-		name          string
-		moreSpecifics bool
-		routes        []*Route
-		needle        *net.Prefix
-		expected      []*Route
-	}{
-		{
-			name:          "Test 1: Search pfx and dump route + more specifics",
-			moreSpecifics: true,
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(strAddr("10.0.0.0"), 8),
-			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-			},
-		},
-		{
-			name: "Test 2: Search pfx and don't dump more specifics",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(strAddr("10.0.0.0"), 8),
-			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-			},
-		},
-		{
-			name:     "Test 3: Empty table",
-			routes:   []*Route{},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 32),
-			expected: nil,
-		},
-		{
-			name: "Test 4: Get Dummy",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 7),
-			expected: nil,
-		},
-		{
-			name: "Test 5",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 10), nil),
-			},
-			needle: net.NewPfx(strAddr("11.100.123.0"), 24),
-			expected: []*Route{
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-			},
-		},
-		{
-			name: "Test 4: Get nonexistent #1",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("11.100.123.0"), 24), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 10),
-			expected: nil,
-		},
-		{
-			name: "Test 4: Get nonexistent #2",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
-			},
-			needle:   net.NewPfx(strAddr("10.0.0.0"), 10),
-			expected: nil,
-		},
-	}
-
-	for _, test := range tests {
-		rt := New()
-		for _, route := range test.routes {
-			rt.Insert(route)
-		}
-		p := rt.Get(test.needle, test.moreSpecifics)
-
-		if p == nil {
-			if test.expected != nil {
-				t.Errorf("Unexpected nil result for test %q", test.name)
-			}
-			continue
-		}
-
-		assert.Equal(t, test.expected, p)
-	}
-}
-
-func TestInsert(t *testing.T) {
-	tests := []struct {
-		name     string
-		routes   []*Route
-		expected *node
-	}{
-		{
-			name: "Insert first node",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-			},
-			expected: &node{
-				route: &Route{
-					pfx:         net.NewPfx(strAddr("10.0.0.0"), 8),
-					activePaths: []*Path{},
-				},
-				skip: 8,
-			},
-		},
-		{
-			name: "Insert duplicate node",
-			routes: []*Route{
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-				NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), nil),
-			},
-			expected: &node{
-				route: &Route{
-					pfx:         net.NewPfx(strAddr("10.0.0.0"), 8),
-					activePaths: []*Path{},
-				},
-				skip: 8,
-			},
-		},
-		/*{
-			name: "Insert triangle",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8), // 10.0.0.0
-				net.NewPfx(167772160, 9), // 10.0.0.0
-				net.NewPfx(176160768, 9), // 10.128.0.0
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-				},
-				skip: 8,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 9), // 10.0.0.0
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(176160768, 9), // 10.128.0.0
-					},
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), // 10.0.0.0/8
-					},
-					skip: 16,
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes plus one child low",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-					l: &node{
-						skip: 1,
-						route: &Route{
-							pfx: net.NewPfx(167772160, 10), // 10.0.0.0/10
-						},
-						l: &node{
-							skip: 1,
-							route: &Route{
-								pfx: net.NewPfx(167772160, 12), // 10.0.0.0
-							},
-						},
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), // 10.0.0.0/8
-					},
-					skip: 16,
-				},
-			},
-		},
-		{
-			name: "Insert disjunct prefixes plus one child high",
-			prefixes: []*net.Prefix{
-				net.NewPfx(167772160, 8),  // 10.0.0.0
-				net.NewPfx(191134464, 24), // 11.100.123.0/24
-				net.NewPfx(167772160, 12), // 10.0.0.0
-				net.NewPfx(167772160, 10), // 10.0.0.0
-				net.NewPfx(191134592, 25), // 11.100.123.128/25
-			},
-			expected: &node{
-				route: &Route{
-					pfx: net.NewPfx(167772160, 7), // 10.0.0.0/7
-				},
-				skip:  7,
-				dummy: true,
-				l: &node{
-					route: &Route{
-						pfx: net.NewPfx(167772160, 8), // 10.0.0.0/8
-					},
-					l: &node{
-						skip: 1,
-						route: &Route{
-							pfx: net.NewPfx(167772160, 10), // 10.0.0.0/10
-						},
-						l: &node{
-							skip: 1,
-							route: &Route{
-								pfx: net.NewPfx(167772160, 12), // 10.0.0.0
-							},
-						},
-					},
-				},
-				h: &node{
-					route: &Route{
-						pfx: net.NewPfx(191134464, 24), //11.100.123.0/24
-					},
-					skip: 16,
-					h: &node{
-						route: &Route{
-							pfx: net.NewPfx(191134592, 25), //11.100.123.128/25
-						},
-					},
-				},
-			},
-		},*/
-	}
-
-	for _, test := range tests {
-		rt := New()
-		for _, route := range test.routes {
-			rt.Insert(route)
-		}
-
-		assert.Equal(t, test.expected, rt.root)
-	}
-}
-
-func strAddr(s string) uint32 {
-	ret, _ := net.StrToAddr(s)
-	return ret
-}
diff --git a/vendor/github.com/bio-routing/bio-rd/rt/static.go b/vendor/github.com/bio-routing/bio-rd/rt/static.go
deleted file mode 100644
index 72720a6548427ce7d0a1d88fbd9039731f96698e..0000000000000000000000000000000000000000
--- a/vendor/github.com/bio-routing/bio-rd/rt/static.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package rt
-
-type StaticPath struct {
-	NextHop uint32
-}
-
-func (r *Route) staticPathSelection() (res []*Path) {
-	if len(r.paths) == 1 {
-		copy(res, r.paths)
-		return res
-	}
-
-	for _, p := range r.paths {
-		if p.Type != StaticPathType {
-			continue
-		}
-
-		res = append(res, p)
-	}
-
-	return
-}