VOL-2632 Error propagation from HashFlowStats
Change-Id: If2872e97e2b6c3c751f64dadfef47bfde3a77551
diff --git a/go.mod b/go.mod
index 9888abb..3612c0a 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@
github.com/gogo/protobuf v1.3.0
github.com/golang/protobuf v1.3.2
github.com/google/uuid v1.1.1
- github.com/opencord/voltha-lib-go/v3 v3.0.14
+ github.com/opencord/voltha-lib-go/v3 v3.0.15
github.com/opencord/voltha-protos/v3 v3.2.3
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/stretchr/testify v1.4.0
diff --git a/go.sum b/go.sum
index fcdaf47..d8fa50f 100644
--- a/go.sum
+++ b/go.sum
@@ -190,8 +190,8 @@
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/opencord/voltha-lib-go/v3 v3.0.14 h1:klI6Qt5iA9bTqI42jflSbU6YyEMJRcpaqh6rRw7qNnI=
-github.com/opencord/voltha-lib-go/v3 v3.0.14/go.mod h1:69Y+rVd25Nq2SUeoY7Q1BXtwrcUPllG0erhq+aK8Qec=
+github.com/opencord/voltha-lib-go/v3 v3.0.15 h1:CA+L1iqzugusANjUYI5bneU4dY657mSzlSdzyHalMoU=
+github.com/opencord/voltha-lib-go/v3 v3.0.15/go.mod h1:69Y+rVd25Nq2SUeoY7Q1BXtwrcUPllG0erhq+aK8Qec=
github.com/opencord/voltha-protos/v3 v3.2.3 h1:Wv73mw1Ye0bCfyhOk5svgrlE2tLizHq6tQluoDq9Vg8=
github.com/opencord/voltha-protos/v3 v3.2.3/go.mod h1:RIGHt7b80BHpHh3ceodknh0DxUjUHCWSbYbZqRx7Og0=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/rw_core/core/logical_device_agent.go b/rw_core/core/logical_device_agent.go
index cfd486a..fc9dd92 100644
--- a/rw_core/core/logical_device_agent.go
+++ b/rw_core/core/logical_device_agent.go
@@ -814,6 +814,7 @@
var flows []*ofp.OfpFlowStats
var meters []*ofp.OfpMeterEntry
var flow *ofp.OfpFlowStats
+ var err error
if lDevice.Flows != nil && lDevice.Flows.Items != nil {
flows = lDevice.Flows.Items
@@ -832,13 +833,19 @@
log.Warnw("overlapped-flows", log.Fields{"logicaldeviceId": agent.logicalDeviceID})
} else {
// Add flow
- flow = fu.FlowStatsEntryFromFlowModMessage(mod)
+ flow, err = fu.FlowStatsEntryFromFlowModMessage(mod)
+ if err != nil {
+ return err
+ }
flows = append(flows, flow)
updatedFlows = append(updatedFlows, flow)
changed = true
}
} else {
- flow = fu.FlowStatsEntryFromFlowModMessage(mod)
+ flow, err = fu.FlowStatsEntryFromFlowModMessage(mod)
+ if err != nil {
+ return err
+ }
idx := fu.FindFlows(flows, flow)
if idx >= 0 {
oldFlow := flows[idx]
@@ -964,7 +971,11 @@
toDelete := make([]*ofp.OfpFlowStats, 0)
for _, f := range flows {
// Check whether the flow and the flowmod matches
- if fu.FlowMatch(f, fu.FlowStatsEntryFromFlowModMessage(mod)) {
+ fs, err := fu.FlowStatsEntryFromFlowModMessage(mod)
+ if err != nil {
+ return err
+ }
+ if fu.FlowMatch(f, fs) {
toDelete = append(toDelete, f)
continue
}
@@ -1098,7 +1109,10 @@
changedFlow := false
changedMeter := false
- flow := fu.FlowStatsEntryFromFlowModMessage(mod)
+ flow, err := fu.FlowStatsEntryFromFlowModMessage(mod)
+ if err != nil {
+ return err
+ }
flowsToDelete := make([]*ofp.OfpFlowStats, 0)
idx := fu.FindFlows(flows, flow)
if idx >= 0 {
diff --git a/rw_core/flowdecomposition/flow_decomposer.go b/rw_core/flowdecomposition/flow_decomposer.go
index 9e996dc..16754b9 100644
--- a/rw_core/flowdecomposition/flow_decomposer.go
+++ b/rw_core/flowdecomposition/flow_decomposer.go
@@ -74,7 +74,7 @@
// Handles special case of any controller-bound flow for a parent device
func (fd *FlowDecomposer) updateOutputPortForControllerBoundFlowForParentDevide(flow *ofp.OfpFlowStats,
- dr *fu.DeviceRules) *fu.DeviceRules {
+ dr *fu.DeviceRules) (*fu.DeviceRules, error) {
EAPOL := fu.EthType(0x888e)
IGMP := fu.IpProto(2)
UDP := fu.IpProto(17)
@@ -100,18 +100,21 @@
uint32(ofp.OfpPortNo_OFPP_CONTROLLER))
}
// Update flow Id as a change in the instruction field will result in a new flow ID
- f.Id = fu.HashFlowStats(f)
+ var err error
+ if f.Id, err = fu.HashFlowStats(f); err != nil {
+ return nil, err
+ }
newDeviceRules.AddFlow(deviceID, (proto.Clone(f)).(*ofp.OfpFlowStats))
}
}
}
- return newDeviceRules
+ return newDeviceRules, nil
}
//processControllerBoundFlow decomposes trap flows
func (fd *FlowDecomposer) processControllerBoundFlow(ctx context.Context, agent coreif.LogicalDeviceAgent, path []route.Hop,
- inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
+ inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) (*fu.DeviceRules, error) {
log.Debugw("trap-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "flow": flow})
deviceRules := fu.NewDeviceRules()
@@ -136,7 +139,11 @@
// Augment the matchfields with the ofpfields from the flow
fg := fu.NewFlowsAndGroups()
fa.MatchFields = append(fa.MatchFields, fu.GetOfbFields(flow, fu.IN_PORT)...)
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ if err != nil {
+ return nil, err
+ }
+ fg.AddFlow(fs)
deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
} else {
// Trap flow for UNI port
@@ -166,7 +173,11 @@
// Augment the matchfields with the ofpfields from the flow
faParent.MatchFields = append(faParent.MatchFields, fu.GetOfbFields(flow, fu.IN_PORT)...)
fgParent := fu.NewFlowsAndGroups()
- fgParent.AddFlow(fu.MkFlowStat(faParent))
+ fs, err := fu.MkFlowStat(faParent)
+ if err != nil {
+ return nil, err
+ }
+ fgParent.AddFlow(fs)
deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fgParent)
log.Debugw("parent-trap-flow-set", log.Fields{"flow": faParent})
@@ -203,13 +214,17 @@
faChild.MatchFields = append(faChild.MatchFields, fu.GetOfbFields(flow, fu.IN_PORT)...)
}
fgChild := fu.NewFlowsAndGroups()
- fgChild.AddFlow(fu.MkFlowStat(faChild))
+ fs, err = fu.MkFlowStat(faChild)
+ if err != nil {
+ return nil, err
+ }
+ fgChild.AddFlow(fs)
deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fgChild)
log.Debugw("child-trap-flow-set", log.Fields{"flow": faChild})
}
}
- return deviceRules
+ return deviceRules, nil
}
// processUpstreamNonControllerBoundFlow processes non-controller bound flow. We assume that anything that is
@@ -217,7 +232,7 @@
// goto-statement. We also assume that the inner tag is applied at the ONU, while the outer tag is
// applied at the OLT
func (fd *FlowDecomposer) processUpstreamNonControllerBoundFlow(ctx context.Context,
- path []route.Hop, inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
+ path []route.Hop, inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) (*fu.DeviceRules, error) {
log.Debugw("upstream-non-controller-bound-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
deviceRules := fu.NewDeviceRules()
@@ -232,7 +247,7 @@
log.Debugw("decomposing-onu-flow-in-upstream-has-next-table", log.Fields{"table_id": flow.TableId})
if outPortNo != 0 {
log.Warnw("outPort-should-not-be-specified", log.Fields{"outPortNo": outPortNo})
- return deviceRules
+ return deviceRules, nil
}
fa := &fu.FlowArgs{
KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie, "meter_id": uint64(meterID), "write_metadata": metadataFromwriteMetadata},
@@ -249,7 +264,11 @@
fa.Actions = append(fa.Actions, fu.Output(ingressHop.Egress))
fg := fu.NewFlowsAndGroups()
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ if err != nil {
+ return nil, err
+ }
+ fg.AddFlow(fs)
deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
} else if flow.TableId == 1 && outPortNo != 0 {
log.Debugw("decomposing-olt-flow-in-upstream-has-next-table", log.Fields{"table_id": flow.TableId})
@@ -269,15 +288,19 @@
fa.Actions = filteredAction
fg := fu.NewFlowsAndGroups()
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ if err != nil {
+ return nil, err
+ }
+ fg.AddFlow(fs)
deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
}
- return deviceRules
+ return deviceRules, nil
}
// processDownstreamFlowWithNextTable decomposes downstream flows containing next table ID instructions
func (fd *FlowDecomposer) processDownstreamFlowWithNextTable(ctx context.Context, agent coreif.LogicalDeviceAgent, path []route.Hop,
- inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
+ inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) (*fu.DeviceRules, error) {
log.Debugw("decomposing-olt-flow-in-downstream-flow-with-next-table", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
deviceRules := fu.NewDeviceRules()
meterID := fu.GetMeterIdFromFlow(flow)
@@ -285,12 +308,12 @@
if outPortNo != 0 {
log.Warnw("outPort-should-not-be-specified", log.Fields{"outPortNo": outPortNo})
- return deviceRules
+ return deviceRules, nil
}
if flow.TableId != 0 {
log.Warnw("This is not olt pipeline table, so skipping", log.Fields{"tableId": flow.TableId})
- return deviceRules
+ return deviceRules, nil
}
ingressHop := path[0]
@@ -302,18 +325,18 @@
recalculatedRoute, err := agent.GetRoute(ctx, inPortNo, portNumber)
if err != nil {
log.Errorw("no-route-double-tag", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "metadata": metadataFromwriteMetadata, "error": err})
- return deviceRules
+ return deviceRules, nil
}
switch len(recalculatedRoute) {
case 0:
log.Errorw("no-route-double-tag", log.Fields{"inPortNo": inPortNo, "outPortNo": portNumber, "comment": "deleting-flow", "metadata": metadataFromwriteMetadata})
//TODO: Delete flow
- return deviceRules
+ return deviceRules, nil
case 2:
log.Debugw("route-found", log.Fields{"ingressHop": ingressHop, "egressHop": egressHop})
default:
log.Errorw("invalid-route-length", log.Fields{"routeLen": len(path)})
- return deviceRules
+ return deviceRules, nil
}
ingressHop = recalculatedRoute[0]
}
@@ -321,7 +344,7 @@
if innerTag == 0 {
log.Errorw("no-inner-route-double-tag", log.Fields{"inPortNo": inPortNo, "outPortNo": portNumber, "comment": "deleting-flow", "metadata": metadataFromwriteMetadata})
//TODO: Delete flow
- return deviceRules
+ return deviceRules, nil
}
fa := &fu.FlowArgs{
KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie, "meter_id": uint64(meterID), "write_metadata": metadataFromwriteMetadata},
@@ -339,7 +362,11 @@
fa.Actions = append(fa.Actions, fu.Output(ingressHop.Egress))
fg := fu.NewFlowsAndGroups()
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ if err != nil {
+ return nil, err
+ }
+ fg.AddFlow(fs)
deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
} else { // Create standard flow
log.Debugw("creating-standard-flow", log.Fields{"flow": flow})
@@ -358,16 +385,20 @@
fa.Actions = append(fa.Actions, fu.Output(ingressHop.Egress))
fg := fu.NewFlowsAndGroups()
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ if err != nil {
+ return nil, err
+ }
+ fg.AddFlow(fs)
deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
}
- return deviceRules
+ return deviceRules, nil
}
// processUnicastFlow decomposes unicast flows
func (fd *FlowDecomposer) processUnicastFlow(ctx context.Context, path []route.Hop,
- inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
+ inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) (*fu.DeviceRules, error) {
log.Debugw("decomposing-onu-flow-in-downstream-unicast-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
deviceRules := fu.NewDeviceRules()
@@ -391,9 +422,13 @@
fa.Actions = filteredAction
fg := fu.NewFlowsAndGroups()
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ if err != nil {
+ return nil, err
+ }
+ fg.AddFlow(fs)
deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
- return deviceRules
+ return deviceRules, nil
}
// processMulticastFlow decompose multicast flows
@@ -457,7 +492,10 @@
// Process controller bound flow
if outPortNo != 0 && (outPortNo&0x7fffffff) == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
- deviceRules = fd.processControllerBoundFlow(ctx, agent, path, inPortNo, outPortNo, flow)
+ deviceRules, err = fd.processControllerBoundFlow(ctx, agent, path, inPortNo, outPortNo, flow)
+ if err != nil {
+ return nil, err
+ }
} else {
var ingressDevice *voltha.Device
var err error
@@ -467,13 +505,22 @@
isUpstream := !ingressDevice.Root
if isUpstream { // Unicast OLT and ONU UL
log.Debug("process-olt-nd-onu-upstream-noncontrollerbound-unicast-flows", log.Fields{"flows": flow})
- deviceRules = fd.processUpstreamNonControllerBoundFlow(ctx, path, inPortNo, outPortNo, flow)
+ deviceRules, err = fd.processUpstreamNonControllerBoundFlow(ctx, path, inPortNo, outPortNo, flow)
+ if err != nil {
+ return nil, err
+ }
} else if fu.HasNextTable(flow) && flow.TableId == 0 { // Unicast OLT flow DL
log.Debugw("process-olt-downstream-noncontrollerbound-flow-with-nexttable", log.Fields{"flows": flow})
- deviceRules = fd.processDownstreamFlowWithNextTable(ctx, agent, path, inPortNo, outPortNo, flow)
+ deviceRules, err = fd.processDownstreamFlowWithNextTable(ctx, agent, path, inPortNo, outPortNo, flow)
+ if err != nil {
+ return nil, err
+ }
} else if flow.TableId == 1 && outPortNo != 0 { // Unicast ONU flow DL
log.Debugw("process-onu-downstream-unicast-flow", log.Fields{"flows": flow})
- deviceRules = fd.processUnicastFlow(ctx, path, inPortNo, outPortNo, flow)
+ deviceRules, err = fd.processUnicastFlow(ctx, path, inPortNo, outPortNo, flow)
+ if err != nil {
+ return nil, err
+ }
} else if grpID := fu.GetGroup(flow); grpID != 0 && flow.TableId == 0 { //Multicast
log.Debugw("process-multicast-flow", log.Fields{"flows": flow})
deviceRules = fd.processMulticastFlow(ctx, path, inPortNo, outPortNo, flow, grpID, groupMap)
@@ -481,6 +528,6 @@
return deviceRules, status.Errorf(codes.Aborted, "unknown downstream flow %v", *flow)
}
}
- deviceRules = fd.updateOutputPortForControllerBoundFlowForParentDevide(flow, deviceRules)
- return deviceRules, nil
+ deviceRules, err = fd.updateOutputPortForControllerBoundFlowForParentDevide(flow, deviceRules)
+ return deviceRules, err
}
diff --git a/rw_core/flowdecomposition/flow_decomposer_test.go b/rw_core/flowdecomposition/flow_decomposer_test.go
index 29c1a6a..6164f0d 100644
--- a/rw_core/flowdecomposition/flow_decomposer_test.go
+++ b/rw_core/flowdecomposition/flow_decomposer_test.go
@@ -125,7 +125,7 @@
logicalPortsNo map[uint32]bool
}
-func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
+func newTestFlowDecomposer(t *testing.T, deviceMgr *testDeviceManager) *testFlowDecomposer {
var tfd testFlowDecomposer
tfd.dMgr = deviceMgr
@@ -346,7 +346,9 @@
fu.Output(1),
},
}
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ fg.AddFlow(fs)
tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
fg = fu.NewFlowsAndGroups()
@@ -360,7 +362,9 @@
fu.Output(1),
},
}
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err = fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ fg.AddFlow(fs)
tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
fg = fu.NewFlowsAndGroups()
@@ -374,7 +378,9 @@
fu.Output(1),
},
}
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err = fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ fg.AddFlow(fs)
tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
fg = fu.NewFlowsAndGroups()
@@ -388,7 +394,9 @@
fu.Output(1),
},
}
- fg.AddFlow(fu.MkFlowStat(fa))
+ fs, err = fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ fg.AddFlow(fs)
tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
//Set up the device graph - flow decomposer uses it only to verify whether a port is a root port.
@@ -482,9 +490,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -508,7 +518,8 @@
fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
},
}
- expectedOltFlow := fu.MkFlowStat(faParent)
+ expectedOltFlow, err := fu.MkFlowStat(faParent)
+ assert.Nil(t, err)
derivedFlow := oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
@@ -525,7 +536,8 @@
fu.Output(1),
},
}
- expectedOnuFlow := fu.MkFlowStat(faChild)
+ expectedOnuFlow, err := fu.MkFlowStat(faChild)
+ assert.Nil(t, err)
derivedFlow = onu1FlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
}
@@ -545,9 +557,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -571,7 +585,8 @@
fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
},
}
- expectedOltFlow := fu.MkFlowStat(faParent)
+ expectedOltFlow, err := fu.MkFlowStat(faParent)
+ assert.Nil(t, err)
derivedFlow := oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
@@ -588,7 +603,8 @@
fu.Output(1),
},
}
- expectedOnuFlow := fu.MkFlowStat(faChild)
+ expectedOnuFlow, err := fu.MkFlowStat(faChild)
+ assert.Nil(t, err)
derivedFlow = onu1FlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
}
@@ -607,9 +623,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -632,7 +650,8 @@
fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
},
}
- expectedOltFlow := fu.MkFlowStat(faParent)
+ expectedOltFlow, err := fu.MkFlowStat(faParent)
+ assert.Nil(t, err)
derivedFlow := oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
@@ -647,7 +666,8 @@
fu.Output(1),
},
}
- expectedOnuFlow := fu.MkFlowStat(faChild)
+ expectedOnuFlow, err := fu.MkFlowStat(faChild)
+ assert.Nil(t, err)
derivedFlow = onu1FlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
}
@@ -669,9 +689,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -699,7 +721,8 @@
fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
},
}
- expectedOltFlow := fu.MkFlowStat(faParent)
+ expectedOltFlow, err := fu.MkFlowStat(faParent)
+ assert.Nil(t, err)
derivedFlow := oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
@@ -718,7 +741,8 @@
fu.Output(1),
},
}
- expectedOnuFlow := fu.MkFlowStat(faChild)
+ expectedOnuFlow, err := fu.MkFlowStat(faChild)
+ assert.Nil(t, err)
derivedFlow = onu1FlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
}
@@ -735,9 +759,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
onu1FlowAndGroup := deviceRules.Rules["onu1"]
@@ -756,7 +782,8 @@
fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
},
}
- expectedOltFlow := fu.MkFlowStat(fa)
+ expectedOltFlow, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
derivedFlow := oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
}
@@ -789,7 +816,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ fs2, err := fu.MkFlowStat(fa2)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs, fs2}}
flows.Items[0].Instructions = []*ofp.OfpInstruction{{
Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
Data: &ofp.OfpInstruction_GotoTable{
@@ -799,7 +830,7 @@
}}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -828,7 +859,8 @@
derivedFlow := onu1FlowAndGroup.GetFlow(0)
// Form the expected flow
- expectedOnu1Flow := fu.MkFlowStat(fa)
+ expectedOnu1Flow, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
Data: &ofp.OfpInstruction_Actions{
@@ -860,7 +892,8 @@
fu.Output(2),
},
}
- expectedOltFlow := fu.MkFlowStat(fa)
+ expectedOltFlow, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
derivedFlow = oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
}
@@ -892,7 +925,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
+ fs1, err := fu.MkFlowStat(fa1)
+ assert.Nil(t, err)
+ fs2, err := fu.MkFlowStat(fa2)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs1, fs2}}
flows.Items[0].Instructions = []*ofp.OfpInstruction{{
Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
Data: &ofp.OfpInstruction_GotoTable{
@@ -902,7 +939,7 @@
}}}
groups := ofp.FlowGroups{}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -928,7 +965,8 @@
}
derivedFlow := oltFlowAndGroup.GetFlow(0)
- expectedOltFlow := fu.MkFlowStat(fa1)
+ expectedOltFlow, err := fu.MkFlowStat(fa1)
+ assert.Nil(t, err)
expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
Data: &ofp.OfpInstruction_Actions{
@@ -956,7 +994,8 @@
fu.Output(2),
},
}
- expectedOnu1Flow := fu.MkFlowStat(fa1)
+ expectedOnu1Flow, err := fu.MkFlowStat(fa1)
+ assert.Nil(t, err)
derivedFlow = onu1FlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
}
@@ -987,9 +1026,11 @@
},
}
- flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
+ fs, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
- tfd := newTestFlowDecomposer(newTestDeviceManager())
+ tfd := newTestFlowDecomposer(t, newTestDeviceManager())
deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
assert.Nil(t, err)
@@ -1010,7 +1051,8 @@
fu.Group(10),
},
}
- expectedOltFlow := fu.MkFlowStat(fa)
+ expectedOltFlow, err := fu.MkFlowStat(fa)
+ assert.Nil(t, err)
derivedFlow := oltFlowAndGroup.GetFlow(0)
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/flows/flow_utils.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/flows/flow_utils.go
index 4de929f..b2086cd 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/flows/flow_utils.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/flows/flow_utils.go
@@ -18,6 +18,7 @@
import (
"bytes"
"crypto/md5"
+ "errors"
"fmt"
"github.com/cevaris/ordered_map"
"github.com/gogo/protobuf/proto"
@@ -678,9 +679,9 @@
// 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 {
+func HashFlowStats(flow *ofp.OfpFlowStats) (uint64, error) {
if flow == nil { // Should never happen
- return 0
+ return 0, errors.New("hash-flow-stats-nil-flow")
}
// Create string with the instructions field first
var instructionString bytes.Buffer
@@ -690,19 +691,18 @@
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()
if _, err := h.Write([]byte(flowString)); err != nil {
- logger.Errorw("hash-flow-status", log.Fields{"error": err})
- return 0
+ return 0, fmt.Errorf("hash-flow-stats-failed-hash: %v", err)
}
hash := big.NewInt(0)
hash.SetBytes(h.Sum(nil))
- return hash.Uint64()
+ return hash.Uint64(), nil
}
// flowStatsEntryFromFlowModMessage maps an ofp_flow_mod message to an ofp_flow_stats message
-func FlowStatsEntryFromFlowModMessage(mod *ofp.OfpFlowMod) *ofp.OfpFlowStats {
+func FlowStatsEntryFromFlowModMessage(mod *ofp.OfpFlowMod) (*ofp.OfpFlowStats, error) {
flow := &ofp.OfpFlowStats{}
if mod == nil {
- return flow
+ return flow, nil
}
flow.TableId = mod.TableId
flow.Priority = mod.Priority
@@ -712,8 +712,12 @@
flow.Cookie = mod.Cookie
flow.Match = mod.Match
flow.Instructions = mod.Instructions
- flow.Id = HashFlowStats(flow)
- return flow
+ var err error
+ if flow.Id, err = HashFlowStats(flow); err != nil {
+ return nil, err
+ }
+
+ return flow, nil
}
func GroupEntryFromGroupMod(mod *ofp.OfpGroupMod) *ofp.OfpGroupEntry {
@@ -913,7 +917,7 @@
}
// MkFlowStat is a helper method to build flows
-func MkFlowStat(fa *FlowArgs) *ofp.OfpFlowStats {
+func MkFlowStat(fa *FlowArgs) (*ofp.OfpFlowStats, error) {
//Build the match-fields
matchFields := make([]*ofp.OfpOxmField, 0)
for _, val := range fa.MatchFields {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 534084d..ebf9c95 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -96,7 +96,7 @@
github.com/modern-go/concurrent
# github.com/modern-go/reflect2 v1.0.1
github.com/modern-go/reflect2
-# github.com/opencord/voltha-lib-go/v3 v3.0.14
+# github.com/opencord/voltha-lib-go/v3 v3.0.15
github.com/opencord/voltha-lib-go/v3/pkg/adapters
github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif
github.com/opencord/voltha-lib-go/v3/pkg/adapters/common