Skip to content
Snippets Groups Projects
Commit 423a5d10 authored by Oliver Herms's avatar Oliver Herms
Browse files

Adding route mirroring

parent bdb10878
Branches
Tags
No related merge requests found
...@@ -32,6 +32,8 @@ go_test( ...@@ -32,6 +32,8 @@ go_test(
"peer_down_test.go", "peer_down_test.go",
"peer_up_test.go", "peer_up_test.go",
"per_peer_header_test.go", "per_peer_header_test.go",
"route_mirroring_test.go",
"route_monitoring_test.go",
"stats_report_test.go", "stats_report_test.go",
"termination_message_test.go", "termination_message_test.go",
], ],
......
...@@ -5,11 +5,8 @@ import ( ...@@ -5,11 +5,8 @@ import (
"fmt" "fmt"
) )
type Msg interface {
MsgType() uint8
}
const ( const (
// MinLen is the minimal length of a BMP message
MinLen = 6 MinLen = 6
RouteMonitoringType = 0 RouteMonitoringType = 0
...@@ -25,8 +22,16 @@ const ( ...@@ -25,8 +22,16 @@ const (
ErroredPDU = 0 ErroredPDU = 0
MessageLost = 1 MessageLost = 1
// BMPVersion is the supported BMP version
BMPVersion = 3
) )
// Msg is an interface that every BMP message must fulfill
type Msg interface {
MsgType() uint8
}
// Decode decodes a BMP message // Decode decodes a BMP message
func Decode(msg []byte) (Msg, error) { func Decode(msg []byte) (Msg, error) {
buf := bytes.NewBuffer(msg) buf := bytes.NewBuffer(msg)
...@@ -36,13 +41,18 @@ func Decode(msg []byte) (Msg, error) { ...@@ -36,13 +41,18 @@ func Decode(msg []byte) (Msg, error) {
return nil, fmt.Errorf("Unable to decode common header: %v", err) return nil, fmt.Errorf("Unable to decode common header: %v", err)
} }
if ch.Version != 3 { if ch.Version != BMPVersion {
return nil, fmt.Errorf("Unsupported BMP version: %d", ch.Version) return nil, fmt.Errorf("Unsupported BMP version: %d", ch.Version)
} }
switch ch.MsgType { switch ch.MsgType {
case RouteMonitoringType: case RouteMonitoringType:
rm, err := decodeRouteMonitoringMsg(buf, ch)
if err != nil {
return nil, fmt.Errorf("Unable to decode route monitoring message: %v", err)
}
return rm, err
case StatisticsReportType: case StatisticsReportType:
sr, err := decodeStatsReport(buf, ch) sr, err := decodeStatsReport(buf, ch)
if err != nil { if err != nil {
......
package packet
import (
"bytes"
"fmt"
)
// RouteMirroringMsg represents a route mirroring message
type RouteMirroringMsg struct {
CommonHeader *CommonHeader
PerPeerHeader *PerPeerHeader
TLVs []*InformationTLV
}
func decodeRouteMirroringMsg(buf *bytes.Buffer, ch *CommonHeader) (*RouteMirroringMsg, error) {
rm := &RouteMirroringMsg{
CommonHeader: ch,
}
pph, err := decodePerPeerHeader(buf)
if err != nil {
return nil, fmt.Errorf("Unable to decode per peer header: %v", err)
}
rm.PerPeerHeader = pph
toRead := buf.Len()
read := 0
for read < toRead {
tlv, err := decodeInformationTLV(buf)
if err != nil {
return nil, fmt.Errorf("Unable to decode TLV: %v", err)
}
rm.TLVs = append(rm.TLVs, tlv)
read += int(tlv.InformationLength) + MinInformationTLVLen
}
return rm, nil
}
package packet
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
)
func TestDecodeRouteMirroringMsg(t *testing.T) {
tests := []struct {
name string
input []byte
ch *CommonHeader
wantFail bool
expected *RouteMirroringMsg
}{
{
name: "Full",
input: []byte{
1,
2,
0, 0, 0, 3,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
0, 0, 200, 124,
0, 0, 0, 123,
0, 0, 0, 100,
0, 0, 0, 200,
0, 1, 0, 2, 100, 200,
0, 1, 0, 2, 100, 200,
},
ch: &CommonHeader{
MsgLength: CommonHeaderLen + PerPeerHeaderLen + 12,
},
wantFail: false,
expected: &RouteMirroringMsg{
CommonHeader: &CommonHeader{
MsgLength: CommonHeaderLen + PerPeerHeaderLen + 12,
},
PerPeerHeader: &PerPeerHeader{
PeerType: 1,
PeerFlags: 2,
PeerDistinguisher: 3,
PeerAddress: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
PeerAS: 51324,
PeerBGPID: 123,
Timestamp: 100,
TimestampMicroSeconds: 200,
},
TLVs: []*InformationTLV{
{
InformationType: 1,
InformationLength: 2,
Information: []byte{100, 200},
},
{
InformationType: 1,
InformationLength: 2,
Information: []byte{100, 200},
},
},
},
},
{
name: "Incomplete",
input: []byte{
1,
2,
0, 0, 0, 3,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
0, 0, 200, 124,
},
ch: &CommonHeader{
MsgLength: CommonHeaderLen + PerPeerHeaderLen + 12,
},
wantFail: true,
},
{
name: "Incomplete TLV",
input: []byte{
1,
2,
0, 0, 0, 3,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
0, 0, 200, 124,
0, 0, 0, 123,
0, 0, 0, 100,
0, 0, 0, 200,
0, 1, 0, 2, 100, 200,
0, 1, 0, 2,
},
ch: &CommonHeader{
MsgLength: CommonHeaderLen + PerPeerHeaderLen + 12,
},
wantFail: true,
},
}
for _, test := range tests {
buf := bytes.NewBuffer(test.input)
r, err := decodeRouteMirroringMsg(buf, test.ch)
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.Equalf(t, test.expected, r, "Test %q", test.name)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment