use of org.onosproject.net.pi.runtime.PiTableEntry in project up4 by omec-project.
the class Up4NorthComponentTest method tunnelPeerInsertionTest.
// ------------------- INSERTION TESTS -------------------------------------
@Test
public void tunnelPeerInsertionTest() throws Exception {
PiTableEntry entry = TestImplConstants.UP4_TUNNEL_PEER;
insertionTest(entry);
assertThat(mockUp4Service.readAll(UpfEntityType.TUNNEL_PEER).size(), equalTo(1));
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project up4 by omec-project.
the class Up4TranslatorImplTest method up4ToUpfEntity.
public UpfEntity up4ToUpfEntity(UpfEntity expected, PiEntity up4Entry) {
UpfEntity translatedEntity;
try {
switch(up4Entry.piEntityType()) {
case TABLE_ENTRY:
translatedEntity = up4Translator.up4TableEntryToUpfEntity((PiTableEntry) up4Entry);
break;
case METER_CELL_CONFIG:
translatedEntity = up4Translator.up4MeterEntryToUpfEntity((PiMeterCellConfig) up4Entry);
break;
case COUNTER_CELL:
translatedEntity = up4Translator.up4CounterEntryToUpfEntity((PiCounterCell) up4Entry);
break;
default:
assertThat("Unsupported PI entity!", false);
return null;
}
} catch (Up4Translator.Up4TranslationException e) {
assertThat("UP4 table entry should translate to UPF entity without error.", false);
return null;
}
assertThat(translatedEntity, equalTo(expected));
return translatedEntity;
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project onos by opennetworkinglab.
the class P4RuntimeFlowRuleProgrammable method getFlowEntries.
@Override
public Collection<FlowEntry> getFlowEntries() {
if (!setupBehaviour("getFlowEntries()")) {
return Collections.emptyList();
}
if (driverBoolProperty(READ_FROM_MIRROR, DEFAULT_READ_FROM_MIRROR)) {
return getFlowEntriesFromMirror();
}
final ImmutableList.Builder<FlowEntry> result = ImmutableList.builder();
final List<PiTableEntry> inconsistentEntries = Lists.newArrayList();
// Read table entries from device.
final Collection<PiTableEntry> deviceEntries = getAllTableEntriesFromDevice();
if (deviceEntries == null) {
// Potential error at the client level.
return Collections.emptyList();
}
// Synchronize mirror with the device state.
tableMirror.sync(deviceId, deviceEntries);
if (deviceEntries.isEmpty()) {
// Nothing to do.
return Collections.emptyList();
}
final Map<PiTableEntryHandle, PiCounterCellData> counterCellMap = readEntryCounters(deviceEntries);
// Forge flow entries with counter values.
for (PiTableEntry entry : deviceEntries) {
final PiTableEntryHandle handle = entry.handle(deviceId);
final FlowEntry flowEntry = forgeFlowEntry(entry, handle, counterCellMap.get(handle));
if (flowEntry == null) {
// program via default_action, which cannot be removed.)
if (!isOriginalDefaultEntry(entry)) {
inconsistentEntries.add(entry);
}
} else {
result.add(flowEntry);
}
}
// Default entries need to be treated in a different way according to the spec:
// the client can modify (reset or update) them but cannot remove the entries
List<PiTableEntry> inconsistentDefaultEntries = Lists.newArrayList();
List<PiTableEntry> tempDefaultEntries = inconsistentEntries.stream().filter(PiTableEntry::isDefaultAction).collect(Collectors.toList());
inconsistentEntries.removeAll(tempDefaultEntries);
// Once we have removed the default entry from inconsistentEntries we need to
// craft for each default entry a copy without the action field. According to
// the spec leaving the action field unset will reset the original default entry.
tempDefaultEntries.forEach(piTableEntry -> {
PiTableEntry resetEntry = PiTableEntry.builder().forTable(piTableEntry.table()).build();
inconsistentDefaultEntries.add(resetEntry);
});
// Clean up of inconsistent entries.
if (!inconsistentEntries.isEmpty() || !inconsistentDefaultEntries.isEmpty()) {
WriteRequest writeRequest = client.write(p4DeviceId, pipeconf);
// Trigger remove of inconsistent entries.
if (!inconsistentEntries.isEmpty()) {
log.warn("Found {} inconsistent table entries on {}, removing them...", inconsistentEntries.size(), deviceId);
writeRequest = writeRequest.entities(inconsistentEntries, DELETE);
}
// Trigger reset of inconsistent default entries.
if (!inconsistentDefaultEntries.isEmpty()) {
log.warn("Found {} inconsistent default table entries on {}, resetting them...", inconsistentDefaultEntries.size(), deviceId);
writeRequest = writeRequest.entities(inconsistentDefaultEntries, MODIFY);
}
// Submit delete request for non-default entries and modify request
// for default entries. Updates mirror when done.
writeRequest.submit().whenComplete((response, ex) -> {
if (ex != null) {
log.error("Exception removing inconsistent table entries", ex);
} else {
log.debug("Successfully removed {} out of {} inconsistent entries", response.success().size(), response.all().size());
}
// We can use the entity as the handle does not contain the action field
// so the key will be removed even if the table entry is different
response.success().forEach(entity -> tableMirror.remove((PiTableEntryHandle) entity.handle()));
});
}
return result.build();
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project onos by opennetworkinglab.
the class P4RuntimeFlowRuleProgrammable method getOriginalDefaultEntry.
private PiTableEntry getOriginalDefaultEntry(PiTableId tableId) {
final PiTableEntryHandle handle = PiTableEntry.builder().forTable(tableId).withMatchKey(PiMatchKey.EMPTY).build().handle(deviceId);
final TimedEntry<PiTableEntry> originalDefaultEntry = defaultEntryMirror.get(handle);
if (originalDefaultEntry != null) {
return originalDefaultEntry.entry();
}
return null;
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project onos by opennetworkinglab.
the class TableEntryEncoderTest method testTableEntryEncoder.
@Test
public void testTableEntryEncoder() throws Exception {
TableEntry tableEntryMsg = Codecs.CODECS.tableEntry().encode(piTableEntry, null, defaultPipeconf);
PiTableEntry decodedPiTableEntry = Codecs.CODECS.tableEntry().decode(tableEntryMsg, null, defaultPipeconf);
// Test equality for decoded entry.
new EqualsTester().addEqualityGroup(piTableEntry, decodedPiTableEntry).testEquals();
// Table ID.
int p4InfoTableId = browser.tables().getByName(tableId.id()).getPreamble().getId();
int encodedTableId = tableEntryMsg.getTableId();
assertThat(encodedTableId, is(p4InfoTableId));
// Ternary match.
byte[] encodedTernaryMatchValue = tableEntryMsg.getMatch(0).getTernary().getValue().toByteArray();
assertThat(encodedTernaryMatchValue, is(ethAddr.canonical().asArray()));
Action actionMsg = tableEntryMsg.getAction().getAction();
// Action ID.
int p4InfoActionId = browser.actions().getByName(outActionId.toString()).getPreamble().getId();
int encodedActionId = actionMsg.getActionId();
assertThat(encodedActionId, is(p4InfoActionId));
// Action param ID.
int p4InfoActionParamId = browser.actionParams(p4InfoActionId).getByName(portParamId.toString()).getId();
int encodedActionParamId = actionMsg.getParams(0).getParamId();
assertThat(encodedActionParamId, is(p4InfoActionParamId));
// Action param value.
byte[] encodedActionParam = actionMsg.getParams(0).getValue().toByteArray();
assertThat(encodedActionParam, is(portValue.asArray()));
// Counter
CounterData counterData = tableEntryMsg.getCounterData();
PiCounterCellData encodedCounterData = new PiCounterCellData(counterData.getPacketCount(), counterData.getByteCount());
assertThat(encodedCounterData, is(counterCellData));
// TODO: improve, assert other field match types (ternary, LPM)
}
Aggregations