github.com/osrg/gobgp/v3@v3.30.0/pkg/packet/bgp/validate_test.go (about)

     1  package bgp
     2  
     3  import (
     4  	"encoding/binary"
     5  	"net"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func bgpupdate() *BGPMessage {
    13  	aspath := []AsPathParamInterface{
    14  		NewAsPathParam(2, []uint16{65001}),
    15  	}
    16  
    17  	p := []PathAttributeInterface{
    18  		NewPathAttributeOrigin(1),
    19  		NewPathAttributeAsPath(aspath),
    20  		NewPathAttributeNextHop("192.168.1.1"),
    21  	}
    22  
    23  	n := []*IPAddrPrefix{NewIPAddrPrefix(24, "10.10.10.0")}
    24  	return NewBGPUpdateMessage(nil, p, n)
    25  }
    26  
    27  func bgpupdateV6() *BGPMessage {
    28  	aspath := []AsPathParamInterface{
    29  		NewAsPathParam(2, []uint16{65001}),
    30  	}
    31  
    32  	prefixes := []AddrPrefixInterface{NewIPv6AddrPrefix(100,
    33  		"fe80:1234:1234:5667:8967:af12:8912:1023")}
    34  
    35  	p := []PathAttributeInterface{
    36  		NewPathAttributeOrigin(1),
    37  		NewPathAttributeAsPath(aspath),
    38  		NewPathAttributeMpReachNLRI("1023::", prefixes),
    39  	}
    40  	return NewBGPUpdateMessage(nil, p, nil)
    41  }
    42  
    43  func Test_Validate_CapV4(t *testing.T) {
    44  	assert := assert.New(t)
    45  	message := bgpupdate().Body.(*BGPUpdate)
    46  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false, false)
    47  	assert.Equal(false, res)
    48  	assert.Error(err)
    49  
    50  	res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
    51  	require.NoError(t, err)
    52  	assert.Equal(true, res)
    53  }
    54  
    55  func Test_Validate_CapV6(t *testing.T) {
    56  	assert := assert.New(t)
    57  	message := bgpupdateV6().Body.(*BGPUpdate)
    58  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false, false)
    59  	assert.NoError(err)
    60  	assert.True(res)
    61  
    62  	res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
    63  	assert.Error(err)
    64  	assert.False(res)
    65  }
    66  
    67  func Test_Validate_OK(t *testing.T) {
    68  	assert := assert.New(t)
    69  	message := bgpupdate().Body.(*BGPUpdate)
    70  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
    71  	assert.Equal(true, res)
    72  	assert.NoError(err)
    73  
    74  }
    75  
    76  // func Test_Validate_wellknown_but_nontransitive(t *testing.T) {
    77  // 	assert := assert.New(t)
    78  // 	message := bgpupdate().Body.(*BGPUpdate)
    79  
    80  // 	originBytes := []byte{0, 1, 1, 1} // 0 means Flags
    81  // 	origin := &PathAttributeOrigin{}
    82  // 	origin.DecodeFromBytes(originBytes)
    83  // 	message.PathAttributes[0] = origin
    84  
    85  // 	res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,})
    86  // 	assert.Equal(false, res)
    87  // 	assert.Error(err)
    88  // 	e := err.(*MessageError)
    89  // 	assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode)
    90  // 	assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode)
    91  // 	assert.Equal(originBytes, e.Data)
    92  // }
    93  
    94  // func Test_Validate_wellknown_but_partial(t *testing.T) {
    95  // 	assert := assert.New(t)
    96  // 	message := bgpupdate().Body.(*BGPUpdate)
    97  
    98  // 	originBytes := []byte{BGP_ATTR_FLAG_PARTIAL, 1, 1, 1}
    99  // 	origin := &PathAttributeOrigin{}
   100  // 	origin.DecodeFromBytes(originBytes)
   101  // 	message.PathAttributes[0] = origin
   102  
   103  // 	res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,})
   104  // 	assert.Equal(false, res)
   105  // 	assert.Error(err)
   106  // 	e := err.(*MessageError)
   107  // 	assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode)
   108  // 	assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode)
   109  // 	assert.Equal(originBytes, e.Data)
   110  // }
   111  
   112  // func Test_Validate_optional_nontransitive_but_partial(t *testing.T) {
   113  // 	assert := assert.New(t)
   114  // 	message := bgpupdate().Body.(*BGPUpdate)
   115  // 	f := BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_PARTIAL
   116  // 	originBytes := []byte{byte(f), 1, 1, 1}
   117  // 	origin := &PathAttributeOrigin{}
   118  // 	origin.DecodeFromBytes(originBytes)
   119  // 	message.PathAttributes[0] = origin
   120  
   121  // 	res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,})
   122  // 	assert.Equal(false, res)
   123  // 	assert.Error(err)
   124  // 	e := err.(*MessageError)
   125  // 	assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode)
   126  // 	assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode)
   127  // 	assert.Equal(originBytes, e.Data)
   128  // }
   129  
   130  // func Test_Validate_flag_mismatch(t *testing.T) {
   131  // 	assert := assert.New(t)
   132  // 	message := bgpupdate().Body.(*BGPUpdate)
   133  // 	f := BGP_ATTR_FLAG_OPTIONAL
   134  // 	// origin needs to be well-known
   135  // 	originBytes := []byte{byte(f), 1, 1, 1}
   136  // 	origin := &PathAttributeOrigin{}
   137  // 	origin.DecodeFromBytes(originBytes)
   138  // 	message.PathAttributes[0] = origin
   139  
   140  // 	res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,})
   141  // 	assert.Equal(false, res)
   142  // 	assert.Error(err)
   143  // 	e := err.(*MessageError)
   144  // 	assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode)
   145  // 	assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode)
   146  // 	assert.Equal(originBytes, e.Data)
   147  // }
   148  
   149  func Test_Validate_duplicate_attribute(t *testing.T) {
   150  	assert := assert.New(t)
   151  	message := bgpupdate().Body.(*BGPUpdate)
   152  	// duplicate origin path attribute
   153  	originBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_ORIGIN]), 1, 1, 1}
   154  	origin := &PathAttributeOrigin{}
   155  	origin.DecodeFromBytes(originBytes)
   156  	message.PathAttributes = append(message.PathAttributes, origin)
   157  
   158  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   159  	assert.Equal(false, res)
   160  	assert.Error(err)
   161  	e := err.(*MessageError)
   162  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   163  	assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), e.SubTypeCode)
   164  	assert.Equal(ERROR_HANDLING_ATTRIBUTE_DISCARD, e.ErrorHandling)
   165  	assert.Nil(e.Data)
   166  }
   167  
   168  func Test_Validate_mandatory_missing(t *testing.T) {
   169  	assert := assert.New(t)
   170  	message := bgpupdate().Body.(*BGPUpdate)
   171  	message.PathAttributes = message.PathAttributes[1:]
   172  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   173  	assert.Equal(false, res)
   174  	assert.Error(err)
   175  	e := err.(*MessageError)
   176  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   177  	assert.Equal(uint8(BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode)
   178  	assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   179  	missing, _ := binary.Uvarint(e.Data)
   180  	assert.Equal(uint64(1), missing)
   181  }
   182  
   183  func Test_Validate_mandatory_missing_nocheck(t *testing.T) {
   184  	assert := assert.New(t)
   185  	message := bgpupdate().Body.(*BGPUpdate)
   186  	message.PathAttributes = message.PathAttributes[1:]
   187  	message.NLRI = nil
   188  
   189  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   190  	assert.Equal(true, res)
   191  	assert.NoError(err)
   192  }
   193  
   194  func Test_Validate_invalid_origin(t *testing.T) {
   195  	assert := assert.New(t)
   196  	message := bgpupdate().Body.(*BGPUpdate)
   197  	// origin needs to be well-known
   198  	originBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_ORIGIN]), 1, 1, 5}
   199  	origin := &PathAttributeOrigin{}
   200  	origin.DecodeFromBytes(originBytes)
   201  	message.PathAttributes[0] = origin
   202  
   203  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   204  	assert.Equal(false, res)
   205  	assert.Error(err)
   206  	e := err.(*MessageError)
   207  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   208  	assert.Equal(uint8(BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE), e.SubTypeCode)
   209  	assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   210  	assert.Equal(originBytes, e.Data)
   211  }
   212  
   213  func Test_Validate_invalid_nexthop_zero(t *testing.T) {
   214  	assert := assert.New(t)
   215  	message := bgpupdate().Body.(*BGPUpdate)
   216  
   217  	// invalid nexthop
   218  	addr := net.ParseIP("0.0.0.1").To4()
   219  	nexthopBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP]), 3, 4}
   220  	nexthopBytes = append(nexthopBytes, addr...)
   221  	nexthop := &PathAttributeNextHop{}
   222  	nexthop.DecodeFromBytes(nexthopBytes)
   223  	message.PathAttributes[2] = nexthop
   224  
   225  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   226  	assert.Equal(false, res)
   227  	assert.Error(err)
   228  	e := err.(*MessageError)
   229  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   230  	assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode)
   231  	assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   232  	assert.Equal(nexthopBytes, e.Data)
   233  }
   234  
   235  func Test_Validate_invalid_nexthop_lo(t *testing.T) {
   236  	tests := []struct {
   237  		desc              string
   238  		inLoopbackAllowed bool
   239  		wantErr           bool
   240  	}{{
   241  		desc:              "loopback-disallowed",
   242  		inLoopbackAllowed: false,
   243  		wantErr:           true,
   244  	}, {
   245  		desc:              "loopback-allowed",
   246  		inLoopbackAllowed: true,
   247  		wantErr:           false,
   248  	}}
   249  
   250  	for _, tt := range tests {
   251  		t.Run(tt.desc, func(t *testing.T) {
   252  			assert := assert.New(t)
   253  			message := bgpupdate().Body.(*BGPUpdate)
   254  
   255  			// invalid nexthop
   256  			addr := net.ParseIP("127.0.0.1").To4()
   257  			nexthopBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP]), 3, 4}
   258  			nexthopBytes = append(nexthopBytes, addr...)
   259  			nexthop := &PathAttributeNextHop{}
   260  			nexthop.DecodeFromBytes(nexthopBytes)
   261  			message.PathAttributes[2] = nexthop
   262  
   263  			res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, tt.inLoopbackAllowed)
   264  			if tt.wantErr {
   265  				assert.Equal(false, res)
   266  				assert.Error(err)
   267  				e := err.(*MessageError)
   268  				assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   269  				assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode)
   270  				assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   271  				assert.Equal(nexthopBytes, e.Data)
   272  			} else {
   273  				assert.Equal(true, res)
   274  				assert.NoError(err)
   275  			}
   276  		})
   277  	}
   278  }
   279  
   280  func Test_Validate_invalid_nexthop_de(t *testing.T) {
   281  	assert := assert.New(t)
   282  	message := bgpupdate().Body.(*BGPUpdate)
   283  
   284  	// invalid nexthop
   285  	addr := net.ParseIP("224.0.0.1").To4()
   286  	nexthopBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP]), 3, 4}
   287  	nexthopBytes = append(nexthopBytes, addr...)
   288  	nexthop := &PathAttributeNextHop{}
   289  	nexthop.DecodeFromBytes(nexthopBytes)
   290  	message.PathAttributes[2] = nexthop
   291  
   292  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   293  	assert.Equal(false, res)
   294  	assert.Error(err)
   295  	e := err.(*MessageError)
   296  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   297  	assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode)
   298  	assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   299  	assert.Equal(nexthopBytes, e.Data)
   300  
   301  }
   302  
   303  func Test_Validate_unrecognized_well_known(t *testing.T) {
   304  
   305  	assert := assert.New(t)
   306  	message := bgpupdate().Body.(*BGPUpdate)
   307  	f := BGP_ATTR_FLAG_TRANSITIVE
   308  	unknownBytes := []byte{byte(f), 30, 1, 1}
   309  	unknown := &PathAttributeUnknown{}
   310  	unknown.DecodeFromBytes(unknownBytes)
   311  	message.PathAttributes = append(message.PathAttributes, unknown)
   312  
   313  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false, false)
   314  	assert.Equal(false, res)
   315  	assert.Error(err)
   316  	e := err.(*MessageError)
   317  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   318  	assert.Equal(uint8(BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode)
   319  	assert.Equal(ERROR_HANDLING_SESSION_RESET, e.ErrorHandling)
   320  	assert.Equal(unknownBytes, e.Data)
   321  }
   322  
   323  func Test_Validate_aspath(t *testing.T) {
   324  	assert := assert.New(t)
   325  	message := bgpupdate().Body.(*BGPUpdate)
   326  
   327  	// VALID AS_PATH
   328  	res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false, false)
   329  	require.NoError(t, err)
   330  	assert.Equal(true, res)
   331  
   332  	// CONFED_SET
   333  	newAttrs := make([]PathAttributeInterface, 0)
   334  	attrs := message.PathAttributes
   335  	for _, attr := range attrs {
   336  		if _, y := attr.(*PathAttributeAsPath); y {
   337  			aspath := []AsPathParamInterface{
   338  				NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65001}),
   339  			}
   340  			newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath))
   341  		} else {
   342  			newAttrs = append(newAttrs, attr)
   343  		}
   344  	}
   345  
   346  	message.PathAttributes = newAttrs
   347  	res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false, false)
   348  	assert.Equal(false, res)
   349  	assert.Error(err)
   350  	e := err.(*MessageError)
   351  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   352  	assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
   353  	assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   354  	assert.Nil(e.Data)
   355  
   356  	res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true, false)
   357  	assert.Equal(false, res)
   358  	assert.Error(err)
   359  	e = err.(*MessageError)
   360  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   361  	assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
   362  	assert.Nil(e.Data)
   363  
   364  	// CONFED_SEQ
   365  	newAttrs = make([]PathAttributeInterface, 0)
   366  	attrs = message.PathAttributes
   367  	for _, attr := range attrs {
   368  		if _, y := attr.(*PathAttributeAsPath); y {
   369  			aspath := []AsPathParamInterface{
   370  				NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65001}),
   371  			}
   372  			newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath))
   373  		} else {
   374  			newAttrs = append(newAttrs, attr)
   375  		}
   376  	}
   377  
   378  	message.PathAttributes = newAttrs
   379  	res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false, false)
   380  	assert.Equal(false, res)
   381  	assert.Error(err)
   382  	e = err.(*MessageError)
   383  	assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
   384  	assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
   385  	assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
   386  	assert.Nil(e.Data)
   387  
   388  	res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true, false)
   389  	require.NoError(t, err)
   390  	assert.Equal(true, res)
   391  }
   392  
   393  func Test_Validate_flowspec(t *testing.T) {
   394  	assert := assert.New(t)
   395  	cmp := make([]FlowSpecComponentInterface, 0)
   396  	cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0")))
   397  	cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0")))
   398  	item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP)
   399  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1}))
   400  	item2 := NewFlowSpecComponentItem(DEC_NUM_OP_GT_EQ, 20)
   401  	item3 := NewFlowSpecComponentItem(DEC_NUM_OP_AND|DEC_NUM_OP_LT_EQ, 30)
   402  	item4 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, 10)
   403  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_PORT, []*FlowSpecComponentItem{item2, item3, item4}))
   404  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_DST_PORT, []*FlowSpecComponentItem{item2, item3, item4}))
   405  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_SRC_PORT, []*FlowSpecComponentItem{item2, item3, item4}))
   406  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_TYPE, []*FlowSpecComponentItem{item2, item3, item4}))
   407  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_CODE, []*FlowSpecComponentItem{item2, item3, item4}))
   408  	item5 := NewFlowSpecComponentItem(0, TCP_FLAG_ACK)
   409  	item6 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_AND|BITMASK_FLAG_OP_NOT, TCP_FLAG_URGENT)
   410  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_TCP_FLAG, []*FlowSpecComponentItem{item5, item6}))
   411  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_PKT_LEN, []*FlowSpecComponentItem{item2, item3, item4}))
   412  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_DSCP, []*FlowSpecComponentItem{item2, item3, item4}))
   413  	isFragment := uint64(0x02)
   414  	item7 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_MATCH, isFragment)
   415  	cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_FRAGMENT, []*FlowSpecComponentItem{item7}))
   416  	n1 := NewFlowSpecIPv4Unicast(cmp)
   417  	a := NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
   418  	m := map[RouteFamily]BGPAddPathMode{RF_FS_IPv4_UC: BGP_ADD_PATH_NONE}
   419  	_, err := ValidateAttribute(a, m, false, false, false)
   420  	assert.Nil(err)
   421  
   422  	cmp = make([]FlowSpecComponentInterface, 0)
   423  	cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0")))
   424  	cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0")))
   425  	n1 = NewFlowSpecIPv4Unicast(cmp)
   426  	a = NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
   427  	// Swaps components order to reproduce the rules order violation.
   428  	n1.Value[0], n1.Value[1] = n1.Value[1], n1.Value[0]
   429  	_, err = ValidateAttribute(a, m, false, false, false)
   430  	assert.NotNil(err)
   431  }
   432  
   433  func TestValidateLargeCommunities(t *testing.T) {
   434  	assert := assert.New(t)
   435  	c1, err := ParseLargeCommunity("10:10:10")
   436  	assert.Nil(err)
   437  	c2, err := ParseLargeCommunity("10:10:10")
   438  	assert.Nil(err)
   439  	c3, err := ParseLargeCommunity("10:10:20")
   440  	assert.Nil(err)
   441  	a := NewPathAttributeLargeCommunities([]*LargeCommunity{c1, c2, c3})
   442  	assert.True(len(a.Values) == 3)
   443  	_, err = ValidateAttribute(a, nil, false, false, false)
   444  	assert.Nil(err)
   445  	assert.True(len(a.Values) == 2)
   446  }
   447  
   448  func FuzzParseLargeCommunity(f *testing.F) {
   449  
   450  	f.Fuzz(func(t *testing.T, data string) {
   451  		ParseLargeCommunity(data)
   452  	})
   453  }