Search in sources :

Example 31 with PiCriterion

use of org.onosproject.net.flow.criteria.PiCriterion in project fabric-tna by stratum.

the class FabricUpfTranslator method buildApplicationCriterion.

public PiCriterion buildApplicationCriterion(UpfApplication appFilter) {
    PiCriterion.Builder matchBuilder = PiCriterion.builder();
    matchBuilder.matchExact(HDR_SLICE_ID, SliceId.of(appFilter.sliceId()).id());
    if (appFilter.ip4Prefix().isPresent()) {
        Ip4Prefix ip4Prefix = appFilter.ip4Prefix().get();
        matchBuilder.matchLpm(HDR_APP_IPV4_ADDR, ip4Prefix.address().toOctets(), ip4Prefix.prefixLength());
    }
    if (appFilter.l4PortRange().isPresent()) {
        Range<Short> l4PortRange = appFilter.l4PortRange().get();
        matchBuilder.matchRange(HDR_APP_L4_PORT, l4PortRange.lowerEndpoint(), l4PortRange.upperEndpoint());
    }
    if (appFilter.ipProto().isPresent()) {
        byte ipProto = appFilter.ipProto().get();
        matchBuilder.matchTernary(HDR_APP_IP_PROTO, ipProto, 0xF);
    }
    return matchBuilder.build();
}
Also used : PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) Ip4Prefix(org.onlab.packet.Ip4Prefix)

Example 32 with PiCriterion

use of org.onosproject.net.flow.criteria.PiCriterion in project fabric-tna by stratum.

the class FabricUpfTranslator method upfApplicationToFabricEntry.

public FlowRule upfApplicationToFabricEntry(UpfApplication appFilter, DeviceId deviceId, ApplicationId appId) throws UpfProgrammableException {
    PiCriterion match = buildApplicationCriterion(appFilter);
    PiAction action = PiAction.builder().withId(FABRIC_INGRESS_UPF_SET_APP_ID).withParameter(new PiActionParam(APP_ID, appFilter.appId())).build();
    return DefaultFlowRule.builder().forDevice(deviceId).fromApp(appId).makePermanent().forTable(FABRIC_INGRESS_UPF_APPLICATIONS).withSelector(DefaultTrafficSelector.builder().matchPi(match).build()).withTreatment(DefaultTrafficTreatment.builder().piTableAction(action).build()).withPriority(appFilter.priority()).build();
}
Also used : PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam) PiAction(org.onosproject.net.pi.runtime.PiAction)

Example 33 with PiCriterion

use of org.onosproject.net.flow.criteria.PiCriterion in project fabric-tna by stratum.

the class StatisticManager method buildFlowRules.

// Prepare flow rules for both ingress and egress
protected List<FlowRule> buildFlowRules(StatisticKey key) {
    // All possible ports in current topology
    List<Port> ports = StreamSupport.stream(deviceService.getAvailableDevices().spliterator(), true).map(Device::id).map(deviceService::getPorts).flatMap(List<Port>::stream).collect(Collectors.toList());
    // Prepare ingress and egress flow rule per port
    List<FlowRule> flowRules = Lists.newArrayList();
    ports.stream().forEach(port -> {
        DeviceId deviceId = (DeviceId) port.element().id();
        PortNumber portNumber = port.number();
        log.debug("Processing flow rule for {}/{}", deviceId, portNumber);
        // Prepare PiCriterion
        PiCriterion ingressPiCriterion = PiCriterion.builder().matchExact(P4InfoConstants.HDR_IG_PORT, portNumber.toLong()).build();
        PiCriterion egressPiCriterion = PiCriterion.builder().matchExact(P4InfoConstants.HDR_STATS_FLOW_ID, key.id()).matchExact(P4InfoConstants.HDR_EG_PORT, portNumber.toLong()).build();
        // Prepare PiTableAction
        PiTableAction ingressPiTableAction = PiAction.builder().withId(P4InfoConstants.FABRIC_INGRESS_STATS_COUNT).withParameter(new PiActionParam(P4InfoConstants.FLOW_ID, key.id())).build();
        PiTableAction egressPiTableAction = PiAction.builder().withId(P4InfoConstants.FABRIC_EGRESS_STATS_COUNT).build();
        // Prepare FlowRule
        FlowRule ingressFlowRule = DefaultFlowRule.builder().forDevice(deviceId).forTable(PiTableId.of(FABRIC_INGRESS_STATS_FLOWS.id())).fromApp(appId).withPriority(key.id()).withSelector(DefaultTrafficSelector.builder(key.selector()).matchPi(ingressPiCriterion).build()).withTreatment(DefaultTrafficTreatment.builder().piTableAction(ingressPiTableAction).build()).makePermanent().build();
        FlowRule egressFlowRule = DefaultFlowRule.builder().forDevice(deviceId).forTable(PiTableId.of(FABRIC_EGRESS_STATS_FLOWS.id())).fromApp(appId).withPriority(key.id()).withSelector(DefaultTrafficSelector.builder().matchPi(egressPiCriterion).build()).withTreatment(DefaultTrafficTreatment.builder().piTableAction(egressPiTableAction).build()).makePermanent().build();
        flowRules.add(ingressFlowRule);
        flowRules.add(egressFlowRule);
    });
    log.debug("Total {} flow rules", flowRules.size());
    return flowRules;
}
Also used : PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) PiTableAction(org.onosproject.net.pi.runtime.PiTableAction) DeviceId(org.onosproject.net.DeviceId) Port(org.onosproject.net.Port) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) PortNumber(org.onosproject.net.PortNumber) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam)

Example 34 with PiCriterion

use of org.onosproject.net.flow.criteria.PiCriterion in project fabric-tna by stratum.

the class FilteringObjectiveTranslator method ingressPortVlanRule.

private void ingressPortVlanRule(FilteringObjective obj, PortCriterion inPortCriterion, VlanIdCriterion outerVlanCriterion, VlanIdCriterion innerVlanCriterion, ObjectiveTranslation.Builder resultBuilder) throws FabricPipelinerException {
    final boolean outerVlanValid = outerVlanCriterion != null && !outerVlanCriterion.vlanId().equals(VlanId.NONE);
    final boolean innerVlanValid = innerVlanCriterion != null && !innerVlanCriterion.vlanId().equals(VlanId.NONE);
    if (innerVlanValid && !capabilities.supportDoubleVlanTerm()) {
        throw new FabricPipelinerException("Found 2 VLAN IDs, but the pipeline does not support double VLAN termination", ObjectiveError.UNSUPPORTED);
    }
    final PiCriterion piCriterion = PiCriterion.builder().matchExact(P4InfoConstants.HDR_VLAN_IS_VALID, outerVlanValid ? ONE : ZERO).build();
    final TrafficSelector.Builder selector = DefaultTrafficSelector.builder().add(inPortCriterion).add(piCriterion);
    if (outerVlanValid) {
        selector.add(outerVlanCriterion);
    }
    if (innerVlanValid) {
        selector.add(innerVlanCriterion);
    }
    final TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
    if (obj.type().equals(FilteringObjective.Type.DENY)) {
        treatmentBuilder.piTableAction(DENY);
    } else {
        // FIXME SDFAB-52 to complete the work on metadata
        Byte portType = portType(obj);
        if (portType == null) {
            throw new FabricPipelinerException(format("Unsupported port_type configuration: metadata=%s", obj.meta()), ObjectiveError.BADPARAMS);
        }
        try {
            treatmentBuilder.piTableAction(mapFilteringTreatment(obj.meta(), P4InfoConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN, portType));
        } catch (PiInterpreterException ex) {
            throw new FabricPipelinerException(format("Unable to map treatment for table '%s': %s", P4InfoConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN, ex.getMessage()), ObjectiveError.UNSUPPORTED);
        }
        // the EgressDscpRewriter table.
        if (portType == PORT_TYPE_EDGE) {
            // We need to make sure that traffic exiting an edge port doesn't
            // carry the SD-Fabric DSCP field.
            resultBuilder.addFlowRule(buildEgressDscpRewriter(obj, inPortCriterion, true));
        } else if (portType == PORT_TYPE_INFRA) {
            // We need to make sure that traffic exiting an infra port carry
            // SD-Fabric DSCP field.
            resultBuilder.addFlowRule(buildEgressDscpRewriter(obj, inPortCriterion, false));
            resultBuilder.addFlowRule(buildTrustDscpEntry(obj, inPortCriterion));
        }
    }
    resultBuilder.addFlowRule(flowRule(obj, P4InfoConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN, selector.build(), treatmentBuilder.build()));
}
Also used : PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) PiInterpreterException(org.onosproject.net.pi.model.PiPipelineInterpreter.PiInterpreterException) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment)

Example 35 with PiCriterion

use of org.onosproject.net.flow.criteria.PiCriterion in project onos by opennetworkinglab.

the class PiFlowRuleTranslatorImpl method translateFieldMatches.

/**
 * Builds a collection of PI field matches out of the given selector,
 * optionally using the given interpreter. The field matches returned are
 * guaranteed to be compatible for the given table model.
 */
private static Collection<PiFieldMatch> translateFieldMatches(PiPipelineInterpreter interpreter, TrafficSelector selector, PiTableModel tableModel) throws PiTranslationException {
    Map<PiMatchFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
    // If present, find a PiCriterion and get its field matches as a map. Otherwise, use an empty map.
    Map<PiMatchFieldId, PiFieldMatch> piCriterionFields = selector.criteria().stream().filter(c -> c.type().equals(PROTOCOL_INDEPENDENT)).map(c -> (PiCriterion) c).findFirst().map(PiCriterion::fieldMatches).map(c -> {
        Map<PiMatchFieldId, PiFieldMatch> fieldMap = Maps.newHashMap();
        c.forEach(fieldMatch -> fieldMap.put(fieldMatch.fieldId(), fieldMatch));
        return fieldMap;
    }).orElse(Maps.newHashMap());
    Set<Criterion> translatedCriteria = Sets.newHashSet();
    Set<Criterion> ignoredCriteria = Sets.newHashSet();
    Set<PiMatchFieldId> usedPiCriterionFields = Sets.newHashSet();
    Set<PiMatchFieldId> ignoredPiCriterionFields = Sets.newHashSet();
    Map<PiMatchFieldId, Criterion> criterionMap = Maps.newHashMap();
    if (interpreter != null) {
        // NOTE: if two criterion types map to the same match field ID, and
        // those two criterion types are present in the selector, this won't
        // work. This is unlikely to happen since those cases should be
        // mutually exclusive:
        // e.g. ICMPV6_TYPE ->  metadata.my_normalized_icmp_type
        // ICMPV4_TYPE ->  metadata.my_normalized_icmp_type
        // A packet can be either ICMPv6 or ICMPv4 but not both.
        selector.criteria().stream().map(Criterion::type).filter(t -> t != PROTOCOL_INDEPENDENT).forEach(t -> {
            PiMatchFieldId mfid = interpreter.mapCriterionType(t).orElse(null);
            if (mfid != null) {
                if (criterionMap.containsKey(mfid)) {
                    log.warn("Detected criterion mapping " + "conflict for PiMatchFieldId {}", mfid);
                }
                criterionMap.put(mfid, selector.getCriterion(t));
            }
        });
    }
    for (PiMatchFieldModel fieldModel : tableModel.matchFields()) {
        PiMatchFieldId fieldId = fieldModel.id();
        int bitWidth = fieldModel.bitWidth();
        Criterion criterion = criterionMap.get(fieldId);
        if (!piCriterionFields.containsKey(fieldId) && criterion == null) {
            // Can ignore if match is ternary-like, as it means "don't care".
            switch(fieldModel.matchType()) {
                case TERNARY:
                case LPM:
                case RANGE:
                case OPTIONAL:
                    // Skip field.
                    break;
                default:
                    throw new PiTranslationException(format("No value found for required match field '%s'", fieldId));
            }
            // Next field.
            continue;
        }
        PiFieldMatch fieldMatch = null;
        // TODO: we currently do not support fields with arbitrary bit width
        if (criterion != null && fieldModel.hasBitWidth()) {
            // Criterion mapping is possible for this field id.
            try {
                fieldMatch = translateCriterion(criterion, fieldId, fieldModel.matchType(), bitWidth);
                translatedCriteria.add(criterion);
            } catch (PiTranslationException ex) {
                // Ignore exception if the same field was found in PiCriterion.
                if (piCriterionFields.containsKey(fieldId)) {
                    ignoredCriteria.add(criterion);
                } else {
                    throw ex;
                }
            }
        }
        if (piCriterionFields.containsKey(fieldId)) {
            // Field was found in PiCriterion.
            if (fieldMatch != null) {
                // Throw exception only if we are trying to match on different values of the same field...
                if (!fieldMatch.equals(piCriterionFields.get(fieldId))) {
                    throw new PiTranslationException(format("Duplicate match field '%s': instance translated from criterion '%s' is different to " + "what found in PiCriterion.", fieldId, criterion.type()));
                }
                ignoredPiCriterionFields.add(fieldId);
            } else {
                fieldMatch = piCriterionFields.get(fieldId);
                fieldMatch = typeCheckFieldMatch(fieldMatch, fieldModel);
                usedPiCriterionFields.add(fieldId);
            }
        }
        fieldMatches.put(fieldId, fieldMatch);
    }
    // Check if all criteria have been translated.
    StringJoiner skippedCriteriaJoiner = new StringJoiner(", ");
    selector.criteria().stream().filter(c -> !c.type().equals(PROTOCOL_INDEPENDENT)).filter(c -> !translatedCriteria.contains(c) && !ignoredCriteria.contains(c)).forEach(c -> skippedCriteriaJoiner.add(c.type().name()));
    if (skippedCriteriaJoiner.length() > 0) {
        throw new PiTranslationException(format("The following criteria cannot be translated for table '%s': %s", tableModel.id(), skippedCriteriaJoiner.toString()));
    }
    // Check if all fields found in PiCriterion have been used.
    StringJoiner skippedPiFieldsJoiner = new StringJoiner(", ");
    piCriterionFields.keySet().stream().filter(k -> !usedPiCriterionFields.contains(k) && !ignoredPiCriterionFields.contains(k)).forEach(k -> skippedPiFieldsJoiner.add(k.id()));
    if (skippedPiFieldsJoiner.length() > 0) {
        throw new PiTranslationException(format("The following PiCriterion field matches are not supported in table '%s': %s", tableModel.id(), skippedPiFieldsJoiner.toString()));
    }
    return fieldMatches.values();
}
Also used : PiTableId(org.onosproject.net.pi.model.PiTableId) PiOptionalFieldMatch(org.onosproject.net.pi.runtime.PiOptionalFieldMatch) PiUtils.getInterpreterOrNull(org.onosproject.net.pi.impl.PiUtils.getInterpreterOrNull) PiPipeconf(org.onosproject.net.pi.model.PiPipeconf) ImmutableByteSequence(org.onlab.util.ImmutableByteSequence) LoggerFactory(org.slf4j.LoggerFactory) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam) PiActionParamModel(org.onosproject.net.pi.model.PiActionParamModel) PiPipelineModel(org.onosproject.net.pi.model.PiPipelineModel) PiMatchKey(org.onosproject.net.pi.runtime.PiMatchKey) PiUtils.translateTableId(org.onosproject.net.pi.impl.PiUtils.translateTableId) ImmutableByteSequence.prefixOnes(org.onlab.util.ImmutableByteSequence.prefixOnes) TrafficSelector(org.onosproject.net.flow.TrafficSelector) PiInstruction(org.onosproject.net.flow.instructions.PiInstruction) PiTableModel(org.onosproject.net.pi.model.PiTableModel) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) Map(java.util.Map) PiTranslationException(org.onosproject.net.pi.service.PiTranslationException) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) PiFieldMatch(org.onosproject.net.pi.runtime.PiFieldMatch) Criterion(org.onosproject.net.flow.criteria.Criterion) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) PiTableAction(org.onosproject.net.pi.runtime.PiTableAction) PiPipelineInterpreter(org.onosproject.net.pi.model.PiPipelineInterpreter) Logger(org.slf4j.Logger) Device(org.onosproject.net.Device) PiActionModel(org.onosproject.net.pi.model.PiActionModel) Instruction(org.onosproject.net.flow.instructions.Instruction) PiMatchFieldModel(org.onosproject.net.pi.model.PiMatchFieldModel) Collection(java.util.Collection) PiRangeFieldMatch(org.onosproject.net.pi.runtime.PiRangeFieldMatch) Set(java.util.Set) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) PiMatchType(org.onosproject.net.pi.model.PiMatchType) String.format(java.lang.String.format) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) ByteSequenceTrimException(org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException) PROTOCOL_INDEPENDENT(org.onosproject.net.flow.criteria.Criterion.Type.PROTOCOL_INDEPENDENT) PiAction(org.onosproject.net.pi.runtime.PiAction) PiTableEntry(org.onosproject.net.pi.runtime.PiTableEntry) CriterionTranslatorHelper.translateCriterion(org.onosproject.net.pi.impl.CriterionTranslatorHelper.translateCriterion) FlowRule(org.onosproject.net.flow.FlowRule) StringJoiner(java.util.StringJoiner) PiTableType(org.onosproject.net.pi.model.PiTableType) PiLpmFieldMatch(org.onosproject.net.pi.runtime.PiLpmFieldMatch) PiActionSet(org.onosproject.net.pi.runtime.PiActionSet) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) PiTranslationException(org.onosproject.net.pi.service.PiTranslationException) PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) Criterion(org.onosproject.net.flow.criteria.Criterion) CriterionTranslatorHelper.translateCriterion(org.onosproject.net.pi.impl.CriterionTranslatorHelper.translateCriterion) PiMatchFieldId(org.onosproject.net.pi.model.PiMatchFieldId) PiFieldMatch(org.onosproject.net.pi.runtime.PiFieldMatch) PiMatchFieldModel(org.onosproject.net.pi.model.PiMatchFieldModel) Map(java.util.Map) StringJoiner(java.util.StringJoiner)

Aggregations

PiCriterion (org.onosproject.net.flow.criteria.PiCriterion)69 PiAction (org.onosproject.net.pi.runtime.PiAction)45 PiActionParam (org.onosproject.net.pi.runtime.PiActionParam)31 TrafficSelector (org.onosproject.net.flow.TrafficSelector)29 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)28 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)27 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)26 FlowRule (org.onosproject.net.flow.FlowRule)25 DefaultFlowRule (org.onosproject.net.flow.DefaultFlowRule)16 PiTableAction (org.onosproject.net.pi.runtime.PiTableAction)13 Test (org.junit.Test)8 UpfProgrammableException (org.onosproject.net.behaviour.upf.UpfProgrammableException)8 DefaultNextObjective (org.onosproject.net.flowobjective.DefaultNextObjective)8 NextObjective (org.onosproject.net.flowobjective.NextObjective)8 PiActionId (org.onosproject.net.pi.model.PiActionId)7 DefaultGroupBucket (org.onosproject.net.group.DefaultGroupBucket)6 DefaultGroupDescription (org.onosproject.net.group.DefaultGroupDescription)6 GroupBucket (org.onosproject.net.group.GroupBucket)6 GroupBuckets (org.onosproject.net.group.GroupBuckets)6 GroupDescription (org.onosproject.net.group.GroupDescription)6