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 -}