summaryrefslogtreecommitdiffhomepage
path: root/packet/bgp/bgp.go
diff options
context:
space:
mode:
authorSatoshi Fujimoto <satoshi.fujimoto7@gmail.com>2017-11-06 11:09:03 +0900
committerSatoshi Fujimoto <satoshi.fujimoto7@gmail.com>2017-11-06 13:22:23 +0900
commit5f9347d0d82a8cf8f32259e2459d370c14d85fc5 (patch)
treec5aa6ca0b52e025f7bae19f8175f4f5821123e9e /packet/bgp/bgp.go
parent9f4cd30e34b7aa4db860392b7934d58ec62348a0 (diff)
packet/bgp: Avoid Varied Flag Representations in Flowspec Filter
Currently, the parsing results of flags in flowsspec filter will be varied every time they are parsed. For example, the tcp-flag '=UFP' may be represented to '=UPF' or '=PUF' and so on. This is due to the use of interation to map. Iterations over maps does not happen in a consistent order. This fixes it by iterating sorted slices instead of maps. Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com>
Diffstat (limited to 'packet/bgp/bgp.go')
-rw-r--r--packet/bgp/bgp.go35
1 files changed, 27 insertions, 8 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index ebab8712..27206d68 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -24,6 +24,7 @@ import (
"net"
"reflect"
"regexp"
+ "sort"
"strconv"
"strings"
)
@@ -3590,7 +3591,7 @@ func formatProto(op int, value int) string {
return fmt.Sprintf("%s%s%s", formatNumericOpFrontQty(op), Protocol(value).String(), formatNumericOpBackLogic(op))
}
-func formatFlag(op int, value int) string {
+func formatTCPFlag(op int, value int) string {
var retString string
if op&BITMASK_FLAG_OP_MATCH > 0 {
retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_MATCH])
@@ -3598,11 +3599,20 @@ func formatFlag(op int, value int) string {
if op&BITMASK_FLAG_OP_NOT > 0 {
retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_NOT])
}
- for flag, valueFlag := range TCPFlagValueMap {
- if value&int(valueFlag) > 0 {
- retString = fmt.Sprintf("%s%s", retString, flag)
+
+ // Prepare a sorted list of flags because map iterations does not happen
+ // in a consistent order in Golang.
+ vs := make([]int, 0)
+ for _, v := range TCPFlagValueMap {
+ vs = append(vs, int(v))
+ }
+ sort.Ints(vs)
+ for _, v := range vs {
+ if value&v > 0 {
+ retString = fmt.Sprintf("%s%s", retString, TCPFlagNameMap[TCPFlag(v)])
}
}
+
if op&BITMASK_FLAG_OP_AND > 0 {
retString = fmt.Sprintf("%s%s", BitmaskFlagOpNameMap[BITMASK_FLAG_OP_AND], retString)
} else { // default is or
@@ -3619,11 +3629,20 @@ func formatFragment(op int, value int) string {
if op&BITMASK_FLAG_OP_NOT > 0 {
retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_NOT])
}
- for flag, valueFlag := range FragmentFlagValueMap {
- if value&int(valueFlag) > 0 {
- retString = fmt.Sprintf("%s%s", retString, flag)
+
+ // Prepare a sorted list of flags because map iterations does not happen
+ // in a consistent order in Golang.
+ vs := make([]int, 0)
+ for _, v := range FragmentFlagValueMap {
+ vs = append(vs, int(v))
+ }
+ sort.Ints(vs)
+ for _, v := range vs {
+ if value&v > 0 {
+ retString = fmt.Sprintf("%s%s", retString, FragmentFlagNameMap[FragmentFlag(v)])
}
}
+
if op&BITMASK_FLAG_OP_AND > 0 {
retString = fmt.Sprintf("%s%s", BitmaskFlagOpNameMap[BITMASK_FLAG_OP_AND], retString)
} else { // default is or
@@ -3644,7 +3663,7 @@ var flowSpecFormatMap = map[BGPFlowSpecType]func(op int, value int) string{
FLOW_SPEC_TYPE_SRC_PORT: formatNumeric,
FLOW_SPEC_TYPE_ICMP_TYPE: formatNumeric,
FLOW_SPEC_TYPE_ICMP_CODE: formatNumeric,
- FLOW_SPEC_TYPE_TCP_FLAG: formatFlag,
+ FLOW_SPEC_TYPE_TCP_FLAG: formatTCPFlag,
FLOW_SPEC_TYPE_PKT_LEN: formatNumeric,
FLOW_SPEC_TYPE_DSCP: formatNumeric,
FLOW_SPEC_TYPE_FRAGMENT: formatFragment,