Search in sources :

Example 6 with Instruction

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

the class Ofdpa2GroupHandler method prepareL2InterfaceGroup.

private List<GroupInfo> prepareL2InterfaceGroup(NextObjective nextObj, VlanId assignedVlan) {
    ImmutableList.Builder<GroupInfo> groupInfoBuilder = ImmutableList.builder();
    // break up broadcast next objective to multiple groups
    Collection<TrafficTreatment> buckets = nextObj.nextTreatments().stream().filter(nt -> nt.type() == NextTreatment.Type.TREATMENT).map(nt -> ((DefaultNextTreatment) nt).treatment()).collect(Collectors.toSet());
    // Each treatment is converted to an L2 interface group
    for (TrafficTreatment treatment : buckets) {
        TrafficTreatment.Builder newTreatment = DefaultTrafficTreatment.builder();
        PortNumber portNum = null;
        VlanId egressVlan = null;
        // ensure that the only allowed treatments are pop-vlan and output
        for (Instruction ins : treatment.allInstructions()) {
            if (ins.type() == Instruction.Type.L2MODIFICATION) {
                L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
                switch(l2ins.subtype()) {
                    case VLAN_POP:
                        newTreatment.add(l2ins);
                        break;
                    case VLAN_ID:
                        egressVlan = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId();
                        break;
                    default:
                        log.debug("action {} not permitted for broadcast nextObj", l2ins.subtype());
                        break;
                }
            } else if (ins.type() == Instruction.Type.OUTPUT) {
                portNum = ((Instructions.OutputInstruction) ins).port();
                newTreatment.add(ins);
            } else {
                log.debug("TrafficTreatment of type {} not permitted in " + " broadcast nextObjective", ins.type());
            }
        }
        if (portNum == null) {
            log.debug("Can't find output port for the bucket {}.", treatment);
            continue;
        }
        // assemble info for l2 interface group
        VlanId l2InterfaceGroupVlan = (egressVlan != null && !assignedVlan.equals(egressVlan)) ? egressVlan : assignedVlan;
        int l2gk = l2InterfaceGroupKey(deviceId, l2InterfaceGroupVlan, portNum.toLong());
        final GroupKey l2InterfaceGroupKey = new DefaultGroupKey(appKryo.serialize(l2gk));
        int l2InterfaceGroupId = L2_INTERFACE_TYPE | ((l2InterfaceGroupVlan.toShort() & THREE_NIBBLE_MASK) << PORT_LEN) | ((int) portNum.toLong() & FOUR_NIBBLE_MASK);
        GroupBucket l2InterfaceGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(newTreatment.build());
        GroupDescription l2InterfaceGroupDescription = new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(l2InterfaceGroupBucket)), l2InterfaceGroupKey, l2InterfaceGroupId, nextObj.appId());
        log.debug("Trying L2-Interface: device:{} gid:{} gkey:{} nextid:{}", deviceId, Integer.toHexString(l2InterfaceGroupId), l2InterfaceGroupKey, nextObj.id());
        groupInfoBuilder.add(new GroupInfo(l2InterfaceGroupDescription, l2InterfaceGroupDescription));
    }
    return groupInfoBuilder.build();
}
Also used : Arrays(java.util.Arrays) TUNNEL_ID(org.onosproject.net.flow.criteria.Criterion.Type.TUNNEL_ID) AtomicCounter(org.onosproject.store.service.AtomicCounter) OfdpaPipelineUtility(org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility) PortNumber(org.onosproject.net.PortNumber) Tools.groupedThreads(org.onlab.util.Tools.groupedThreads) Operation(org.onosproject.net.flowobjective.Objective.Operation) DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) PortCriterion(org.onosproject.net.flow.criteria.PortCriterion) ServiceDirectory(org.onlab.osgi.ServiceDirectory) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) ObjectiveError(org.onosproject.net.flowobjective.ObjectiveError) INDIRECT(org.onosproject.net.group.GroupDescription.Type.INDIRECT) StorageService(org.onosproject.store.service.StorageService) GroupListener(org.onosproject.net.group.GroupListener) ApplicationId(org.onosproject.core.ApplicationId) NextObjective(org.onosproject.net.flowobjective.NextObjective) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) IN_PORT(org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT) SELECT(org.onosproject.net.group.GroupDescription.Type.SELECT) ALL(org.onosproject.net.group.GroupDescription.Type.ALL) PipelinerContext(org.onosproject.net.behaviour.PipelinerContext) VLAN_VID(org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) FlowObjectiveStore(org.onosproject.net.flowobjective.FlowObjectiveStore) GroupEvent(org.onosproject.net.group.GroupEvent) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) L2_MULTICAST_TYPE(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.L2_MULTICAST_TYPE) List(java.util.List) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) GroupBuckets(org.onosproject.net.group.GroupBuckets) Optional(java.util.Optional) CacheBuilder(com.google.common.cache.CacheBuilder) DeviceId(org.onosproject.net.DeviceId) Ofdpa2Pipeline(org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline) TunnelIdCriterion(org.onosproject.net.flow.criteria.TunnelIdCriterion) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) IpPrefix(org.onlab.packet.IpPrefix) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) OfdpaSetAllowVlanTranslation(org.onosproject.driver.extensions.OfdpaSetAllowVlanTranslation) NextTreatment(org.onosproject.net.flowobjective.NextTreatment) OfdpaSetVlanVid(org.onosproject.driver.extensions.OfdpaSetVlanVid) DefaultNextTreatment(org.onosproject.net.flowobjective.DefaultNextTreatment) GroupBucket(org.onosproject.net.group.GroupBucket) NextGroup(org.onosproject.net.behaviour.NextGroup) GroupKey(org.onosproject.net.group.GroupKey) Deque(java.util.Deque) Group(org.onosproject.net.group.Group) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) TrafficSelector(org.onosproject.net.flow.TrafficSelector) ImmutableList(com.google.common.collect.ImmutableList) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) OfdpaGroupHandlerUtility.l2MulticastGroupKey(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) OfdpaGroupHandlerUtility(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility) Criterion(org.onosproject.net.flow.criteria.Criterion) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) RemovalNotification(com.google.common.cache.RemovalNotification) Ofdpa3AllowVlanTranslationType(org.onosproject.driver.extensions.Ofdpa3AllowVlanTranslationType) Instructions(org.onosproject.net.flow.instructions.Instructions) Logger(org.slf4j.Logger) MplsLabel(org.onlab.packet.MplsLabel) Instruction(org.onosproject.net.flow.instructions.Instruction) VlanId(org.onlab.packet.VlanId) GroupService(org.onosproject.net.group.GroupService) GroupInstruction(org.onosproject.net.flow.instructions.Instructions.GroupInstruction) DefaultGroupBucket(org.onosproject.net.group.DefaultGroupBucket) IdNextTreatment(org.onosproject.net.flowobjective.IdNextTreatment) TimeUnit(java.util.concurrent.TimeUnit) RemovalCause(com.google.common.cache.RemovalCause) GroupId(org.onosproject.core.GroupId) VlanIdCriterion(org.onosproject.net.flow.criteria.VlanIdCriterion) LoggerFactory.getLogger(org.slf4j.LoggerFactory.getLogger) MacAddress(org.onlab.packet.MacAddress) Cache(com.google.common.cache.Cache) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) ImmutableList(com.google.common.collect.ImmutableList) GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) OfdpaGroupHandlerUtility.l2MulticastGroupKey(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) GroupInstruction(org.onosproject.net.flow.instructions.Instructions.GroupInstruction) GroupBuckets(org.onosproject.net.group.GroupBuckets) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) DefaultNextTreatment(org.onosproject.net.flowobjective.DefaultNextTreatment) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) GroupBucket(org.onosproject.net.group.GroupBucket) DefaultGroupBucket(org.onosproject.net.group.DefaultGroupBucket) PortNumber(org.onosproject.net.PortNumber) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) VlanId(org.onlab.packet.VlanId)

Example 7 with Instruction

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

the class Ofdpa2GroupHandler method processSimpleNextObjective.

/**
 * As per the OFDPA 2.0 TTP, packets are sent out of ports by using
 * a chain of groups. The simple Next Objective passed in by the application
 * is broken up into a group chain. The following chains can be created
 * depending on the parameters in the Next Objective.
 * 1. L2 Interface group (no chaining)
 * 2. L3 Unicast group -> L2 Interface group
 * 3. MPLS Interface group -> L2 Interface group
 * 4. MPLS Swap group -> MPLS Interface group -> L2 Interface group
 * 5. PW initiation group chain
 *
 * @param nextObj  the nextObjective of type SIMPLE
 */
private void processSimpleNextObjective(NextObjective nextObj) {
    TrafficTreatment treatment = nextObj.next().iterator().next();
    // determine if plain L2 or L3->L2 or MPLS Swap -> MPLS Interface -> L2
    boolean plainL2 = true;
    boolean mplsSwap = false;
    MplsLabel mplsLabel = null;
    for (Instruction ins : treatment.allInstructions()) {
        if (ins.type() == Instruction.Type.L2MODIFICATION) {
            L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
            if (l2ins.subtype() == L2ModificationInstruction.L2SubType.ETH_DST || l2ins.subtype() == L2ModificationInstruction.L2SubType.ETH_SRC) {
                plainL2 = false;
            }
            // a MPLS Swap group before the MPLS Interface Group
            if (l2ins.subtype() == L2ModificationInstruction.L2SubType.MPLS_LABEL) {
                mplsSwap = true;
                mplsLabel = ((L2ModificationInstruction.ModMplsLabelInstruction) l2ins).label();
            }
        }
    }
    if (plainL2) {
        createL2InterfaceGroup(nextObj);
        return;
    }
    // In order to understand if it is a pseudowire related
    // next objective we look for the tunnel id in the meta.
    boolean isPw = false;
    if (nextObj.meta() != null) {
        TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) nextObj.meta().getCriterion(TUNNEL_ID);
        if (tunnelIdCriterion != null) {
            isPw = true;
        }
    }
    if (mplsSwap && !isPw) {
        log.debug("Creating a MPLS Swap -> MPLS Interface -> L2 Interface group chain.");
        // break up simple next objective to GroupChain objects
        GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(), nextObj.appId(), true, nextObj.meta());
        if (groupInfo == null) {
            log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId);
            fail(nextObj, ObjectiveError.BADPARAMS);
            return;
        }
        Deque<GroupKey> gkeyChain = new ArrayDeque<>();
        // l2 interface
        gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
        // mpls interface
        gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
        // creating the mpls swap group and adding it to the chain
        int nextGid = groupInfo.nextGroupDesc().givenGroupId();
        int index = getNextAvailableIndex();
        GroupDescription swapGroupDescription = createMplsSwap(nextGid, OfdpaMplsGroupSubType.MPLS_SWAP_LABEL, index, mplsLabel, nextObj.appId());
        // ensure swap group is added after L2L3 chain
        GroupKey swapGroupKey = swapGroupDescription.appCookie();
        GroupChainElem swapChainElem = new GroupChainElem(swapGroupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), swapChainElem);
        gkeyChain.addFirst(swapGroupKey);
        // ensure nextObjective waits on the outermost groupKey
        List<Deque<GroupKey>> allGroupKeys = Lists.newArrayList();
        allGroupKeys.add(gkeyChain);
        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj);
        updatePendingNextObjective(swapGroupKey, ofdpaGrp);
        // now we are ready to send the l2 groupDescription (inner), as all the stores
        // that will get async replies have been updated. By waiting to update
        // the stores, we prevent nasty race conditions.
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    } else if (!isPw) {
        boolean isMpls = false;
        if (nextObj.meta() != null) {
            isMpls = isNotMplsBos(nextObj.meta());
        }
        log.debug("Creating a {} -> L2 Interface group chain.", (isMpls) ? "MPLS Interface" : "L3 Unicast");
        // break up simple next objective to GroupChain objects
        GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(), nextObj.appId(), isMpls, nextObj.meta());
        if (groupInfo == null) {
            log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId);
            fail(nextObj, ObjectiveError.BADPARAMS);
            return;
        }
        // create object for local and distributed storage
        Deque<GroupKey> gkeyChain = new ArrayDeque<>();
        gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
        gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
        List<Deque<GroupKey>> allGroupKeys = Lists.newArrayList();
        allGroupKeys.add(gkeyChain);
        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj);
        // store l3groupkey with the ofdpaNextGroup for the nextObjective that depends on it
        updatePendingNextObjective(groupInfo.nextGroupDesc().appCookie(), ofdpaGrp);
        // now we are ready to send the l2 groupDescription (inner), as all the stores
        // that will get async replies have been updated. By waiting to update
        // the stores, we prevent nasty race conditions.
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    } else {
        // We handle the pseudo wire with a different a procedure.
        // This procedure is meant to handle both initiation and
        // termination of the pseudo wire.
        processPwNextObjective(nextObj);
    }
}
Also used : TunnelIdCriterion(org.onosproject.net.flow.criteria.TunnelIdCriterion) GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) OfdpaGroupHandlerUtility.l2MulticastGroupKey(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) GroupInstruction(org.onosproject.net.flow.instructions.Instructions.GroupInstruction) Deque(java.util.Deque) ArrayDeque(java.util.ArrayDeque) ArrayDeque(java.util.ArrayDeque) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) MplsLabel(org.onlab.packet.MplsLabel) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList)

Example 8 with Instruction

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

the class Ofdpa2Pipeline method versatileTreatmentBuilder.

/**
 * Helper function to create traffic treatment builder for versatile forwarding objectives.
 *
 * @param fwd original forwarding objective
 * @return treatment builder for the flow rule, or null if there is an error.
 */
protected TrafficTreatment.Builder versatileTreatmentBuilder(ForwardingObjective fwd) {
    // XXX driver does not currently do type checking as per Tables 65-67 in
    // OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
    TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
    if (fwd.treatment() != null) {
        for (Instruction ins : fwd.treatment().allInstructions()) {
            if (ins instanceof OutputInstruction) {
                OutputInstruction o = (OutputInstruction) ins;
                if (PortNumber.CONTROLLER.equals(o.port())) {
                    ttBuilder.add(o);
                } else {
                    log.warn("Only allowed treatments in versatile forwarding " + "objectives are punts to the controller");
                }
            } else if (ins instanceof NoActionInstruction) {
            // No action is allowed and nothing needs to be done
            } else {
                log.warn("Cannot process instruction in versatile fwd {}", ins);
            }
        }
        if (fwd.treatment().clearedDeferred()) {
            ttBuilder.wipeDeferred();
        }
    }
    if (fwd.nextId() != null) {
        // Override case
        NextGroup next = getGroupForNextObjective(fwd.nextId());
        if (next == null) {
            fail(fwd, ObjectiveError.BADPARAMS);
            return 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 null;
        }
        ttBuilder.deferred().group(group.id());
    }
    return ttBuilder;
}
Also used : OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) ModMplsHeaderInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction) ArrayDeque(java.util.ArrayDeque) Deque(java.util.Deque)

Example 9 with Instruction

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

the class Ofdpa2Pipeline method processEthTypeSpecificInternal.

/**
 * Internal implementation of processEthTypeSpecific.
 * <p>
 * Wildcarded IPv4_DST is not supported in OFDPA i12. Therefore, we break
 * the rule into 0.0.0.0/1 and 128.0.0.0/1.
 * The allowDefaultRoute must be set to false for OFDPA i12.
 * </p>
 *
 * @param fwd the forwarding objective
 * @param allowDefaultRoute allow wildcarded IPv4_DST or not
 * @param mplsNextTable next MPLS table
 * @return A collection of flow rules, or an empty set
 */
protected Collection<FlowRule> processEthTypeSpecificInternal(ForwardingObjective fwd, boolean allowDefaultRoute, int mplsNextTable) {
    TrafficSelector selector = fwd.selector();
    EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
    boolean emptyGroup = false;
    int forTableId;
    TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
    TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
    if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
        if (buildIpv4Selector(filteredSelector, complementarySelector, fwd, allowDefaultRoute) < 0) {
            return Collections.emptyList();
        }
        // We need to set properly the next table
        IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
        if (ipv4Dst.isMulticast()) {
            forTableId = MULTICAST_ROUTING_TABLE;
        } else {
            forTableId = UNICAST_ROUTING_TABLE;
        }
    // TODO decrementing IP ttl is done automatically for routing, this
    // action is ignored or rejected in ofdpa as it is not fully implemented
    // if (fwd.treatment() != null) {
    // for (Instruction instr : fwd.treatment().allInstructions()) {
    // if (instr instanceof L3ModificationInstruction &&
    // ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
    // tb.deferred().add(instr);
    // }
    // }
    // }
    } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
        if (buildIpv6Selector(filteredSelector, fwd) < 0) {
            return Collections.emptyList();
        }
        // We need to set the proper next table
        IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
        if (ipv6Dst.isMulticast()) {
            forTableId = MULTICAST_ROUTING_TABLE;
        } else {
            forTableId = UNICAST_ROUTING_TABLE;
        }
    // TODO decrementing IP ttl is done automatically for routing, this
    // action is ignored or rejected in ofdpa as it is not fully implemented
    // if (fwd.treatment() != null) {
    // for (Instruction instr : fwd.treatment().allInstructions()) {
    // if (instr instanceof L3ModificationInstruction &&
    // ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
    // tb.deferred().add(instr);
    // }
    // }
    // }
    } else {
        filteredSelector.matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(((MplsCriterion) selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
        MplsBosCriterion bos = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
        if (bos != null && requireMplsBosMatch()) {
            filteredSelector.matchMplsBos(bos.mplsBos());
        }
        forTableId = MPLS_TABLE_1;
        log.debug("processing MPLS specific forwarding objective {} -> next:{}" + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
        if (fwd.treatment() != null) {
            for (Instruction instr : fwd.treatment().allInstructions()) {
                if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2SubType.MPLS_POP) {
                    // setting the MPLS_TYPE so pop can happen down the pipeline
                    if (requireMplsPop()) {
                        if (mplsNextTable == MPLS_TYPE_TABLE && isNotMplsBos(selector)) {
                            tb.immediate().popMpls();
                        }
                    } else {
                        // Skip mpls pop action for mpls_unicast label
                        if (instr instanceof ModMplsHeaderInstruction && !((ModMplsHeaderInstruction) instr).ethernetType().equals(EtherType.MPLS_UNICAST.ethType())) {
                            tb.immediate().add(instr);
                        }
                    }
                }
                if (requireMplsTtlModification()) {
                    if (instr instanceof L3ModificationInstruction && ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
                        // FIXME Should modify the app to send the correct DEC_MPLS_TTL instruction
                        tb.immediate().decMplsTtl();
                    }
                    if (instr instanceof L3ModificationInstruction && ((L3ModificationInstruction) instr).subtype() == L3SubType.TTL_IN) {
                        tb.immediate().add(instr);
                    }
                }
            }
        }
    }
    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();
            }
            if (isNotMplsBos(selector) && group.type().equals(SELECT)) {
                log.warn("SR CONTINUE case cannot be handled as MPLS ECMP " + "is not implemented in OF-DPA yet. Aborting flow {} -> next:{} " + "in this device {}", fwd.id(), fwd.nextId(), deviceId);
                fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
                return Collections.emptySet();
            }
            tb.deferred().group(group.id());
            // retrying flows may be necessary due to bug CORD-554
            if (gkeys.size() == 1 && gkeys.get(0).size() == 1) {
                if (shouldRetry()) {
                    log.warn("Found empty group 0x{} in dev:{} .. will retry fwd:{}", Integer.toHexString(group.id().id()), deviceId, fwd.id());
                    emptyGroup = true;
                }
            }
        } else {
            log.warn("Cannot find group for nextId:{} in dev:{}. Aborting fwd:{}", fwd.nextId(), deviceId, fwd.id());
            fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
            return Collections.emptySet();
        }
    }
    if (forTableId == MPLS_TABLE_1) {
        if (mplsNextTable == MPLS_L3_TYPE_TABLE) {
            Ofdpa3SetMplsType setMplsType = new Ofdpa3SetMplsType(Ofdpa3MplsType.L3_PHP);
            // set mpls type as apply_action
            tb.immediate().extension(setMplsType, deviceId);
        }
        tb.transition(mplsNextTable);
    } else {
        tb.transition(ACL_TABLE);
    }
    if (fwd.treatment() != null && fwd.treatment().clearedDeferred()) {
        if (supportsUnicastBlackHole()) {
            tb.wipeDeferred();
        } else {
            log.warn("Clear Deferred is not supported Unicast Routing Table on device {}", deviceId);
            return Collections.emptySet();
        }
    }
    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 (!allowDefaultRoute) {
        flowRuleCollection.add(defaultRoute(fwd, complementarySelector, forTableId, tb));
        log.debug("Default rule 0.0.0.0/0 is being installed two rules");
    }
    if (emptyGroup) {
        retryExecutorService.schedule(new RetryFlows(fwd, flowRuleCollection), RETRY_MS, TimeUnit.MILLISECONDS);
    }
    return flowRuleCollection;
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) IPCriterion(org.onosproject.net.flow.criteria.IPCriterion) ArrayList(java.util.ArrayList) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) NoActionInstruction(org.onosproject.net.flow.instructions.Instructions.NoActionInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) ModMplsHeaderInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction) ModMplsHeaderInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsHeaderInstruction) IpPrefix(org.onlab.packet.IpPrefix) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) MplsCriterion(org.onosproject.net.flow.criteria.MplsCriterion) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) ArrayDeque(java.util.ArrayDeque) Deque(java.util.Deque) MplsBosCriterion(org.onosproject.net.flow.criteria.MplsBosCriterion) DefaultFlowRule(org.onosproject.net.flow.DefaultFlowRule) FlowRule(org.onosproject.net.flow.FlowRule) Ofdpa3SetMplsType(org.onosproject.driver.extensions.Ofdpa3SetMplsType)

Example 10 with Instruction

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

the class Ofdpa3GroupHandler method processPwNextObjective.

@Override
protected void processPwNextObjective(NextObjective nextObjective) {
    log.info("Started deploying nextObjective id={} for pseudowire", nextObjective.id());
    TrafficTreatment treatment = nextObjective.next().iterator().next();
    Deque<GroupKey> gkeyChain = new ArrayDeque<>();
    GroupChainElem groupChainElem;
    GroupKey groupKey;
    GroupDescription groupDescription;
    // Now we separate the mpls actions from the l2/l3 actions
    TrafficTreatment.Builder l2L3Treatment = DefaultTrafficTreatment.builder();
    TrafficTreatment.Builder mplsTreatment = DefaultTrafficTreatment.builder();
    createL2L3AndMplsTreatments(treatment, l2L3Treatment, mplsTreatment);
    // We create the chain from mpls intf group to
    // l2 intf group.
    GroupInfo groupInfo = createL2L3ChainInternal(l2L3Treatment.build(), nextObjective.id(), nextObjective.appId(), true, nextObjective.meta(), false);
    if (groupInfo == null) {
        log.error("Could not process nextObj={} in dev:{}", nextObjective.id(), deviceId);
        OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.GROUPINSTALLATIONFAILED);
        return;
    }
    // We update the chain with the last two groups;
    gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
    gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
    // We retrieve also all mpls instructions.
    List<List<Instruction>> mplsInstructionSets = Lists.newArrayList();
    List<Instruction> mplsInstructionSet = Lists.newArrayList();
    L3ModificationInstruction l3Ins;
    for (Instruction ins : treatment.allInstructions()) {
        // Each mpls instruction set is delimited by a
        // copy ttl outward action.
        mplsInstructionSet.add(ins);
        if (ins.type() == Instruction.Type.L3MODIFICATION) {
            l3Ins = (L3ModificationInstruction) ins;
            if (l3Ins.subtype() == TTL_OUT) {
                mplsInstructionSets.add(mplsInstructionSet);
                mplsInstructionSet = Lists.newArrayList();
            }
        }
    }
    if (mplsInstructionSets.size() > MAX_DEPTH_UNPROTECTED_PW) {
        log.error("Next Objective for pseudo wire should have at " + "most {} mpls instruction sets. Next Objective Id:{}", MAX_DEPTH_UNPROTECTED_PW, nextObjective.id());
        OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.BADPARAMS);
        return;
    }
    log.debug("Size of mpls instructions is {}.", mplsInstructionSets.size());
    log.debug("mpls instructions sets are {}.", mplsInstructionSets);
    int nextGid = groupInfo.nextGroupDesc().givenGroupId();
    int index;
    // this is for inter-co pws
    if (mplsInstructionSets.size() == MAX_DEPTH_UNPROTECTED_PW) {
        log.debug("Creating inter-co pw mpls chains with nextid {}", nextObjective.id());
        // We deal with the label 2 group.
        index = getNextAvailableIndex();
        groupDescription = createMplsTunnelLabelGroup(nextGid, OfdpaMplsGroupSubType.MPLS_TUNNEL_LABEL_2, index, mplsInstructionSets.get(2), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        // We update the chain.
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        // We have to create tunnel label group and
        // l2 vpn group before to send the inner most
        // group. We update the nextGid.
        nextGid = groupDescription.givenGroupId();
        groupInfo = new GroupInfo(groupInfo.innerMostGroupDesc(), groupDescription);
        log.debug("Trying Label 2 Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
    }
    // inside a single co
    if (mplsInstructionSets.size() == 2) {
        log.debug("Creating leaf-leaf pw mpls chains with nextid {}", nextObjective.id());
        // We deal with the label 1 group.
        index = getNextAvailableIndex();
        groupDescription = createMplsTunnelLabelGroup(nextGid, OfdpaMplsGroupSubType.MPLS_TUNNEL_LABEL_1, index, mplsInstructionSets.get(1), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        // We have to create the l2 vpn group before
        // to send the inner most group.
        nextGid = groupDescription.givenGroupId();
        groupInfo = new GroupInfo(groupInfo.innerMostGroupDesc(), groupDescription);
        log.debug("Trying Label 1 Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
        // Finally we create the l2 vpn group.
        index = getNextAvailableIndex();
        groupDescription = createMplsL2VpnGroup(nextGid, index, mplsInstructionSets.get(0), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObjective);
        updatePendingNextObjective(groupKey, ofdpaGrp);
        log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
        // Finally we send the innermost group.
        log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    }
    // only one label is used
    if (mplsInstructionSets.size() == 1) {
        log.debug("Creating leaf-spine pw mpls chains with nextid {}", nextObjective.id());
        // Finally we create the l2 vpn group.
        index = getNextAvailableIndex();
        groupDescription = createMplsL2VpnGroup(nextGid, index, mplsInstructionSets.get(0), nextObjective.appId());
        groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
        groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
        gkeyChain.addFirst(groupKey);
        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObjective);
        updatePendingNextObjective(groupKey, ofdpaGrp);
        log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
        // Finally we send the innermost group.
        log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    }
}
Also used : L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) L3ModificationInstruction(org.onosproject.net.flow.instructions.L3ModificationInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction) ArrayDeque(java.util.ArrayDeque) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) List(java.util.List)

Aggregations

Instruction (org.onosproject.net.flow.instructions.Instruction)104 L2ModificationInstruction (org.onosproject.net.flow.instructions.L2ModificationInstruction)59 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)48 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)44 Criterion (org.onosproject.net.flow.criteria.Criterion)42 TrafficSelector (org.onosproject.net.flow.TrafficSelector)34 VlanIdCriterion (org.onosproject.net.flow.criteria.VlanIdCriterion)33 Instructions (org.onosproject.net.flow.instructions.Instructions)33 OutputInstruction (org.onosproject.net.flow.instructions.Instructions.OutputInstruction)32 L3ModificationInstruction (org.onosproject.net.flow.instructions.L3ModificationInstruction)32 PortNumber (org.onosproject.net.PortNumber)30 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)28 EthTypeCriterion (org.onosproject.net.flow.criteria.EthTypeCriterion)27 IPCriterion (org.onosproject.net.flow.criteria.IPCriterion)26 VlanId (org.onlab.packet.VlanId)25 DeviceId (org.onosproject.net.DeviceId)25 EthCriterion (org.onosproject.net.flow.criteria.EthCriterion)25 PortCriterion (org.onosproject.net.flow.criteria.PortCriterion)25 FlowRule (org.onosproject.net.flow.FlowRule)24 Group (org.onosproject.net.group.Group)23