VOL-2153 remove flow_utils.go from voltha-go
Change-Id: I81bdc9ed78e6a6b00a176f9c8366ff56fb7777b0
diff --git a/rw_core/core/device_agent.go b/rw_core/core/device_agent.go
index 4a5274b..c8e07a9 100755
--- a/rw_core/core/device_agent.go
+++ b/rw_core/core/device_agent.go
@@ -19,8 +19,9 @@
"context"
"fmt"
"github.com/gogo/protobuf/proto"
- fu "github.com/opencord/voltha-go/rw_core/utils"
+ coreutils "github.com/opencord/voltha-go/rw_core/utils"
"github.com/opencord/voltha-lib-go/pkg/db/model"
+ fu "github.com/opencord/voltha-lib-go/pkg/flows"
"github.com/opencord/voltha-lib-go/pkg/log"
ic "github.com/opencord/voltha-protos/go/inter_container"
ofp "github.com/opencord/voltha-protos/go/openflow_13"
@@ -323,7 +324,7 @@
device.FlowGroups = &voltha.FlowGroups{Items: updatedGroups}
go agent.updateDeviceWithoutLockAsync(device, chdB)
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chAdapters, chdB); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chAdapters, chdB); res != nil {
log.Debugw("Failed to get response from adapter[or] DB", log.Fields{"result": res})
return status.Errorf(codes.Aborted, "errors-%s", res)
}
@@ -414,7 +415,7 @@
device.FlowGroups = &voltha.FlowGroups{Items: groupsToKeep}
go agent.updateDeviceWithoutLockAsync(device, chdB)
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chAdapters, chdB); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chAdapters, chdB); res != nil {
return status.Errorf(codes.Aborted, "errors-%s", res)
}
return nil
@@ -522,7 +523,7 @@
device.FlowGroups = &voltha.FlowGroups{Items: updatedGroups}
go agent.updateDeviceWithoutLockAsync(device, chdB)
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chAdapters, chdB); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chAdapters, chdB); res != nil {
return status.Errorf(codes.Aborted, "errors-%s", res)
}
return nil
diff --git a/rw_core/core/logical_device_agent.go b/rw_core/core/logical_device_agent.go
index 21f65fa..c36e1a2 100644
--- a/rw_core/core/logical_device_agent.go
+++ b/rw_core/core/logical_device_agent.go
@@ -22,8 +22,9 @@
"github.com/gogo/protobuf/proto"
fd "github.com/opencord/voltha-go/rw_core/flow_decomposition"
"github.com/opencord/voltha-go/rw_core/graph"
- fu "github.com/opencord/voltha-go/rw_core/utils"
+ coreutils "github.com/opencord/voltha-go/rw_core/utils"
"github.com/opencord/voltha-lib-go/pkg/db/model"
+ fu "github.com/opencord/voltha-lib-go/pkg/flows"
"github.com/opencord/voltha-lib-go/pkg/log"
ic "github.com/opencord/voltha-protos/go/inter_container"
ofp "github.com/opencord/voltha-protos/go/openflow_13"
@@ -406,7 +407,7 @@
}(child, ch)
}
// Wait for completion
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
return status.Errorf(codes.Aborted, "errors-%s", res)
}
}
@@ -1034,7 +1035,7 @@
}(deviceId, value.ListFlows(), value.ListGroups())
}
// Wait for completion
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
return status.Errorf(codes.Aborted, "errors-%s", res)
}
return nil
@@ -1056,7 +1057,7 @@
}(deviceId, value.ListFlows(), value.ListGroups())
}
// Wait for completion
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
return status.Errorf(codes.Aborted, "errors-%s", res)
}
return nil
@@ -1078,7 +1079,7 @@
}(deviceId, value.ListFlows(), value.ListGroups())
}
// Wait for completion
- if res := fu.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
+ if res := coreutils.WaitForNilOrErrorResponses(agent.defaultTimeout, chnlsList...); res != nil {
return status.Errorf(codes.Aborted, "errors-%s", res)
}
return nil
diff --git a/rw_core/flow_decomposition/flow_decomposer.go b/rw_core/flow_decomposition/flow_decomposer.go
index d28a803..ff9225c 100644
--- a/rw_core/flow_decomposition/flow_decomposer.go
+++ b/rw_core/flow_decomposition/flow_decomposer.go
@@ -20,7 +20,7 @@
"github.com/gogo/protobuf/proto"
"github.com/opencord/voltha-go/rw_core/coreIf"
"github.com/opencord/voltha-go/rw_core/graph"
- fu "github.com/opencord/voltha-go/rw_core/utils"
+ fu "github.com/opencord/voltha-lib-go/pkg/flows"
"github.com/opencord/voltha-lib-go/pkg/log"
ofp "github.com/opencord/voltha-protos/go/openflow_13"
"github.com/opencord/voltha-protos/go/voltha"
diff --git a/rw_core/flow_decomposition/flow_decomposer_test.go b/rw_core/flow_decomposition/flow_decomposer_test.go
index 3264c12..37faa25 100644
--- a/rw_core/flow_decomposition/flow_decomposer_test.go
+++ b/rw_core/flow_decomposition/flow_decomposer_test.go
@@ -18,7 +18,7 @@
import (
"errors"
"github.com/opencord/voltha-go/rw_core/graph"
- fu "github.com/opencord/voltha-go/rw_core/utils"
+ fu "github.com/opencord/voltha-lib-go/pkg/flows"
"github.com/opencord/voltha-lib-go/pkg/log"
ofp "github.com/opencord/voltha-protos/go/openflow_13"
"github.com/opencord/voltha-protos/go/voltha"
diff --git a/rw_core/utils/flow_utils.go b/rw_core/utils/flow_utils.go
deleted file mode 100644
index 7cb718e..0000000
--- a/rw_core/utils/flow_utils.go
+++ /dev/null
@@ -1,1332 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package utils
-
-import (
- "bytes"
- "crypto/md5"
- "fmt"
- "github.com/cevaris/ordered_map"
- "github.com/gogo/protobuf/proto"
- "github.com/opencord/voltha-lib-go/pkg/log"
- ofp "github.com/opencord/voltha-protos/go/openflow_13"
- "math/big"
- "strings"
-)
-
-var (
- // Instructions shortcut
- APPLY_ACTIONS = ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS
- WRITE_METADATA = ofp.OfpInstructionType_OFPIT_WRITE_METADATA
- METER_ACTION = ofp.OfpInstructionType_OFPIT_METER
-
- //OFPAT_* shortcuts
- OUTPUT = ofp.OfpActionType_OFPAT_OUTPUT
- COPY_TTL_OUT = ofp.OfpActionType_OFPAT_COPY_TTL_OUT
- COPY_TTL_IN = ofp.OfpActionType_OFPAT_COPY_TTL_IN
- SET_MPLS_TTL = ofp.OfpActionType_OFPAT_SET_MPLS_TTL
- DEC_MPLS_TTL = ofp.OfpActionType_OFPAT_DEC_MPLS_TTL
- PUSH_VLAN = ofp.OfpActionType_OFPAT_PUSH_VLAN
- POP_VLAN = ofp.OfpActionType_OFPAT_POP_VLAN
- PUSH_MPLS = ofp.OfpActionType_OFPAT_PUSH_MPLS
- POP_MPLS = ofp.OfpActionType_OFPAT_POP_MPLS
- SET_QUEUE = ofp.OfpActionType_OFPAT_SET_QUEUE
- GROUP = ofp.OfpActionType_OFPAT_GROUP
- SET_NW_TTL = ofp.OfpActionType_OFPAT_SET_NW_TTL
- NW_TTL = ofp.OfpActionType_OFPAT_DEC_NW_TTL
- SET_FIELD = ofp.OfpActionType_OFPAT_SET_FIELD
- PUSH_PBB = ofp.OfpActionType_OFPAT_PUSH_PBB
- POP_PBB = ofp.OfpActionType_OFPAT_POP_PBB
- EXPERIMENTER = ofp.OfpActionType_OFPAT_EXPERIMENTER
-
- //OFPXMT_OFB_* shortcuts (incomplete)
- IN_PORT = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT
- IN_PHY_PORT = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT
- METADATA = ofp.OxmOfbFieldTypes_OFPXMT_OFB_METADATA
- ETH_DST = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST
- ETH_SRC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC
- ETH_TYPE = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE
- VLAN_VID = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
- VLAN_PCP = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP
- IP_DSCP = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_DSCP
- IP_ECN = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_ECN
- IP_PROTO = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO
- IPV4_SRC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC
- IPV4_DST = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST
- TCP_SRC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TCP_SRC
- TCP_DST = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TCP_DST
- UDP_SRC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC
- UDP_DST = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST
- SCTP_SRC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_SCTP_SRC
- SCTP_DST = ofp.OxmOfbFieldTypes_OFPXMT_OFB_SCTP_DST
- ICMPV4_TYPE = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV4_TYPE
- ICMPV4_CODE = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV4_CODE
- ARP_OP = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_OP
- ARP_SPA = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_SPA
- ARP_TPA = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_TPA
- ARP_SHA = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_SHA
- ARP_THA = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_THA
- IPV6_SRC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_SRC
- IPV6_DST = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_DST
- IPV6_FLABEL = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_FLABEL
- ICMPV6_TYPE = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV6_TYPE
- ICMPV6_CODE = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV6_CODE
- IPV6_ND_TARGET = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_TARGET
- OFB_IPV6_ND_SLL = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_SLL
- IPV6_ND_TLL = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_TLL
- MPLS_LABEL = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_LABEL
- MPLS_TC = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_TC
- MPLS_BOS = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_BOS
- PBB_ISID = ofp.OxmOfbFieldTypes_OFPXMT_OFB_PBB_ISID
- TUNNEL_ID = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TUNNEL_ID
- IPV6_EXTHDR = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_EXTHDR
-)
-
-//ofp_action_* shortcuts
-
-func Output(port uint32, maxLen ...ofp.OfpControllerMaxLen) *ofp.OfpAction {
- maxLength := ofp.OfpControllerMaxLen_OFPCML_MAX
- if len(maxLen) > 0 {
- maxLength = maxLen[0]
- }
- return &ofp.OfpAction{Type: OUTPUT, Action: &ofp.OfpAction_Output{Output: &ofp.OfpActionOutput{Port: port, MaxLen: uint32(maxLength)}}}
-}
-
-func MplsTtl(ttl uint32) *ofp.OfpAction {
- return &ofp.OfpAction{Type: SET_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: ttl}}}
-}
-
-func PushVlan(ethType uint32) *ofp.OfpAction {
- return &ofp.OfpAction{Type: PUSH_VLAN, Action: &ofp.OfpAction_Push{Push: &ofp.OfpActionPush{Ethertype: ethType}}}
-}
-
-func PopVlan() *ofp.OfpAction {
- return &ofp.OfpAction{Type: POP_VLAN}
-}
-
-func PopMpls(ethType uint32) *ofp.OfpAction {
- return &ofp.OfpAction{Type: POP_MPLS, Action: &ofp.OfpAction_PopMpls{PopMpls: &ofp.OfpActionPopMpls{Ethertype: ethType}}}
-}
-
-func Group(groupId uint32) *ofp.OfpAction {
- return &ofp.OfpAction{Type: GROUP, Action: &ofp.OfpAction_Group{Group: &ofp.OfpActionGroup{GroupId: groupId}}}
-}
-
-func NwTtl(nwTtl uint32) *ofp.OfpAction {
- return &ofp.OfpAction{Type: NW_TTL, Action: &ofp.OfpAction_NwTtl{NwTtl: &ofp.OfpActionNwTtl{NwTtl: nwTtl}}}
-}
-
-func SetField(field *ofp.OfpOxmOfbField) *ofp.OfpAction {
- actionSetField := &ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: &ofp.OfpOxmField_OfbField{OfbField: field}}
- return &ofp.OfpAction{Type: SET_FIELD, Action: &ofp.OfpAction_SetField{SetField: &ofp.OfpActionSetField{Field: actionSetField}}}
-}
-
-func Experimenter(experimenter uint32, data []byte) *ofp.OfpAction {
- return &ofp.OfpAction{Type: EXPERIMENTER, Action: &ofp.OfpAction_Experimenter{Experimenter: &ofp.OfpActionExperimenter{Experimenter: experimenter, Data: data}}}
-}
-
-//ofb_field generators (incomplete set)
-
-func InPort(inPort uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IN_PORT, Value: &ofp.OfpOxmOfbField_Port{Port: inPort}}
-}
-
-func InPhyPort(inPhyPort uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IN_PHY_PORT, Value: &ofp.OfpOxmOfbField_Port{Port: inPhyPort}}
-}
-
-func Metadata_ofp(tableMetadata uint64) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: METADATA, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: tableMetadata}}
-}
-
-// should Metadata_ofp used here ?????
-func EthDst(ethDst uint64) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ETH_DST, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: ethDst}}
-}
-
-// should Metadata_ofp used here ?????
-func EthSrc(ethSrc uint64) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ETH_SRC, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: ethSrc}}
-}
-
-func EthType(ethType uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ETH_TYPE, Value: &ofp.OfpOxmOfbField_EthType{EthType: ethType}}
-}
-
-func VlanVid(vlanVid uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: VLAN_VID, Value: &ofp.OfpOxmOfbField_VlanVid{VlanVid: vlanVid}}
-}
-
-func VlanPcp(vlanPcp uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: VLAN_PCP, Value: &ofp.OfpOxmOfbField_VlanPcp{VlanPcp: vlanPcp}}
-}
-
-func IpDscp(ipDscp uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IP_DSCP, Value: &ofp.OfpOxmOfbField_IpDscp{IpDscp: ipDscp}}
-}
-
-func IpEcn(ipEcn uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IP_ECN, Value: &ofp.OfpOxmOfbField_IpEcn{IpEcn: ipEcn}}
-}
-
-func IpProto(ipProto uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IP_PROTO, Value: &ofp.OfpOxmOfbField_IpProto{IpProto: ipProto}}
-}
-
-func Ipv4Src(ipv4Src uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV4_SRC, Value: &ofp.OfpOxmOfbField_Ipv4Src{Ipv4Src: ipv4Src}}
-}
-
-func Ipv4Dst(ipv4Dst uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV4_DST, Value: &ofp.OfpOxmOfbField_Ipv4Dst{Ipv4Dst: ipv4Dst}}
-}
-
-func TcpSrc(tcpSrc uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: TCP_SRC, Value: &ofp.OfpOxmOfbField_TcpSrc{TcpSrc: tcpSrc}}
-}
-
-func TcpDst(tcpDst uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: TCP_DST, Value: &ofp.OfpOxmOfbField_TcpDst{TcpDst: tcpDst}}
-}
-
-func UdpSrc(udpSrc uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: UDP_SRC, Value: &ofp.OfpOxmOfbField_UdpSrc{UdpSrc: udpSrc}}
-}
-
-func UdpDst(udpDst uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: UDP_DST, Value: &ofp.OfpOxmOfbField_UdpDst{UdpDst: udpDst}}
-}
-
-func SctpSrc(sctpSrc uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: SCTP_SRC, Value: &ofp.OfpOxmOfbField_SctpSrc{SctpSrc: sctpSrc}}
-}
-
-func SctpDst(sctpDst uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: SCTP_DST, Value: &ofp.OfpOxmOfbField_SctpDst{SctpDst: sctpDst}}
-}
-
-func Icmpv4Type(icmpv4Type uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ICMPV4_TYPE, Value: &ofp.OfpOxmOfbField_Icmpv4Type{Icmpv4Type: icmpv4Type}}
-}
-
-func Icmpv4Code(icmpv4Code uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ICMPV4_CODE, Value: &ofp.OfpOxmOfbField_Icmpv4Code{Icmpv4Code: icmpv4Code}}
-}
-
-func ArpOp(arpOp uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ARP_OP, Value: &ofp.OfpOxmOfbField_ArpOp{ArpOp: arpOp}}
-}
-
-func ArpSpa(arpSpa uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ARP_SPA, Value: &ofp.OfpOxmOfbField_ArpSpa{ArpSpa: arpSpa}}
-}
-
-func ArpTpa(arpTpa uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ARP_TPA, Value: &ofp.OfpOxmOfbField_ArpTpa{ArpTpa: arpTpa}}
-}
-
-func ArpSha(arpSha []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ARP_SHA, Value: &ofp.OfpOxmOfbField_ArpSha{ArpSha: arpSha}}
-}
-
-func ArpTha(arpTha []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ARP_THA, Value: &ofp.OfpOxmOfbField_ArpTha{ArpTha: arpTha}}
-}
-
-func Ipv6Src(ipv6Src []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV6_SRC, Value: &ofp.OfpOxmOfbField_Ipv6Src{Ipv6Src: ipv6Src}}
-}
-
-func Ipv6Dst(ipv6Dst []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV6_DST, Value: &ofp.OfpOxmOfbField_Ipv6Dst{Ipv6Dst: ipv6Dst}}
-}
-
-func Ipv6Flabel(ipv6Flabel uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV6_FLABEL, Value: &ofp.OfpOxmOfbField_Ipv6Flabel{Ipv6Flabel: ipv6Flabel}}
-}
-
-func Icmpv6Type(icmpv6Type uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ICMPV6_TYPE, Value: &ofp.OfpOxmOfbField_Icmpv6Type{Icmpv6Type: icmpv6Type}}
-}
-
-func Icmpv6Code(icmpv6Code uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: ICMPV6_CODE, Value: &ofp.OfpOxmOfbField_Icmpv6Code{Icmpv6Code: icmpv6Code}}
-}
-
-func Ipv6NdTarget(ipv6NdTarget []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV6_ND_TARGET, Value: &ofp.OfpOxmOfbField_Ipv6NdTarget{Ipv6NdTarget: ipv6NdTarget}}
-}
-
-func OfbIpv6NdSll(ofbIpv6NdSll []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: OFB_IPV6_ND_SLL, Value: &ofp.OfpOxmOfbField_Ipv6NdSsl{Ipv6NdSsl: ofbIpv6NdSll}}
-}
-
-func Ipv6NdTll(ipv6NdTll []byte) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV6_ND_TLL, Value: &ofp.OfpOxmOfbField_Ipv6NdTll{Ipv6NdTll: ipv6NdTll}}
-}
-
-func MplsLabel(mplsLabel uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: MPLS_LABEL, Value: &ofp.OfpOxmOfbField_MplsLabel{MplsLabel: mplsLabel}}
-}
-
-func MplsTc(mplsTc uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: MPLS_TC, Value: &ofp.OfpOxmOfbField_MplsTc{MplsTc: mplsTc}}
-}
-
-func MplsBos(mplsBos uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: MPLS_BOS, Value: &ofp.OfpOxmOfbField_MplsBos{MplsBos: mplsBos}}
-}
-
-func PbbIsid(pbbIsid uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: PBB_ISID, Value: &ofp.OfpOxmOfbField_PbbIsid{PbbIsid: pbbIsid}}
-}
-
-func TunnelId(tunnelId uint64) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: TUNNEL_ID, Value: &ofp.OfpOxmOfbField_TunnelId{TunnelId: tunnelId}}
-}
-
-func Ipv6Exthdr(ipv6Exthdr uint32) *ofp.OfpOxmOfbField {
- return &ofp.OfpOxmOfbField{Type: IPV6_EXTHDR, Value: &ofp.OfpOxmOfbField_Ipv6Exthdr{Ipv6Exthdr: ipv6Exthdr}}
-}
-
-//frequently used extractors
-
-func excludeAction(action *ofp.OfpAction, exclude ...ofp.OfpActionType) bool {
- for _, actionToExclude := range exclude {
- if action.Type == actionToExclude {
- return true
- }
- }
- return false
-}
-
-func GetActions(flow *ofp.OfpFlowStats, exclude ...ofp.OfpActionType) []*ofp.OfpAction {
- if flow == nil {
- return nil
- }
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
- instActions := instruction.GetActions()
- if instActions == nil {
- return nil
- }
- if len(exclude) == 0 {
- return instActions.Actions
- } else {
- filteredAction := make([]*ofp.OfpAction, 0)
- for _, action := range instActions.Actions {
- if !excludeAction(action, exclude...) {
- filteredAction = append(filteredAction, action)
- }
- }
- return filteredAction
- }
- }
- }
- return nil
-}
-
-func UpdateOutputPortByActionType(flow *ofp.OfpFlowStats, actionType uint32, toPort uint32) *ofp.OfpFlowStats {
- if flow == nil {
- return nil
- }
- nFlow := (proto.Clone(flow)).(*ofp.OfpFlowStats)
- nFlow.Instructions = nil
- nInsts := make([]*ofp.OfpInstruction, 0)
- for _, instruction := range flow.Instructions {
- if instruction.Type == actionType {
- instActions := instruction.GetActions()
- if instActions == nil {
- return nil
- }
- nActions := make([]*ofp.OfpAction, 0)
- for _, action := range instActions.Actions {
- if action.GetOutput() != nil {
- nActions = append(nActions, Output(toPort))
- } else {
- nActions = append(nActions, action)
- }
- }
- instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: nActions}}
- nInsts = append(nInsts, &ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction})
- } else {
- nInsts = append(nInsts, instruction)
- }
- }
- nFlow.Instructions = nInsts
- return nFlow
-}
-
-func excludeOxmOfbField(field *ofp.OfpOxmOfbField, exclude ...ofp.OxmOfbFieldTypes) bool {
- for _, fieldToExclude := range exclude {
- if field.Type == fieldToExclude {
- return true
- }
- }
- return false
-}
-
-func GetOfbFields(flow *ofp.OfpFlowStats, exclude ...ofp.OxmOfbFieldTypes) []*ofp.OfpOxmOfbField {
- if flow == nil || flow.Match == nil || flow.Match.Type != ofp.OfpMatchType_OFPMT_OXM {
- return nil
- }
- ofbFields := make([]*ofp.OfpOxmOfbField, 0)
- for _, field := range flow.Match.OxmFields {
- if field.OxmClass == ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
- ofbFields = append(ofbFields, field.GetOfbField())
- }
- }
- if len(exclude) == 0 {
- return ofbFields
- } else {
- filteredFields := make([]*ofp.OfpOxmOfbField, 0)
- for _, ofbField := range ofbFields {
- if !excludeOxmOfbField(ofbField, exclude...) {
- filteredFields = append(filteredFields, ofbField)
- }
- }
- return filteredFields
- }
-}
-
-func GetPacketOutPort(packet *ofp.OfpPacketOut) uint32 {
- if packet == nil {
- return 0
- }
- for _, action := range packet.GetActions() {
- if action.Type == OUTPUT {
- return action.GetOutput().Port
- }
- }
- return 0
-}
-
-func GetOutPort(flow *ofp.OfpFlowStats) uint32 {
- if flow == nil {
- return 0
- }
- for _, action := range GetActions(flow) {
- if action.Type == OUTPUT {
- out := action.GetOutput()
- if out == nil {
- return 0
- }
- return out.GetPort()
- }
- }
- return 0
-}
-
-func GetInPort(flow *ofp.OfpFlowStats) uint32 {
- if flow == nil {
- return 0
- }
- for _, field := range GetOfbFields(flow) {
- if field.Type == IN_PORT {
- return field.GetPort()
- }
- }
- return 0
-}
-
-func GetGotoTableId(flow *ofp.OfpFlowStats) uint32 {
- if flow == nil {
- return 0
- }
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE) {
- gotoTable := instruction.GetGotoTable()
- if gotoTable == nil {
- return 0
- }
- return gotoTable.GetTableId()
- }
- }
- return 0
-}
-
-func GetMeterId(flow *ofp.OfpFlowStats) uint32 {
- if flow == nil {
- return 0
- }
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_METER) {
- MeterInstruction := instruction.GetMeter()
- if MeterInstruction == nil {
- return 0
- }
- return MeterInstruction.GetMeterId()
- }
- }
- return 0
-}
-
-func GetVlanVid(flow *ofp.OfpFlowStats) *uint32 {
- if flow == nil {
- return nil
- }
- for _, field := range GetOfbFields(flow) {
- if field.Type == VLAN_VID {
- ret := field.GetVlanVid()
- return &ret
- }
- }
- // Dont return 0 if the field is missing as vlan id value 0 has meaning and cannot be overloaded as "not found"
- return nil
-}
-
-func GetTunnelId(flow *ofp.OfpFlowStats) uint64 {
- if flow == nil {
- return 0
- }
- for _, field := range GetOfbFields(flow) {
- if field.Type == TUNNEL_ID {
- return field.GetTunnelId()
- }
- }
- return 0
-}
-
-//GetMetaData - legacy get method (only want lower 32 bits)
-func GetMetaData(flow *ofp.OfpFlowStats) uint32 {
- if flow == nil {
- return 0
- }
- for _, field := range GetOfbFields(flow) {
- if field.Type == METADATA {
- return uint32(field.GetTableMetadata() & 0xFFFFFFFF)
- }
- }
- log.Debug("No-metadata-present")
- return 0
-}
-
-func GetMetaData64Bit(flow *ofp.OfpFlowStats) uint64 {
- if flow == nil {
- return 0
- }
- for _, field := range GetOfbFields(flow) {
- if field.Type == METADATA {
- return field.GetTableMetadata()
- }
- }
- log.Debug("No-metadata-present")
- return 0
-}
-
-// function returns write metadata value from write_metadata action field
-func GetMetadataFromWriteMetadataAction(flow *ofp.OfpFlowStats) uint64 {
- if flow != nil {
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(WRITE_METADATA) {
- if writeMetadata := instruction.GetWriteMetadata(); writeMetadata != nil {
- return writeMetadata.GetMetadata()
- }
- }
- }
- }
- log.Debugw("No-write-metadata-present", log.Fields{"flow": flow})
- return 0
-}
-
-func GetTechProfileIDFromWriteMetaData(metadata uint64) uint16 {
- /*
- Write metadata instruction value (metadata) is 8 bytes:
- MS 2 bytes: C Tag
- Next 2 bytes: Technology Profile Id
- Next 4 bytes: Port number (uni or nni)
-
- This is set in the ONOS OltPipeline as a write metadata instruction
- */
- var tpId uint16 = 0
- log.Debugw("Write metadata value for Techprofile ID", log.Fields{"metadata": metadata})
- if metadata != 0 {
- tpId = uint16((metadata >> 32) & 0xFFFF)
- log.Debugw("Found techprofile ID from write metadata action", log.Fields{"tpid": tpId})
- }
- return tpId
-}
-
-func GetEgressPortNumberFromWriteMetadata(flow *ofp.OfpFlowStats) uint32 {
- /*
- Write metadata instruction value (metadata) is 8 bytes:
- MS 2 bytes: C Tag
- Next 2 bytes: Technology Profile Id
- Next 4 bytes: Port number (uni or nni)
- This is set in the ONOS OltPipeline as a write metadata instruction
- */
- var uniPort uint32 = 0
- md := GetMetadataFromWriteMetadataAction(flow)
- log.Debugw("Metadata found for egress/uni port ", log.Fields{"metadata": md})
- if md != 0 {
- uniPort = uint32(md & 0xFFFFFFFF)
- log.Debugw("Found EgressPort from write metadata action", log.Fields{"egress_port": uniPort})
- }
- return uniPort
-
-}
-
-func GetInnerTagFromMetaData(flow *ofp.OfpFlowStats) uint16 {
- /*
- Write metadata instruction value (metadata) is 8 bytes:
- MS 2 bytes: C Tag
- Next 2 bytes: Technology Profile Id
- Next 4 bytes: Port number (uni or nni)
- This is set in the ONOS OltPipeline as a write metadata instruction
- */
- var innerTag uint16 = 0
- md := GetMetadataFromWriteMetadataAction(flow)
- if md != 0 {
- innerTag = uint16((md >> 48) & 0xFFFF)
- log.Debugw("Found CVLAN from write metadate action", log.Fields{"c_vlan": innerTag})
- }
- return innerTag
-}
-
-//GetInnerTagFromMetaData retrieves the inner tag from the Metadata_ofp. The port number (UNI on ONU) is in the
-// lower 32-bits of Metadata_ofp and the inner_tag is in the upper 32-bits. This is set in the ONOS OltPipeline as
-//// a Metadata_ofp field
-/*func GetInnerTagFromMetaData(flow *ofp.OfpFlowStats) uint64 {
- md := GetMetaData64Bit(flow)
- if md == 0 {
- return 0
- }
- if md <= 0xffffffff {
- log.Debugw("onos-upgrade-suggested", log.Fields{"Metadata_ofp": md, "message": "Legacy MetaData detected form OltPipeline"})
- return md
- }
- return (md >> 32) & 0xffffffff
-}*/
-
-// Extract the child device port from a flow that contains the parent device peer port. Typically the UNI port of an
-// ONU child device. Per TST agreement this will be the lower 32 bits of tunnel id reserving upper 32 bits for later
-// use
-func GetChildPortFromTunnelId(flow *ofp.OfpFlowStats) uint32 {
- tid := GetTunnelId(flow)
- if tid == 0 {
- return 0
- }
- // Per TST agreement we are keeping any child port id (uni port id) in the lower 32 bits
- return uint32(tid & 0xffffffff)
-}
-
-func HasNextTable(flow *ofp.OfpFlowStats) bool {
- if flow == nil {
- return false
- }
- return GetGotoTableId(flow) != 0
-}
-
-func GetGroup(flow *ofp.OfpFlowStats) uint32 {
- if flow == nil {
- return 0
- }
- for _, action := range GetActions(flow) {
- if action.Type == GROUP {
- grp := action.GetGroup()
- if grp == nil {
- return 0
- }
- return grp.GetGroupId()
- }
- }
- return 0
-}
-
-func HasGroup(flow *ofp.OfpFlowStats) bool {
- return GetGroup(flow) != 0
-}
-
-// GetNextTableId returns the next table ID if the "table_id" is present in the map, otherwise return nil
-func GetNextTableId(kw OfpFlowModArgs) *uint32 {
- if val, exist := kw["table_id"]; exist {
- ret := uint32(val)
- return &ret
- }
- return nil
-}
-
-// GetMeterIdFlowModArgs returns the meterId if the "meter_id" is present in the map, otherwise return 0
-func GetMeterIdFlowModArgs(kw OfpFlowModArgs) uint32 {
- if val, exist := kw["meter_id"]; exist {
- return uint32(val)
- }
- return 0
-}
-
-// Function returns the metadata if the "write_metadata" is present in the map, otherwise return nil
-func GetMetadataFlowModArgs(kw OfpFlowModArgs) uint64 {
- if val, exist := kw["write_metadata"]; exist {
- ret := uint64(val)
- return ret
- }
- return 0
-}
-
-// Return unique 64-bit integer hash for flow covering the following attributes:
-// 'table_id', 'priority', 'flags', 'cookie', 'match', '_instruction_string'
-func HashFlowStats(flow *ofp.OfpFlowStats) uint64 {
- if flow == nil { // Should never happen
- return 0
- }
- // Create string with the instructions field first
- var instructionString bytes.Buffer
- for _, instruction := range flow.Instructions {
- instructionString.WriteString(instruction.String())
- }
- var flowString = fmt.Sprintf("%d%d%d%d%s%s", flow.TableId, flow.Priority, flow.Flags, flow.Cookie, flow.Match.String(), instructionString.String())
- h := md5.New()
- h.Write([]byte(flowString))
- hash := big.NewInt(0)
- hash.SetBytes(h.Sum(nil))
- return hash.Uint64()
-}
-
-// flowStatsEntryFromFlowModMessage maps an ofp_flow_mod message to an ofp_flow_stats message
-func FlowStatsEntryFromFlowModMessage(mod *ofp.OfpFlowMod) *ofp.OfpFlowStats {
- flow := &ofp.OfpFlowStats{}
- if mod == nil {
- return flow
- }
- flow.TableId = mod.TableId
- flow.Priority = mod.Priority
- flow.IdleTimeout = mod.IdleTimeout
- flow.HardTimeout = mod.HardTimeout
- flow.Flags = mod.Flags
- flow.Cookie = mod.Cookie
- flow.Match = mod.Match
- flow.Instructions = mod.Instructions
- flow.Id = HashFlowStats(flow)
- return flow
-}
-
-func GroupEntryFromGroupMod(mod *ofp.OfpGroupMod) *ofp.OfpGroupEntry {
- group := &ofp.OfpGroupEntry{}
- if mod == nil {
- return group
- }
- group.Desc = &ofp.OfpGroupDesc{Type: mod.Type, GroupId: mod.GroupId, Buckets: mod.Buckets}
- group.Stats = &ofp.OfpGroupStats{GroupId: mod.GroupId}
- //TODO do we need to instantiate bucket bins?
- return group
-}
-
-// flowStatsEntryFromFlowModMessage maps an ofp_flow_mod message to an ofp_flow_stats message
-func MeterEntryFromMeterMod(meterMod *ofp.OfpMeterMod) *ofp.OfpMeterEntry {
- bandStats := make([]*ofp.OfpMeterBandStats, 0)
- meter := &ofp.OfpMeterEntry{Config: &ofp.OfpMeterConfig{},
- Stats: &ofp.OfpMeterStats{BandStats: bandStats}}
- if meterMod == nil {
- log.Error("Invalid meter mod command")
- return meter
- }
- // config init
- meter.Config.MeterId = meterMod.MeterId
- meter.Config.Flags = meterMod.Flags
- meter.Config.Bands = meterMod.Bands
- // meter stats init
- meter.Stats.MeterId = meterMod.MeterId
- meter.Stats.FlowCount = 0
- meter.Stats.PacketInCount = 0
- meter.Stats.ByteInCount = 0
- meter.Stats.DurationSec = 0
- meter.Stats.DurationNsec = 0
- // band stats init
- for _, _ = range meterMod.Bands {
- band := &ofp.OfpMeterBandStats{}
- band.PacketBandCount = 0
- band.ByteBandCount = 0
- bandStats = append(bandStats, band)
- }
- meter.Stats.BandStats = bandStats
- log.Debugw("Allocated meter entry", log.Fields{"meter": *meter})
- return meter
-
-}
-
-func GetMeterIdFromFlow(flow *ofp.OfpFlowStats) uint32 {
- if flow != nil {
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(METER_ACTION) {
- if meterInst := instruction.GetMeter(); meterInst != nil {
- return meterInst.GetMeterId()
- }
- }
- }
- }
-
- return uint32(0)
-}
-
-func MkOxmFields(matchFields []ofp.OfpOxmField) []*ofp.OfpOxmField {
- oxmFields := make([]*ofp.OfpOxmField, 0)
- for _, matchField := range matchFields {
- oxmField := ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: matchField.Field}
- oxmFields = append(oxmFields, &oxmField)
- }
- return oxmFields
-}
-
-func MkInstructionsFromActions(actions []*ofp.OfpAction) []*ofp.OfpInstruction {
- instructions := make([]*ofp.OfpInstruction, 0)
- instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: actions}}
- instruction := ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction}
- instructions = append(instructions, &instruction)
- return instructions
-}
-
-// Convenience function to generare ofp_flow_mod message with OXM BASIC match composed from the match_fields, and
-// single APPLY_ACTIONS instruction with a list if ofp_action objects.
-func MkSimpleFlowMod(matchFields []*ofp.OfpOxmField, actions []*ofp.OfpAction, command *ofp.OfpFlowModCommand, kw OfpFlowModArgs) *ofp.OfpFlowMod {
-
- // Process actions instructions
- instructions := make([]*ofp.OfpInstruction, 0)
- instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: actions}}
- instruction := ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction}
- instructions = append(instructions, &instruction)
-
- // Process next table
- if tableId := GetNextTableId(kw); tableId != nil {
- var instGotoTable ofp.OfpInstruction_GotoTable
- instGotoTable.GotoTable = &ofp.OfpInstructionGotoTable{TableId: *tableId}
- inst := ofp.OfpInstruction{Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE), Data: &instGotoTable}
- instructions = append(instructions, &inst)
- }
- // Process meter action
- if meterId := GetMeterIdFlowModArgs(kw); meterId != 0 {
- var instMeter ofp.OfpInstruction_Meter
- instMeter.Meter = &ofp.OfpInstructionMeter{MeterId: meterId}
- inst := ofp.OfpInstruction{Type: uint32(METER_ACTION), Data: &instMeter}
- instructions = append(instructions, &inst)
- }
- //process write_metadata action
- if metadata := GetMetadataFlowModArgs(kw); metadata != 0 {
- var instWriteMetadata ofp.OfpInstruction_WriteMetadata
- instWriteMetadata.WriteMetadata = &ofp.OfpInstructionWriteMetadata{Metadata: metadata}
- inst := ofp.OfpInstruction{Type: uint32(WRITE_METADATA), Data: &instWriteMetadata}
- instructions = append(instructions, &inst)
- }
-
- // Process match fields
- oxmFields := make([]*ofp.OfpOxmField, 0)
- for _, matchField := range matchFields {
- oxmField := ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: matchField.Field}
- oxmFields = append(oxmFields, &oxmField)
- }
- var match ofp.OfpMatch
- match.Type = ofp.OfpMatchType_OFPMT_OXM
- match.OxmFields = oxmFields
-
- // Create ofp_flow_message
- msg := &ofp.OfpFlowMod{}
- if command == nil {
- msg.Command = ofp.OfpFlowModCommand_OFPFC_ADD
- } else {
- msg.Command = *command
- }
- msg.Instructions = instructions
- msg.Match = &match
-
- // Set the variadic argument values
- msg = setVariadicModAttributes(msg, kw)
-
- return msg
-}
-
-func MkMulticastGroupMod(groupId uint32, buckets []*ofp.OfpBucket, command *ofp.OfpGroupModCommand) *ofp.OfpGroupMod {
- group := &ofp.OfpGroupMod{}
- if command == nil {
- group.Command = ofp.OfpGroupModCommand_OFPGC_ADD
- } else {
- group.Command = *command
- }
- group.Type = ofp.OfpGroupType_OFPGT_ALL
- group.GroupId = groupId
- group.Buckets = buckets
- return group
-}
-
-//SetVariadicModAttributes sets only uint64 or uint32 fields of the ofp_flow_mod message
-func setVariadicModAttributes(mod *ofp.OfpFlowMod, args OfpFlowModArgs) *ofp.OfpFlowMod {
- if args == nil {
- return mod
- }
- for key, val := range args {
- switch key {
- case "cookie":
- mod.Cookie = val
- case "cookie_mask":
- mod.CookieMask = val
- case "table_id":
- mod.TableId = uint32(val)
- case "idle_timeout":
- mod.IdleTimeout = uint32(val)
- case "hard_timeout":
- mod.HardTimeout = uint32(val)
- case "priority":
- mod.Priority = uint32(val)
- case "buffer_id":
- mod.BufferId = uint32(val)
- case "out_port":
- mod.OutPort = uint32(val)
- case "out_group":
- mod.OutGroup = uint32(val)
- case "flags":
- mod.Flags = uint32(val)
- }
- }
- return mod
-}
-
-func MkPacketIn(port uint32, packet []byte) *ofp.OfpPacketIn {
- packetIn := &ofp.OfpPacketIn{
- Reason: ofp.OfpPacketInReason_OFPR_ACTION,
- Match: &ofp.OfpMatch{
- Type: ofp.OfpMatchType_OFPMT_OXM,
- OxmFields: []*ofp.OfpOxmField{
- {
- OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC,
- Field: &ofp.OfpOxmField_OfbField{
- OfbField: InPort(port)},
- },
- },
- },
- Data: packet,
- }
- return packetIn
-}
-
-// MkFlowStat is a helper method to build flows
-func MkFlowStat(fa *FlowArgs) *ofp.OfpFlowStats {
- //Build the match-fields
- matchFields := make([]*ofp.OfpOxmField, 0)
- for _, val := range fa.MatchFields {
- matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
- }
- return FlowStatsEntryFromFlowModMessage(MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV))
-}
-
-func MkGroupStat(ga *GroupArgs) *ofp.OfpGroupEntry {
- return GroupEntryFromGroupMod(MkMulticastGroupMod(ga.GroupId, ga.Buckets, ga.Command))
-}
-
-type OfpFlowModArgs map[string]uint64
-
-type FlowArgs struct {
- MatchFields []*ofp.OfpOxmOfbField
- Actions []*ofp.OfpAction
- Command *ofp.OfpFlowModCommand
- Priority uint32
- KV OfpFlowModArgs
-}
-
-type GroupArgs struct {
- GroupId uint32
- Buckets []*ofp.OfpBucket
- Command *ofp.OfpGroupModCommand
-}
-
-type FlowsAndGroups struct {
- Flows *ordered_map.OrderedMap
- Groups *ordered_map.OrderedMap
-}
-
-func NewFlowsAndGroups() *FlowsAndGroups {
- var fg FlowsAndGroups
- fg.Flows = ordered_map.NewOrderedMap()
- fg.Groups = ordered_map.NewOrderedMap()
- return &fg
-}
-
-func (fg *FlowsAndGroups) Copy() *FlowsAndGroups {
- copyFG := NewFlowsAndGroups()
- iter := fg.Flows.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
- copyFG.Flows.Set(kv.Key, proto.Clone(protoMsg))
- }
- }
- iter = fg.Groups.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
- copyFG.Groups.Set(kv.Key, proto.Clone(protoMsg))
- }
- }
- return copyFG
-}
-
-func (fg *FlowsAndGroups) GetFlow(index int) *ofp.OfpFlowStats {
- iter := fg.Flows.IterFunc()
- pos := 0
- for kv, ok := iter(); ok; kv, ok = iter() {
- if pos == index {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
- return protoMsg
- }
- return nil
- }
- pos += 1
- }
- return nil
-}
-
-func (fg *FlowsAndGroups) ListFlows() []*ofp.OfpFlowStats {
- flows := make([]*ofp.OfpFlowStats, 0)
- iter := fg.Flows.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
- flows = append(flows, protoMsg)
- }
- }
- return flows
-}
-
-func (fg *FlowsAndGroups) ListGroups() []*ofp.OfpGroupEntry {
- groups := make([]*ofp.OfpGroupEntry, 0)
- iter := fg.Groups.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
- groups = append(groups, protoMsg)
- }
- }
- return groups
-}
-
-func (fg *FlowsAndGroups) String() string {
- var buffer bytes.Buffer
- iter := fg.Flows.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
- buffer.WriteString("\nFlow:\n")
- buffer.WriteString(proto.MarshalTextString(protoMsg))
- buffer.WriteString("\n")
- }
- }
- iter = fg.Groups.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
- buffer.WriteString("\nGroup:\n")
- buffer.WriteString(proto.MarshalTextString(protoMsg))
- buffer.WriteString("\n")
- }
- }
- return buffer.String()
-}
-
-func (fg *FlowsAndGroups) AddFlow(flow *ofp.OfpFlowStats) {
- if flow == nil {
- return
- }
-
- if fg.Flows == nil {
- fg.Flows = ordered_map.NewOrderedMap()
- }
- if fg.Groups == nil {
- fg.Groups = ordered_map.NewOrderedMap()
- }
- //Add flow only if absent
- if _, exist := fg.Flows.Get(flow.Id); !exist {
- fg.Flows.Set(flow.Id, flow)
- }
-}
-
-func (fg *FlowsAndGroups) AddGroup(group *ofp.OfpGroupEntry) {
- if group == nil {
- return
- }
-
- if fg.Flows == nil {
- fg.Flows = ordered_map.NewOrderedMap()
- }
- if fg.Groups == nil {
- fg.Groups = ordered_map.NewOrderedMap()
- }
- //Add group only if absent
- if _, exist := fg.Groups.Get(group.Desc.GroupId); !exist {
- fg.Groups.Set(group.Desc.GroupId, group)
- }
-}
-
-//AddFrom add flows and groups from the argument into this structure only if they do not already exist
-func (fg *FlowsAndGroups) AddFrom(from *FlowsAndGroups) {
- iter := from.Flows.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpFlowStats); isMsg {
- if _, exist := fg.Flows.Get(protoMsg.Id); !exist {
- fg.Flows.Set(protoMsg.Id, protoMsg)
- }
- }
- }
- iter = from.Groups.IterFunc()
- for kv, ok := iter(); ok; kv, ok = iter() {
- if protoMsg, isMsg := kv.Value.(*ofp.OfpGroupEntry); isMsg {
- if _, exist := fg.Groups.Get(protoMsg.Stats.GroupId); !exist {
- fg.Groups.Set(protoMsg.Stats.GroupId, protoMsg)
- }
- }
- }
-}
-
-type DeviceRules struct {
- Rules map[string]*FlowsAndGroups
-}
-
-func NewDeviceRules() *DeviceRules {
- var dr DeviceRules
- dr.Rules = make(map[string]*FlowsAndGroups)
- return &dr
-}
-
-func (dr *DeviceRules) Copy() *DeviceRules {
- copyDR := NewDeviceRules()
- if dr != nil {
- for key, val := range dr.Rules {
- if val != nil {
- copyDR.Rules[key] = val.Copy()
- }
- }
- }
- return copyDR
-}
-
-func (dr *DeviceRules) ClearFlows(deviceId string) {
- if _, exist := dr.Rules[deviceId]; exist {
- dr.Rules[deviceId].Flows = ordered_map.NewOrderedMap()
- }
-}
-
-func (dr *DeviceRules) FilterRules(deviceIds map[string]string) *DeviceRules {
- filteredDR := NewDeviceRules()
- for key, val := range dr.Rules {
- if _, exist := deviceIds[key]; exist {
- filteredDR.Rules[key] = val.Copy()
- }
- }
- return filteredDR
-}
-
-func (dr *DeviceRules) AddFlow(deviceId string, flow *ofp.OfpFlowStats) {
- if _, exist := dr.Rules[deviceId]; !exist {
- dr.Rules[deviceId] = NewFlowsAndGroups()
- }
- dr.Rules[deviceId].AddFlow(flow)
-}
-
-func (dr *DeviceRules) GetRules() map[string]*FlowsAndGroups {
- return dr.Rules
-}
-
-func (dr *DeviceRules) String() string {
- var buffer bytes.Buffer
- for key, value := range dr.Rules {
- buffer.WriteString("DeviceId:")
- buffer.WriteString(key)
- buffer.WriteString(value.String())
- buffer.WriteString("\n\n")
- }
- return buffer.String()
-}
-
-func (dr *DeviceRules) AddFlowsAndGroup(deviceId string, fg *FlowsAndGroups) {
- if _, ok := dr.Rules[deviceId]; !ok {
- dr.Rules[deviceId] = NewFlowsAndGroups()
- }
- dr.Rules[deviceId] = fg
-}
-
-// CreateEntryIfNotExist creates a new deviceId in the Map if it does not exist and assigns an
-// empty FlowsAndGroups to it. Otherwise, it does nothing.
-func (dr *DeviceRules) CreateEntryIfNotExist(deviceId string) {
- if _, ok := dr.Rules[deviceId]; !ok {
- dr.Rules[deviceId] = NewFlowsAndGroups()
- }
-}
-
-/*
- * Common flow routines
- */
-
-//FindOverlappingFlows return a list of overlapping flow(s) where mod is the flow request
-func FindOverlappingFlows(flows []*ofp.OfpFlowStats, mod *ofp.OfpFlowMod) []*ofp.OfpFlowStats {
- return nil //TODO - complete implementation
-}
-
-// FindFlowById returns the index of the flow in the flows array if present. Otherwise, it returns -1
-func FindFlowById(flows []*ofp.OfpFlowStats, flow *ofp.OfpFlowStats) int {
- for idx, f := range flows {
- if flow.Id == f.Id {
- return idx
- }
- }
- return -1
-}
-
-// FindFlows returns the index in flows where flow if present. Otherwise, it returns -1
-func FindFlows(flows []*ofp.OfpFlowStats, flow *ofp.OfpFlowStats) int {
- for idx, f := range flows {
- if FlowMatch(f, flow) {
- return idx
- }
- }
- return -1
-}
-
-//FlowMatch returns true if two flows matches on the following flow attributes:
-//TableId, Priority, Flags, Cookie, Match
-func FlowMatch(f1 *ofp.OfpFlowStats, f2 *ofp.OfpFlowStats) bool {
- if f1 == nil || f2 == nil {
- return false
- }
- keysMatter := []string{"TableId", "Priority", "Flags", "Cookie", "Match"}
- for _, key := range keysMatter {
- switch key {
- case "TableId":
- if f1.TableId != f2.TableId {
- return false
- }
- case "Priority":
- if f1.Priority != f2.Priority {
- return false
- }
- case "Flags":
- if f1.Flags != f2.Flags {
- return false
- }
- case "Cookie":
- if f1.Cookie != f2.Cookie {
- return false
- }
- case "Match":
- if strings.Compare(f1.Match.String(), f2.Match.String()) != 0 {
- return false
- }
- }
- }
- return true
-}
-
-//FlowMatchesMod returns True if given flow is "covered" by the wildcard flow_mod, taking into consideration of
-//both exact matches as well as masks-based match fields if any. Otherwise return False
-func FlowMatchesMod(flow *ofp.OfpFlowStats, mod *ofp.OfpFlowMod) bool {
- if flow == nil || mod == nil {
- return false
- }
- //Check if flow.cookie is covered by mod.cookie and mod.cookie_mask
- if (flow.Cookie & mod.CookieMask) != (mod.Cookie & mod.CookieMask) {
- return false
- }
-
- //Check if flow.table_id is covered by flow_mod.table_id
- if mod.TableId != uint32(ofp.OfpTable_OFPTT_ALL) && flow.TableId != mod.TableId {
- return false
- }
-
- //Check out_port
- if (mod.OutPort&0x7fffffff) != uint32(ofp.OfpPortNo_OFPP_ANY) && !FlowHasOutPort(flow, mod.OutPort) {
- return false
- }
-
- // Check out_group
- if (mod.OutGroup&0x7fffffff) != uint32(ofp.OfpGroup_OFPG_ANY) && !FlowHasOutGroup(flow, mod.OutGroup) {
- return false
- }
-
- //Priority is ignored
-
- //Check match condition
- //If the flow_mod match field is empty, that is a special case and indicates the flow entry matches
- if (mod.Match == nil) || (mod.Match.OxmFields == nil) || (len(mod.Match.OxmFields) == 0) {
- //If we got this far and the match is empty in the flow spec, than the flow matches
- return true
- } // TODO : implement the flow match analysis
- return false
-
-}
-
-//FlowHasOutPort returns True if flow has a output command with the given out_port
-func FlowHasOutPort(flow *ofp.OfpFlowStats, outPort uint32) bool {
- if flow == nil {
- return false
- }
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
- if instruction.GetActions() == nil {
- return false
- }
- for _, action := range instruction.GetActions().Actions {
- if action.Type == ofp.OfpActionType_OFPAT_OUTPUT {
- if (action.GetOutput() != nil) && (action.GetOutput().Port == outPort) {
- return true
- }
- }
-
- }
- }
- }
- return false
-}
-
-//FlowHasOutGroup return True if flow has a output command with the given out_group
-func FlowHasOutGroup(flow *ofp.OfpFlowStats, groupID uint32) bool {
- if flow == nil {
- return false
- }
- for _, instruction := range flow.Instructions {
- if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
- if instruction.GetActions() == nil {
- return false
- }
- for _, action := range instruction.GetActions().Actions {
- if action.Type == ofp.OfpActionType_OFPAT_GROUP {
- if (action.GetGroup() != nil) && (action.GetGroup().GroupId == groupID) {
- return true
- }
- }
-
- }
- }
- }
- return false
-}
-
-//FindGroup returns index of group if found, else returns -1
-func FindGroup(groups []*ofp.OfpGroupEntry, groupId uint32) int {
- for idx, group := range groups {
- if group.Desc.GroupId == groupId {
- return idx
- }
- }
- return -1
-}
-
-func FlowsDeleteByGroupId(flows []*ofp.OfpFlowStats, groupId uint32) (bool, []*ofp.OfpFlowStats) {
- toKeep := make([]*ofp.OfpFlowStats, 0)
-
- for _, f := range flows {
- if !FlowHasOutGroup(f, groupId) {
- toKeep = append(toKeep, f)
- }
- }
- return len(toKeep) < len(flows), toKeep
-}
-
-func ToOfpOxmField(from []*ofp.OfpOxmOfbField) []*ofp.OfpOxmField {
- matchFields := make([]*ofp.OfpOxmField, 0)
- for _, val := range from {
- matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
- }
- return matchFields
-}
diff --git a/rw_core/utils/flow_utils_test.go b/rw_core/utils/flow_utils_test.go
deleted file mode 100644
index c51a778..0000000
--- a/rw_core/utils/flow_utils_test.go
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * Copyright 2019-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package utils
-
-import (
- "github.com/opencord/voltha-lib-go/pkg/log"
- ofp "github.com/opencord/voltha-protos/go/openflow_13"
- "github.com/stretchr/testify/assert"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/status"
- "strings"
- "testing"
-)
-
-func init() {
- log.AddPackage(log.JSON, log.WarnLevel, nil)
- timeoutError = status.Errorf(codes.Aborted, "timeout")
- taskFailureError = status.Error(codes.Internal, "test failure task")
-}
-
-func TestFlowsAndGroups_AddFlow(t *testing.T) {
- fg := NewFlowsAndGroups()
- allFlows := fg.ListFlows()
- assert.Equal(t, 0, len(allFlows))
- fg.AddFlow(nil)
- allFlows = fg.ListFlows()
- assert.Equal(t, 0, len(allFlows))
-
- var fa *FlowArgs
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(1),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1),
- TunnelId(uint64(1)),
- EthType(0x0800),
- Ipv4Dst(0xffffffff),
- IpProto(17),
- UdpSrc(68),
- UdpDst(67),
- },
- Actions: []*ofp.OfpAction{
- PushVlan(0x8100),
- SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
- Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
- },
- }
- flow := MkFlowStat(fa)
- fg.AddFlow(flow)
-
- allFlows = fg.ListFlows()
- assert.Equal(t, 1, len(allFlows))
- assert.True(t, FlowMatch(flow, allFlows[0]))
-}
-
-func TestFlowsAndGroups_AddGroup(t *testing.T) {
- var ga *GroupArgs
-
- fg := NewFlowsAndGroups()
- allGroups := fg.ListGroups()
- assert.Equal(t, 0, len(allGroups))
- fg.AddGroup(nil)
- allGroups = fg.ListGroups()
- assert.Equal(t, 0, len(allGroups))
-
- ga = &GroupArgs{
- GroupId: 10,
- Buckets: []*ofp.OfpBucket{
- {Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- },
- },
- }
- group := MkGroupStat(ga)
- fg.AddGroup(group)
-
- allGroups = fg.ListGroups()
- assert.Equal(t, 1, len(allGroups))
- assert.Equal(t, ga.GroupId, allGroups[0].Desc.GroupId)
-}
-
-func TestFlowsAndGroups_Copy(t *testing.T) {
- fg := NewFlowsAndGroups()
- var fa *FlowArgs
- var ga *GroupArgs
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- },
- Actions: []*ofp.OfpAction{
- SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 10)),
- Output(1),
- },
- }
- flow := MkFlowStat(fa)
- fg.AddFlow(flow)
-
- ga = &GroupArgs{
- GroupId: 10,
- Buckets: []*ofp.OfpBucket{
- {Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- },
- },
- }
- group := MkGroupStat(ga)
- fg.AddGroup(group)
-
- fgCopy := fg.Copy()
-
- allFlows := fgCopy.ListFlows()
- assert.Equal(t, 1, len(allFlows))
- assert.True(t, FlowMatch(flow, allFlows[0]))
-
- allGroups := fgCopy.ListGroups()
- assert.Equal(t, 1, len(allGroups))
- assert.Equal(t, ga.GroupId, allGroups[0].Desc.GroupId)
-
- fg = NewFlowsAndGroups()
- fgCopy = fg.Copy()
- allFlows = fgCopy.ListFlows()
- allGroups = fgCopy.ListGroups()
- assert.Equal(t, 0, len(allFlows))
- assert.Equal(t, 0, len(allGroups))
-}
-
-func TestFlowsAndGroups_GetFlow(t *testing.T) {
- fg := NewFlowsAndGroups()
- var fa1 *FlowArgs
- var fa2 *FlowArgs
- var ga *GroupArgs
-
- fa1 = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- Metadata_ofp((1000 << 32) | 1),
- VlanPcp(0),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- },
- }
- flow1 := MkFlowStat(fa1)
-
- fa2 = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 1500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(5),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- },
- Actions: []*ofp.OfpAction{
- PushVlan(0x8100),
- SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
- SetField(VlanPcp(0)),
- Output(2),
- },
- }
- flow2 := MkFlowStat(fa2)
-
- fg.AddFlow(flow1)
- fg.AddFlow(flow2)
-
- ga = &GroupArgs{
- GroupId: 10,
- Buckets: []*ofp.OfpBucket{
- {Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- },
- },
- }
- group := MkGroupStat(ga)
- fg.AddGroup(group)
-
- gf1 := fg.GetFlow(0)
- assert.True(t, FlowMatch(flow1, gf1))
-
- gf2 := fg.GetFlow(1)
- assert.True(t, FlowMatch(flow2, gf2))
-
- gf3 := fg.GetFlow(2)
- assert.Nil(t, gf3)
-
- allFlows := fg.ListFlows()
- assert.True(t, FlowMatch(flow1, allFlows[0]))
- assert.True(t, FlowMatch(flow2, allFlows[1]))
-}
-
-func TestFlowsAndGroups_String(t *testing.T) {
- fg := NewFlowsAndGroups()
- var fa *FlowArgs
- var ga *GroupArgs
-
- str := fg.String()
- assert.True(t, str == "")
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Group(10),
- },
- }
- flow := MkFlowStat(fa)
- fg.AddFlow(flow)
-
- ga = &GroupArgs{
- GroupId: 10,
- Buckets: []*ofp.OfpBucket{
- {Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- },
- },
- }
- group := MkGroupStat(ga)
- fg.AddGroup(group)
-
- str = fg.String()
- assert.True(t, strings.Contains(str, "id: 1143307409938767207"))
- assert.True(t, strings.Contains(str, "group_id: 10"))
- assert.True(t, strings.Contains(str, "oxm_class: OFPXMC_OPENFLOW_BASICOFPXMC_OPENFLOW_BASIC"))
- assert.True(t, strings.Contains(str, "type: OFPXMT_OFB_VLAN_VIDOFPXMT_OFB_VLAN_VID"))
- assert.True(t, strings.Contains(str, "vlan_vid: 4096"))
- assert.True(t, strings.Contains(str, "buckets:"))
-}
-
-func TestFlowsAndGroups_AddFrom(t *testing.T) {
- fg := NewFlowsAndGroups()
- var fa *FlowArgs
- var ga *GroupArgs
-
- str := fg.String()
- assert.True(t, str == "")
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- Metadata_ofp(1000),
- TunnelId(uint64(1)),
- VlanPcp(0),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- }
- flow := MkFlowStat(fa)
- fg.AddFlow(flow)
-
- ga = &GroupArgs{
- GroupId: 10,
- Buckets: []*ofp.OfpBucket{
- {Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- },
- },
- }
- group := MkGroupStat(ga)
- fg.AddGroup(group)
-
- fg1 := NewFlowsAndGroups()
- fg1.AddFrom(fg)
-
- allFlows := fg1.ListFlows()
- allGroups := fg1.ListGroups()
- assert.Equal(t, 1, len(allFlows))
- assert.Equal(t, 1, len(allGroups))
- assert.True(t, FlowMatch(flow, allFlows[0]))
- assert.Equal(t, group.Desc.GroupId, allGroups[0].Desc.GroupId)
-}
-
-func TestDeviceRules_AddFlow(t *testing.T) {
- dr := NewDeviceRules()
- rules := dr.GetRules()
- assert.True(t, len(rules) == 0)
-
- dr.AddFlow("123456", nil)
- rules = dr.GetRules()
- assert.True(t, len(rules) == 1)
- val, ok := rules["123456"]
- assert.True(t, ok)
- assert.Equal(t, 0, len(val.ListFlows()))
- assert.Equal(t, 0, len(val.ListGroups()))
-
- var fa *FlowArgs
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- Metadata_ofp(1000),
- TunnelId(uint64(1)),
- VlanPcp(0),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- }
- flow := MkFlowStat(fa)
- dr.AddFlow("123456", flow)
- rules = dr.GetRules()
- assert.True(t, len(rules) == 1)
- val, ok = rules["123456"]
- assert.True(t, ok)
- assert.Equal(t, 1, len(val.ListFlows()))
- assert.True(t, FlowMatch(flow, val.ListFlows()[0]))
- assert.Equal(t, 0, len(val.ListGroups()))
-}
-
-func TestDeviceRules_AddFlowsAndGroup(t *testing.T) {
- fg := NewFlowsAndGroups()
- var fa *FlowArgs
- var ga *GroupArgs
-
- str := fg.String()
- assert.True(t, str == "")
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 2000},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- Metadata_ofp(1000),
- TunnelId(uint64(1)),
- VlanPcp(0),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- }
- flow := MkFlowStat(fa)
- fg.AddFlow(flow)
-
- ga = &GroupArgs{
- GroupId: 10,
- Buckets: []*ofp.OfpBucket{
- {Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- },
- },
- }
- group := MkGroupStat(ga)
- fg.AddGroup(group)
-
- dr := NewDeviceRules()
- dr.AddFlowsAndGroup("123456", fg)
- rules := dr.GetRules()
- assert.True(t, len(rules) == 1)
- val, ok := rules["123456"]
- assert.True(t, ok)
- assert.Equal(t, 1, len(val.ListFlows()))
- assert.Equal(t, 1, len(val.ListGroups()))
- assert.True(t, FlowMatch(flow, val.ListFlows()[0]))
- assert.Equal(t, 10, int(val.ListGroups()[0].Desc.GroupId))
-}
-
-func TestFlowHasOutPort(t *testing.T) {
- var flow *ofp.OfpFlowStats
- assert.False(t, FlowHasOutPort(flow, 1))
-
- fa := &FlowArgs{
- KV: OfpFlowModArgs{"priority": 2000},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- Metadata_ofp(1000),
- TunnelId(uint64(1)),
- VlanPcp(0),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- }
- flow = MkFlowStat(fa)
- assert.True(t, FlowHasOutPort(flow, 1))
- assert.False(t, FlowHasOutPort(flow, 2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 2000},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- },
- }
- flow = MkFlowStat(fa)
- assert.False(t, FlowHasOutPort(flow, 1))
-}
-
-func TestFlowHasOutGroup(t *testing.T) {
- var flow *ofp.OfpFlowStats
- assert.False(t, FlowHasOutGroup(flow, 10))
-
- fa := &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Group(10),
- },
- }
- flow = MkFlowStat(fa)
- assert.True(t, FlowHasOutGroup(flow, 10))
- assert.False(t, FlowHasOutGroup(flow, 11))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Output(1),
- },
- }
- flow = MkFlowStat(fa)
- assert.False(t, FlowHasOutGroup(flow, 1))
-}
-
-func TestMatchFlow(t *testing.T) {
- assert.False(t, FlowMatch(nil, nil))
- fa := &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Group(10),
- },
- }
- flow1 := MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, nil))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Group(10),
- },
- }
- flow2 := MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
- assert.False(t, FlowMatch(nil, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.True(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 501, "table_id": 1, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Group(10),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 2, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268467, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 14},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(4),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.False(t, FlowMatch(flow1, flow2))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1, "cookie": 38268468, "flags": 12},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- }
- flow2 = MkFlowStat(fa)
- assert.True(t, FlowMatch(flow1, flow2))
-}
-
-func TestFlowMatchesMod(t *testing.T) {
- assert.False(t, FlowMatchesMod(nil, nil))
- fa := &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- Output(1),
- Group(10),
- },
- }
- flow := MkFlowStat(fa)
- assert.False(t, FlowMatchesMod(flow, nil))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"priority": 500, "table_id": 1},
- MatchFields: []*ofp.OfpOxmOfbField{
- InPort(2),
- VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
- VlanPcp(0),
- EthType(0x800),
- Ipv4Dst(0xe00a0a0a),
- },
- Actions: []*ofp.OfpAction{
- PopVlan(),
- Output(1),
- },
- }
- flowMod := MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
- assert.False(t, FlowMatchesMod(nil, flowMod))
- assert.False(t, FlowMatchesMod(flow, flowMod))
- assert.True(t, FlowMatch(flow, FlowStatsEntryFromFlowModMessage(flowMod)))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"table_id": uint64(ofp.OfpTable_OFPTT_ALL),
- "cookie_mask": 0,
- "out_port": uint64(ofp.OfpPortNo_OFPP_ANY),
- "out_group": uint64(ofp.OfpGroup_OFPG_ANY),
- },
- }
- flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
- assert.True(t, FlowMatchesMod(flow, flowMod))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"table_id": 1,
- "cookie_mask": 0,
- "out_port": uint64(ofp.OfpPortNo_OFPP_ANY),
- "out_group": uint64(ofp.OfpGroup_OFPG_ANY),
- },
- }
- flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
- assert.True(t, FlowMatchesMod(flow, flowMod))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"table_id": 1,
- "cookie_mask": 0,
- "out_port": 1,
- "out_group": uint64(ofp.OfpGroup_OFPG_ANY),
- },
- }
- flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
- assert.True(t, FlowMatchesMod(flow, flowMod))
-
- fa = &FlowArgs{
- KV: OfpFlowModArgs{"table_id": 1,
- "cookie_mask": 0,
- "out_port": 1,
- "out_group": 10,
- },
- }
- flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
- assert.True(t, FlowMatchesMod(flow, flowMod))
-}