summaryrefslogtreecommitdiffhomepage
path: root/pkg/packet/bgp/validate_test.go
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-07-07 13:48:38 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-07-07 20:44:25 +0900
commitc4775c42510d1f1ddd55036dc19e982712fa6a0b (patch)
tree6ec8b61d4338c809e239e3003a2d32d480898e22 /pkg/packet/bgp/validate_test.go
parentb3079759aa13172fcb548a83da9a9653d8d5fed4 (diff)
follow Standard Go Project Layout
https://github.com/golang-standards/project-layout Now you can see clearly what are private and public library code. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'pkg/packet/bgp/validate_test.go')
-rw-r--r--pkg/packet/bgp/validate_test.go423
1 files changed, 423 insertions, 0 deletions
diff --git a/pkg/packet/bgp/validate_test.go b/pkg/packet/bgp/validate_test.go
new file mode 100644
index 00000000..8bdec550
--- /dev/null
+++ b/pkg/packet/bgp/validate_test.go
@@ -0,0 +1,423 @@
+package bgp
+
+import (
+ "encoding/binary"
+ "net"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func bgpupdate() *BGPMessage {
+ aspath := []AsPathParamInterface{
+ NewAsPathParam(2, []uint16{65001}),
+ }
+
+ p := []PathAttributeInterface{
+ NewPathAttributeOrigin(1),
+ NewPathAttributeAsPath(aspath),
+ NewPathAttributeNextHop("192.168.1.1"),
+ }
+
+ n := []*IPAddrPrefix{NewIPAddrPrefix(24, "10.10.10.0")}
+ return NewBGPUpdateMessage(nil, p, n)
+}
+
+func bgpupdateV6() *BGPMessage {
+ aspath := []AsPathParamInterface{
+ NewAsPathParam(2, []uint16{65001}),
+ }
+
+ prefixes := []AddrPrefixInterface{NewIPv6AddrPrefix(100,
+ "fe80:1234:1234:5667:8967:af12:8912:1023")}
+
+ p := []PathAttributeInterface{
+ NewPathAttributeOrigin(1),
+ NewPathAttributeAsPath(aspath),
+ NewPathAttributeMpReachNLRI("1023::", prefixes),
+ }
+ return NewBGPUpdateMessage(nil, p, nil)
+}
+
+func Test_Validate_CapV4(t *testing.T) {
+ assert := assert.New(t)
+ message := bgpupdate().Body.(*BGPUpdate)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ require.NoError(t, err)
+ assert.Equal(true, res)
+}
+
+func Test_Validate_CapV6(t *testing.T) {
+ assert := assert.New(t)
+ message := bgpupdateV6().Body.(*BGPUpdate)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.NoError(err)
+ assert.True(res)
+
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Error(err)
+ assert.False(res)
+}
+
+func Test_Validate_OK(t *testing.T) {
+ assert := assert.New(t)
+ message := bgpupdate().Body.(*BGPUpdate)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ 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, []RouteFamily{RF_IPv4_UC,})
+// 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, []RouteFamily{RF_IPv4_UC,})
+// 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, []RouteFamily{RF_IPv4_UC,})
+// 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, []RouteFamily{RF_IPv4_UC,})
+// 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{byte(PathAttrFlags[BGP_ATTR_TYPE_ORIGIN]), 1, 1, 1}
+ origin := &PathAttributeOrigin{}
+ origin.DecodeFromBytes(originBytes)
+ message.PathAttributes = append(message.PathAttributes, origin)
+
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_ATTRIBUTE_DISCARD, e.ErrorHandling)
+ 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, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ missing, _ := binary.Uvarint(e.Data)
+ assert.Equal(uint64(1), missing)
+}
+
+func Test_Validate_mandatory_missing_nocheck(t *testing.T) {
+ assert := assert.New(t)
+ message := bgpupdate().Body.(*BGPUpdate)
+ message.PathAttributes = message.PathAttributes[1:]
+ message.NLRI = nil
+
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(true, res)
+ assert.NoError(err)
+}
+
+func Test_Validate_invalid_origin(t *testing.T) {
+ assert := assert.New(t)
+ message := bgpupdate().Body.(*BGPUpdate)
+ // origin needs to be well-known
+ originBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_ORIGIN]), 1, 1, 5}
+ origin := &PathAttributeOrigin{}
+ origin.DecodeFromBytes(originBytes)
+ message.PathAttributes[0] = origin
+
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ 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{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, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ 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{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, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ 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{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, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ 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, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_SESSION_RESET, e.ErrorHandling)
+ assert.Equal(unknownBytes, e.Data)
+}
+
+func Test_Validate_aspath(t *testing.T) {
+ assert := assert.New(t)
+ message := bgpupdate().Body.(*BGPUpdate)
+
+ // VALID AS_PATH
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false)
+ require.NoError(t, err)
+ assert.Equal(true, res)
+
+ // CONFED_SET
+ newAttrs := make([]PathAttributeInterface, 0)
+ attrs := message.PathAttributes
+ for _, attr := range attrs {
+ if _, y := attr.(*PathAttributeAsPath); y {
+ aspath := []AsPathParamInterface{
+ NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65001}),
+ }
+ newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath))
+ } else {
+ newAttrs = append(newAttrs, attr)
+ }
+ }
+
+ message.PathAttributes = newAttrs
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e := err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ assert.Nil(e.Data)
+
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e = err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
+ assert.Nil(e.Data)
+
+ // CONFED_SEQ
+ newAttrs = make([]PathAttributeInterface, 0)
+ attrs = message.PathAttributes
+ for _, attr := range attrs {
+ if _, y := attr.(*PathAttributeAsPath); y {
+ aspath := []AsPathParamInterface{
+ NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65001}),
+ }
+ newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath))
+ } else {
+ newAttrs = append(newAttrs, attr)
+ }
+ }
+
+ message.PathAttributes = newAttrs
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e = err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
+ assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
+ assert.Nil(e.Data)
+
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true)
+ require.NoError(t, err)
+ assert.Equal(true, res)
+}
+
+func Test_Validate_flowspec(t *testing.T) {
+ assert := assert.New(t)
+ cmp := make([]FlowSpecComponentInterface, 0)
+ cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0")))
+ cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0")))
+ item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP)
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1}))
+ item2 := NewFlowSpecComponentItem(DEC_NUM_OP_GT_EQ, 20)
+ item3 := NewFlowSpecComponentItem(DEC_NUM_OP_AND|DEC_NUM_OP_LT_EQ, 30)
+ item4 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, 10)
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_PORT, []*FlowSpecComponentItem{item2, item3, item4}))
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_DST_PORT, []*FlowSpecComponentItem{item2, item3, item4}))
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_SRC_PORT, []*FlowSpecComponentItem{item2, item3, item4}))
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_TYPE, []*FlowSpecComponentItem{item2, item3, item4}))
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_CODE, []*FlowSpecComponentItem{item2, item3, item4}))
+ item5 := NewFlowSpecComponentItem(0, TCP_FLAG_ACK)
+ item6 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_AND|BITMASK_FLAG_OP_NOT, TCP_FLAG_URGENT)
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_TCP_FLAG, []*FlowSpecComponentItem{item5, item6}))
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_PKT_LEN, []*FlowSpecComponentItem{item2, item3, item4}))
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_DSCP, []*FlowSpecComponentItem{item2, item3, item4}))
+ isFragment := uint64(0x02)
+ item7 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_MATCH, isFragment)
+ cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_FRAGMENT, []*FlowSpecComponentItem{item7}))
+ n1 := NewFlowSpecIPv4Unicast(cmp)
+ a := NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
+ m := map[RouteFamily]BGPAddPathMode{RF_FS_IPv4_UC: BGP_ADD_PATH_NONE}
+ _, err := ValidateAttribute(a, m, false, false)
+ assert.Nil(err)
+
+ cmp = make([]FlowSpecComponentInterface, 0)
+ cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0")))
+ cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0")))
+ n1 = NewFlowSpecIPv4Unicast(cmp)
+ a = NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
+ // Swaps components order to reproduce the rules order violation.
+ n1.Value[0], n1.Value[1] = n1.Value[1], n1.Value[0]
+ _, err = ValidateAttribute(a, m, false, false)
+ assert.NotNil(err)
+}
+
+func TestValidateLargeCommunities(t *testing.T) {
+ assert := assert.New(t)
+ c1, err := ParseLargeCommunity("10:10:10")
+ assert.Nil(err)
+ c2, err := ParseLargeCommunity("10:10:10")
+ assert.Nil(err)
+ c3, err := ParseLargeCommunity("10:10:20")
+ assert.Nil(err)
+ a := NewPathAttributeLargeCommunities([]*LargeCommunity{c1, c2, c3})
+ assert.True(len(a.Values) == 3)
+ _, err = ValidateAttribute(a, nil, false, false)
+ assert.Nil(err)
+ assert.True(len(a.Values) == 2)
+}