Search in sources :

Example 26 with FlowRule

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

the class Ofdpa3Pipeline method processInitPwVersatile.

/**
 * Helper method to process the pw forwarding objectives.
 *
 * @param forwardingObjective the fw objective to process
 * @return a singleton list of flow rule
 */
private Collection<FlowRule> processInitPwVersatile(ForwardingObjective forwardingObjective) {
    // We retrieve the matching criteria for mpls l2 port.
    TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) forwardingObjective.selector().getCriterion(TUNNEL_ID);
    PortCriterion portCriterion = (PortCriterion) forwardingObjective.selector().getCriterion(IN_PORT);
    TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
    int mplsLogicalPort;
    long tunnelId;
    // Mpls tunnel ids according to the OFDPA manual have to be
    // in the range [2^17-1, 2^16].
    tunnelId = MPLS_TUNNEL_ID_BASE | tunnelIdCriterion.tunnelId();
    if (tunnelId > MPLS_TUNNEL_ID_MAX) {
        log.error("Pw Versatile Forwarding Objective must include tunnel id < {}", MPLS_TUNNEL_ID_MAX);
        fail(forwardingObjective, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    // Port has not been null.
    if (portCriterion == null) {
        log.error("Pw Versatile Forwarding Objective must include port");
        fail(forwardingObjective, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    // 0x0000XXXX is UNI interface.
    if (portCriterion.port().toLong() > MPLS_UNI_PORT_MAX) {
        log.error("Pw Versatile Forwarding Objective invalid logical port {}", portCriterion.port().toLong());
        fail(forwardingObjective, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    mplsLogicalPort = ((int) portCriterion.port().toLong());
    if (forwardingObjective.nextId() == null) {
        log.error("Pw Versatile Forwarding Objective must contain nextId ", forwardingObjective.nextId());
        fail(forwardingObjective, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    // We don't expect a treatment.
    if (forwardingObjective.treatment() != null && !forwardingObjective.treatment().equals(DefaultTrafficTreatment.emptyTreatment())) {
        log.error("Pw Versatile Forwarding Objective cannot contain a treatment ", forwardingObjective.nextId());
        fail(forwardingObjective, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    // We retrieve the l2 vpn group and point the mpls
    // l2 port to this.
    NextGroup next = getGroupForNextObjective(forwardingObjective.nextId());
    if (next == null) {
        log.warn("next-id:{} not found in dev:{}", forwardingObjective.nextId(), deviceId);
        fail(forwardingObjective, ObjectiveError.GROUPMISSING);
        return Collections.emptySet();
    }
    List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
    Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
    if (group == null) {
        log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), forwardingObjective.nextId(), deviceId);
        fail(forwardingObjective, ObjectiveError.GROUPMISSING);
        return Collections.emptySet();
    }
    // We prepare the flow rule for the mpls l2 port table.
    selector.matchTunnelId(tunnelId);
    selector.extension(new Ofdpa3MatchMplsL2Port(mplsLogicalPort), deviceId);
    // This should not be necessary but without we receive an error
    treatment.extension(new Ofdpa3SetQosIndex(0), deviceId);
    treatment.transition(MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE);
    treatment.deferred().group(group.id());
    FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(forwardingObjective.appId()).withPriority(MPLS_L2_PORT_PRIORITY).forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).makePermanent().forTable(MPLS_L2_PORT_FLOW_TABLE);
    return Collections.singletonList(ruleBuilder.build());
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) TunnelIdCriterion(org.onosproject.net.flow.criteria.TunnelIdCriterion) Ofdpa3MatchMplsL2Port(org.onosproject.driver.extensions.Ofdpa3MatchMplsL2Port) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) Deque(java.util.Deque) Ofdpa3SetQosIndex(org.onosproject.driver.extensions.Ofdpa3SetQosIndex) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule)

Example 27 with FlowRule

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

the class Ofdpa3Pipeline method processFilter.

@Override
protected void processFilter(FilteringObjective filteringObjective, boolean install, ApplicationId applicationId) {
    // Check if filter is intended for pseudowire
    boolean isPw = isPseudowire(filteringObjective);
    if (isPw) {
        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
        PortCriterion portCriterion;
        VlanIdCriterion innerVlanIdCriterion = null;
        for (Criterion criterion : filteringObjective.conditions()) {
            if (criterion.type() == INNER_VLAN_VID) {
                innerVlanIdCriterion = (VlanIdCriterion) criterion;
                break;
            }
        }
        VlanIdCriterion outerVlanIdCriterion = null;
        // We extract the expected port criterion in the key.
        portCriterion = (PortCriterion) filteringObjective.key();
        // We extract the outer vlan id criterion.
        for (Criterion criterion : filteringObjective.conditions()) {
            if (criterion.type() == VLAN_VID) {
                outerVlanIdCriterion = (VlanIdCriterion) criterion;
                break;
            }
        }
        // We extract the tunnel id.
        long tunnelId;
        VlanId egressVlan;
        if (filteringObjective.meta() != null && filteringObjective.meta().allInstructions().size() != 2) {
            log.warn("Bad filtering objective from app: {}. Not" + "processing filtering objective", applicationId);
            fail(filteringObjective, ObjectiveError.BADPARAMS);
            return;
        } else if (filteringObjective.meta() != null && filteringObjective.meta().allInstructions().size() == 2 && filteringObjective.meta().allInstructions().get(0).type() == L2MODIFICATION && filteringObjective.meta().allInstructions().get(1).type() == L2MODIFICATION) {
            L2ModificationInstruction l2instruction = (L2ModificationInstruction) filteringObjective.meta().allInstructions().get(0);
            if (l2instruction.subtype() != L2SubType.TUNNEL_ID) {
                log.warn("Bad filtering objective from app: {}. Not" + "processing filtering objective", applicationId);
                fail(filteringObjective, ObjectiveError.BADPARAMS);
                return;
            } else {
                tunnelId = ((ModTunnelIdInstruction) l2instruction).tunnelId();
            }
            L2ModificationInstruction vlanInstruction = (L2ModificationInstruction) filteringObjective.meta().allInstructions().get(1);
            if (vlanInstruction.subtype() != L2SubType.VLAN_ID) {
                log.warn("Bad filtering objective from app: {}. Not" + "processing filtering objective", applicationId);
                fail(filteringObjective, ObjectiveError.BADPARAMS);
                return;
            } else {
                egressVlan = ((L2ModificationInstruction.ModVlanIdInstruction) vlanInstruction).vlanId();
            }
        } else {
            log.warn("Bad filtering objective from app: {}. Not" + "processing filtering objective", applicationId);
            fail(filteringObjective, ObjectiveError.BADPARAMS);
            return;
        }
        // Mpls tunnel ids according to the OFDPA manual have to be
        // in the range [2^17-1, 2^16].
        tunnelId = MPLS_TUNNEL_ID_BASE | tunnelId;
        // Sanity check for the filtering objective.
        if (portCriterion == null || outerVlanIdCriterion == null || tunnelId > MPLS_TUNNEL_ID_MAX) {
            log.warn("Bad filtering objective from app: {}. Not" + "processing filtering objective", applicationId);
            fail(filteringObjective, ObjectiveError.BADPARAMS);
            return;
        }
        // 0x0000XXXX is UNI interface.
        if (portCriterion.port().toLong() > MPLS_UNI_PORT_MAX) {
            log.error("Filtering Objective invalid logical port {}", portCriterion.port().toLong());
            fail(filteringObjective, ObjectiveError.BADPARAMS);
            return;
        }
        // We create the flows.
        List<FlowRule> pwRules = processPwFilter(portCriterion, innerVlanIdCriterion, outerVlanIdCriterion, tunnelId, applicationId, egressVlan);
        // We tag the flow for adding or for removing.
        for (FlowRule pwRule : pwRules) {
            log.debug("adding filtering rule in VLAN tables: {} for dev: {}", pwRule, deviceId);
            ops = install ? ops.add(pwRule) : ops.remove(pwRule);
        }
        // We push the filtering rules for the pw.
        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {

            @Override
            public void onSuccess(FlowRuleOperations ops) {
                log.info("Applied {} filtering rules in device {}", ops.stages().get(0).size(), deviceId);
                pass(filteringObjective);
            }

            @Override
            public void onError(FlowRuleOperations ops) {
                log.info("Failed to apply all filtering rules in dev {}", deviceId);
                fail(filteringObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
            }
        }));
    } else if (isDoubleTagged(filteringObjective)) {
        processDoubleTaggedFilter(filteringObjective, install, applicationId);
    } else {
        // If it is not a pseudo wire flow or double-tagged filter, we fall back
        // to the OFDPA 2.0 pipeline.
        super.processFilter(filteringObjective, install, applicationId);
    }
}
Also used : ModTunnelIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction) FlowRuleOperations(org.onosproject.net.flow.FlowRuleOperations) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) TunnelIdCriterion(org.onosproject.net.flow.criteria.TunnelIdCriterion) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) Criterion(org.onosproject.net.flow.criteria.Criterion) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) VlanId(org.onlab.packet.VlanId) FlowRuleOperationsContext(org.onosproject.net.flow.FlowRuleOperationsContext) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion)

Example 28 with FlowRule

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

the class OvsOfdpaPipeline method processDoubleTaggedFilter.

/**
 * Configure filtering rules of outer and inner VLAN IDs, and a MAC address.
 * Filtering happens in three tables (VLAN_TABLE, VLAN_1_TABLE, TMAC_TABLE).
 *
 * @param filteringObjective the filtering objective
 * @param install            true to add, false to remove
 * @param applicationId      for application programming this filter
 */
private void processDoubleTaggedFilter(FilteringObjective filteringObjective, boolean install, ApplicationId applicationId) {
    PortCriterion portCriterion = null;
    EthCriterion ethCriterion = null;
    VlanIdCriterion innervidCriterion = null;
    VlanIdCriterion outerVidCriterion = null;
    boolean popVlan = false;
    TrafficTreatment meta = filteringObjective.meta();
    if (!filteringObjective.key().equals(Criteria.dummy()) && filteringObjective.key().type() == Criterion.Type.IN_PORT) {
        portCriterion = (PortCriterion) filteringObjective.key();
    }
    if (portCriterion == null) {
        log.warn("No IN_PORT defined in filtering objective from app: {}" + "Failed to program VLAN tables.", applicationId);
        return;
    } else {
        log.debug("Received filtering objective for dev/port: {}/{}", deviceId, portCriterion.port());
    }
    // meta should have only one instruction, popVlan.
    if (meta != null && meta.allInstructions().size() == 1) {
        L2ModificationInstruction l2Inst = (L2ModificationInstruction) meta.allInstructions().get(0);
        if (l2Inst.subtype().equals(L2ModificationInstruction.L2SubType.VLAN_POP)) {
            popVlan = true;
        } else {
            log.warn("Filtering objective can have only VLAN_POP instruction.");
            return;
        }
    } else {
        log.warn("Filtering objective should have one instruction.");
        return;
    }
    FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
    for (Criterion criterion : filteringObjective.conditions()) {
        switch(criterion.type()) {
            case ETH_DST:
            case ETH_DST_MASKED:
                ethCriterion = (EthCriterion) criterion;
                break;
            case VLAN_VID:
                outerVidCriterion = (VlanIdCriterion) criterion;
                break;
            case INNER_VLAN_VID:
                innervidCriterion = (VlanIdCriterion) criterion;
                break;
            default:
                log.warn("Unsupported filter {}", criterion);
                fail(filteringObjective, ObjectiveError.UNSUPPORTED);
                return;
        }
    }
    if (innervidCriterion == null || outerVidCriterion == null) {
        log.warn("filtering objective should have two vidCriterion.");
        return;
    }
    if (ethCriterion == null || ethCriterion.mac().equals(NONE)) {
        // NOTE: it is possible that a filtering objective only has vidCriterion
        log.warn("filtering objective missing dstMac, cannot program TMAC table");
        return;
    } else {
        MacAddress unicastMac = readEthDstFromTreatment(filteringObjective.meta());
        List<List<FlowRule>> allStages = processEthDstFilter(portCriterion, ethCriterion, innervidCriterion, innervidCriterion.vlanId(), unicastMac, applicationId);
        for (List<FlowRule> flowRules : allStages) {
            log.trace("Starting a new flow rule stage for TMAC table flow");
            ops.newStage();
            for (FlowRule flowRule : flowRules) {
                log.trace("{} flow rules in TMAC table: {} for dev: {}", (install) ? "adding" : "removing", flowRules, deviceId);
                if (install) {
                    ops = ops.add(flowRule);
                } else {
                    // same VLAN on this device if TMAC doesn't support matching on in_port.
                    if (matchInPortTmacTable() || (filteringObjective.meta() != null && filteringObjective.meta().clearedDeferred())) {
                        ops = ops.remove(flowRule);
                    } else {
                        log.debug("Abort TMAC flow removal on {}. Some other ports still share this TMAC flow");
                    }
                }
            }
        }
    }
    List<FlowRule> rules;
    rules = processDoubleVlanIdFilter(portCriterion, innervidCriterion, outerVidCriterion, popVlan, applicationId);
    for (FlowRule flowRule : rules) {
        log.trace("{} flow rule in VLAN table: {} for dev: {}", (install) ? "adding" : "removing", flowRule, deviceId);
        ops = install ? ops.add(flowRule) : ops.remove(flowRule);
    }
    // apply filtering flow rules
    flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {

        @Override
        public void onSuccess(FlowRuleOperations ops) {
            log.debug("Applied {} filtering rules in device {}", ops.stages().get(0).size(), deviceId);
            pass(filteringObjective);
        }

        @Override
        public void onError(FlowRuleOperations ops) {
            log.info("Failed to apply all filtering rules in dev {}", deviceId);
            fail(filteringObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
        }
    }));
}
Also used : FlowRuleOperations(org.onosproject.net.flow.FlowRuleOperations) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) MacAddress(org.onlab.packet.MacAddress) MplsBosCriterion(org.onosproject.net.flow.criteria.MplsBosCriterion) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) MplsCriterion(org.onosproject.net.flow.criteria.MplsCriterion) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) Criterion(org.onosproject.net.flow.criteria.Criterion) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) FlowRuleOperationsContext(org.onosproject.net.flow.FlowRuleOperationsContext) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion)

Example 29 with FlowRule

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

the class OvsOfdpaPipeline method processEthDstSpecific.

@Override
protected Collection<FlowRule> processEthDstSpecific(ForwardingObjective fwd) {
    List<FlowRule> rules = new ArrayList<>();
    // Build filtered selector
    TrafficSelector selector = fwd.selector();
    EthCriterion ethCriterion = (EthCriterion) selector.getCriterion(Criterion.Type.ETH_DST);
    VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) selector.getCriterion(VLAN_VID);
    if (vlanIdCriterion == null) {
        log.warn("Forwarding objective for bridging requires vlan. Not " + "installing fwd:{} in dev:{}", fwd.id(), deviceId);
        fail(fwd, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    TrafficSelector.Builder filteredSelectorBuilder = DefaultTrafficSelector.builder();
    // Do not match MacAddress for subnet broadcast entry
    if (!ethCriterion.mac().equals(NONE) && !ethCriterion.mac().equals(BROADCAST)) {
        filteredSelectorBuilder.matchEthDst(ethCriterion.mac());
        log.debug("processing L2 forwarding objective:{} -> next:{} in dev:{}", fwd.id(), fwd.nextId(), deviceId);
    } else {
        log.debug("processing L2 Broadcast forwarding objective:{} -> next:{} " + "in dev:{} for vlan:{}", fwd.id(), fwd.nextId(), deviceId, vlanIdCriterion.vlanId());
    }
    filteredSelectorBuilder.matchVlanId(vlanIdCriterion.vlanId());
    TrafficSelector filteredSelector = filteredSelectorBuilder.build();
    if (fwd.treatment() != null) {
        log.warn("Ignoring traffic treatment in fwd rule {} meant for L2 table" + "for dev:{}. Expecting only nextId", fwd.id(), deviceId);
    }
    TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
    if (fwd.nextId() != null) {
        NextGroup next = getGroupForNextObjective(fwd.nextId());
        if (next != null) {
            List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
            // we only need the top level group's key to point the flow to it
            Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
            if (group != null) {
                treatmentBuilder.deferred().group(group.id());
            } else {
                log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
                fail(fwd, ObjectiveError.GROUPMISSING);
                return Collections.emptySet();
            }
        }
    }
    treatmentBuilder.immediate().transition(ACL_TABLE);
    TrafficTreatment filteredTreatment = treatmentBuilder.build();
    // Build bridging table entries
    FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
    flowRuleBuilder.fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(filteredSelector).withTreatment(filteredTreatment).forTable(BRIDGING_TABLE);
    if (fwd.permanent()) {
        flowRuleBuilder.makePermanent();
    } else {
        flowRuleBuilder.makeTemporary(fwd.timeout());
    }
    rules.add(flowRuleBuilder.build());
    return rules;
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) ArrayList(java.util.ArrayList) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) Deque(java.util.Deque) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion)

Example 30 with FlowRule

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

the class OvsOfdpaPipeline method processEthTypeSpecific.

/*
     * Open vSwitch emulation allows MPLS ECMP.
     *
     * (non-Javadoc)
     * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthTypeSpecific
     */
@Override
protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
    if (isDoubleTagged(fwd)) {
        return processDoubleTaggedFwd(fwd);
    }
    TrafficSelector selector = fwd.selector();
    EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
    if ((ethType == null) || (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST) && (ethType.ethType().toShort() != Ethernet.TYPE_IPV6)) {
        log.warn("processSpecific: Unsupported forwarding objective criteria" + "ethType:{} in dev:{}", ethType, deviceId);
        fail(fwd, ObjectiveError.UNSUPPORTED);
        return Collections.emptySet();
    }
    boolean defaultRule = false;
    int forTableId;
    TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
    TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
    if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
        IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
        if (ipv4Dst.isMulticast()) {
            if (ipv4Dst.prefixLength() != 32) {
                log.warn("Multicast specific forwarding objective can only be /32");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            VlanId assignedVlan = readVlanFromSelector(fwd.meta());
            if (assignedVlan == null) {
                log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            filteredSelector.matchVlanId(assignedVlan);
            filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
            forTableId = MULTICAST_ROUTING_TABLE;
            log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
        } else {
            if (ipv4Dst.prefixLength() == 0) {
                // The entire IPV4_DST field is wildcarded intentionally
                filteredSelector.matchEthType(Ethernet.TYPE_IPV4);
            } else {
                filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
            }
            forTableId = UNICAST_ROUTING_TABLE;
            log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
        }
    } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
        IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
        if (ipv6Dst.isMulticast()) {
            if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
                log.debug("Multicast specific IPv6 forwarding objective can only be /128");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            VlanId assignedVlan = readVlanFromSelector(fwd.meta());
            if (assignedVlan == null) {
                log.debug("VLAN ID required by multicast specific fwd obj is missing. Abort.");
                fail(fwd, ObjectiveError.BADPARAMS);
                return ImmutableSet.of();
            }
            filteredSelector.matchVlanId(assignedVlan);
            filteredSelector.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
            forTableId = MULTICAST_ROUTING_TABLE;
            log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
        } else {
            if (buildIpv6Selector(filteredSelector, fwd) < 0) {
                return Collections.emptyList();
            }
            forTableId = UNICAST_ROUTING_TABLE;
        }
    } else {
        filteredSelector.matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(((MplsCriterion) selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
        MplsBosCriterion bos = (MplsBosCriterion) selector.getCriterion(Criterion.Type.MPLS_BOS);
        if (bos != null) {
            filteredSelector.matchMplsBos(bos.mplsBos());
        }
        forTableId = MPLS_TABLE_1;
        log.debug("processing MPLS specific forwarding objective {} -> next:{}" + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
    }
    TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
    if (fwd.treatment() != null) {
        for (Instruction i : fwd.treatment().allInstructions()) {
            if (i instanceof L3ModificationInstruction) {
                L3ModificationInstruction l3instr = (L3ModificationInstruction) i;
                if (l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_IN) || l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_OUT)) {
                    continue;
                }
            }
            /*
                 * NOTE: OF-DPA does not support immediate instruction in
                 * L3 unicast and MPLS table.
                 */
            tb.deferred().add(i);
        }
    }
    if (fwd.nextId() != null) {
        NextGroup next = getGroupForNextObjective(fwd.nextId());
        if (next != null) {
            List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
            // we only need the top level group's key to point the flow to it
            Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
            if (group == null) {
                log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
                fail(fwd, ObjectiveError.GROUPMISSING);
                return Collections.emptySet();
            }
            tb.deferred().group(group.id());
        }
    }
    tb.transition(ACL_TABLE);
    FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(filteredSelector.build()).withTreatment(tb.build()).forTable(forTableId);
    if (fwd.permanent()) {
        ruleBuilder.makePermanent();
    } else {
        ruleBuilder.makeTemporary(fwd.timeout());
    }
    Collection<FlowRule> flowRuleCollection = new ArrayList<>();
    flowRuleCollection.add(ruleBuilder.build());
    if (defaultRule) {
        flowRuleCollection.add(defaultRoute(fwd, complementarySelector, forTableId, tb));
        log.debug("Default rule 0.0.0.0/0 is being installed two rules");
    }
    return flowRuleCollection;
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) ArrayList(java.util.ArrayList) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) Deque(java.util.Deque) ConnectPoint(org.onosproject.net.ConnectPoint) IpPrefix(org.onlab.packet.IpPrefix) MplsBosCriterion(org.onosproject.net.flow.criteria.MplsBosCriterion) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) MplsCriterion(org.onosproject.net.flow.criteria.MplsCriterion) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) VlanId(org.onlab.packet.VlanId)

Aggregations

FlowRule (org.onosproject.net.flow.FlowRule)432 DefaultFlowRule (org.onosproject.net.flow.DefaultFlowRule)279 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)226 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)225 TrafficSelector (org.onosproject.net.flow.TrafficSelector)193 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)189 Test (org.junit.Test)173 List (java.util.List)101 DeviceId (org.onosproject.net.DeviceId)101 FlowRuleIntent (org.onosproject.net.intent.FlowRuleIntent)90 Intent (org.onosproject.net.intent.Intent)88 Collection (java.util.Collection)75 Collectors (java.util.stream.Collectors)75 CoreService (org.onosproject.core.CoreService)72 Collections (java.util.Collections)70 VlanId (org.onlab.packet.VlanId)65 FlowEntry (org.onosproject.net.flow.FlowEntry)63 VlanIdCriterion (org.onosproject.net.flow.criteria.VlanIdCriterion)61 PortNumber (org.onosproject.net.PortNumber)57 ArrayList (java.util.ArrayList)56