diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-11-28 11:39:42 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-11-28 15:23:04 +0900 |
commit | 76c289ea3624502f12d03ee9a5a34340d571df88 (patch) | |
tree | 15120098ecd56f831b119edfb87503cd8b69c1bf /packet | |
parent | 5440f32fcd85264b659d126573f447a80eb3db31 (diff) |
packet/bgp: Use fixed len types in FlowSpec components
Currently, the "FlowSpecComponentItem" uses int type for the "Op" and
"Value" fields, but Golang int type has 4 bytes length on the 32-bit
env and 8 bytes length on the 64-bit env.
For example, to support the SNAP (Type 20) rule, which has 5 bytes
value field, int type has not enough length on 32-bit env.
This patch fixes to use the fixed length integer types for the
FlowSpec components and avoid overflows of value range.
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Diffstat (limited to 'packet')
-rw-r--r-- | packet/bgp/bgp.go | 90 | ||||
-rw-r--r-- | packet/bgp/bgp_test.go | 46 | ||||
-rw-r--r-- | packet/bgp/constant.go | 4 | ||||
-rw-r--r-- | packet/bgp/validate_test.go | 19 |
4 files changed, 71 insertions, 88 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index 86b4cfd7..b7abe886 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -2988,7 +2988,7 @@ func normalizeFlowSpecOpValues(args []string) []string { // Parses the FlowSpec numeric operator using the given submatch which should be // the return value of func (*Regexp) FindStringSubmatch. -func parseFlowSpecNumericOperator(submatch []string) (operator int, err error) { +func parseFlowSpecNumericOperator(submatch []string) (operator uint8, err error) { if submatch[1] == "&" { operator = DEC_NUM_OP_AND } @@ -2996,7 +2996,7 @@ func parseFlowSpecNumericOperator(submatch []string) (operator int, err error) { if !ok { return 0, fmt.Errorf("invalid numeric operator: %s%s", submatch[1], submatch[2]) } - operator |= int(value) + operator |= uint8(value) return operator, nil } @@ -3006,7 +3006,7 @@ func parseFlowSpecNumericOperator(submatch []string) (operator int, err error) { // Note: Each of the args should be formatted in single pair of operator and // value before calling this function. // e.g.) "&==100", ">=200" or "&<300" -func parseFlowSpecNumericOpValues(typ BGPFlowSpecType, args []string, validationFunc func(int) error) (FlowSpecComponentInterface, error) { +func parseFlowSpecNumericOpValues(typ BGPFlowSpecType, args []string, validationFunc func(uint64) error) (FlowSpecComponentInterface, error) { argsLen := len(args) items := make([]*FlowSpecComponentItem, 0, argsLen) re := regexp.MustCompile("(&?)(==|=|>|>=|<|<=|!|!=|=!)?(\\d+|-\\d|true|false)") @@ -3023,15 +3023,15 @@ func parseFlowSpecNumericOpValues(typ BGPFlowSpecType, args []string, validation return nil, err } // "true" and "false" is operator, but here handles them as value. - value := 0 + var value uint64 switch m[3] { case "true", "false": if idx != argsLen-1 { return nil, fmt.Errorf("%s should be the last of each rule", m[3]) } - operator = int(DECNumOpValueMap[m[3]]) + operator = uint8(DECNumOpValueMap[m[3]]) default: - if value, err = strconv.Atoi(m[3]); err != nil { + if value, err = strconv.ParseUint(m[3], 10, 64); err != nil { return nil, fmt.Errorf("invalid numeric value: %s", m[3]) } if err = validationFunc(value); err != nil { @@ -3042,7 +3042,7 @@ func parseFlowSpecNumericOpValues(typ BGPFlowSpecType, args []string, validation } // Marks end-of-list bit - items[argsLen-1].Op |= int(DEC_NUM_OP_END) + items[argsLen-1].Op |= uint8(DEC_NUM_OP_END) return NewFlowSpecComponent(typ, items), nil } @@ -3050,8 +3050,8 @@ func parseFlowSpecNumericOpValues(typ BGPFlowSpecType, args []string, validation func flowSpecNumeric1ByteParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { args = normalizeFlowSpecOpValues(args) - f := func(i int) error { - if 0 <= i && i <= 0xff { // 1 byte + f := func(i uint64) error { + if i <= 0xff { // 1 byte return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3063,8 +3063,8 @@ func flowSpecNumeric1ByteParser(_ RouteFamily, typ BGPFlowSpecType, args []strin func flowSpecNumeric2BytesParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { args = normalizeFlowSpecOpValues(args) - f := func(i int) error { - if 0 <= i && i <= 0xffff { // 2 bytes + f := func(i uint64) error { + if i <= 0xffff { // 2 bytes return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3075,7 +3075,7 @@ func flowSpecNumeric2BytesParser(_ RouteFamily, typ BGPFlowSpecType, args []stri // Parses the FlowSpec bitmask operand using the given submatch which should be // the return value of func (*Regexp) FindStringSubmatch. -func parseFlowSpecBitmaskOperand(submatch []string) (operand int, err error) { +func parseFlowSpecBitmaskOperand(submatch []string) (operand uint8, err error) { if submatch[1] == "&" { operand = BITMASK_FLAG_OP_AND } @@ -3083,7 +3083,7 @@ func parseFlowSpecBitmaskOperand(submatch []string) (operand int, err error) { if !ok { return 0, fmt.Errorf("invalid bitmask operand: %s%s", submatch[1], submatch[2]) } - operand |= int(value) + operand |= uint8(value) return operand, nil } @@ -3173,8 +3173,8 @@ func flowSpecIpProtoParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (F } args = strings.Split(s, " ") - f := func(i int) error { - if 0 <= i && i <= 0xff { // 1 byte + f := func(i uint64) error { + if i <= 0xff { // 1 byte return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3211,10 +3211,10 @@ func flowSpecTcpFlagParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (F if err != nil { return nil, err } - value := 0 + var value uint64 for flag, name := range TCPFlagNameMap { if strings.Contains(m[4], name) { - value |= int(flag) + value |= uint64(flag) } } items = append(items, NewFlowSpecComponentItem(operand, value)) @@ -3229,8 +3229,8 @@ func flowSpecTcpFlagParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (F func flowSpecDscpParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { args = normalizeFlowSpecOpValues(args) - f := func(i int) error { - if 0 <= i && i < 64 { // 6 bits + f := func(i uint64) error { + if i < 64 { // 6 bits return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3267,12 +3267,12 @@ func flowSpecFragmentParser(_ RouteFamily, typ BGPFlowSpecType, args []string) ( if err != nil { return nil, err } - value := 0 + var value uint64 // Example: // m[3] = "first-fragment+last-fragment" for flag, name := range FragmentFlagNameMap { if strings.Contains(m[3], name) { - value |= int(flag) + value |= uint64(flag) } } items = append(items, NewFlowSpecComponentItem(operand, value)) @@ -3292,8 +3292,8 @@ func flowSpecLabelParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (Fl args = normalizeFlowSpecOpValues(args) - f := func(i int) error { - if 0 <= i && i <= 0xfffff { // 20 bits + f := func(i uint64) error { + if i <= 0xfffff { // 20 bits return nil } return fmt.Errorf("flow label range exceeded") @@ -3321,8 +3321,8 @@ func flowSpecEtherTypeParser(rf RouteFamily, typ BGPFlowSpecType, args []string) } args = strings.Split(s, " ") - f := func(i int) error { - if 0 <= i && i <= 0xffff { // 2 bytes + f := func(i uint64) error { + if i <= 0xffff { // 2 bytes return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3366,8 +3366,8 @@ func flowSpecSnapParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (Flo args = normalizeFlowSpecOpValues(args) - f := func(i int) error { - if 0 <= i && i <= 0xffffffffff { // 5 bytes + f := func(i uint64) error { + if i <= 0xffffffffff { // 5 bytes return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3388,8 +3388,8 @@ func flowSpecVlanIDParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (F } args = strings.Split(s, " ") - f := func(i int) error { - if 0 <= i && i <= 4095 { // 12 bits + f := func(i uint64) error { + if i <= 4095 { // 12 bits return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3410,8 +3410,8 @@ func flowSpecVlanCosParser(rf RouteFamily, typ BGPFlowSpecType, args []string) ( } args = strings.Split(s, " ") - f := func(i int) error { - if 0 <= i && i <= 7 { // 3 bits + f := func(i uint64) error { + if i <= 7 { // 3 bits return nil } return fmt.Errorf("%s range exceeded", typ.String()) @@ -3691,8 +3691,8 @@ func NewFlowSpecDestinationMac(mac net.HardwareAddr) *FlowSpecDestinationMac { } type FlowSpecComponentItem struct { - Op int `json:"op"` - Value int `json:"value"` + Op uint8 `json:"op"` + Value uint64 `json:"value"` } func (v *FlowSpecComponentItem) Len() int { @@ -3725,7 +3725,7 @@ func (v *FlowSpecComponentItem) Serialize() ([]byte, error) { return buf, nil } -func NewFlowSpecComponentItem(op int, value int) *FlowSpecComponentItem { +func NewFlowSpecComponentItem(op uint8, value uint64) *FlowSpecComponentItem { v := &FlowSpecComponentItem{op, value} order := uint32(math.Log2(float64(v.Len()))) // we don't know if not initialized properly or initialized to @@ -3744,7 +3744,7 @@ func NewFlowSpecComponentItem(op int, value int) *FlowSpecComponentItem { if order > 3 { return nil } - v.Op = int(uint32(v.Op) | order<<4) + v.Op = uint8(uint32(v.Op) | order<<4) return v } @@ -3766,8 +3766,8 @@ func (p *FlowSpecComponent) DecodeFromBytes(data []byte, options ...*Marshalling l := 1 << ((op >> 4) & 0x3) // (min, max) = (1, 8) v := make([]byte, 8) copy(v[8-l:], data[1:1+l]) - i := int(binary.BigEndian.Uint64(v)) - item := &FlowSpecComponentItem{int(op), i} + i := binary.BigEndian.Uint64(v) + item := &FlowSpecComponentItem{op, i} p.Items = append(p.Items, item) if end > 0 { break @@ -3807,20 +3807,20 @@ func (p *FlowSpecComponent) Type() BGPFlowSpecType { return p.typ } -func formatRaw(op int, value int) string { +func formatRaw(op uint8, value uint64) string { return fmt.Sprintf("op:%b,value:%d", op, value) } -func formatNumeric(op int, value int) string { +func formatNumeric(op uint8, value uint64) string { cmpFlag := DECNumOp(op & 0x7) // lower 3 bits if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { // Omit value field return DECNumOp(op).String() } - return fmt.Sprint(DECNumOp(op).String(), strconv.Itoa(value)) + return fmt.Sprint(DECNumOp(op).String(), value) } -func formatProto(op int, value int) string { +func formatProto(op uint8, value uint64) string { cmpFlag := DECNumOp(op & 0x7) // lower 3 bits if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { // Omit value field @@ -3829,15 +3829,15 @@ func formatProto(op int, value int) string { return fmt.Sprint(DECNumOp(op).String(), Protocol(value).String()) } -func formatTCPFlag(op int, value int) string { +func formatTCPFlag(op uint8, value uint64) string { return fmt.Sprint(BitmaskFlagOp(op).String(), TCPFlag(value).String()) } -func formatFragment(op int, value int) string { +func formatFragment(op uint8, value uint64) string { return fmt.Sprint(BitmaskFlagOp(op).String(), FragmentFlag(value).String()) } -func formatEtherType(op int, value int) string { +func formatEtherType(op uint8, value uint64) string { cmpFlag := DECNumOp(op & 0x7) // lower 3 bits if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { // Omit value field @@ -3846,7 +3846,7 @@ func formatEtherType(op int, value int) string { return fmt.Sprint(DECNumOp(op).String(), EthernetType(value).String()) } -var flowSpecFormatMap = map[BGPFlowSpecType]func(op int, value int) string{ +var flowSpecFormatMap = map[BGPFlowSpecType]func(op uint8, value uint64) string{ FLOW_SPEC_TYPE_UNKNOWN: formatRaw, FLOW_SPEC_TYPE_IP_PROTO: formatProto, FLOW_SPEC_TYPE_PORT: formatNumeric, diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go index d3e2719f..ba3cabbd 100644 --- a/packet/bgp/bgp_test.go +++ b/packet/bgp/bgp_test.go @@ -367,16 +367,11 @@ func Test_FlowSpecNlri(t *testing.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"))) - eq := 0x1 - gt := 0x2 - lt := 0x4 - and := 0x40 - not := 0x2 - item1 := NewFlowSpecComponentItem(eq, TCP) + item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) - item2 := NewFlowSpecComponentItem(gt|eq, 20) - item3 := NewFlowSpecComponentItem(and|lt|eq, 30) - item4 := NewFlowSpecComponentItem(eq, 10) + 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_GT_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})) @@ -384,14 +379,13 @@ func Test_FlowSpecNlri(t *testing.T) { cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_CODE, []*FlowSpecComponentItem{item2, item3, item4})) 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 - lastFlagment := 0x08 - match := 0x1 - item5 := NewFlowSpecComponentItem(match, isFlagment) - item6 := NewFlowSpecComponentItem(and, lastFlagment) + isFragment := uint64(0x02) + lastFragment := uint64(0x08) + item5 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_MATCH, isFragment) + item6 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_AND, lastFragment) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_FRAGMENT, []*FlowSpecComponentItem{item5, item6})) item7 := NewFlowSpecComponentItem(0, TCP_FLAG_ACK) - item8 := NewFlowSpecComponentItem(and|not, TCP_FLAG_URGENT) + item8 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_AND|BITMASK_FLAG_OP_NOT, TCP_FLAG_URGENT) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_TCP_FLAG, []*FlowSpecComponentItem{item7, item8})) n1 := NewFlowSpecIPv4Unicast(cmp) buf1, err := n1.Serialize() @@ -461,16 +455,11 @@ func Test_FlowSpecNlriv6(t *testing.T) { cmp := make([]FlowSpecComponentInterface, 0) cmp = append(cmp, NewFlowSpecDestinationPrefix6(NewIPv6AddrPrefix(64, "2001::"), 12)) cmp = append(cmp, NewFlowSpecSourcePrefix6(NewIPv6AddrPrefix(64, "2001::"), 12)) - eq := 0x1 - gt := 0x2 - lt := 0x4 - and := 0x40 - not := 0x2 - item1 := NewFlowSpecComponentItem(eq, TCP) + item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) - item2 := NewFlowSpecComponentItem(gt|eq, 20) - item3 := NewFlowSpecComponentItem(and|lt|eq, 30) - item4 := NewFlowSpecComponentItem(eq, 10) + 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})) @@ -479,11 +468,11 @@ func Test_FlowSpecNlriv6(t *testing.T) { 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})) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_LABEL, []*FlowSpecComponentItem{item2, item3, item4})) - isFlagment := 0x02 - item5 := NewFlowSpecComponentItem(isFlagment, 0) + isFragment := uint64(0x02) + item5 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_MATCH, isFragment) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_FRAGMENT, []*FlowSpecComponentItem{item5})) item6 := NewFlowSpecComponentItem(0, TCP_FLAG_ACK) - item7 := NewFlowSpecComponentItem(and|not, TCP_FLAG_URGENT) + item7 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_AND|BITMASK_FLAG_OP_NOT, TCP_FLAG_URGENT) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_TCP_FLAG, []*FlowSpecComponentItem{item6, item7})) n1 := NewFlowSpecIPv6Unicast(cmp) buf1, err := n1.Serialize() @@ -529,8 +518,7 @@ func Test_FlowSpecNlriL2(t *testing.T) { cmp := make([]FlowSpecComponentInterface, 0) cmp = append(cmp, NewFlowSpecDestinationMac(mac)) cmp = append(cmp, NewFlowSpecSourceMac(mac)) - eq := 0x1 - item1 := NewFlowSpecComponentItem(eq, int(IPv4)) + item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, uint64(IPv4)) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ETHERNET_TYPE, []*FlowSpecComponentItem{item1})) rd, _ := ParseRouteDistinguisher("100:100") n1 := NewFlowSpecL2VPN(rd, cmp) diff --git a/packet/bgp/constant.go b/packet/bgp/constant.go index d4120471..5ea7b414 100644 --- a/packet/bgp/constant.go +++ b/packet/bgp/constant.go @@ -126,7 +126,7 @@ func (f TCPFlag) String() string { return strings.Join(flags, "") } -type BitmaskFlagOp int +type BitmaskFlagOp uint8 const ( BITMASK_FLAG_OP_OR BitmaskFlagOp = iota @@ -215,7 +215,7 @@ func (f FragmentFlag) String() string { return strings.Join(flags, "+") } -type DECNumOp int +type DECNumOp uint8 const ( DEC_NUM_OP_TRUE DECNumOp = iota // true always with END bit set diff --git a/packet/bgp/validate_test.go b/packet/bgp/validate_test.go index 12f81e03..4228c260 100644 --- a/packet/bgp/validate_test.go +++ b/packet/bgp/validate_test.go @@ -368,28 +368,23 @@ func Test_Validate_flowspec(t *testing.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"))) - eq := 0x1 - gt := 0x2 - lt := 0x4 - and := 0x40 - not := 0x2 - item1 := NewFlowSpecComponentItem(eq, TCP) + item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) - item2 := NewFlowSpecComponentItem(gt|eq, 20) - item3 := NewFlowSpecComponentItem(and|lt|eq, 30) - item4 := NewFlowSpecComponentItem(eq, 10) + 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(and|not, TCP_FLAG_URGENT) + 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 := 0x02 - item7 := NewFlowSpecComponentItem(isFragment, 0) + 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}) |