diff --git a/config/peer.go b/config/peer.go index 5bcfa49af2c68951ed5aecb12d2402e6284a42f2..5f151fe56c59ffa4ca410eb174745e755b15c09d 100644 --- a/config/peer.go +++ b/config/peer.go @@ -1,20 +1,21 @@ package config import ( - "net" "time" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" ) +// Peer defines the configuration for a BGP session type Peer struct { AdminEnabled bool ReconnectInterval time.Duration KeepAlive time.Duration HoldTime time.Duration - LocalAddress net.IP - PeerAddress net.IP + LocalAddress bnet.IP + PeerAddress bnet.IP LocalAS uint32 PeerAS uint32 Passive bool diff --git a/main.go b/main.go index 7c5bd7f1ba15450a5679688079307d3e0428e626..6b924601418c4335d5c7ccb7878eb4281d29710c 100644 --- a/main.go +++ b/main.go @@ -42,8 +42,8 @@ func main() { AdminEnabled: true, LocalAS: 65200, PeerAS: 65300, - PeerAddress: net.IP([]byte{172, 17, 0, 3}), - LocalAddress: net.IP([]byte{169, 254, 200, 0}), + PeerAddress: bnet.IPv4FromOctets(172, 17, 0, 3), + LocalAddress: bnet.IPv4FromOctets(169, 254, 200, 0), ReconnectInterval: time.Second * 15, HoldTime: time.Second * 90, KeepAlive: time.Second * 30, @@ -61,8 +61,8 @@ func main() { AdminEnabled: true, LocalAS: 65200, PeerAS: 65100, - PeerAddress: net.IP([]byte{172, 17, 0, 2}), - LocalAddress: net.IP([]byte{169, 254, 100, 1}), + PeerAddress: bnet.IPv4FromOctets(172, 17, 0, 2), + LocalAddress: bnet.IPv4FromOctets(169, 254, 100, 1), ReconnectInterval: time.Second * 15, HoldTime: time.Second * 90, KeepAlive: time.Second * 30, diff --git a/net/ip.go b/net/ip.go index 143505ca49eb2d2868bc31ce4fee04b1a26ff3aa..46b7350dd8a10fe3fa2359073f2a6ce69874ea6b 100644 --- a/net/ip.go +++ b/net/ip.go @@ -2,6 +2,7 @@ package net import ( "fmt" + "net" ) // IP represents an IPv4 or IPv6 address @@ -45,9 +46,14 @@ func (ip *IP) ToUint32() uint32 { return uint32(^uint64(0) >> 32 & ip.lower) } +// Equal returns true if ip is equal to other +func (ip IP) Equal(other IP) bool { + return ip == other +} + // Compare compares two IP addresses (returns 0 if equal, -1 if `ip` is smaller than `other`, 1 if `ip` is greater than `other`) func (ip IP) Compare(other IP) int { - if ip == other { + if ip.Equal(other) { return 0 } @@ -133,3 +139,8 @@ func (ip IP) bytesIPv6() []byte { byte(ip.lower & 0x00000000000000FF), } } + +// ToNetIP converts the IP address in a `net.IP` +func (ip IP) ToNetIP() net.IP { + return net.IP(ip.Bytes()) +} diff --git a/net/ip_test.go b/net/ip_test.go index c6358d069b287bc539aab07fb837772ff95787c2..a10019322f390dab4890ffe2c3f4eafbd0ade8fb 100644 --- a/net/ip_test.go +++ b/net/ip_test.go @@ -2,6 +2,7 @@ package net import ( "math" + "net" "testing" "github.com/stretchr/testify/assert" @@ -254,3 +255,36 @@ func TestIPv6FromBlocks(t *testing.T) { }) } } + +func TestToNetIP(t *testing.T) { + tests := []struct { + name string + ip IP + expected net.IP + }{ + { + name: "IPv4", + ip: IPv4FromOctets(192, 168, 1, 1), + expected: net.IP{192, 168, 1, 1}, + }, + { + name: "IPv6", + ip: IPv6FromBlocks( + 0x2001, + 0x678, + 0x1e0, + 0x1234, + 0x5678, + 0xdead, + 0xbeef, + 0xcafe), + expected: net.IP{32, 1, 6, 120, 1, 224, 18, 52, 86, 120, 222, 173, 190, 239, 202, 254}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, test.ip.ToNetIP()) + }) + } +} diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go index e85bda8cc21d6c47ac2c300639177aab8623859f..991f1b60853631a7b88d7fbb38c0e81ff551cc6e 100644 --- a/protocols/bgp/server/fsm.go +++ b/protocols/bgp/server/fsm.go @@ -170,7 +170,7 @@ func (fsm *FSM) tcpConnector() error { for { select { case <-fsm.initiateCon: - c, err := net.DialTCP("tcp", &net.TCPAddr{IP: fsm.local}, &net.TCPAddr{IP: fsm.peer.addr, Port: BGPPORT}) + c, err := net.DialTCP("tcp", &net.TCPAddr{IP: fsm.local}, &net.TCPAddr{IP: fsm.peer.addr.ToNetIP(), Port: BGPPORT}) if err != nil { select { case fsm.conErrCh <- err: diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go index feaf1ee14badba4dae6ff8648a9308380c7db92a..40694d339c2b7b263b2c8b5ce8496fb5106a6bd4 100644 --- a/protocols/bgp/server/fsm_established.go +++ b/protocols/bgp/server/fsm_established.go @@ -73,7 +73,7 @@ func (s *establishedState) init() error { n := &routingtable.Neighbor{ Type: route.BGPPathType, - Address: bnet.IPv4(bnet.IPv4ToUint32(s.fsm.peer.addr)), + Address: s.fsm.peer.addr, IBGP: s.fsm.peer.localASN == s.fsm.peer.peerASN, LocalASN: s.fsm.peer.localASN, RouteServerClient: s.fsm.peer.routeServerClient, @@ -219,7 +219,7 @@ func (s *establishedState) updates(u *packet.BGPUpdate) { path := &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ - Source: bnet.IPv4(bnet.IPv4ToUint32(s.fsm.peer.addr)), + Source: s.fsm.peer.addr, EBGP: s.fsm.peer.localASN != s.fsm.peer.peerASN, }, } diff --git a/protocols/bgp/server/fsm_test.go b/protocols/bgp/server/fsm_test.go index 9cff29b3706dc30d11a1017a7d963d30bafcb1f2..2af938822e25b265831033c1b74fd690eef4e90d 100644 --- a/protocols/bgp/server/fsm_test.go +++ b/protocols/bgp/server/fsm_test.go @@ -1,7 +1,6 @@ package server import ( - "net" "sync" "testing" "time" @@ -10,12 +9,14 @@ import ( "github.com/bio-routing/bio-rd/routingtable/filter" "github.com/bio-routing/bio-rd/routingtable/locRIB" "github.com/stretchr/testify/assert" + + bnet "github.com/bio-routing/bio-rd/net" ) // TestFSM100Updates emulates receiving 100 BGP updates and withdraws. Checks route counts. func TestFSM100Updates(t *testing.T) { fsmA := newFSM2(&peer{ - addr: net.ParseIP("169.254.100.100"), + addr: bnet.IPv4FromOctets(169, 254, 100, 100), rib: locRIB.New(), importFilter: filter.NewAcceptAllFilter(), exportFilter: filter.NewAcceptAllFilter(), diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go index 125393fb8fbfbfb5ed4bb626a5bc0aa352094d82..2772903061d6180c6d49ff48c70e3f96af4dfc33 100644 --- a/protocols/bgp/server/peer.go +++ b/protocols/bgp/server/peer.go @@ -1,11 +1,11 @@ package server import ( - "net" "sync" "time" "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/protocols/bgp/packet" "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" @@ -13,14 +13,14 @@ import ( ) type PeerInfo struct { - PeerAddr net.IP + PeerAddr bnet.IP PeerASN uint32 LocalASN uint32 } type peer struct { server *bgpServer - addr net.IP + addr bnet.IP peerASN uint32 localASN uint32 @@ -184,7 +184,7 @@ func filterOrDefault(f *filter.Filter) *filter.Filter { } // GetAddr returns the IP address of the peer -func (p *peer) GetAddr() net.IP { +func (p *peer) GetAddr() bnet.IP { return p.addr } diff --git a/protocols/bgp/server/server_test.go b/protocols/bgp/server/server_test.go index baf30a19344cb12c284ec22eb364809d7dc4cd72..fffe879ce078deaa77a6a795d357f64ef74e3796 100644 --- a/protocols/bgp/server/server_test.go +++ b/protocols/bgp/server/server_test.go @@ -1,7 +1,6 @@ package server import ( - "net" "testing" "time" @@ -9,6 +8,8 @@ import ( "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" "github.com/bio-routing/bio-rd/routingtable/locRIB" + + bnet "github.com/bio-routing/bio-rd/net" ) func TestBgpServerPeerSnapshot(t *testing.T) { @@ -30,8 +31,8 @@ func TestBgpServerPeerSnapshot(t *testing.T) { pc := config.Peer{ AdminEnabled: true, PeerAS: 65300, - PeerAddress: net.IP([]byte{169, 254, 200, 1}), - LocalAddress: net.IP([]byte{169, 254, 200, 0}), + PeerAddress: bnet.IPv4FromOctets(169, 254, 200, 1), + LocalAddress: bnet.IPv4FromOctets(169, 254, 200, 0), ReconnectInterval: time.Second * 15, HoldTime: time.Second * 90, KeepAlive: time.Second * 30, @@ -56,7 +57,7 @@ func TestBgpServerPeerSnapshot(t *testing.T) { break } - if want, got := net.ParseIP("169.254.200.1"), peer.PeerAddr; !want.Equal(got) { + if want, got := bnet.IPv4FromOctets(169, 254, 200, 1), peer.PeerAddr; !want.Equal(got) { t.Errorf("PeerAddr: got %v, want %v", got, want) } if want, got := uint32(65300), peer.PeerASN; want != got {