diff options
author | Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> | 2017-11-06 11:09:03 +0900 |
---|---|---|
committer | Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> | 2017-11-06 13:22:23 +0900 |
commit | 5f9347d0d82a8cf8f32259e2459d370c14d85fc5 (patch) | |
tree | c5aa6ca0b52e025f7bae19f8175f4f5821123e9e | |
parent | 9f4cd30e34b7aa4db860392b7934d58ec62348a0 (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>
-rw-r--r-- | packet/bgp/bgp.go | 35 |
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, |