use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4NorthComponent method setPhysicalSizes.
/**
* Update the logical p4info with physical resource sizes.
*
* @param p4Info a logical UP4 switch's p4info
* @return the same p4info, but with resource sizes set to the sizes from the physical switch
*/
@VisibleForTesting
P4InfoOuterClass.P4Info setPhysicalSizes(P4InfoOuterClass.P4Info p4Info) {
var newP4InfoBuilder = P4InfoOuterClass.P4Info.newBuilder(p4Info).clearCounters().clearTables().clearMeters();
long physicalCounterSize;
long physicalSessionMeterSize;
long physicalAppMeterSize;
long physicalSessionsUlTableSize;
long physicalSessionsDlTableSize;
long physicalTerminationsUlTableSize;
long physicalTerminationsDlTableSize;
long physicalTunnelPeerTableSize;
try {
physicalCounterSize = up4Service.tableSize(UpfEntityType.COUNTER);
physicalSessionMeterSize = up4Service.tableSize(UpfEntityType.SESSION_METER);
physicalAppMeterSize = up4Service.tableSize(UpfEntityType.APPLICATION_METER);
physicalSessionsUlTableSize = up4Service.tableSize(UpfEntityType.SESSION_UPLINK);
physicalSessionsDlTableSize = up4Service.tableSize(UpfEntityType.SESSION_DOWNLINK);
physicalTerminationsUlTableSize = up4Service.tableSize(UpfEntityType.TERMINATION_UPLINK);
physicalTerminationsDlTableSize = up4Service.tableSize(UpfEntityType.TERMINATION_DOWNLINK);
physicalTunnelPeerTableSize = up4Service.tableSize(UpfEntityType.TUNNEL_PEER);
} catch (UpfProgrammableException e) {
throw new IllegalStateException("Error while getting physical sizes! " + e.getMessage());
}
int ingressPdrCounterId;
int egressPdrCounterId;
int sessionMeterId;
int appMeterId;
int sessionsUlTable;
int sessionsDlTable;
int terminationsUlTable;
int terminationsDlTable;
int tunnelPeerTable;
try {
P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);
ingressPdrCounterId = browser.counters().getByName(PRE_QOS_PIPE_PRE_QOS_COUNTER.id()).getPreamble().getId();
sessionMeterId = browser.meters().getByName(PRE_QOS_PIPE_SESSION_METER.id()).getPreamble().getId();
appMeterId = browser.meters().getByName(PRE_QOS_PIPE_APP_METER.id()).getPreamble().getId();
egressPdrCounterId = browser.counters().getByName(POST_QOS_PIPE_POST_QOS_COUNTER.id()).getPreamble().getId();
sessionsUlTable = browser.tables().getByName(PRE_QOS_PIPE_SESSIONS_UPLINK.id()).getPreamble().getId();
sessionsDlTable = browser.tables().getByName(PRE_QOS_PIPE_SESSIONS_DOWNLINK.id()).getPreamble().getId();
terminationsUlTable = browser.tables().getByName(PRE_QOS_PIPE_TERMINATIONS_UPLINK.id()).getPreamble().getId();
terminationsDlTable = browser.tables().getByName(PRE_QOS_PIPE_TERMINATIONS_DOWNLINK.id()).getPreamble().getId();
tunnelPeerTable = browser.tables().getByName(PRE_QOS_PIPE_TUNNEL_PEERS.id()).getPreamble().getId();
} catch (P4InfoBrowser.NotFoundException e) {
throw new NoSuchElementException("A UP4 counter/table that should always exist does not exist.");
}
p4Info.getCountersList().forEach(counter -> {
if (counter.getPreamble().getId() == ingressPdrCounterId || counter.getPreamble().getId() == egressPdrCounterId) {
// Change the sizes of the PDR counters
newP4InfoBuilder.addCounters(P4InfoOuterClass.Counter.newBuilder(counter).setSize(physicalCounterSize).build());
} else {
// Any other counters go unchanged (for now)
newP4InfoBuilder.addCounters(counter);
}
});
p4Info.getMetersList().forEach(meter -> {
if (meter.getPreamble().getId() == sessionMeterId) {
newP4InfoBuilder.addMeters(P4InfoOuterClass.Meter.newBuilder(meter).setSize(physicalSessionMeterSize)).build();
} else if (meter.getPreamble().getId() == appMeterId) {
newP4InfoBuilder.addMeters(P4InfoOuterClass.Meter.newBuilder(meter).setSize(physicalAppMeterSize)).build();
} else {
// Any other meters go unchanged
newP4InfoBuilder.addMeters(meter);
}
});
p4Info.getTablesList().forEach(table -> {
if (table.getPreamble().getId() == sessionsUlTable) {
newP4InfoBuilder.addTables(P4InfoOuterClass.Table.newBuilder(table).setSize(physicalSessionsUlTableSize).build());
} else if (table.getPreamble().getId() == sessionsDlTable) {
newP4InfoBuilder.addTables(P4InfoOuterClass.Table.newBuilder(table).setSize(physicalSessionsDlTableSize).build());
} else if (table.getPreamble().getId() == terminationsUlTable) {
newP4InfoBuilder.addTables(P4InfoOuterClass.Table.newBuilder(table).setSize(physicalTerminationsUlTableSize).build());
} else if (table.getPreamble().getId() == terminationsDlTable) {
newP4InfoBuilder.addTables(P4InfoOuterClass.Table.newBuilder(table).setSize(physicalTerminationsDlTableSize).build());
} else if (table.getPreamble().getId() == tunnelPeerTable) {
newP4InfoBuilder.addTables(P4InfoOuterClass.Table.newBuilder(table).setSize(physicalTunnelPeerTableSize).build());
} else {
// Any tables aside from the PDR and FAR tables go unchanged
newP4InfoBuilder.addTables(table);
}
});
return newP4InfoBuilder.build();
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4DeviceManager method readCounter.
@Override
public UpfCounter readCounter(int counterIdx) throws UpfProgrammableException {
if (isMaxUeSet() && counterIdx >= getMaxUe() * 2) {
throw new UpfProgrammableException("Requested PDR counter cell index above max supported UE value.", UpfProgrammableException.Type.ENTITY_OUT_OF_RANGE, UpfEntityType.COUNTER);
}
// When reading counters we need to explicitly read on all UPF physical
// devices and aggregate counter values.
assertUpfIsReady();
// TODO: add get on builder can simply this, by removing the need for building the PdrStat every time.
UpfCounter.Builder builder = UpfCounter.builder();
builder.withCellId(counterIdx);
UpfCounter prevStats = builder.build();
for (UpfProgrammable upfProg : upfProgrammables.values()) {
UpfCounter pdrStat = upfProg.readCounter(counterIdx);
builder.setIngress(pdrStat.getIngressPkts() + prevStats.getIngressPkts(), pdrStat.getIngressBytes() + prevStats.getIngressBytes());
builder.setEgress(pdrStat.getEgressPkts() + prevStats.getEgressPkts(), pdrStat.getEgressBytes() + prevStats.getEgressBytes());
prevStats = builder.build();
}
builder.withCellId(counterIdx);
return builder.build();
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4DeviceManager method apply.
@Override
public void apply(UpfEntity entity) throws UpfProgrammableException {
switch(entity.type()) {
case SESSION_DOWNLINK:
UpfSessionDownlink sessDl = (UpfSessionDownlink) entity;
if (sessDl.needsBuffering()) {
// Override tunnel peer id with the DBUF
entity = convertToBuffering(sessDl);
up4Store.learnBufferingUe(sessDl.ueAddress());
}
break;
case TERMINATION_UPLINK:
UpfTerminationUplink termUl = (UpfTerminationUplink) entity;
if (isMaxUeSet() && termUl.counterId() >= getMaxUe() * 2) {
throw new UpfProgrammableException("Counter cell index referenced by uplink UPF termination " + "rule above max supported UE value.", UpfProgrammableException.Type.ENTITY_OUT_OF_RANGE, UpfEntityType.TERMINATION_UPLINK);
}
break;
case TERMINATION_DOWNLINK:
UpfTerminationDownlink termDl = (UpfTerminationDownlink) entity;
if (isMaxUeSet() && termDl.counterId() >= getMaxUe() * 2) {
throw new UpfProgrammableException("Counter cell index referenced by downlink UPF termination " + "rule above max supported UE value.", UpfProgrammableException.Type.ENTITY_OUT_OF_RANGE, UpfEntityType.TERMINATION_DOWNLINK);
}
break;
case INTERFACE:
UpfInterface intf = (UpfInterface) entity;
if (intf.isDbufReceiver()) {
throw new UpfProgrammableException("Cannot apply the DBUF interface entry!");
}
break;
case TUNNEL_PEER:
UpfGtpTunnelPeer tunnelPeer = (UpfGtpTunnelPeer) entity;
if (tunnelPeer.tunPeerId() == DBUF_TUNNEL_ID) {
throw new UpfProgrammableException("Cannot apply the DBUF GTP Tunnel Peer");
}
break;
default:
break;
}
getLeaderUpfProgrammable().apply(entity);
// Drain from DBUF if necessary
if (entity.type().equals(SESSION_DOWNLINK)) {
UpfSessionDownlink sess = (UpfSessionDownlink) entity;
if (!sess.needsBuffering() && up4Store.forgetBufferingUe(sess.ueAddress())) {
// TODO: Should we wait for rules to be installed on all devices before
// triggering drain?
// When a fwd FAR is changed to buff FAR,
// both session_downlink & downlink_termination rules are updated.
// If the drain action starts immediately right after applying session_downlink,
// the downlink_termination rule may not be updated,
// thus, the TEID may wrong in such case.
// Run the outbound rpc in a forked context so it doesn't cancel if it was called
// by an inbound rpc that completes faster than the drain call
Ip4Address ueAddr = sess.ueAddress();
Context ctx = Context.current().fork();
ctx.run(() -> {
if (dbufClient == null) {
log.error("Cannot start dbuf drain for {}, dbufClient is null", ueAddr);
return;
}
if (config == null || config.dbufDrainAddr() == null) {
log.error("Cannot start dbuf drain for {}, dbufDrainAddr is null", ueAddr);
return;
}
log.info("Started dbuf drain for {}", ueAddr);
dbufClient.drain(ueAddr, config.dbufDrainAddr(), GTP_PORT).whenComplete((result, ex) -> {
if (ex != null) {
log.error("Exception while draining dbuf for {}: {}", ueAddr, ex);
} else if (result) {
log.info("Dbuf drain completed for {}", ueAddr);
} else {
log.warn("Unknown error while draining dbuf for {}", ueAddr);
}
});
});
}
}
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class ReadUpfEntitiesCommand method doExecute.
@Override
protected void doExecute() {
Up4AdminService up4Admin = get(Up4AdminService.class);
Up4Service up4Service = get(Up4Service.class);
boolean filterCounters = false;
try {
List<UpfEntityType> printedTypes = new ArrayList<>();
if (all) {
printedTypes.add(UpfEntityType.APPLICATION);
printedTypes.add(UpfEntityType.SESSION_UPLINK);
printedTypes.add(UpfEntityType.SESSION_DOWNLINK);
printedTypes.add(UpfEntityType.TERMINATION_UPLINK);
printedTypes.add(UpfEntityType.TERMINATION_DOWNLINK);
printedTypes.add(UpfEntityType.TUNNEL_PEER);
printedTypes.add(UpfEntityType.INTERFACE);
printedTypes.add(UpfEntityType.SESSION_METER);
printedTypes.add(UpfEntityType.APPLICATION_METER);
filterCounters = true;
} else if (ue) {
printedTypes.add(UpfEntityType.APPLICATION);
printedTypes.add(UpfEntityType.SESSION_UPLINK);
printedTypes.add(UpfEntityType.SESSION_DOWNLINK);
printedTypes.add(UpfEntityType.TERMINATION_UPLINK);
printedTypes.add(UpfEntityType.TERMINATION_DOWNLINK);
printedTypes.add(UpfEntityType.TUNNEL_PEER);
printedTypes.add(UpfEntityType.SESSION_METER);
printedTypes.add(UpfEntityType.APPLICATION_METER);
filterCounters = true;
} else {
if (application) {
printedTypes.add(UpfEntityType.APPLICATION);
}
if (sessions) {
printedTypes.add(UpfEntityType.SESSION_UPLINK);
printedTypes.add(UpfEntityType.SESSION_DOWNLINK);
}
if (termination) {
printedTypes.add(UpfEntityType.TERMINATION_UPLINK);
printedTypes.add(UpfEntityType.TERMINATION_DOWNLINK);
}
if (tunnels) {
printedTypes.add(UpfEntityType.TUNNEL_PEER);
}
if (counters) {
printedTypes.add(UpfEntityType.COUNTER);
filterCounters = false;
}
if (interfaces) {
printedTypes.add(UpfEntityType.INTERFACE);
}
if (appMeters) {
printedTypes.add(UpfEntityType.APPLICATION_METER);
}
if (sessMeters) {
printedTypes.add(UpfEntityType.SESSION_METER);
}
}
for (var type : printedTypes) {
if (type.equals(UpfEntityType.TERMINATION_UPLINK)) {
Collection<? extends UpfEntity> terminations = up4Admin.adminReadAll(type);
for (var t : terminations) {
UpfTerminationUplink term = (UpfTerminationUplink) t;
print(term.toString());
if (filterCounters) {
print(up4Service.readCounter(term.counterId()).toString());
}
}
} else if (type.equals(UpfEntityType.TERMINATION_DOWNLINK)) {
Collection<? extends UpfEntity> terminations = up4Admin.adminReadAll(type);
for (var t : terminations) {
UpfTerminationDownlink term = (UpfTerminationDownlink) t;
print(term.toString());
if (filterCounters) {
print(up4Service.readCounter(term.counterId()).toString());
}
}
} else {
up4Admin.adminReadAll(type).forEach(upfEntity -> print(upfEntity.toString()));
}
}
} catch (UpfProgrammableException e) {
print("Error while reading UPF entity: " + e.getMessage());
}
}
use of org.onosproject.net.behaviour.upf.UpfProgrammableException in project up4 by omec-project.
the class Up4DeviceManager method deleteAll.
@Override
public void deleteAll(UpfEntityType entityType) throws UpfProgrammableException {
switch(entityType) {
case TERMINATION_DOWNLINK:
getLeaderUpfProgrammable().deleteAll(entityType);
up4Store.reset();
break;
case INTERFACE:
Collection<? extends UpfEntity> intfs = getLeaderUpfProgrammable().readAll(UpfEntityType.INTERFACE).stream().filter(t -> !((UpfInterface) t).isDbufReceiver()).collect(Collectors.toList());
for (UpfEntity i : intfs) {
getLeaderUpfProgrammable().delete(i);
}
break;
case TUNNEL_PEER:
Collection<? extends UpfEntity> tunnels = getLeaderUpfProgrammable().readAll(UpfEntityType.TUNNEL_PEER).stream().filter(t -> ((UpfGtpTunnelPeer) t).tunPeerId() != DBUF_TUNNEL_ID).collect(Collectors.toList());
for (UpfEntity tun : tunnels) {
getLeaderUpfProgrammable().delete(tun);
}
break;
default:
getLeaderUpfProgrammable().deleteAll(entityType);
}
}
Aggregations