Search in sources :

Example 36 with GroupKey

use of org.onosproject.net.group.GroupKey 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 37 with GroupKey

use of org.onosproject.net.group.GroupKey in project onos by opennetworkinglab.

the class Ofdpa2GroupHandler method createL2FloodGroup.

private void createL2FloodGroup(NextObjective nextObj, VlanId vlanId, List<GroupInfo> groupInfos) {
    // assemble info for l2 flood group. Since there can be only one flood
    // group for a vlan, its index is always the same - 0
    Integer l2FloodGroupId = L2_FLOOD_TYPE | (vlanId.toShort() << 16);
    final GroupKey l2FloodGroupKey = l2FloodGroupKey(vlanId, deviceId);
    // collection of group buckets pointing to all the l2 interface groups
    List<GroupBucket> l2floodBuckets = generateNextGroupBuckets(groupInfos, ALL);
    // create the l2flood group-description to wait for all the
    // l2interface groups to be processed
    GroupDescription l2floodGroupDescription = new DefaultGroupDescription(deviceId, ALL, new GroupBuckets(l2floodBuckets), l2FloodGroupKey, l2FloodGroupId, nextObj.appId());
    log.debug("Trying L2-Flood: device:{} gid:{} gkey:{} nextid:{}", deviceId, Integer.toHexString(l2FloodGroupId), l2FloodGroupKey, nextObj.id());
    // Put all dependency information into allGroupKeys
    List<Deque<GroupKey>> allGroupKeys = Lists.newArrayList();
    groupInfos.forEach(groupInfo -> {
        Deque<GroupKey> groupKeyChain = new ArrayDeque<>();
        // In this case we should have L2 interface group only
        groupKeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
        groupKeyChain.addFirst(l2FloodGroupKey);
        allGroupKeys.add(groupKeyChain);
    });
    // Point the next objective to this group
    OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj);
    updatePendingNextObjective(l2FloodGroupKey, ofdpaGrp);
    GroupChainElem gce = new GroupChainElem(l2floodGroupDescription, groupInfos.size(), false, deviceId);
    groupInfos.forEach(groupInfo -> {
        // Point this group to the next group
        updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), gce);
        // Start installing the inner-most group
        groupService.addGroup(groupInfo.innerMostGroupDesc());
    });
}
Also used : GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) OfdpaGroupHandlerUtility.l2MulticastGroupKey(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey) GroupBuckets(org.onosproject.net.group.GroupBuckets) Deque(java.util.Deque) ArrayDeque(java.util.ArrayDeque) ArrayDeque(java.util.ArrayDeque) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) GroupBucket(org.onosproject.net.group.GroupBucket) DefaultGroupBucket(org.onosproject.net.group.DefaultGroupBucket) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription)

Example 38 with GroupKey

use of org.onosproject.net.group.GroupKey in project onos by opennetworkinglab.

the class SpringOpenTTP method removeGroup.

private void removeGroup(NextObjective nextObjective) {
    log.debug("removeGroup in {}: for next objective id {}", deviceId, nextObjective.id());
    final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
    groupService.removeGroup(deviceId, key, appId);
}
Also used : GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey)

Example 39 with GroupKey

use of org.onosproject.net.group.GroupKey in project onos by opennetworkinglab.

the class SpringOpenTTP method processVersatile.

private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
    log.debug("Processing versatile forwarding objective in dev:{}", deviceId);
    TrafficSelector selector = fwd.selector();
    EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
    if (ethType == null) {
        log.error("Versatile forwarding objective must include ethType");
        fail(fwd, ObjectiveError.UNKNOWN);
        return Collections.emptySet();
    }
    if (fwd.treatment() == null && fwd.nextId() == null) {
        log.error("VERSATILE forwarding objective needs next objective ID " + "or treatment.");
        return Collections.emptySet();
    }
    // emulation of ACL table (for versatile fwd objective) requires
    // overriding any previous instructions
    TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
    treatmentBuilder.wipeDeferred();
    if (fwd.nextId() != null) {
        NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
        if (next != null) {
            SpringOpenGroup soGroup = appKryo.deserialize(next.data());
            if (soGroup.dummy) {
                // need to convert to flow-actions
                for (Instruction ins : soGroup.treatment.allInstructions()) {
                    treatmentBuilder.add(ins);
                }
            } else {
                GroupKey key = soGroup.key;
                Group group = groupService.getGroup(deviceId, key);
                if (group == null) {
                    log.warn("The group left!");
                    fail(fwd, ObjectiveError.GROUPMISSING);
                    return Collections.emptySet();
                }
                treatmentBuilder.deferred().group(group.id());
                log.debug("Adding OUTGROUP action");
            }
        }
    }
    if (fwd.treatment() != null) {
        if (fwd.treatment().allInstructions().size() == 1 && fwd.treatment().allInstructions().get(0).type() == Instruction.Type.OUTPUT) {
            OutputInstruction o = (OutputInstruction) fwd.treatment().allInstructions().get(0);
            if (o.port() == PortNumber.CONTROLLER) {
                treatmentBuilder.popVlan();
                treatmentBuilder.punt();
            } else {
                treatmentBuilder.add(o);
            }
        } else {
            for (Instruction ins : fwd.treatment().allInstructions()) {
                treatmentBuilder.add(ins);
            }
        }
    }
    FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(fwd.selector()).withTreatment(treatmentBuilder.build());
    if (fwd.permanent()) {
        ruleBuilder.makePermanent();
    } else {
        ruleBuilder.makeTemporary(fwd.timeout());
    }
    ruleBuilder.forTable(aclTableId);
    return Collections.singletonList(ruleBuilder.build());
}
Also used : NextGroup(org.onosproject.net.behaviour.NextGroup) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) EthTypeCriterion(org.onosproject.net.flow.criteria.EthTypeCriterion) GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) 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) L2ModificationInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction) OutputInstruction(org.onosproject.net.flow.instructions.Instructions.OutputInstruction) ModVlanIdInstruction(org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction) Instruction(org.onosproject.net.flow.instructions.Instruction)

Example 40 with GroupKey

use of org.onosproject.net.group.GroupKey in project onos by opennetworkinglab.

the class SpringOpenTTP method addGroup.

private void addGroup(NextObjective nextObjective) {
    log.debug("addGroup with type{} for nextObjective id {}", nextObjective.type(), nextObjective.id());
    List<GroupBucket> buckets;
    switch(nextObjective.type()) {
        case SIMPLE:
            Collection<TrafficTreatment> treatments = nextObjective.next();
            if (treatments.size() == 1) {
                // Spring Open TTP converts simple nextObjective to flow-actions
                // in a dummy group
                TrafficTreatment treatment = nextObjective.next().iterator().next();
                log.debug("Converting SIMPLE group for next objective id {} " + "to {} flow-actions in device:{}", nextObjective.id(), treatment.allInstructions().size(), deviceId);
                flowObjectiveStore.putNextGroup(nextObjective.id(), new SpringOpenGroup(null, treatment));
            }
            break;
        case HASHED:
            // we convert MPLS ECMP groups to flow-actions for a single
            // bucket(output port).
            boolean mplsEcmp = false;
            if (nextObjective.meta() != null) {
                for (Criterion c : nextObjective.meta().criteria()) {
                    if (c.type() == Type.MPLS_LABEL) {
                        mplsEcmp = true;
                    }
                }
            }
            if (mplsEcmp) {
                // covert to flow-actions in a dummy group by choosing the first bucket
                log.debug("Converting HASHED group for next objective id {} " + "to flow-actions in device:{}", nextObjective.id(), deviceId);
                TrafficTreatment treatment = nextObjective.next().iterator().next();
                flowObjectiveStore.putNextGroup(nextObjective.id(), new SpringOpenGroup(null, treatment));
            } else {
                // process as ECMP group
                buckets = nextObjective.next().stream().map(DefaultGroupBucket::createSelectGroupBucket).collect(Collectors.toList());
                if (!buckets.isEmpty()) {
                    final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
                    GroupDescription groupDescription = new DefaultGroupDescription(deviceId, GroupDescription.Type.SELECT, new GroupBuckets(buckets), key, null, nextObjective.appId());
                    log.debug("Creating HASHED group for next objective id {}" + " in dev:{}", nextObjective.id(), deviceId);
                    pendingGroups.put(key, nextObjective);
                    groupService.addGroup(groupDescription);
                    verifyPendingGroupLater();
                }
            }
            break;
        case BROADCAST:
            buckets = nextObjective.next().stream().map(DefaultGroupBucket::createAllGroupBucket).collect(Collectors.toList());
            if (!buckets.isEmpty()) {
                final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
                GroupDescription groupDescription = new DefaultGroupDescription(deviceId, GroupDescription.Type.ALL, new GroupBuckets(buckets), key, null, nextObjective.appId());
                log.debug("Creating BROADCAST group for next objective id {} " + "in device {}", nextObjective.id(), deviceId);
                pendingGroups.put(key, nextObjective);
                groupService.addGroup(groupDescription);
                verifyPendingGroupLater();
            }
            break;
        case FAILOVER:
            log.debug("FAILOVER next objectives not supported");
            fail(nextObjective, ObjectiveError.UNSUPPORTED);
            log.warn("Unsupported next objective type {}", nextObjective.type());
            break;
        default:
            fail(nextObjective, ObjectiveError.UNKNOWN);
            log.warn("Unknown next objective type {}", nextObjective.type());
    }
}
Also used : GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) GroupBuckets(org.onosproject.net.group.GroupBuckets) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription) GroupDescription(org.onosproject.net.group.GroupDescription) DefaultGroupBucket(org.onosproject.net.group.DefaultGroupBucket) 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) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) GroupBucket(org.onosproject.net.group.GroupBucket) DefaultGroupBucket(org.onosproject.net.group.DefaultGroupBucket) DefaultGroupDescription(org.onosproject.net.group.DefaultGroupDescription)

Aggregations

GroupKey (org.onosproject.net.group.GroupKey)99 DefaultGroupKey (org.onosproject.net.group.DefaultGroupKey)83 GroupBuckets (org.onosproject.net.group.GroupBuckets)59 GroupBucket (org.onosproject.net.group.GroupBucket)58 DefaultGroupDescription (org.onosproject.net.group.DefaultGroupDescription)52 Group (org.onosproject.net.group.Group)50 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)48 DefaultGroupBucket (org.onosproject.net.group.DefaultGroupBucket)48 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)47 GroupDescription (org.onosproject.net.group.GroupDescription)46 GroupId (org.onosproject.core.GroupId)31 ArrayList (java.util.ArrayList)29 PortNumber (org.onosproject.net.PortNumber)27 DefaultGroup (org.onosproject.net.group.DefaultGroup)27 NextGroup (org.onosproject.net.behaviour.NextGroup)24 OfdpaGroupHandlerUtility.l2MulticastGroupKey (org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey)21 ArrayDeque (java.util.ArrayDeque)20 Deque (java.util.Deque)19 TrafficSelector (org.onosproject.net.flow.TrafficSelector)18 Instruction (org.onosproject.net.flow.instructions.Instruction)18