summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gobgp/cmd/global.go27
-rw-r--r--packet/bgp/bgp.go58
-rw-r--r--packet/bgp/bgp_test.go17
-rw-r--r--packet/bgp/validate_test.go6
-rw-r--r--table/path.go33
5 files changed, 66 insertions, 75 deletions
diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go
index 4922875a..6ab87024 100644
--- a/gobgp/cmd/global.go
+++ b/gobgp/cmd/global.go
@@ -25,10 +25,11 @@ import (
"strings"
"time"
+ "github.com/spf13/cobra"
+
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
- "github.com/spf13/cobra"
)
type ExtCommType int
@@ -334,34 +335,28 @@ func ParseFlowSpecArgs(rf bgp.RouteFamily, args []string, rd bgp.RouteDistinguis
return nil, nil, fmt.Errorf("invalid format")
}
matchArgs := args[1:thenPos]
- cmp, err := bgp.ParseFlowSpecComponents(rf, strings.Join(matchArgs, " "))
+
+ rules, err := bgp.ParseFlowSpecComponents(rf, strings.Join(matchArgs, " "))
if err != nil {
return nil, nil, err
}
+
var nlri bgp.AddrPrefixInterface
- var fnlri *bgp.FlowSpecNLRI
switch rf {
case bgp.RF_FS_IPv4_UC:
- nlri = bgp.NewFlowSpecIPv4Unicast(cmp)
- fnlri = &nlri.(*bgp.FlowSpecIPv4Unicast).FlowSpecNLRI
+ nlri = bgp.NewFlowSpecIPv4Unicast(rules)
case bgp.RF_FS_IPv6_UC:
- nlri = bgp.NewFlowSpecIPv6Unicast(cmp)
- fnlri = &nlri.(*bgp.FlowSpecIPv6Unicast).FlowSpecNLRI
+ nlri = bgp.NewFlowSpecIPv6Unicast(rules)
case bgp.RF_FS_IPv4_VPN:
- nlri = bgp.NewFlowSpecIPv4VPN(rd, cmp)
- fnlri = &nlri.(*bgp.FlowSpecIPv4VPN).FlowSpecNLRI
+ nlri = bgp.NewFlowSpecIPv4VPN(rd, rules)
case bgp.RF_FS_IPv6_VPN:
- nlri = bgp.NewFlowSpecIPv6VPN(rd, cmp)
- fnlri = &nlri.(*bgp.FlowSpecIPv6VPN).FlowSpecNLRI
+ nlri = bgp.NewFlowSpecIPv6VPN(rd, rules)
case bgp.RF_FS_L2_VPN:
- nlri = bgp.NewFlowSpecL2VPN(rd, cmp)
- fnlri = &nlri.(*bgp.FlowSpecL2VPN).FlowSpecNLRI
+ nlri = bgp.NewFlowSpecL2VPN(rd, rules)
default:
return nil, nil, fmt.Errorf("invalid route family")
}
- var comms table.FlowSpecComponents
- comms = fnlri.Value
- sort.Sort(comms)
+
return nlri, args[thenPos+1:], nil
}
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index ef31817c..987bf328 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -4027,6 +4027,10 @@ func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...*
n.Value = append(n.Value, i)
}
+ // Sort Traffic Filtering Rules in types order to avoid the unordered rules
+ // are determined different.
+ sort.SliceStable(n.Value, func(i, j int) bool { return n.Value[i].Type() < n.Value[j].Type() })
+
return nil
}
@@ -4246,7 +4250,13 @@ func (n *FlowSpecIPv4Unicast) DecodeFromBytes(data []byte, options ...*Marshalli
}
func NewFlowSpecIPv4Unicast(value []FlowSpecComponentInterface) *FlowSpecIPv4Unicast {
- return &FlowSpecIPv4Unicast{FlowSpecNLRI{Value: value, rf: RF_FS_IPv4_UC}}
+ sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() })
+ return &FlowSpecIPv4Unicast{
+ FlowSpecNLRI: FlowSpecNLRI{
+ Value: value,
+ rf: RF_FS_IPv4_UC,
+ },
+ }
}
type FlowSpecIPv4VPN struct {
@@ -4258,7 +4268,14 @@ func (n *FlowSpecIPv4VPN) DecodeFromBytes(data []byte, options ...*MarshallingOp
}
func NewFlowSpecIPv4VPN(rd RouteDistinguisherInterface, value []FlowSpecComponentInterface) *FlowSpecIPv4VPN {
- return &FlowSpecIPv4VPN{FlowSpecNLRI{Value: value, rf: RF_FS_IPv4_VPN, rd: rd}}
+ sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() })
+ return &FlowSpecIPv4VPN{
+ FlowSpecNLRI: FlowSpecNLRI{
+ Value: value,
+ rf: RF_FS_IPv4_VPN,
+ rd: rd,
+ },
+ }
}
type FlowSpecIPv6Unicast struct {
@@ -4270,10 +4287,13 @@ func (n *FlowSpecIPv6Unicast) DecodeFromBytes(data []byte, options ...*Marshalli
}
func NewFlowSpecIPv6Unicast(value []FlowSpecComponentInterface) *FlowSpecIPv6Unicast {
- return &FlowSpecIPv6Unicast{FlowSpecNLRI{
- Value: value,
- rf: RF_FS_IPv6_UC,
- }}
+ sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() })
+ return &FlowSpecIPv6Unicast{
+ FlowSpecNLRI: FlowSpecNLRI{
+ Value: value,
+ rf: RF_FS_IPv6_UC,
+ },
+ }
}
type FlowSpecIPv6VPN struct {
@@ -4285,11 +4305,14 @@ func (n *FlowSpecIPv6VPN) DecodeFromBytes(data []byte, options ...*MarshallingOp
}
func NewFlowSpecIPv6VPN(rd RouteDistinguisherInterface, value []FlowSpecComponentInterface) *FlowSpecIPv6VPN {
- return &FlowSpecIPv6VPN{FlowSpecNLRI{
- Value: value,
- rf: RF_FS_IPv6_VPN,
- rd: rd,
- }}
+ sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() })
+ return &FlowSpecIPv6VPN{
+ FlowSpecNLRI: FlowSpecNLRI{
+ Value: value,
+ rf: RF_FS_IPv6_VPN,
+ rd: rd,
+ },
+ }
}
type FlowSpecL2VPN struct {
@@ -4301,11 +4324,14 @@ func (n *FlowSpecL2VPN) DecodeFromBytes(data []byte, options ...*MarshallingOpti
}
func NewFlowSpecL2VPN(rd RouteDistinguisherInterface, value []FlowSpecComponentInterface) *FlowSpecL2VPN {
- return &FlowSpecL2VPN{FlowSpecNLRI{
- Value: value,
- rf: RF_FS_L2_VPN,
- rd: rd,
- }}
+ sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() })
+ return &FlowSpecL2VPN{
+ FlowSpecNLRI: FlowSpecNLRI{
+ Value: value,
+ rf: RF_FS_L2_VPN,
+ rd: rd,
+ },
+ }
}
type OpaqueNLRI struct {
diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go
index c3833fa8..d3e2719f 100644
--- a/packet/bgp/bgp_test.go
+++ b/packet/bgp/bgp_test.go
@@ -787,20 +787,21 @@ func Test_CompareFlowSpecNLRI(t *testing.T) {
assert := assert.New(t)
cmp, err := ParseFlowSpecComponents(RF_FS_IPv4_UC, "destination 10.0.0.2/32 source 10.0.0.1/32 destination-port ==3128 protocol tcp")
assert.Nil(err)
- n1 := &FlowSpecNLRI{Value: cmp, rf: RF_FS_IPv4_UC}
+ // Note: Use NewFlowSpecIPv4Unicast() for the consistent ordered rules.
+ n1 := NewFlowSpecIPv4Unicast(cmp).FlowSpecNLRI
cmp, err = ParseFlowSpecComponents(RF_FS_IPv4_UC, "source 10.0.0.0/24 destination-port ==3128 protocol tcp")
assert.Nil(err)
- n2 := &FlowSpecNLRI{Value: cmp, rf: RF_FS_IPv4_UC}
+ n2 := NewFlowSpecIPv4Unicast(cmp).FlowSpecNLRI
+ r, err := CompareFlowSpecNLRI(&n1, &n2)
+ assert.Nil(err)
+ assert.True(r > 0)
cmp, err = ParseFlowSpecComponents(RF_FS_IPv4_UC, "source 10.0.0.9/32 port ==80 ==8080 destination-port >8080&<8080 ==3128 source-port >1024 protocol ==udp ==tcp")
- n3 := &FlowSpecNLRI{Value: cmp, rf: RF_FS_IPv4_UC}
+ n3 := NewFlowSpecIPv4Unicast(cmp).FlowSpecNLRI
assert.Nil(err)
cmp, err = ParseFlowSpecComponents(RF_FS_IPv4_UC, "destination 192.168.0.2/32")
- n4 := &FlowSpecNLRI{Value: cmp, rf: RF_FS_IPv4_UC}
+ n4 := NewFlowSpecIPv4Unicast(cmp).FlowSpecNLRI
assert.Nil(err)
- r, err := CompareFlowSpecNLRI(n1, n2)
- assert.Nil(err)
- assert.True(r > 0)
- r, err = CompareFlowSpecNLRI(n3, n4)
+ r, err = CompareFlowSpecNLRI(&n3, &n4)
assert.Nil(err)
assert.True(r < 0)
}
diff --git a/packet/bgp/validate_test.go b/packet/bgp/validate_test.go
index 3bb60639..12f81e03 100644
--- a/packet/bgp/validate_test.go
+++ b/packet/bgp/validate_test.go
@@ -388,8 +388,8 @@ func Test_Validate_flowspec(t *testing.T) {
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}))
- isFlagment := 0x02
- item7 := NewFlowSpecComponentItem(isFlagment, 0)
+ isFragment := 0x02
+ item7 := NewFlowSpecComponentItem(isFragment, 0)
cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_FRAGMENT, []*FlowSpecComponentItem{item7}))
n1 := NewFlowSpecIPv4Unicast(cmp)
a := NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
@@ -402,6 +402,8 @@ func Test_Validate_flowspec(t *testing.T) {
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)
}
diff --git a/table/path.go b/table/path.go
index cf4603f2..9f041786 100644
--- a/table/path.go
+++ b/table/path.go
@@ -136,20 +136,6 @@ type Validation struct {
UnmatchedLength []*ROA
}
-type FlowSpecComponents []bgp.FlowSpecComponentInterface
-
-func (c FlowSpecComponents) Len() int {
- return len(c)
-}
-
-func (c FlowSpecComponents) Swap(i, j int) {
- c[i], c[j] = c[j], c[i]
-}
-
-func (c FlowSpecComponents) Less(i, j int) bool {
- return c[i].Type() < c[j].Type()
-}
-
type Path struct {
info *originInfo
IsWithdraw bool
@@ -173,25 +159,6 @@ func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pa
return nil
}
- if nlri != nil && (nlri.SAFI() == bgp.SAFI_FLOW_SPEC_UNICAST || nlri.SAFI() == bgp.SAFI_FLOW_SPEC_VPN) {
- var coms FlowSpecComponents
- var f *bgp.FlowSpecNLRI
- switch nlri.(type) {
- case *bgp.FlowSpecIPv4Unicast:
- f = &nlri.(*bgp.FlowSpecIPv4Unicast).FlowSpecNLRI
- case *bgp.FlowSpecIPv4VPN:
- f = &nlri.(*bgp.FlowSpecIPv4VPN).FlowSpecNLRI
- case *bgp.FlowSpecIPv6Unicast:
- f = &nlri.(*bgp.FlowSpecIPv6Unicast).FlowSpecNLRI
- case *bgp.FlowSpecIPv6VPN:
- f = &nlri.(*bgp.FlowSpecIPv6VPN).FlowSpecNLRI
- }
- if f != nil {
- coms = f.Value
- sort.Sort(coms)
- }
- }
-
return &Path{
info: &originInfo{
nlri: nlri,