Search in sources :

Example 1 with PiCounterCell

use of org.onosproject.net.pi.runtime.PiCounterCell in project onos by opennetworkinglab.

the class PortStatisticsDiscoveryImpl method discoverPortStatistics.

@Override
public Collection<PortStatistics> discoverPortStatistics() {
    DeviceService deviceService = this.handler().get(DeviceService.class);
    DeviceId deviceId = this.data().deviceId();
    PiPipeconfService piPipeconfService = handler().get(PiPipeconfService.class);
    if (!piPipeconfService.ofDevice(deviceId).isPresent() || !piPipeconfService.getPipeconf(piPipeconfService.ofDevice(deviceId).get()).isPresent()) {
        log.warn("Unable to get the pipeconf of {}, aborting operation", deviceId);
        return Collections.emptyList();
    }
    PiPipeconf pipeconf = piPipeconfService.getPipeconf(piPipeconfService.ofDevice(deviceId).get()).get();
    P4RuntimeController controller = handler().get(P4RuntimeController.class);
    P4RuntimeClient client = controller.get(deviceId);
    if (client == null) {
        log.warn("Unable to find client for {}, aborting operation", deviceId);
        return Collections.emptyList();
    }
    Map<Long, DefaultPortStatistics.Builder> portStatBuilders = Maps.newHashMap();
    deviceService.getPorts(deviceId).forEach(p -> portStatBuilders.put(p.number().toLong(), DefaultPortStatistics.builder().setPort(p.number()).setDeviceId(deviceId).setDurationSec(getDuration(p.number()))));
    Set<PiCounterCellId> counterCellIds = Sets.newHashSet();
    portStatBuilders.keySet().forEach(p -> {
        // Counter cell/index = port number.
        counterCellIds.add(PiCounterCellId.ofIndirect(ingressCounterId(), p));
        counterCellIds.add(PiCounterCellId.ofIndirect(egressCounterId(), p));
    });
    Set<PiCounterCellHandle> counterCellHandles = counterCellIds.stream().map(id -> PiCounterCellHandle.of(deviceId, id)).collect(Collectors.toSet());
    // Query the device.
    Collection<PiCounterCell> counterEntryResponse = client.read(DEFAULT_P4_DEVICE_ID, pipeconf).handles(counterCellHandles).submitSync().all(PiCounterCell.class);
    counterEntryResponse.forEach(counterCell -> {
        if (counterCell.cellId().counterType() != INDIRECT) {
            log.warn("Invalid counter data type {}, skipping", counterCell.cellId().counterType());
            return;
        }
        PiCounterCellId indCellId = counterCell.cellId();
        if (!portStatBuilders.containsKey(indCellId.index())) {
            log.warn("Unrecognized counter index {}, skipping", counterCell);
            return;
        }
        DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(indCellId.index());
        if (counterCell.cellId().counterId().equals(ingressCounterId())) {
            statsBuilder.setPacketsReceived(counterCell.data().packets());
            statsBuilder.setBytesReceived(counterCell.data().bytes());
        } else if (counterCell.cellId().counterId().equals(egressCounterId())) {
            statsBuilder.setPacketsSent(counterCell.data().packets());
            statsBuilder.setBytesSent(counterCell.data().bytes());
        } else {
            log.warn("Unrecognized counter ID {}, skipping", counterCell);
        }
    });
    return portStatBuilders.values().stream().map(DefaultPortStatistics.Builder::build).collect(Collectors.toList());
}
Also used : INGRESS_PORT_COUNTERS_INGRESS_INGRESS_PORT_COUNTER(org.onosproject.pipelines.basic.BasicConstants.INGRESS_PORT_COUNTERS_INGRESS_INGRESS_PORT_COUNTER) PiPipeconfService(org.onosproject.net.pi.service.PiPipeconfService) PortStatistics(org.onosproject.net.device.PortStatistics) PiCounterId(org.onosproject.net.pi.model.PiCounterId) PiPipeconf(org.onosproject.net.pi.model.PiPipeconf) PortNumber(org.onosproject.net.PortNumber) DeviceService(org.onosproject.net.device.DeviceService) LoggerFactory(org.slf4j.LoggerFactory) AbstractHandlerBehaviour(org.onosproject.net.driver.AbstractHandlerBehaviour) PiCounterCellHandle(org.onosproject.net.pi.runtime.PiCounterCellHandle) Pair(org.apache.commons.lang3.tuple.Pair) P4RuntimeController(org.onosproject.p4runtime.api.P4RuntimeController) Map(java.util.Map) DefaultPortStatistics(org.onosproject.net.device.DefaultPortStatistics) PortStatisticsDiscovery(org.onosproject.net.device.PortStatisticsDiscovery) PiCounterCellId(org.onosproject.net.pi.runtime.PiCounterCellId) Logger(org.slf4j.Logger) INDIRECT(org.onosproject.net.pi.model.PiCounterType.INDIRECT) P4RuntimeClient(org.onosproject.p4runtime.api.P4RuntimeClient) Collection(java.util.Collection) Set(java.util.Set) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell) EGRESS_PORT_COUNTERS_EGRESS_EGRESS_PORT_COUNTER(org.onosproject.pipelines.basic.BasicConstants.EGRESS_PORT_COUNTERS_EGRESS_EGRESS_PORT_COUNTER) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) DeviceId(org.onosproject.net.DeviceId) Collections(java.util.Collections) DefaultPortStatistics(org.onosproject.net.device.DefaultPortStatistics) PiCounterCellId(org.onosproject.net.pi.runtime.PiCounterCellId) PiCounterCellHandle(org.onosproject.net.pi.runtime.PiCounterCellHandle) DeviceId(org.onosproject.net.DeviceId) PiPipeconf(org.onosproject.net.pi.model.PiPipeconf) DeviceService(org.onosproject.net.device.DeviceService) PiPipeconfService(org.onosproject.net.pi.service.PiPipeconfService) P4RuntimeClient(org.onosproject.p4runtime.api.P4RuntimeClient) P4RuntimeController(org.onosproject.p4runtime.api.P4RuntimeController) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell)

Example 2 with PiCounterCell

use of org.onosproject.net.pi.runtime.PiCounterCell in project up4 by omec-project.

the class Up4NorthComponentTest method readCounterTest.

private void readCounterTest(PiCounterId counterId, long expectedPackets, long expectedBytes) {
    MockStreamObserver<P4RuntimeOuterClass.ReadResponse> responseObserver = new MockStreamObserver<>();
    int cellIndex = 1;
    PiCounterCell requestedCell = new PiCounterCell(PiCounterCellId.ofIndirect(counterId, cellIndex), 0, 0);
    P4RuntimeOuterClass.Entity entity;
    try {
        entity = Codecs.CODECS.entity().encode(requestedCell, null, pipeconf);
    } catch (CodecException e) {
        fail("Unable to encode counter cell to p4runtime entity.");
        return;
    }
    P4RuntimeOuterClass.ReadRequest request = P4RuntimeOuterClass.ReadRequest.newBuilder().addEntities(entity).setDeviceId(NorthTestConstants.P4RUNTIME_DEVICE_ID).build();
    up4NorthService.read(request, responseObserver);
    var response = responseObserver.lastResponse();
    PiCounterCell expectedCell = new PiCounterCell(PiCounterCellId.ofIndirect(counterId, cellIndex), expectedPackets, expectedBytes);
    P4RuntimeOuterClass.Entity expectedEntity;
    try {
        expectedEntity = Codecs.CODECS.entity().encode(expectedCell, null, pipeconf);
    } catch (CodecException e) {
        fail("Unable to encode counter cell to p4runtime entity.");
        return;
    }
    assertThat(response.getEntitiesCount(), equalTo(1));
    assertThat(response.getEntitiesList().get(0), equalTo(expectedEntity));
}
Also used : P4RuntimeOuterClass(p4.v1.P4RuntimeOuterClass) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell) CodecException(org.onosproject.p4runtime.ctl.codec.CodecException)

Example 3 with PiCounterCell

use of org.onosproject.net.pi.runtime.PiCounterCell in project up4 by omec-project.

the class Up4NorthComponentTest method entityToCounterCell.

private PiCounterCell entityToCounterCell(P4RuntimeOuterClass.Entity entity) {
    PiEntity responsePiEntity;
    try {
        responsePiEntity = Codecs.CODECS.entity().decode(entity, null, pipeconf);
    } catch (CodecException e) {
        fail("Unable to decode p4runtime entity from read response.");
        return null;
    }
    assertThat(responsePiEntity.piEntityType(), equalTo(PiEntityType.COUNTER_CELL));
    return (PiCounterCell) responsePiEntity;
}
Also used : PiEntity(org.onosproject.net.pi.runtime.PiEntity) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell) CodecException(org.onosproject.p4runtime.ctl.codec.CodecException)

Example 4 with PiCounterCell

use of org.onosproject.net.pi.runtime.PiCounterCell in project onos by opennetworkinglab.

the class PortStatisticsDiscoveryImpl method discoverPortStatistics.

@Override
public Collection<PortStatistics> discoverPortStatistics() {
    DeviceService deviceService = this.handler().get(DeviceService.class);
    DeviceId deviceId = this.data().deviceId();
    // Get a client for this device.
    P4RuntimeController controller = handler().get(P4RuntimeController.class);
    P4RuntimeClient client = controller.get(deviceId);
    if (client == null) {
        log.warn("Unable to find client for {}, aborting operation", deviceId);
        return Collections.emptyList();
    }
    // Get the pipeconf of this device.
    PiPipeconfService piPipeconfService = handler().get(PiPipeconfService.class);
    if (!piPipeconfService.ofDevice(deviceId).isPresent() || !piPipeconfService.getPipeconf(piPipeconfService.ofDevice(deviceId).get()).isPresent()) {
        log.warn("Unable to get the pipeconf of {}, aborting operation", deviceId);
        return Collections.emptyList();
    }
    PiPipeconf pipeconf = piPipeconfService.getPipeconf(piPipeconfService.ofDevice(deviceId).get()).get();
    // Prepare PortStatistics objects to return, one per port of this device.
    Map<Long, DefaultPortStatistics.Builder> portStatBuilders = Maps.newHashMap();
    deviceService.getPorts(deviceId).forEach(p -> portStatBuilders.put(p.number().toLong(), DefaultPortStatistics.builder().setPort(p.number()).setDeviceId(deviceId)));
    // Generate the counter cell IDs.
    Set<PiCounterCellId> counterCellIds = Sets.newHashSet();
    portStatBuilders.keySet().forEach(p -> {
        // Counter cell/index = port number.
        counterCellIds.add(PiCounterCellId.ofIndirect(INGRESS_COUNTER_ID, p));
        counterCellIds.add(PiCounterCellId.ofIndirect(EGRESS_COUNTER_ID, p));
    });
    Set<PiCounterCellHandle> counterCellHandles = counterCellIds.stream().map(id -> PiCounterCellHandle.of(deviceId, id)).collect(Collectors.toSet());
    // Query the device.
    Collection<PiCounterCell> counterEntryResponse = client.read(DEFAULT_P4_DEVICE_ID, pipeconf).handles(counterCellHandles).submitSync().all(PiCounterCell.class);
    // Process response.
    counterEntryResponse.forEach(counterCell -> {
        if (counterCell.cellId().counterType() != INDIRECT) {
            log.warn("Invalid counter data type {}, skipping", counterCell.cellId().counterType());
            return;
        }
        if (!portStatBuilders.containsKey(counterCell.cellId().index())) {
            log.warn("Unrecognized counter index {}, skipping", counterCell);
            return;
        }
        DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(counterCell.cellId().index());
        if (counterCell.cellId().counterId().equals(INGRESS_COUNTER_ID)) {
            statsBuilder.setPacketsReceived(counterCell.data().packets());
            statsBuilder.setBytesReceived(counterCell.data().bytes());
        } else if (counterCell.cellId().counterId().equals(EGRESS_COUNTER_ID)) {
            statsBuilder.setPacketsSent(counterCell.data().packets());
            statsBuilder.setBytesSent(counterCell.data().bytes());
        } else {
            log.warn("Unrecognized counter ID {}, skipping", counterCell);
        }
    });
    return portStatBuilders.values().stream().map(DefaultPortStatistics.Builder::build).collect(Collectors.toList());
}
Also used : PiCounterCellId(org.onosproject.net.pi.runtime.PiCounterCellId) PiPipeconfService(org.onosproject.net.pi.service.PiPipeconfService) Logger(org.slf4j.Logger) INDIRECT(org.onosproject.net.pi.model.PiCounterType.INDIRECT) P4RuntimeClient(org.onosproject.p4runtime.api.P4RuntimeClient) PortStatistics(org.onosproject.net.device.PortStatistics) PiCounterId(org.onosproject.net.pi.model.PiCounterId) PiPipeconf(org.onosproject.net.pi.model.PiPipeconf) Collection(java.util.Collection) DeviceService(org.onosproject.net.device.DeviceService) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) AbstractHandlerBehaviour(org.onosproject.net.driver.AbstractHandlerBehaviour) PiCounterCellHandle(org.onosproject.net.pi.runtime.PiCounterCellHandle) P4RuntimeController(org.onosproject.p4runtime.api.P4RuntimeController) Map(java.util.Map) DefaultPortStatistics(org.onosproject.net.device.DefaultPortStatistics) DeviceId(org.onosproject.net.DeviceId) Collections(java.util.Collections) PortStatisticsDiscovery(org.onosproject.net.device.PortStatisticsDiscovery) DefaultPortStatistics(org.onosproject.net.device.DefaultPortStatistics) PiCounterCellId(org.onosproject.net.pi.runtime.PiCounterCellId) PiCounterCellHandle(org.onosproject.net.pi.runtime.PiCounterCellHandle) DeviceId(org.onosproject.net.DeviceId) PiPipeconf(org.onosproject.net.pi.model.PiPipeconf) DeviceService(org.onosproject.net.device.DeviceService) PiPipeconfService(org.onosproject.net.pi.service.PiPipeconfService) P4RuntimeClient(org.onosproject.p4runtime.api.P4RuntimeClient) P4RuntimeController(org.onosproject.p4runtime.api.P4RuntimeController) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell)

Example 5 with PiCounterCell

use of org.onosproject.net.pi.runtime.PiCounterCell 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;
}
Also used : UpfEntity(org.onosproject.net.behaviour.upf.UpfEntity) PiEntity(org.onosproject.net.pi.runtime.PiEntity) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) HexString(org.onlab.util.HexString) UpfCounter(org.onosproject.net.behaviour.upf.UpfCounter) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) UpfProgrammableException(org.onosproject.net.behaviour.upf.UpfProgrammableException) PiCounterCell(org.onosproject.net.pi.runtime.PiCounterCell) CodecException(org.onosproject.p4runtime.ctl.codec.CodecException) PiCounterId(org.onosproject.net.pi.model.PiCounterId) P4InfoBrowser(org.onosproject.p4runtime.ctl.utils.P4InfoBrowser)

Aggregations

PiCounterCell (org.onosproject.net.pi.runtime.PiCounterCell)6 CodecException (org.onosproject.p4runtime.ctl.codec.CodecException)4 PiCounterId (org.onosproject.net.pi.model.PiCounterId)3 Maps (com.google.common.collect.Maps)2 Sets (com.google.common.collect.Sets)2 Collection (java.util.Collection)2 Collections (java.util.Collections)2 Map (java.util.Map)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2 DeviceId (org.onosproject.net.DeviceId)2 DefaultPortStatistics (org.onosproject.net.device.DefaultPortStatistics)2 DeviceService (org.onosproject.net.device.DeviceService)2 PortStatistics (org.onosproject.net.device.PortStatistics)2 PortStatisticsDiscovery (org.onosproject.net.device.PortStatisticsDiscovery)2 AbstractHandlerBehaviour (org.onosproject.net.driver.AbstractHandlerBehaviour)2 INDIRECT (org.onosproject.net.pi.model.PiCounterType.INDIRECT)2 PiPipeconf (org.onosproject.net.pi.model.PiPipeconf)2 PiCounterCellHandle (org.onosproject.net.pi.runtime.PiCounterCellHandle)2 PiCounterCellId (org.onosproject.net.pi.runtime.PiCounterCellId)2