[VOL-4123] Fix no flows being discarded by ofAgent
This commit fixes an issue in ofAgent where it fails to send
stats to ONOS if there are no flows/ no ports/ no port desc. This
situation arises if the rw-core does not persist flows and is
restarted.
This fix was tested with a rw-core that does not persist flows,
meters and groups. The rw-core was restarted after 512 ONUs were
already activated and had their flows pushed. After the rw-core
retart, with this fix, the flows were pushed from ONOS.
Change-Id: I10ee627e4153134ec5a5d12d1dcd67f64213e83d
diff --git a/VERSION b/VERSION
index 9c6d629..fdd3be6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.1
+1.6.2
diff --git a/internal/pkg/openflow/stats.go b/internal/pkg/openflow/stats.go
index 1cd656e..1cc9926 100644
--- a/internal/pkg/openflow/stats.go
+++ b/internal/pkg/openflow/stats.go
@@ -343,7 +343,7 @@
if err != nil {
return nil, err
}
- logger.Debugw(ctx, "logicalDeviceFlows", log.Fields{"flows": resp})
+ logger.Debugw(ctx, "logicalDeviceFlows", log.Fields{"logical-device-id": ofc.DeviceID, "num-flows": len(resp.Items)})
var flows []*ofp.FlowStatsEntry
for _, item := range resp.GetItems() {
entry := ofp.NewFlowStatsEntry()
@@ -387,23 +387,29 @@
flows = append(flows, entry)
}
var responses []*ofp.FlowStatsReply
+
chunkSize := ofc.flowsChunkSize
total := len(flows) / chunkSize
n := 0
for n <= total {
+ response := ofp.NewFlowStatsReply()
+ response.SetXid(request.GetXid())
+ response.SetVersion(request.GetVersion())
+ response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
limit := (n * chunkSize) + chunkSize
-
chunk := flows[n*chunkSize : min(limit, len(flows))]
if len(chunk) == 0 {
+ // Special case - no flows
+ if len(flows) == 0 {
+ logger.Debugw(ctx, "no-flows-present", log.Fields{"logical-device-id": ofc.DeviceID})
+ response.SetEntries(chunk)
+ responses = append(responses, response)
+ }
break
}
- response := ofp.NewFlowStatsReply()
- response.SetXid(request.GetXid())
- response.SetVersion(4)
- response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
if limit < len(flows) {
response.SetFlags(ofp.StatsReplyFlags(ofp.OFPSFReplyMore))
}
@@ -607,24 +613,32 @@
}
var responses []*ofp.PortStatsReply
+
chunkSize := ofc.portsChunkSize
total := len(entries) / chunkSize
n := 0
for n <= total {
+ response := ofp.NewPortStatsReply()
+ response.SetXid(request.GetXid())
+ response.SetVersion(request.GetVersion())
+ response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
chunk := entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))]
if len(chunk) == 0 {
+ // handle the case of no ports
+ if len(entries) == 0 {
+ logger.Debugw(ctx, "no-ports-present", log.Fields{"logical-device-id": ofc.DeviceID})
+ response.SetEntries(chunk)
+ responses = append(responses, response)
+ }
break
}
- response := ofp.NewPortStatsReply()
- response.SetXid(request.GetXid())
- response.SetVersion(request.GetVersion())
if total != n {
response.SetFlags(ofp.StatsReplyFlags(ofp.OFPSFReplyMore))
}
- response.SetEntries(entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))])
+ response.SetEntries(chunk)
responses = append(responses, response)
n++
}
@@ -667,21 +681,27 @@
}
var responses []*ofp.PortDescStatsReply
+
chunkSize := ofc.portsDescChunkSize
total := len(entries) / chunkSize
n := 0
for n <= total {
-
- chunk := entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))]
-
- if len(chunk) == 0 {
- break
- }
-
response := ofp.NewPortDescStatsReply()
response.SetVersion(request.GetVersion())
response.SetXid(request.GetXid())
response.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
+
+ chunk := entries[n*chunkSize : min((n*chunkSize)+chunkSize, len(entries))]
+
+ if len(chunk) == 0 {
+ if len(entries) == 0 {
+ logger.Debugw(ctx, "no-ports-desc-present", log.Fields{"logical-device-id": ofc.DeviceID})
+ response.SetEntries(chunk)
+ responses = append(responses, response)
+ }
+ break
+ }
+
if total != n {
response.SetFlags(ofp.StatsReplyFlags(ofp.OFPSFReplyMore))
}