use of org.onosproject.net.pi.runtime.PiMeterCellHandle in project onos by opennetworkinglab.
the class P4RuntimeMeterProgrammable method getMeters.
@Override
public CompletableFuture<Collection<Meter>> getMeters() {
if (!setupBehaviour("getMeters()")) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Collection<PiMeterCellConfig> piMeterCellConfigs;
Set<PiMeterId> meterIds = new HashSet<>();
for (PiMeterModel mode : pipelineModel.meters()) {
meterIds.add(mode.id());
}
piMeterCellConfigs = client.read(p4DeviceId, pipeconf).meterCells(meterIds).submitSync().all(PiMeterCellConfig.class).stream().filter(piMeterCellConfig -> !piMeterCellConfig.isDefaultConfig()).collect(Collectors.toList());
meterMirror.sync(deviceId, piMeterCellConfigs);
if (piMeterCellConfigs.isEmpty()) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
List<PiMeterCellId> inconsistentOrDefaultCells = Lists.newArrayList();
List<Meter> meters = Lists.newArrayList();
// Check the consistency of meter config
for (PiMeterCellConfig config : piMeterCellConfigs) {
PiMeterCellHandle handle = PiMeterCellHandle.of(deviceId, config);
DefaultMeter meter = (DefaultMeter) forgeMeter(config, handle);
if (meter == null) {
// A default config cannot be used to forge meter
// because meter has at least 1 band while default config has no band
inconsistentOrDefaultCells.add(config.cellId());
} else {
meters.add(meter);
}
}
// Reset all inconsistent meter cells to the default config
if (!inconsistentOrDefaultCells.isEmpty()) {
WriteRequest request = client.write(p4DeviceId, pipeconf);
for (PiMeterCellId cellId : inconsistentOrDefaultCells) {
PiMeterCellHandle handle = PiMeterCellHandle.of(deviceId, cellId);
appendEntryToWriteRequestOrSkip(request, handle, PiMeterCellConfig.reset(cellId));
}
request.submit().whenComplete((response, ex) -> {
if (ex != null) {
log.error("Exception resetting inconsistent meter entries", ex);
} else {
log.debug("Successfully removed {} out of {} inconsistent meter entries", response.success().size(), response.all().size());
}
response.success().forEach(entity -> meterMirror.remove((PiMeterCellHandle) entity.handle()));
});
}
return CompletableFuture.completedFuture(meters);
}
use of org.onosproject.net.pi.runtime.PiMeterCellHandle in project onos by opennetworkinglab.
the class P4RuntimeMeterProgrammable method processMeterOp.
private boolean processMeterOp(MeterOperation meterOp) {
PiMeterCellConfig piMeterCellConfig;
final PiMeterCellHandle handle = PiMeterCellHandle.of(deviceId, (PiMeterCellId) meterOp.meter().meterCellId());
boolean result = true;
WRITE_LOCKS.get(deviceId).lock();
try {
switch(meterOp.type()) {
case ADD:
case MODIFY:
// Create a config for modify operation
try {
piMeterCellConfig = translator.translate(meterOp.meter(), pipeconf);
} catch (PiTranslationException e) {
log.warn("Unable translate meter, aborting meter operation {}: {}", meterOp.type(), e.getMessage());
log.debug("exception", e);
return false;
}
translator.learn(handle, new PiTranslatedEntity<>(meterOp.meter(), piMeterCellConfig, handle));
break;
case REMOVE:
// Create a empty config for reset operation
PiMeterCellId piMeterCellId = (PiMeterCellId) meterOp.meter().meterCellId();
piMeterCellConfig = PiMeterCellConfig.reset(piMeterCellId);
translator.forget(handle);
break;
default:
log.warn("Meter Operation type {} not supported", meterOp.type());
return false;
}
WriteRequest request = client.write(p4DeviceId, pipeconf);
appendEntryToWriteRequestOrSkip(request, handle, piMeterCellConfig);
if (!request.pendingUpdates().isEmpty()) {
result = request.submitSync().isSuccess();
if (result) {
meterMirror.applyWriteRequest(request);
}
}
} finally {
WRITE_LOCKS.get(deviceId).unlock();
}
return result;
}
Aggregations