No need to map table counters in PI pipeline interpreter
This is related to ONOS-7595. In a recent P4Runtime update, it has been
made explicit that tables can support at most 1 direct counter. Hence,
the pipeline interpreter no longer needs to provide a mapping between a
table and one of potentially many counters. If needed, such mapping can
be derived from the pipeline model (i.e. the p4info)
Change-Id: Ibdece52f35a4d187ab9dbeb90f5527b6285e9788
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
index 352eca8..00fe9380 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
@@ -29,7 +29,6 @@
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleProgrammable;
-import org.onosproject.net.pi.model.PiCounterId;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
import org.onosproject.net.pi.model.PiPipelineModel;
import org.onosproject.net.pi.model.PiTableId;
@@ -87,6 +86,11 @@
private static final String READ_FROM_MIRROR = "tableReadFromMirror";
private static final boolean DEFAULT_READ_FROM_MIRROR = false;
+ // If true, we read counters when reading table entries (if table has
+ // counters). Otherwise, we don't.
+ private static final String SUPPORT_TABLE_COUNTERS = "supportTableCounters";
+ private static final boolean DEFAULT_SUPPORT_TABLE_COUNTERS = true;
+
// If true, we read all direct counters of a table with one request.
// Otherwise, we send as many requests as the number of table entries.
private static final String READ_ALL_DIRECT_COUNTERS = "tableReadAllDirectCounters";
@@ -166,13 +170,8 @@
}
// Read table direct counters (if any).
- final Map<PiTableEntry, PiCounterCellData> counterCellMap;
- if (interpreter.mapTableCounter(piTableId).isPresent()) {
- PiCounterId piCounterId = interpreter.mapTableCounter(piTableId).get();
- counterCellMap = readEntryCounters(piCounterId, installedEntries);
- } else {
- counterCellMap = Collections.emptyMap();
- }
+ final Map<PiTableEntry, PiCounterCellData> counterCellMap =
+ readEntryCounters(installedEntries);
// Forge flow entries with counter values.
for (PiTableEntry installedEntry : installedEntries) {
@@ -391,7 +390,12 @@
}
private Map<PiTableEntry, PiCounterCellData> readEntryCounters(
- PiCounterId counterId, Collection<PiTableEntry> tableEntries) {
+ Collection<PiTableEntry> tableEntries) {
+ if (!driverBoolProperty(SUPPORT_TABLE_COUNTERS,
+ DEFAULT_SUPPORT_TABLE_COUNTERS)) {
+ return Collections.emptyMap();
+ }
+
Collection<PiCounterCellData> cellDatas;
try {
if (driverBoolProperty(READ_ALL_DIRECT_COUNTERS,
@@ -403,6 +407,7 @@
cellDatas = Collections.emptyList();
} else {
Set<PiCounterCellId> cellIds = tableEntries.stream()
+ .filter(e -> tableHasCounter(e.table()))
.map(PiCounterCellId::ofDirect)
.collect(Collectors.toSet());
cellDatas = client.readCounterCells(cellIds, pipeconf).get();
@@ -412,13 +417,18 @@
} catch (InterruptedException | ExecutionException e) {
if (!(e.getCause() instanceof StatusRuntimeException)) {
// gRPC errors are logged in the client.
- log.error("Exception while reading counter '{}' from {}: {}",
- counterId, deviceId, e);
+ log.error("Exception while reading table counters from {}: {}",
+ deviceId, e);
}
return Collections.emptyMap();
}
}
+ private boolean tableHasCounter(PiTableId tableId) {
+ return pipelineModel.table(tableId).isPresent() &&
+ !pipelineModel.table(tableId).get().counters().isEmpty();
+ }
+
enum Operation {
APPLY, REMOVE
}