org.onosproject.net.pi.model.PiPipelineModel Java Examples

The following examples show how to use org.onosproject.net.pi.model.PiPipelineModel. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: P4RuntimeTableStatisticsDiscovery.java    From onos with Apache License 2.0 6 votes vote down vote up
@Override
public List<TableStatisticsEntry> getTableStatistics() {
    if (!setupBehaviour("getTableStatistics()")) {
        return Collections.emptyList();
    }
    FlowRuleService flowService = handler().get(FlowRuleService.class);
    PiPipelineInterpreter interpreter = getInterpreter(handler());
    PiPipelineModel model = pipeconf.pipelineModel();
    List<TableStatisticsEntry> tableStatsList;

    List<FlowEntry> rules = newArrayList(flowService.getFlowEntries(deviceId));
    Map<PiTableId, Integer> piTableFlowCount = piFlowRuleCounting(model, interpreter, rules);
    Map<PiTableId, Long> piTableMatchCount = piMatchedCounting(model, interpreter, rules);
    tableStatsList = generatePiFlowTableStatistics(piTableFlowCount, piTableMatchCount, model, deviceId);

    return tableStatsList;
}
 
Example #2
Source File: P4RuntimeTableStatisticsDiscovery.java    From onos with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the number of added flows in each table.
 *
 * @param model pipeline model
 * @param interpreter pipeline interpreter
 * @param rules flow rules in this device
 * @return hashmap containing matched packet counting for each table
 */
private Map<PiTableId, Integer> piFlowRuleCounting(PiPipelineModel model, PiPipelineInterpreter interpreter,
                                                   List<FlowEntry> rules) {
    Map<PiTableId, Integer> piTableFlowCount = new HashMap<>();
    for (PiTableModel tableModel : model.tables()) {
        piTableFlowCount.put(tableModel.id(), 0);
    }
    for (FlowEntry f : rules) {
        if (f.state() == FlowEntry.FlowEntryState.ADDED) {
            PiTableId piTableId = getPiTableId(f, interpreter);
            if (piTableId != null) {
                piTableFlowCount.put(piTableId, piTableFlowCount.get(piTableId) + 1);
            }
        }
    }
    return piTableFlowCount;
}
 
Example #3
Source File: P4RuntimeTableStatisticsDiscovery.java    From onos with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the number of matched packets for each table.
 *
 * @param model pipeline model
 * @param interpreter pipeline interpreter
 * @param rules flow rules in this device
 * @return hashmap containing flow rule counting for each table
 */
private Map<PiTableId, Long> piMatchedCounting(PiPipelineModel model, PiPipelineInterpreter interpreter,
                                               List<FlowEntry> rules) {
    Map<PiTableId, Long> piTableMatchCount = new HashMap<>();
    for (PiTableModel tableModel : model.tables()) {
        piTableMatchCount.put(tableModel.id(), (long) 0);
    }
    for (FlowEntry f : rules) {
        if (f.state() == FlowEntry.FlowEntryState.ADDED) {
            PiTableId piTableId = getPiTableId(f, interpreter);
            if (piTableId != null) {
                piTableMatchCount.put(piTableId, piTableMatchCount.get(piTableId) + f.packets());
            }
        }
    }
    return piTableMatchCount;
}
 
Example #4
Source File: P4RuntimeTableStatisticsDiscovery.java    From onos with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the list of table statistics for P4 switch.
 *
 * @param piTableFlowCount hashmap containing the number of flow rules for each table
 * @param piTableMatchCount hashmap containing the number of matched packets for each table
 * @param model pipeline model
 * @param deviceId device ID
 * @return list of table statistics for P4 switch
 */
private List<TableStatisticsEntry> generatePiFlowTableStatistics(Map<PiTableId, Integer> piTableFlowCount,
                                                                   Map<PiTableId, Long> piTableMatchCount,
                                                                   PiPipelineModel model, DeviceId deviceId) {
    List<TableStatisticsEntry> tableStatsList;
    Iterator it = piTableFlowCount.entrySet().iterator();
    tableStatsList = new ArrayList<>();
    while (it.hasNext()) {
        Map.Entry pair = (Map.Entry) it.next();
        TableStatisticsEntry tableStat = DefaultTableStatisticsEntry.builder()
                .withDeviceId(deviceId)
                .withTableId((PiTableId) pair.getKey())
                .withActiveFlowEntries(piTableFlowCount.get(pair.getKey()))
                .withPacketsMatchedCount(piTableMatchCount.get(pair.getKey()))
                .withMaxSize(model.table((PiTableId) pair.getKey()).get().maxSize()).build();
        tableStatsList.add(tableStat);
        it.remove();
    }
    return tableStatsList;
}
 
Example #5
Source File: PipeconfLoader.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
private PiPipeconf buildPipeconf() throws P4InfoParserException {

        final URL p4InfoUrl = PipeconfLoader.class.getResource(P4INFO_PATH);
        final URL bmv2JsonUrlUrl = PipeconfLoader.class.getResource(BMV2_JSON_PATH);
        final PiPipelineModel pipelineModel = P4InfoParser.parse(p4InfoUrl);

        return DefaultPiPipeconf.builder()
                .withId(PIPECONF_ID)
                .withPipelineModel(pipelineModel)
                .addBehaviour(PiPipelineInterpreter.class, InterpreterImpl.class)
                .addBehaviour(Pipeliner.class, PipelinerImpl.class)
                .addExtension(P4_INFO_TEXT, p4InfoUrl)
                .addExtension(BMV2_JSON, bmv2JsonUrlUrl)
                .build();
    }
 
Example #6
Source File: PipeconfFactory.java    From onos with Apache License 2.0 5 votes vote down vote up
private PiPipeconf buildPipeconf() throws P4InfoParserException {

        final PiPipelineModel pipelineModel = P4InfoParser.parse(P4INFO_URL);

        return DefaultPiPipeconf.builder()
                .withId(PIPECONF_ID)
                .withPipelineModel(pipelineModel)
                .addBehaviour(PiPipelineInterpreter.class, PipelineInterpreterImpl.class)
                .addBehaviour(PortStatisticsDiscovery.class, PortStatisticsDiscoveryImpl.class)
                // Since mytunnel.p4 defines only 1 table, we re-use the existing single-table pipeliner.
                .addBehaviour(Pipeliner.class, DefaultSingleTablePipeline.class)
                .addExtension(P4_INFO_TEXT, P4INFO_URL)
                .addExtension(BMV2_JSON, BMV2_JSON_URL)
                .build();
    }
 
Example #7
Source File: PipeconfLoader.java    From onos with Apache License 2.0 5 votes vote down vote up
private static PiPipelineModel parseP4Info(URL p4InfoUrl) {
    try {
        return P4InfoParser.parse(p4InfoUrl);
    } catch (P4InfoParserException e) {
        throw new IllegalStateException(e);
    }
}
 
Example #8
Source File: FabricPipeconfManager.java    From onos with Apache License 2.0 5 votes vote down vote up
private static PiPipelineModel parseP4Info(URL p4InfoUrl) {
    try {
        return P4InfoParser.parse(p4InfoUrl);
    } catch (P4InfoParserException e) {
        // FIXME: propagate exception that can be handled by whoever is
        //  trying to build pipeconfs.
        throw new IllegalStateException(e);
    }
}
 
Example #9
Source File: P4RuntimeGroupTest.java    From onos with Apache License 2.0 5 votes vote down vote up
private static PiPipeconf buildPipeconf() {
    final URL p4InfoUrl = P4RuntimeGroupTest.class.getResource(P4INFO_PATH);
    return DefaultPiPipeconf.builder()
            .withId(new PiPipeconfId(PIPECONF_ID))
            .withPipelineModel(EasyMock.niceMock(PiPipelineModel.class))
            .addExtension(P4_INFO_TEXT, p4InfoUrl)
            .build();
}
 
Example #10
Source File: AbstractP4RuntimePipelineProgrammable.java    From onos with Apache License 2.0 5 votes vote down vote up
/**
 * Once the pipeconf is set successfully, we should store all the default entries
 * before notify other service to prevent overwriting the default entries.
 * Default entries may be used in P4RuntimeFlowRuleProgrammable.
 * <p>
 * This method returns a completable future with the result of the pipeconf set
 * operation (which might not be true).
 *
 * @param pipeconfSet completable future for setting pipeconf
 * @param pipeconf pipeconf
 * @return completable future eventually true if the pipeconf set successfully
 */
private CompletableFuture<Boolean> getDefaultEntries(CompletableFuture<Boolean> pipeconfSet, PiPipeconf pipeconf) {
    if (!driverBoolProperty(
            SUPPORT_DEFAULT_TABLE_ENTRY,
            DEFAULT_SUPPORT_DEFAULT_TABLE_ENTRY)) {
        return pipeconfSet;
    }
    return pipeconfSet.thenApply(setSuccess -> {
        if (!setSuccess) {
            return setSuccess;
        }
        final P4RuntimeDefaultEntryMirror mirror = handler()
                .get(P4RuntimeDefaultEntryMirror.class);

        final PiPipelineModel pipelineModel = pipeconf.pipelineModel();
        final P4RuntimeReadClient.ReadRequest request = client.read(
                p4DeviceId, pipeconf);
        // Read default entries from all non-constant tables.
        // Ignore constant default entries.
        pipelineModel.tables().stream()
                .filter(t -> !t.isConstantTable())
                .forEach(t -> {
                    if (!t.constDefaultAction().isPresent()) {
                        request.defaultTableEntry(t.id());
                    }
                });
        final P4RuntimeReadClient.ReadResponse response = request.submitSync();
        mirror.sync(deviceId, response.all(PiTableEntry.class));
        return true;
    });
}
 
Example #11
Source File: PipeconfLoader.java    From onos-p4-tutorial with Apache License 2.0 5 votes vote down vote up
private PiPipeconf buildPipeconf() throws P4InfoParserException {

        final URL p4InfoUrl = PipeconfLoader.class.getResource(P4INFO_PATH);
        final URL bmv2JsonUrlUrl = PipeconfLoader.class.getResource(BMV2_JSON_PATH);
        final PiPipelineModel pipelineModel = P4InfoParser.parse(p4InfoUrl);

        return DefaultPiPipeconf.builder()
                .withId(PIPECONF_ID)
                .withPipelineModel(pipelineModel)
                .addBehaviour(PiPipelineInterpreter.class, InterpreterImpl.class)
                .addBehaviour(Pipeliner.class, PipelinerImpl.class)
                .addExtension(P4_INFO_TEXT, p4InfoUrl)
                .addExtension(BMV2_JSON, bmv2JsonUrlUrl)
                .build();
    }
 
Example #12
Source File: PipeconfLoader.java    From ngsdn-tutorial with Apache License 2.0 5 votes vote down vote up
private PiPipeconf buildPipeconf() throws P4InfoParserException {

        final URL p4InfoUrl = PipeconfLoader.class.getResource(P4INFO_PATH);
        final URL bmv2JsonUrlUrl = PipeconfLoader.class.getResource(BMV2_JSON_PATH);
        final PiPipelineModel pipelineModel = P4InfoParser.parse(p4InfoUrl);

        return DefaultPiPipeconf.builder()
                .withId(PIPECONF_ID)
                .withPipelineModel(pipelineModel)
                .addBehaviour(PiPipelineInterpreter.class, InterpreterImpl.class)
                .addBehaviour(Pipeliner.class, PipelinerImpl.class)
                .addExtension(P4_INFO_TEXT, p4InfoUrl)
                .addExtension(BMV2_JSON, bmv2JsonUrlUrl)
                .build();
    }
 
Example #13
Source File: PipeconfViewMessageHandler.java    From onos with Apache License 2.0 4 votes vote down vote up
@Override
public void process(ObjectNode payload) {
    PiPipeconfService piPipeconfService = get(PiPipeconfService.class);
    DeviceService deviceService = get(DeviceService.class);
    ObjectNode responseData = objectNode();
    String devId = string(payload, DEVICE_ID);
    if (devId == null || devId.isEmpty()) {
        log.warn("{}: Invalid device id", PIPECONF_REQUEST);
        sendMessage(NO_PIPECONF_RESP, null);
        return;
    }
    DeviceId deviceId = DeviceId.deviceId(devId);
    Optional<PiPipeconfId> pipeconfId = piPipeconfService.ofDevice(deviceId);
    if (!pipeconfId.isPresent()) {
        log.warn("{}: Can't find pipeconf id for device {}", PIPECONF_REQUEST, deviceId);
        sendMessage(NO_PIPECONF_RESP, null);
        return;
    }

    Optional<PiPipeconf> pipeconf = piPipeconfService.getPipeconf(pipeconfId.get());
    if (!pipeconf.isPresent()) {
        log.warn("{}: Can't find pipeconf {}", PIPECONF_REQUEST, pipeconfId);
        sendMessage(NO_PIPECONF_RESP, null);
        return;
    }
    CodecContext codecContext = getJsonCodecContext();

    ObjectNode pipeconfData = codecContext.encode(pipeconf.get(), PiPipeconf.class);
    responseData.set(PIPECONF, pipeconfData);

    // Filtered out models not exists in interpreter
    // usually they generated by compiler automatically
    Device device = deviceService.getDevice(deviceId);
    if (device == null || !deviceService.isAvailable(deviceId)) {
        log.warn("{}: Device {} is not available", PIPECONF_REQUEST, deviceId);
        sendMessage(NO_PIPECONF_RESP, null);
        return;
    }
    PiPipelineModel pipelineModel = pipeconf.get().pipelineModel();

    ObjectNode pipelineModelData =
            codecContext.encode(pipelineModel, PiPipelineModel.class);
    responseData.set(PIPELINE_MODEL, pipelineModelData);

    sendMessage(PIPECONF_RESP, responseData);
}
 
Example #14
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 4 votes vote down vote up
/**
 * Returns a PI table entry equivalent to the given flow rule, for the given
 * pipeconf and device.
 *
 * @param rule     flow rule
 * @param pipeconf pipeconf
 * @param device   device
 * @return PI table entry
 * @throws PiTranslationException if the flow rule cannot be translated
 */
static PiTableEntry translate(FlowRule rule, PiPipeconf pipeconf, Device device)
        throws PiTranslationException {

    PiPipelineModel pipelineModel = pipeconf.pipelineModel();

    // Retrieve interpreter, if any.
    final PiPipelineInterpreter interpreter = getInterpreterOrNull(device, pipeconf);
    // Get table model.
    final PiTableId piTableId = translateTableId(rule.table(), interpreter);
    final PiTableModel tableModel = getTableModel(piTableId, pipelineModel);
    // Translate selector.
    final PiMatchKey piMatchKey;
    final boolean needPriority;
    if (rule.selector().criteria().isEmpty()) {
        piMatchKey = PiMatchKey.EMPTY;
        needPriority = false;
    } else {
        final Collection<PiFieldMatch> fieldMatches = translateFieldMatches(
                interpreter, rule.selector(), tableModel);
        piMatchKey = PiMatchKey.builder()
                .addFieldMatches(fieldMatches)
                .build();
        // FIXME: P4Runtime limit
        // Need to ignore priority if no TCAM lookup match field
        needPriority = tableModel.matchFields().stream()
                .anyMatch(match -> match.matchType() == PiMatchType.TERNARY ||
                        match.matchType() == PiMatchType.RANGE);
    }
    // Translate treatment.
    final PiTableAction piTableAction = translateTreatment(rule.treatment(), interpreter, piTableId, pipelineModel);

    // Build PI entry.
    final PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();

    tableEntryBuilder
            .forTable(piTableId)
            .withMatchKey(piMatchKey);

    if (piTableAction != null) {
        tableEntryBuilder.withAction(piTableAction);
    }

    if (needPriority) {
        // FIXME: move priority check to P4Runtime driver.
        final int newPriority;
        if (rule.priority() > MAX_PI_PRIORITY) {
            log.warn("Flow rule priority too big, setting translated priority to max value {}: {}",
                     MAX_PI_PRIORITY, rule);
            newPriority = MAX_PI_PRIORITY;
        } else {
            newPriority = MIN_PI_PRIORITY + rule.priority();
        }
        tableEntryBuilder.withPriority(newPriority);
    }

    if (!rule.isPermanent()) {
        if (tableModel.supportsAging()) {
            tableEntryBuilder.withTimeout((double) rule.timeout());
        } else {
            log.debug("Flow rule is temporary, but table '{}' doesn't support " +
                              "aging, translating to permanent.", tableModel.id());
        }

    }

    return tableEntryBuilder.build();
}
 
Example #15
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 4 votes vote down vote up
private static PiTableModel getTableModel(PiTableId piTableId, PiPipelineModel pipelineModel)
        throws PiTranslationException {
    return pipelineModel.table(piTableId)
            .orElseThrow(() -> new PiTranslationException(format(
                    "Not such a table in pipeline model: %s", piTableId)));
}
 
Example #16
Source File: CodecManager.java    From onos with Apache License 2.0 4 votes vote down vote up
@Activate
public void activate() {
    codecs.clear();
    registerCodec(Application.class, new ApplicationCodec());
    registerCodec(ApplicationId.class, new ApplicationIdCodec());
    registerCodec(ControllerNode.class, new ControllerNodeCodec());
    registerCodec(Annotations.class, new AnnotationsCodec());
    registerCodec(Device.class, new DeviceCodec());
    registerCodec(Port.class, new PortCodec());
    registerCodec(ConnectPoint.class, new ConnectPointCodec());
    registerCodec(Link.class, new LinkCodec());
    registerCodec(Host.class, new HostCodec());
    registerCodec(HostLocation.class, new HostLocationCodec());
    registerCodec(HostToHostIntent.class, new HostToHostIntentCodec());
    registerCodec(IntentMiniSummary.class, new IntentMiniSummaryCodec());
    registerCodec(PointToPointIntent.class, new PointToPointIntentCodec());
    registerCodec(SinglePointToMultiPointIntent.class, new SinglePointToMultiPointIntentCodec());
    registerCodec(MultiPointToSinglePointIntent.class, new MultiPointToSinglePointIntentCodec());
    registerCodec(Intent.class, new IntentCodec());
    registerCodec(ConnectivityIntent.class, new ConnectivityIntentCodec());
    registerCodec(FlowEntry.class, new FlowEntryCodec());
    registerCodec(FlowRule.class, new FlowRuleCodec());
    registerCodec(TrafficTreatment.class, new TrafficTreatmentCodec());
    registerCodec(TrafficSelector.class, new TrafficSelectorCodec());
    registerCodec(Instruction.class, new InstructionCodec());
    registerCodec(Criterion.class, new CriterionCodec());
    registerCodec(Ethernet.class, new EthernetCodec());
    registerCodec(Constraint.class, new ConstraintCodec());
    registerCodec(Topology.class, new TopologyCodec());
    registerCodec(TopologyCluster.class, new TopologyClusterCodec());
    registerCodec(Path.class, new PathCodec());
    registerCodec(DisjointPath.class, new DisjointPathCodec());
    registerCodec(Group.class, new GroupCodec());
    registerCodec(Driver.class, new DriverCodec());
    registerCodec(GroupBucket.class, new GroupBucketCodec());
    registerCodec(Load.class, new LoadCodec());
    registerCodec(MeterRequest.class, new MeterRequestCodec());
    registerCodec(Meter.class, new MeterCodec());
    registerCodec(Band.class, new MeterBandCodec());
    registerCodec(TableStatisticsEntry.class, new TableStatisticsEntryCodec());
    registerCodec(PortStatistics.class, new PortStatisticsCodec());
    registerCodec(Metric.class, new MetricCodec());
    registerCodec(FilteringObjective.class, new FilteringObjectiveCodec());
    registerCodec(ForwardingObjective.class, new ForwardingObjectiveCodec());
    registerCodec(NextObjective.class, new NextObjectiveCodec());
    registerCodec(McastRoute.class, new McastRouteCodec());
    registerCodec(DeviceKey.class, new DeviceKeyCodec());
    registerCodec(Region.class, new RegionCodec());
    registerCodec(TenantId.class, new TenantIdCodec());
    registerCodec(MastershipTerm.class, new MastershipTermCodec());
    registerCodec(MastershipRole.class, new MastershipRoleCodec());
    registerCodec(RoleInfo.class, new RoleInfoCodec());
    registerCodec(FilteredConnectPoint.class, new FilteredConnectPointCodec());
    registerCodec(TransportEndpointDescription.class, new TransportEndpointDescriptionCodec());
    registerCodec(PacketRequest.class, new PacketRequestCodec());
    registerCodec(PiActionModel.class, new PiActionModelCodec());
    registerCodec(PiPipelineModel.class, new PiPipelineModelCodec());
    registerCodec(PiPipeconf.class, new PiPipeconfCodec());
    registerCodec(PiTableModel.class, new PiTableModelCodec());
    registerCodec(PiMatchFieldModel.class, new PiMatchFieldModelCodec());
    registerCodec(PiActionParamModel.class, new PiActionParamModelCodec());
    registerCodec(Interface.class, new InterfaceCodec());
    log.info("Started");
}
 
Example #17
Source File: PiFlowRuleTranslatorImpl.java    From onos with Apache License 2.0 3 votes vote down vote up
/**
 * Returns a PI action equivalent to the given treatment, optionally using
 * the given interpreter. This method also checks that the produced PI table
 * action is suitable for the given table ID and pipeline model. If
 * suitable, the returned action instance will have parameters well-sized,
 * according to the table model.
 *
 * @param treatment     traffic treatment
 * @param interpreter   interpreter
 * @param tableId       PI table ID
 * @param pipelineModel pipeline model
 * @return PI table action
 * @throws PiTranslationException if the treatment cannot be translated or
 *                                if the PI action is not suitable for the
 *                                given pipeline model
 */
static PiTableAction translateTreatment(TrafficTreatment treatment, PiPipelineInterpreter interpreter,
                                        PiTableId tableId, PiPipelineModel pipelineModel)
        throws PiTranslationException {
    PiTableModel tableModel = getTableModel(tableId, pipelineModel);
    return typeCheckAction(buildAction(treatment, interpreter, tableId), tableModel);
}