diff options
Diffstat (limited to 'packet/validate_test.go')
-rw-r--r-- | packet/validate_test.go | 217 |
1 files changed, 213 insertions, 4 deletions
diff --git a/packet/validate_test.go b/packet/validate_test.go index 3bdb0949..801c3868 100644 --- a/packet/validate_test.go +++ b/packet/validate_test.go @@ -1,11 +1,13 @@ package bgp import ( + "encoding/binary" "github.com/stretchr/testify/assert" + "net" "testing" ) -func update1() *BGPMessage { +func bgpupdate() *BGPMessage { aspath := []AsPathParamInterface{ NewAsPathParam(2, []uint16{65001}), } @@ -21,9 +23,216 @@ func update1() *BGPMessage { } func Test_Validate_OK(t *testing.T) { - message := update1().Body.(*BGPUpdate) + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) res, err := ValidateUpdateMsg(message) - assert.Equal(t, true, res) - assert.NoError(t, err) + assert.Equal(true, res) + assert.NoError(err) } + +func Test_Validate_wellknown_but_nontransitive(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + + originBytes := []byte{0, 1, 1, 1} // 0 means Flags + origin := &PathAttributeOrigin{} + origin.DecodeFromBytes(originBytes) + message.PathAttributes[0] = origin + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) + assert.Equal(originBytes, e.Data) +} + +func Test_Validate_wellknown_but_partial(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + + originBytes := []byte{BGP_ATTR_FLAG_PARTIAL, 1, 1, 1} + origin := &PathAttributeOrigin{} + origin.DecodeFromBytes(originBytes) + message.PathAttributes[0] = origin + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) + assert.Equal(originBytes, e.Data) +} + +func Test_Validate_optional_nontransitive_but_partial(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + f := BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_PARTIAL + originBytes := []byte{byte(f), 1, 1, 1} + origin := &PathAttributeOrigin{} + origin.DecodeFromBytes(originBytes) + message.PathAttributes[0] = origin + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) + assert.Equal(originBytes, e.Data) +} + +func Test_Validate_flag_mismatch(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + f := BGP_ATTR_FLAG_OPTIONAL + // origin needs to be well-known + originBytes := []byte{byte(f), 1, 1, 1} + origin := &PathAttributeOrigin{} + origin.DecodeFromBytes(originBytes) + message.PathAttributes[0] = origin + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) + assert.Equal(originBytes, e.Data) +} + +func Test_Validate_duplicate_attribute(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + // duplicate origin path attribute + originBytes := []byte{pathAttrFlags[BGP_ATTR_TYPE_ORIGIN], 1, 1, 1} + origin := &PathAttributeOrigin{} + origin.DecodeFromBytes(originBytes) + message.PathAttributes = append(message.PathAttributes, origin) + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, e.SubTypeCode) + assert.Nil(e.Data) +} + +func Test_Validate_mandatory_missing(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + message.PathAttributes = message.PathAttributes[1:] + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE, e.SubTypeCode) + missing, _ := binary.Uvarint(e.Data) + assert.Equal(1, missing) +} + +func Test_Validate_invalid_origin(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + // origin needs to be well-known + originBytes := []byte{pathAttrFlags[BGP_ATTR_TYPE_ORIGIN], 1, 1, 5} + origin := &PathAttributeOrigin{} + origin.DecodeFromBytes(originBytes) + message.PathAttributes[0] = origin + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE, e.SubTypeCode) + assert.Equal(originBytes, e.Data) +} + +func Test_Validate_invalid_nexthop_zero(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + + // invalid nexthop + addr := net.ParseIP("0.0.0.1").To4() + nexthopBytes := []byte{pathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP], 3, 4} + nexthopBytes = append(nexthopBytes, addr...) + nexthop := &PathAttributeNextHop{} + nexthop.DecodeFromBytes(nexthopBytes) + message.PathAttributes[2] = nexthop + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE, e.SubTypeCode) + assert.Equal(nexthopBytes, e.Data) +} + +func Test_Validate_invalid_nexthop_lo(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + + // invalid nexthop + addr := net.ParseIP("127.0.0.1").To4() + nexthopBytes := []byte{pathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP], 3, 4} + nexthopBytes = append(nexthopBytes, addr...) + nexthop := &PathAttributeNextHop{} + nexthop.DecodeFromBytes(nexthopBytes) + message.PathAttributes[2] = nexthop + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE, e.SubTypeCode) + assert.Equal(nexthopBytes, e.Data) +} + +func Test_Validate_invalid_nexthop_de(t *testing.T) { + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + + // invalid nexthop + addr := net.ParseIP("224.0.0.1").To4() + nexthopBytes := []byte{pathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP], 3, 4} + nexthopBytes = append(nexthopBytes, addr...) + nexthop := &PathAttributeNextHop{} + nexthop.DecodeFromBytes(nexthopBytes) + message.PathAttributes[2] = nexthop + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE, e.SubTypeCode) + assert.Equal(nexthopBytes, e.Data) + +} + +func Test_Validate_unrecognized_well_known(t *testing.T) { + + assert := assert.New(t) + message := bgpupdate().Body.(*BGPUpdate) + f := BGP_ATTR_FLAG_TRANSITIVE + unknownBytes := []byte{byte(f), 30, 1, 1} + unknown := &PathAttributeUnknown{} + unknown.DecodeFromBytes(unknownBytes) + message.PathAttributes = append(message.PathAttributes, unknown) + + res, err := ValidateUpdateMsg(message) + assert.Equal(false, res) + assert.Error(err) + e := err.(*MessageError) + assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) + assert.Equal(BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE, e.SubTypeCode) + assert.Equal(unknownBytes, e.Data) +} |