use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4DeviceManager method delete.
@Override
public void delete(UpfEntity entity) throws UpfProgrammableException {
switch(entity.type()) {
case SESSION_DOWNLINK:
UpfSessionDownlink sess = (UpfSessionDownlink) entity;
if (sess.needsBuffering()) {
entity = convertToBuffering(sess);
}
break;
case INTERFACE:
UpfInterface intf = (UpfInterface) entity;
if (intf.isDbufReceiver()) {
throw new UpfProgrammableException("Cannot delete the DBUF interface rule!");
}
break;
case TUNNEL_PEER:
UpfGtpTunnelPeer tunnel = (UpfGtpTunnelPeer) entity;
if (tunnel.tunPeerId() == DBUF_TUNNEL_ID) {
throw new UpfProgrammableException("Cannot delete the DBUF GTP tunnel peer");
}
break;
default:
break;
}
getLeaderUpfProgrammable().delete(entity);
forgetBufferingUeIfRequired(entity);
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4NorthComponent method readCountersAndTranslate.
/**
* Read the all p4 counter cell requested by the message, and translate them to p4runtime
* entities for crafting a p4runtime read response.
*
* @param message a p4runtime CounterEntry message from a read request
* @return the requested counter cells' contents, as a list of p4runtime entities
* @throws StatusException if the counter index is out of range
*/
private List<P4RuntimeOuterClass.Entity> readCountersAndTranslate(P4RuntimeOuterClass.CounterEntry message) throws StatusException {
ArrayList<PiCounterCell> responseCells = new ArrayList<>();
Integer index = null;
// FYI a counter read message with no index corresponds to a wildcard read of all indices
if (message.hasIndex()) {
index = (int) message.getIndex().getIndex();
}
String counterName = null;
PiCounterId piCounterId = null;
int counterId = message.getCounterId();
// FYI a counterId of 0 corresponds to a wildcard read of all counters
if (counterId != 0) {
try {
counterName = PipeconfHelper.getP4InfoBrowser(pipeconf).counters().getById(message.getCounterId()).getPreamble().getName();
piCounterId = PiCounterId.of(counterName);
} catch (P4InfoBrowser.NotFoundException e) {
log.warn("Unable to find UP4 counter with ID {}", counterId);
throw INVALID_ARGUMENT.withDescription("Invalid UP4 counter identifier.").asException();
}
}
// cell was requested.
if (counterName != null && index != null) {
// A single counter cell was requested
UpfCounter ctrValues;
try {
ctrValues = up4Service.readCounter(index);
} catch (UpfProgrammableException e) {
throw INVALID_ARGUMENT.withDescription(e.getMessage()).asException();
}
long pkts;
long bytes;
if (piCounterId.equals(PRE_QOS_PIPE_PRE_QOS_COUNTER)) {
pkts = ctrValues.getIngressPkts();
bytes = ctrValues.getIngressBytes();
} else if (piCounterId.equals(POST_QOS_PIPE_POST_QOS_COUNTER)) {
pkts = ctrValues.getEgressPkts();
bytes = ctrValues.getEgressBytes();
} else {
log.warn("Received read request for unknown counter {}", piCounterId);
throw INVALID_ARGUMENT.withDescription("Invalid UP4 counter identifier.").asException();
}
responseCells.add(new PiCounterCell(PiCounterCellId.ofIndirect(piCounterId, index), pkts, bytes));
} else {
// All cells were requested, either for a specific counter or all counters
// FIXME: only read the counter that was requested, instead of both ingress and egress unconditionally
Collection<UpfCounter> allStats;
try {
allStats = up4Service.readCounters(-1);
} catch (UpfProgrammableException e) {
throw io.grpc.Status.UNKNOWN.withDescription(e.getMessage()).asException();
}
for (UpfCounter stat : allStats) {
if (piCounterId == null || piCounterId.equals(PRE_QOS_PIPE_PRE_QOS_COUNTER)) {
// If all counters were requested, or just the ingress one
responseCells.add(new PiCounterCell(PiCounterCellId.ofIndirect(PRE_QOS_PIPE_PRE_QOS_COUNTER, stat.getCellId()), stat.getIngressPkts(), stat.getIngressBytes()));
}
if (piCounterId == null || piCounterId.equals(POST_QOS_PIPE_POST_QOS_COUNTER)) {
// If all counters were requested, or just the egress one
responseCells.add(new PiCounterCell(PiCounterCellId.ofIndirect(POST_QOS_PIPE_POST_QOS_COUNTER, stat.getCellId()), stat.getEgressPkts(), stat.getEgressBytes()));
}
}
}
List<P4RuntimeOuterClass.Entity> responseEntities = new ArrayList<>();
for (PiCounterCell cell : responseCells) {
try {
responseEntities.add(Codecs.CODECS.entity().encode(cell, null, pipeconf));
log.trace("Encoded response to counter read request for counter {} and index {}", cell.cellId().counterId(), cell.cellId().index());
} catch (CodecException e) {
log.error("Unable to encode counter cell into a p4runtime entity: {}", e.getMessage());
throw io.grpc.Status.INTERNAL.withDescription("Unable to encode counter cell into a p4runtime entity.").asException();
}
}
log.debug("Encoded response to counter read request for {} cells", responseEntities.size());
return responseEntities;
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4DeviceManager method ensureInterfacesInstalled.
/**
* Ensure that all interfaces present in the UP4 config file are installed in the UPF leader device.
*/
private void ensureInterfacesInstalled() {
log.info("Ensuring all interfaces present in app config are present on the leader device.");
Collection<? extends UpfEntity> installedInterfaces;
UpfProgrammable leader = getLeaderUpfProgrammable();
try {
installedInterfaces = leader.readAll(UpfEntityType.INTERFACE);
} catch (UpfProgrammableException e) {
log.warn("Failed to read interface: {}", e.getMessage());
return;
}
for (UpfInterface iface : configInterfaces()) {
if (!installedInterfaces.contains(iface)) {
log.warn("{} is missing from leader device! Installing", iface);
try {
leader.apply(iface);
} catch (UpfProgrammableException e) {
log.warn("Failed to insert interface: {}", e.getMessage());
}
}
}
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4NorthComponent method readEntriesAndTranslate.
/**
* Find all table entries or meter entries that match the requested entry,
* and translate them to p4runtime entities for responding to a read request.
*
* @param requestedEntry the entry from a p4runtime read request
* @return all entries that match the request, translated to p4runtime entities
* @throws StatusException if the requested entry fails translation
*/
private List<P4RuntimeOuterClass.Entity> readEntriesAndTranslate(PiEntity requestedEntry) throws StatusException {
List<P4RuntimeOuterClass.Entity> translatedEntries = new ArrayList<>();
// TODO: return more specific responses matching the requested entry
try {
UpfEntityType entityType = up4Translator.getEntityType(requestedEntry);
boolean isMeter = entityType.equals(UpfEntityType.SESSION_METER) || entityType.equals(UpfEntityType.APPLICATION_METER);
Collection<? extends UpfEntity> entities = up4Service.readAll(entityType);
for (UpfEntity entity : entities) {
log.debug("Translating a {} entity for a read request: {}", entity.type(), entity);
P4RuntimeOuterClass.Entity responseEntity;
if (isMeter) {
responseEntity = Codecs.CODECS.entity().encode(up4Translator.upfEntityToUp4MeterEntry(entity), null, pipeconf);
} else {
responseEntity = Codecs.CODECS.entity().encode(up4Translator.upfEntityToUp4TableEntry(entity), null, pipeconf);
}
translatedEntries.add(responseEntity);
}
} catch (Up4Translator.Up4TranslationException | UpfProgrammableException | CodecException e) {
log.warn("Unable to encode/translate a read entry to a UP4 read response: {}", e.getMessage());
throw INVALID_ARGUMENT.withDescription("Unable to translate a read table entry to a p4runtime entity.").asException();
}
return translatedEntries;
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4NorthComponent method translateEntryAndApply.
/**
* Translate the given logical pipeline table entry or meter cell config
* to a Up4Service entry apply call.
*
* @param entry The logical table entry or meter cell config to be applied
* @throws StatusException if the entry fails translation or cannot be applied
*/
private void translateEntryAndApply(PiEntity entry) throws StatusException {
log.debug("Translating UP4 write request to fabric entry.");
try {
switch(entry.piEntityType()) {
case TABLE_ENTRY:
PiTableEntry tableEntry = (PiTableEntry) entry;
if (tableEntry.action().type() != PiTableAction.Type.ACTION) {
log.warn("Action profile entry insertion not supported.");
throw UNIMPLEMENTED.withDescription("Action profile entries not supported by UP4.").asException();
}
up4Service.apply(up4Translator.up4TableEntryToUpfEntity(tableEntry));
break;
case METER_CELL_CONFIG:
up4Service.apply(up4Translator.up4MeterEntryToUpfEntity((PiMeterCellConfig) entry));
break;
default:
throw UNIMPLEMENTED.withDescription("Unsupported entity type: " + entry.piEntityType()).asException();
}
} catch (Up4Translator.Up4TranslationException e) {
log.warn("Failed to parse entry from a write request: {}", e.getMessage());
throw INVALID_ARGUMENT.withDescription("Translation error: " + e.getMessage()).asException();
} catch (UpfProgrammableException e) {
log.warn("Failed to complete table entry insertion request: {}", e.getMessage());
switch(e.getType()) {
case ENTITY_EXHAUSTED:
throw io.grpc.Status.RESOURCE_EXHAUSTED.withDescription(e.getMessage()).asException();
case ENTITY_OUT_OF_RANGE:
throw INVALID_ARGUMENT.withDescription(e.getMessage()).asException();
case UNKNOWN:
default:
throw io.grpc.Status.UNAVAILABLE.withDescription(e.getMessage()).asException();
}
}
}
Aggregations