diff --git a/config/peer.go b/config/peer.go new file mode 100644 index 0000000000000000000000000000000000000000..8f7692b085e39fae5b1ec998233bf2d174a84581 --- /dev/null +++ b/config/peer.go @@ -0,0 +1,17 @@ +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/config/server.go b/config/server.go new file mode 100644 index 0000000000000000000000000000000000000000..fed6f908365319418abb5b5dee1290ec666d418e --- /dev/null +++ b/config/server.go @@ -0,0 +1,136 @@ +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/config/server_test.go b/config/server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d44821f8fa1ed70bd101e0a07cbb8a114d610778 --- /dev/null +++ b/config/server_test.go @@ -0,0 +1,80 @@ +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/main.go b/main.go index 108c326eb83ecb4054c7f2e98407936c94211f62..fbf3692f7b40265edd9b39c6d151809bd130b2e4 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,8 @@ import ( "github.com/sirupsen/logrus" - "github.com/taktv6/tbgp/config" - "github.com/taktv6/tbgp/server" + "github.com/bio-routing/bio-rd/config" + "github.com/bio-routing/bio-rd/protocols/bgp/server" ) func main() { diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go index 6b49d6044abf6e3ffad4ea31f6c762d9d6a31686..de4fca43bf829e5aa5e99713f5f4110896b35978 100644 --- a/protocols/bgp/server/fsm.go +++ b/protocols/bgp/server/fsm.go @@ -7,12 +7,11 @@ import ( "net" "time" - "github.com/taktv6/tbgp/rt" - + "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/tbgp/config" - tnet "github.com/taktv6/tbgp/net" - "github.com/taktv6/tbgp/packet" "github.com/taktv6/tflow2/convert" tomb "gopkg.in/tomb.v2" ) diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go index d6ac7855bbc9a6381c0e7766d60f444bcad34383..02051838f9d3e496ff7e4dfe590786f3e7b193f1 100644 --- a/protocols/bgp/server/peer.go +++ b/protocols/bgp/server/peer.go @@ -3,7 +3,7 @@ package server import ( "net" - "github.com/taktv6/tbgp/config" + "github.com/bio-routing/bio-rd/config" ) type Peer struct { diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go index 3bc9b19368c5c309921f4f6c806fbb6d45fe7603..6bf46ac7634f684b5d060ea2e5ffd7417819e417 100644 --- a/protocols/bgp/server/server.go +++ b/protocols/bgp/server/server.go @@ -6,9 +6,9 @@ import ( "net" "strings" + "github.com/bio-routing/bio-rd/config" + "github.com/bio-routing/bio-rd/protocols/bgp/packet" log "github.com/sirupsen/logrus" - "github.com/taktv6/tbgp/config" - "github.com/taktv6/tbgp/packet" ) const ( diff --git a/rt/routing_table_test.go b/rt/routing_table_test.go index a1de4f03d372cef1dcb7af517f20b27f350547f7..e4f4e993bc7162074d8860f8e8be42334087cfb7 100644 --- a/rt/routing_table_test.go +++ b/rt/routing_table_test.go @@ -30,46 +30,46 @@ func TestRemovePath(t *testing.T) { BGPPath: &BGPPath{}, }, }), - NewRoute(net.NewPfx(167772160, 9), []*Path{ + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.0.0.0/9 - NewRoute(net.NewPfx(176160768, 9), []*Path{ + }), + NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.128.0.0/9 + }), }, remove: []*Route{ - NewRoute(net.NewPfx(167772160, 8), []*Path{ + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.0.0.0 + }), }, expected: []*Route{ - NewRoute(net.NewPfx(167772160, 9), []*Path{ + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.0.0.0 - NewRoute(net.NewPfx(176160768, 9), []*Path{ + }), + NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.128.0.0 + }), }, }, { name: "Remove a path that is one of two for a prefix", routes: []*Route{ - NewRoute(net.NewPfx(167772160, 8), []*Path{ + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{ @@ -82,51 +82,51 @@ func TestRemovePath(t *testing.T) { LocalPref: 2000, }, }, - }), // 10.0.0.0/8 - NewRoute(net.NewPfx(167772160, 9), []*Path{ + }), + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.0.0.0/9 - NewRoute(net.NewPfx(176160768, 9), []*Path{ + }), + NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.128.0.0/9 + }), }, remove: []*Route{ - NewRoute(net.NewPfx(167772160, 8), []*Path{ + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{ LocalPref: 1000, }, }, - }), // 10.0.0.0 + }), }, expected: []*Route{ - NewRoute(net.NewPfx(167772160, 8), []*Path{ + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{ LocalPref: 2000, }, }, - }), // 10.0.0.0/8 - NewRoute(net.NewPfx(167772160, 9), []*Path{ + }), + NewRoute(net.NewPfx(strAddr("10.0.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.0.0.0/9 - NewRoute(net.NewPfx(176160768, 9), []*Path{ + }), + NewRoute(net.NewPfx(strAddr("10.128.0.0"), 9), []*Path{ { Type: BGPPathType, BGPPath: &BGPPath{}, }, - }), // 10.128.0.0/9 + }), }, }, }