use of org.onosproject.net.pi.runtime.PiTableEntry in project onos by opennetworkinglab.
the class P4RuntimeFlowRuleProgrammable method appendEntryToWriteRequestOrSkip.
private boolean appendEntryToWriteRequestOrSkip(final WriteRequest writeRequest, final PiTableEntryHandle handle, PiTableEntry piEntryToApply, final Operation driverOperation) {
// Depending on the driver operation, and if a matching rule exists on
// the device/mirror, decide which P4Runtime update operation to perform
// for this entry. In some cases, the entry is skipped from the write
// request but we want to return the corresponding flow rule as
// successfully written. In this case, we return true.
final TimedEntry<PiTableEntry> piEntryOnDevice = tableMirror.get(handle);
final UpdateType updateType;
final boolean supportDefaultEntry = driverBoolProperty(SUPPORT_DEFAULT_TABLE_ENTRY, DEFAULT_SUPPORT_DEFAULT_TABLE_ENTRY);
final boolean deleteBeforeUpdate = driverBoolProperty(DELETE_BEFORE_UPDATE, DEFAULT_DELETE_BEFORE_UPDATE);
if (driverOperation == APPLY) {
if (piEntryOnDevice == null) {
// Entry is first-timer, INSERT or MODIFY if default action.
updateType = !piEntryToApply.isDefaultAction() || !supportDefaultEntry ? INSERT : MODIFY;
} else {
if (piEntryToApply.action().equals(piEntryOnDevice.entry().action())) {
// FIXME: should we check for other attributes of the table
// entry? For example can we modify the priority?
log.debug("Ignoring re-apply of existing entry: {}", piEntryToApply);
return true;
} else if (deleteBeforeUpdate && !piEntryToApply.isDefaultAction()) {
// Some devices return error when updating existing entries.
// If requested, remove entry before re-inserting the
// modified one, except the default action entry, that
// cannot be removed.
writeRequest.delete(handle);
updateType = INSERT;
} else {
updateType = MODIFY;
}
}
} else {
// REMOVE.
if (piEntryToApply.isDefaultAction()) {
// Cannot remove default action. Instead we should modify it to
// use the original one as specified in the P4 program.
final PiTableEntry originalDefaultEntry = getOriginalDefaultEntry(piEntryToApply.table());
if (originalDefaultEntry == null) {
return false;
}
return appendEntryToWriteRequestOrSkip(writeRequest, originalDefaultEntry.handle(deviceId), originalDefaultEntry, APPLY);
} else {
if (piEntryOnDevice == null) {
log.debug("Ignoring delete of missing entry: {}", piEntryToApply);
return true;
}
updateType = DELETE;
}
}
writeRequest.entity(piEntryToApply, updateType);
return false;
}
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.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)
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project up4 by omec-project.
the class Up4TranslatorImpl method upfEntityToUp4TableEntry.
@Override
public PiTableEntry upfEntityToUp4TableEntry(UpfEntity entity) throws Up4TranslationException {
PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();
PiAction.Builder actionBuilder = PiAction.builder();
PiMatchKey.Builder matchBuilder = PiMatchKey.builder();
switch(entity.type()) {
case INTERFACE:
tableEntryBuilder.forTable(PRE_QOS_PIPE_INTERFACES);
UpfInterface upfIntf = (UpfInterface) entity;
byte direction;
byte srcIface;
actionBuilder.withId(PRE_QOS_PIPE_SET_SOURCE_IFACE);
if (upfIntf.isAccess()) {
srcIface = IFACE_ACCESS;
direction = DIRECTION_UPLINK;
} else if (upfIntf.isCore()) {
srcIface = IFACE_CORE;
direction = DIRECTION_DOWNLINK;
} else {
throw new Up4TranslationException("UPF Interface is not Access nor CORE: " + upfIntf);
}
actionBuilder.withParameter(new PiActionParam(SRC_IFACE, srcIface)).withParameter(new PiActionParam(DIRECTION, direction)).withParameter(new PiActionParam(SLICE_ID, (byte) upfIntf.sliceId()));
matchBuilder.addFieldMatch(new PiLpmFieldMatch(HDR_IPV4_DST_PREFIX, ImmutableByteSequence.copyFrom(upfIntf.prefix().address().toOctets()), upfIntf.prefix().prefixLength()));
break;
case SESSION_UPLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_SESSIONS_UPLINK);
UpfSessionUplink sessionUplink = (UpfSessionUplink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_N3_ADDRESS, ImmutableByteSequence.copyFrom(sessionUplink.tunDstAddr().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_TEID, ImmutableByteSequence.copyFrom(sessionUplink.teid())));
if (sessionUplink.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_UPLINK_DROP);
} else {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_UPLINK);
actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionUplink.sessionMeterIdx()));
}
break;
case SESSION_DOWNLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_SESSIONS_DOWNLINK);
UpfSessionDownlink sessionDownlink = (UpfSessionDownlink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(sessionDownlink.ueAddress().toOctets())));
if (sessionDownlink.needsDropping() && sessionDownlink.needsBuffering()) {
log.error("We don't support DROP + BUFF on the UP4 northbound! Defaulting to only BUFF");
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_BUFF);
actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionDownlink.sessionMeterIdx()));
} else if (sessionDownlink.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_DROP);
} else {
actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionDownlink.sessionMeterIdx()));
if (sessionDownlink.needsBuffering()) {
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_BUFF);
} else {
actionBuilder.withParameter(new PiActionParam(TUNNEL_PEER_ID, ImmutableByteSequence.copyFrom(sessionDownlink.tunPeerId())));
actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK);
}
}
break;
case TERMINATION_UPLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_TERMINATIONS_UPLINK);
UpfTerminationUplink upfTerminationUl = (UpfTerminationUplink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(upfTerminationUl.ueSessionId().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_APP_ID, ImmutableByteSequence.copyFrom(upfTerminationUl.applicationId())));
actionBuilder.withParameter(new PiActionParam(CTR_IDX, upfTerminationUl.counterId()));
if (upfTerminationUl.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_DROP);
} else {
if (upfTerminationUl.trafficClass() != null) {
actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_FWD);
actionBuilder.withParameter(new PiActionParam(TC, upfTerminationUl.trafficClass()));
} else {
actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_FWD_NO_TC);
}
actionBuilder.withParameter(new PiActionParam(APP_METER_IDX, upfTerminationUl.appMeterIdx()));
}
break;
case TERMINATION_DOWNLINK:
tableEntryBuilder.forTable(PRE_QOS_PIPE_TERMINATIONS_DOWNLINK);
UpfTerminationDownlink upfTerminationDl = (UpfTerminationDownlink) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(upfTerminationDl.ueSessionId().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_APP_ID, ImmutableByteSequence.copyFrom(upfTerminationDl.applicationId())));
actionBuilder.withParameter(new PiActionParam(CTR_IDX, upfTerminationDl.counterId()));
if (upfTerminationDl.needsDropping()) {
actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_DROP);
} else {
actionBuilder.withParameter(new PiActionParam(TEID, upfTerminationDl.teid())).withParameter(new PiActionParam(QFI, upfTerminationDl.qfi()));
if (upfTerminationDl.trafficClass() != null) {
actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_FWD);
actionBuilder.withParameter(new PiActionParam(TC, upfTerminationDl.trafficClass()));
} else {
actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_FWD_NO_TC);
}
actionBuilder.withParameter(new PiActionParam(APP_METER_IDX, upfTerminationDl.appMeterIdx()));
}
break;
case TUNNEL_PEER:
tableEntryBuilder.forTable(PRE_QOS_PIPE_TUNNEL_PEERS);
UpfGtpTunnelPeer gtpTunnelPeer = (UpfGtpTunnelPeer) entity;
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_TUNNEL_PEER_ID, ImmutableByteSequence.copyFrom(gtpTunnelPeer.tunPeerId())));
actionBuilder.withId(PRE_QOS_PIPE_LOAD_TUNNEL_PARAM).withParameter(new PiActionParam(SRC_ADDR, gtpTunnelPeer.src().toOctets())).withParameter(new PiActionParam(DST_ADDR, gtpTunnelPeer.dst().toOctets())).withParameter(new PiActionParam(SPORT, gtpTunnelPeer.srcPort()));
break;
case APPLICATION:
tableEntryBuilder.forTable(PRE_QOS_PIPE_APPLICATIONS);
UpfApplication application = (UpfApplication) entity;
tableEntryBuilder.withPriority(application.priority());
actionBuilder.withId(PRE_QOS_PIPE_SET_APP_ID).withParameter(new PiActionParam(APP_ID, application.appId()));
matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_SLICE_ID, ImmutableByteSequence.copyFrom((byte) application.sliceId())));
if (application.ip4Prefix().isPresent()) {
Ip4Prefix ipPrefix = application.ip4Prefix().get();
matchBuilder.addFieldMatch(new PiLpmFieldMatch(HDR_APP_IP_ADDR, ImmutableByteSequence.copyFrom(ipPrefix.address().toOctets()), ipPrefix.prefixLength()));
}
if (application.l4PortRange().isPresent()) {
Range<Short> portRange = application.l4PortRange().get();
matchBuilder.addFieldMatch(new PiRangeFieldMatch(HDR_APP_L4_PORT, ImmutableByteSequence.copyFrom(portRange.lowerEndpoint()), ImmutableByteSequence.copyFrom(portRange.upperEndpoint())));
}
if (application.ipProto().isPresent()) {
byte ipProto = application.ipProto().get();
matchBuilder.addFieldMatch(new PiTernaryFieldMatch(HDR_APP_IP_PROTO, ImmutableByteSequence.copyFrom(ipProto), ImmutableByteSequence.ofOnes(1)));
}
break;
case SESSION_METER:
case APPLICATION_METER:
case COUNTER:
default:
throw new Up4TranslationException("Attempting to translate an unsupported UPF entity to a table entry! " + entity);
}
return tableEntryBuilder.withMatchKey(matchBuilder.build()).withAction(actionBuilder.build()).build();
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project up4 by omec-project.
the class Up4NorthComponentTest method downlinkTerminationInsertionTest.
@Test
public void downlinkTerminationInsertionTest() throws Exception {
PiTableEntry entry = TestImplConstants.UP4_DOWNLINK_TERMINATION;
insertionTest(entry);
assertThat(mockUp4Service.readAll(UpfEntityType.TERMINATION_DOWNLINK).size(), equalTo(1));
}
use of org.onosproject.net.pi.runtime.PiTableEntry in project up4 by omec-project.
the class Up4NorthComponentTest method uplinkInterfaceInsertionTest.
@Test
public void uplinkInterfaceInsertionTest() throws Exception {
PiTableEntry entry = TestImplConstants.UP4_UPLINK_INTERFACE;
insertionTest(entry);
assertThat(mockUp4Service.readAll(UpfEntityType.INTERFACE).size(), equalTo(1));
}
Aggregations