Search in sources :

Example 56 with FlowRule

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

the class Ofdpa2Pipeline method processEthDstSpecific.

/**
 * Handles forwarding rules to the L2 bridging table. Flow actions are not
 * allowed in the bridging table - instead we use L2 Interface group or
 * L2 flood group
 *
 * @param fwd the forwarding objective
 * @return A collection of flow rules, or an empty set
 */
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(Criterion.Type.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();
    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 {
        // Use wildcard DST_MAC if the MacAddress is None or Broadcast
        log.debug("processing L2 Broadcast forwarding objective:{} -> next:{} " + "in dev:{} for vlan:{}", fwd.id(), fwd.nextId(), deviceId, vlanIdCriterion.vlanId());
    }
    if (requireVlanExtensions()) {
        OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanIdCriterion.vlanId());
        filteredSelectorBuilder.extension(ofdpaMatchVlanVid, deviceId);
    } else {
        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) ArrayDeque(java.util.ArrayDeque) Deque(java.util.Deque) OfdpaMatchVlanVid(org.onosproject.driver.extensions.OfdpaMatchVlanVid) 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 57 with FlowRule

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

the class Ofdpa2Pipeline method sendForwards.

// Builds the batch using the accumulated flow rules
private void sendForwards(List<Pair<ForwardingObjective, Collection<FlowRule>>> pairs) {
    FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
    log.debug("Sending {} fwd-objs", pairs.size());
    List<Objective> fwdObjs = Lists.newArrayList();
    // Iterates over all accumulated flow rules and then build an unique batch
    pairs.forEach(pair -> {
        ForwardingObjective fwd = pair.getLeft();
        Collection<FlowRule> rules = pair.getRight();
        switch(fwd.op()) {
            case ADD:
                rules.stream().filter(Objects::nonNull).forEach(flowOpsBuilder::add);
                log.debug("Applying a add fwd-obj {} to sw:{}", fwd.id(), deviceId);
                fwdObjs.add(fwd);
                break;
            case REMOVE:
                rules.stream().filter(Objects::nonNull).forEach(flowOpsBuilder::remove);
                log.debug("Deleting a flow rule to sw:{}", deviceId);
                fwdObjs.add(fwd);
                break;
            default:
                fail(fwd, ObjectiveError.UNKNOWN);
                log.warn("Unknown forwarding type {}", fwd.op());
        }
    });
    // Finally applies the operations
    flowRuleService.apply(flowOpsBuilder.build(new FlowRuleOperationsContext() {

        @Override
        public void onSuccess(FlowRuleOperations ops) {
            log.trace("Flow rule operations onSuccess {}", ops);
            fwdObjs.forEach(OfdpaPipelineUtility::pass);
        }

        @Override
        public void onError(FlowRuleOperations ops) {
            ObjectiveError error = ObjectiveError.FLOWINSTALLATIONFAILED;
            log.warn("Flow rule operations onError {}. Reason = {}", ops, error);
            fwdObjs.forEach(fwdObj -> fail(fwdObj, error));
        }
    }));
}
Also used : NextObjective(org.onosproject.net.flowobjective.NextObjective) FilteringObjective(org.onosproject.net.flowobjective.FilteringObjective) Objective(org.onosproject.net.flowobjective.Objective) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) FlowRuleOperations(org.onosproject.net.flow.FlowRuleOperations) OfdpaPipelineUtility(org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) FlowRuleOperationsContext(org.onosproject.net.flow.FlowRuleOperationsContext) ObjectiveError(org.onosproject.net.flowobjective.ObjectiveError)

Example 58 with FlowRule

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

the class Ofdpa2Pipeline method processVersatile.

/**
 * In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
 * ACL table.
 * @param fwd  the forwarding objective of type 'versatile'
 * @return     a collection of flow rules to be sent to the switch. An empty
 *             collection may be returned if there is a problem in processing
 *             the flow rule
 */
protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
    log.debug("Processing versatile forwarding objective:{} in dev:{}", fwd.id(), deviceId);
    List<FlowRule> flowRules = new ArrayList<>();
    final AtomicBoolean ethTypeUsed = new AtomicBoolean(false);
    if (fwd.nextId() == null && fwd.treatment() == null) {
        log.error("Forwarding objective {} from {} must contain " + "nextId or Treatment", fwd.selector(), fwd.appId());
        fail(fwd, ObjectiveError.BADPARAMS);
        return Collections.emptySet();
    }
    TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
    fwd.selector().criteria().forEach(criterion -> {
        if (criterion instanceof VlanIdCriterion) {
            VlanId vlanId = ((VlanIdCriterion) criterion).vlanId();
            // match untagged packets this way in the ACL table.
            if (vlanId.equals(VlanId.NONE)) {
                return;
            }
            if (requireVlanExtensions()) {
                OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanId);
                sbuilder.extension(ofdpaMatchVlanVid, deviceId);
            } else {
                sbuilder.matchVlanId(vlanId);
            }
        } else if (criterion instanceof Icmpv6TypeCriterion) {
            byte icmpv6Type = (byte) ((Icmpv6TypeCriterion) criterion).icmpv6Type();
            sbuilder.matchIcmpv6Type(icmpv6Type);
        } else if (criterion instanceof Icmpv6CodeCriterion) {
            byte icmpv6Code = (byte) ((Icmpv6CodeCriterion) criterion).icmpv6Code();
            sbuilder.matchIcmpv6Type(icmpv6Code);
        } else if (criterion instanceof TcpPortCriterion || criterion instanceof UdpPortCriterion) {
            // We need to revisit this if L4 dst port is used for other purpose in the future.
            if (!supportIpv6L4Dst() && isIpv6(fwd.selector())) {
                switch(criterion.type()) {
                    case UDP_DST:
                    case UDP_DST_MASKED:
                    case TCP_DST:
                    case TCP_DST_MASKED:
                        break;
                    default:
                        sbuilder.add(criterion);
                }
            } else {
                sbuilder.add(criterion);
            }
        } else if (criterion instanceof EthTypeCriterion) {
            sbuilder.add(criterion);
            ethTypeUsed.set(true);
        } else {
            sbuilder.add(criterion);
        }
    });
    TrafficTreatment.Builder ttBuilder = versatileTreatmentBuilder(fwd);
    if (ttBuilder == null) {
        return Collections.emptySet();
    }
    FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sbuilder.build()).withTreatment(ttBuilder.build()).makePermanent().forTable(ACL_TABLE);
    flowRules.add(ruleBuilder.build());
    if (!ethTypeUsed.get() && requireEthType()) {
        log.debug("{} doesn't match on ethType but requireEthType is true, adding complementary ACL flow.", sbuilder.toString());
        sbuilder.matchEthType(Ethernet.TYPE_IPV6);
        FlowRule.Builder ethTypeRuleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sbuilder.build()).withTreatment(ttBuilder.build()).makePermanent().forTable(ACL_TABLE);
        flowRules.add(ethTypeRuleBuilder.build());
    }
    return flowRules;
}
Also used : EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) UdpPortCriterion(org.onosproject.net.flow.criteria.UdpPortCriterion) ArrayList(java.util.ArrayList) Icmpv6TypeCriterion(org.onosproject.net.flow.criteria.Icmpv6TypeCriterion) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) OfdpaMatchVlanVid(org.onosproject.driver.extensions.OfdpaMatchVlanVid) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Icmpv6CodeCriterion(org.onosproject.net.flow.criteria.Icmpv6CodeCriterion) TcpPortCriterion(org.onosproject.net.flow.criteria.TcpPortCriterion) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) VlanId(org.onlab.packet.VlanId) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion)

Example 59 with FlowRule

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

the class Ofdpa2Pipeline method processFilter.

// ////////////////////////////////////
// Flow handling
// ////////////////////////////////////
/**
 * As per OFDPA 2.0 TTP, filtering of VLAN ids and MAC addresses (for routing)
 * configured on switch ports happen in different tables.
 *
 * @param filt      the filtering objective
 * @param install   indicates whether to add or remove the objective
 * @param applicationId     the application that sent this objective
 */
protected void processFilter(FilteringObjective filt, boolean install, ApplicationId applicationId) {
    // This driver only processes filtering criteria defined with switch
    // ports as the key
    PortCriterion portCriterion = null;
    EthCriterion ethCriterion = null;
    VlanIdCriterion vidCriterion = null;
    if (!filt.key().equals(Criteria.dummy()) && filt.key().type() == Criterion.Type.IN_PORT) {
        portCriterion = (PortCriterion) filt.key();
    }
    if (portCriterion == null) {
        log.debug("No IN_PORT defined in filtering objective from app: {}", applicationId);
    } else {
        log.debug("Received filtering objective for dev/port: {}/{}", deviceId, portCriterion.port());
    }
    // convert filtering conditions for switch-intfs into flowrules
    FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
    for (Criterion criterion : filt.conditions()) {
        switch(criterion.type()) {
            case ETH_DST:
            case ETH_DST_MASKED:
                ethCriterion = (EthCriterion) criterion;
                break;
            case VLAN_VID:
                vidCriterion = (VlanIdCriterion) criterion;
                break;
            default:
                log.warn("Unsupported filter {}", criterion);
                fail(filt, ObjectiveError.UNSUPPORTED);
                return;
        }
    }
    VlanId assignedVlan = null;
    if (vidCriterion != null) {
        // Use the VLAN in criterion if metadata is not present and the traffic is tagged
        if (!vidCriterion.vlanId().equals(VlanId.NONE)) {
            assignedVlan = vidCriterion.vlanId();
        }
        // If the meta VLAN is present let's update the assigned vlan
        if (filt.meta() != null) {
            VlanId metaVlan = readVlanFromTreatment(filt.meta());
            if (metaVlan != null) {
                assignedVlan = metaVlan;
            }
        }
        if (assignedVlan == null) {
            log.error("Driver fails to extract VLAN information. " + "Not processing VLAN filters on device {}.", deviceId);
            log.debug("VLAN ID in criterion={}, metadata={}", readVlanFromTreatment(filt.meta()), vidCriterion.vlanId());
            fail(filt, ObjectiveError.BADPARAMS);
            return;
        }
    }
    if (ethCriterion == null || ethCriterion.mac().equals(NONE)) {
        // NOTE: it is possible that a filtering objective only has vidCriterion
        log.debug("filtering objective missing dstMac, won't program TMAC table");
    } else {
        MacAddress unicastMac = readEthDstFromTreatment(filt.meta());
        List<List<FlowRule>> allStages = processEthDstFilter(portCriterion, ethCriterion, vidCriterion, assignedVlan, 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 rule in TMAC table: {} for dev: {}", (install) ? "adding" : "removing", flowRule, deviceId);
                if (install) {
                    ops = ops.add(flowRule);
                } else {
                    // same VLAN on this device if TMAC doesn't support matching on in_port.
                    if (filt.meta() != null && filt.meta().clearedDeferred()) {
                        // TMac mcast does not match on the input port - we have to remove it
                        // only if this is the last port
                        FlowRule rule = buildTmacRuleForMcastFromUnicast(flowRule, applicationId);
                        // IPv6 or IPv4 tmac rule
                        if (rule != null) {
                            // Add first the mcast rule and then open a new stage for the unicast
                            ops = ops.remove(rule);
                            ops.newStage();
                        }
                        ops = ops.remove(flowRule);
                    } else if (matchInPortTmacTable()) {
                        ops = ops.remove(flowRule);
                    } else {
                        log.debug("Abort TMAC flow removal on {}. " + "Some other ports still share this TMAC flow", deviceId);
                    }
                }
            }
        }
    }
    if (vidCriterion == null) {
        // NOTE: it is possible that a filtering objective only has ethCriterion
        log.info("filtering objective missing VLAN, cannot program VLAN Table");
    } else {
        List<List<FlowRule>> allStages = processVlanIdFilter(portCriterion, vidCriterion, assignedVlan, applicationId, install);
        for (List<FlowRule> flowRules : allStages) {
            log.trace("Starting a new flow rule stage for VLAN table flow");
            ops.newStage();
            for (FlowRule flowRule : flowRules) {
                log.trace("{} flow rules 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(filt);
        }

        @Override
        public void onError(FlowRuleOperations ops) {
            log.info("Failed to apply all filtering rules in dev {}", deviceId);
            fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
        }
    }));
}
Also used : FlowRuleOperations(org.onosproject.net.flow.FlowRuleOperations) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) UdpPortCriterion(org.onosproject.net.flow.criteria.UdpPortCriterion) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) TcpPortCriterion(org.onosproject.net.flow.criteria.TcpPortCriterion) MacAddress(org.onlab.packet.MacAddress) EthCriterion(org.onosproject.net.flow.criteria.EthCriterion) Criterion(org.onosproject.net.flow.criteria.Criterion) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) UdpPortCriterion(org.onosproject.net.flow.criteria.UdpPortCriterion) Icmpv6CodeCriterion(org.onosproject.net.flow.criteria.Icmpv6CodeCriterion) MplsBosCriterion(org.onosproject.net.flow.criteria.MplsBosCriterion) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) Icmpv6TypeCriterion(org.onosproject.net.flow.criteria.Icmpv6TypeCriterion) MplsCriterion(org.onosproject.net.flow.criteria.MplsCriterion) TcpPortCriterion(org.onosproject.net.flow.criteria.TcpPortCriterion) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) 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 60 with FlowRule

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

the class Ofdpa2Pipeline method processEthDstOnlyFilter.

protected List<List<FlowRule>> processEthDstOnlyFilter(EthCriterion ethCriterion, ApplicationId applicationId) {
    ImmutableList.Builder<FlowRule> builder = ImmutableList.builder();
    TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
    selector.matchEthType(Ethernet.TYPE_IPV4);
    selector.matchEthDst(ethCriterion.mac());
    treatment.transition(UNICAST_ROUTING_TABLE);
    FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(DEFAULT_PRIORITY).fromApp(applicationId).makePermanent().forTable(TMAC_TABLE).build();
    builder.add(rule);
    selector = DefaultTrafficSelector.builder();
    treatment = DefaultTrafficTreatment.builder();
    selector.matchEthType(Ethernet.TYPE_IPV6);
    selector.matchEthDst(ethCriterion.mac());
    treatment.transition(UNICAST_ROUTING_TABLE);
    rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(DEFAULT_PRIORITY).fromApp(applicationId).makePermanent().forTable(TMAC_TABLE).build();
    return ImmutableList.of(builder.add(rule).build());
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment)

Aggregations

FlowRule (org.onosproject.net.flow.FlowRule)351 DefaultFlowRule (org.onosproject.net.flow.DefaultFlowRule)226 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)207 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)207 TrafficSelector (org.onosproject.net.flow.TrafficSelector)174 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)174 Test (org.junit.Test)133 FlowRuleIntent (org.onosproject.net.intent.FlowRuleIntent)90 Intent (org.onosproject.net.intent.Intent)88 DeviceId (org.onosproject.net.DeviceId)87 List (java.util.List)86 Collection (java.util.Collection)68 Collectors (java.util.stream.Collectors)68 CoreService (org.onosproject.core.CoreService)66 VlanId (org.onlab.packet.VlanId)65 VlanIdCriterion (org.onosproject.net.flow.criteria.VlanIdCriterion)61 Collections (java.util.Collections)60 FlowEntry (org.onosproject.net.flow.FlowEntry)59 MplsCriterion (org.onosproject.net.flow.criteria.MplsCriterion)56 ArrayList (java.util.ArrayList)54