Search in sources :

Example 11 with NextObjective

use of org.onosproject.net.flowobjective.NextObjective in project trellis-control by opennetworkinglab.

the class DefaultL2TunnelHandler method deployPseudoWireInit.

/**
 * Handles the tunnel establishment which consists in
 * create the next objectives related to the initiation.
 *
 * @param l2Tunnel  the tunnel to deploy
 * @param ingress   the ingress connect point
 * @param egress    the egress connect point
 * @param direction the direction of the pw
 * @param nextHop next hop of the initiation point
 * @param oneHop if this pseudowire has only one link
 * @param termVlanId the termination vlan id
 * @return the result of the operation
 */
private Result deployPseudoWireInit(L2Tunnel l2Tunnel, ConnectPoint ingress, ConnectPoint egress, Direction direction, Link nextHop, boolean oneHop, VlanId termVlanId) {
    log.debug("Started deploying init next objectives for pseudowire {} for tunnel {} -> {}.", l2Tunnel.tunnelId(), ingress, egress);
    if (nextHop == null) {
        log.warn("No path between ingress and egress connection points for tunnel {}", l2Tunnel.tunnelId());
        return WRONG_PARAMETERS;
    }
    // We create the next objective without the metadata
    // context and id. We check if it already exists in the
    // store. If not we store as it is in the store.
    NextObjective.Builder nextObjectiveBuilder = createNextObjective(INITIATION, nextHop.src(), nextHop.dst(), l2Tunnel, egress.deviceId(), oneHop, termVlanId);
    if (nextObjectiveBuilder == null) {
        return INTERNAL_ERROR;
    }
    // We set the metadata. We will use this metadata
    // to inform the driver we are doing a l2 tunnel.
    TrafficSelector metadata = DefaultTrafficSelector.builder().matchTunnelId(l2Tunnel.tunnelId()).build();
    nextObjectiveBuilder.withMeta(metadata);
    int nextId = srManager.flowObjectiveService.allocateNextId();
    if (nextId < 0) {
        log.warn("Not able to allocate a next id for initiation");
        return INTERNAL_ERROR;
    }
    nextObjectiveBuilder.withId(nextId);
    String key = generateKey(l2Tunnel.tunnelId(), direction);
    l2InitiationNextObjStore.put(key, nextObjectiveBuilder.add());
    ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("Initiation l2 tunnel rule for {} populated", l2Tunnel.tunnelId()), (objective, error) -> {
        log.warn("Failed to populate Initiation l2 tunnel rule for {}: {}", l2Tunnel.tunnelId(), error);
        srManager.invalidateNextObj(objective.id());
    });
    NextObjective nextObjective = nextObjectiveBuilder.add(context);
    srManager.flowObjectiveService.next(ingress.deviceId(), nextObjective);
    log.debug("Initiation next objective for {} not found. Creating new NextObj with id={}", l2Tunnel.tunnelId(), nextObjective.id());
    Result result = SUCCESS;
    result.setNextId(nextObjective.id());
    return result;
}
Also used : DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) NextObjective(org.onosproject.net.flowobjective.NextObjective) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) ConnectPoint(org.onosproject.net.ConnectPoint) Result(org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Result)

Example 12 with NextObjective

use of org.onosproject.net.flowobjective.NextObjective in project trellis-control by opennetworkinglab.

the class DefaultL2TunnelHandler method deployPseudoWireTerm.

/**
 * Handles the tunnel termination, which consists in the creation
 * of a forwarding objective and a next objective.
 *
 * @param l2Tunnel   the tunnel to terminate
 * @param egress     the egress point
 * @param egressVlan the expected vlan at egress
 * @param direction  the direction
 * @return the result of the operation
 */
private Result deployPseudoWireTerm(L2Tunnel l2Tunnel, ConnectPoint egress, VlanId egressVlan, Direction direction, boolean oneHop) {
    log.debug("Started deploying termination objectives for pseudowire {} , direction {}.", l2Tunnel.tunnelId(), direction == FWD ? "forward" : "reverse");
    // We create the group relative to the termination.
    NextObjective.Builder nextObjectiveBuilder = createNextObjective(TERMINATION, egress, null, l2Tunnel, egress.deviceId(), oneHop, egressVlan);
    if (nextObjectiveBuilder == null) {
        return INTERNAL_ERROR;
    }
    TrafficSelector metadata = DefaultTrafficSelector.builder().matchVlanId(egressVlan).build();
    nextObjectiveBuilder.withMeta(metadata);
    int nextId = srManager.flowObjectiveService.allocateNextId();
    if (nextId < 0) {
        log.warn("Not able to allocate a next id for initiation");
        return INTERNAL_ERROR;
    }
    nextObjectiveBuilder.withId(nextId);
    String key = generateKey(l2Tunnel.tunnelId(), direction);
    l2TerminationNextObjStore.put(key, nextObjectiveBuilder.add());
    ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("Termination l2 tunnel rule for {} populated", l2Tunnel.tunnelId()), (objective, error) -> {
        log.warn("Failed to populate termination l2 tunnel rule for {}: {}", l2Tunnel.tunnelId(), error);
        srManager.invalidateNextObj(objective.id());
    });
    NextObjective nextObjective = nextObjectiveBuilder.add(context);
    srManager.flowObjectiveService.next(egress.deviceId(), nextObjective);
    log.debug("Termination next objective for {} not found. Creating new NextObj with id={}", l2Tunnel.tunnelId(), nextObjective.id());
    // We create the flow relative to the termination.
    ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(l2Tunnel.pwLabel(), l2Tunnel.tunnelId(), egress.port(), nextObjective.id());
    context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for tunnel termination {} populated", l2Tunnel.tunnelId()), (objective, error) -> log.warn("Failed to populate fwdrObj" + " for tunnel termination {} : {}", l2Tunnel.tunnelId(), error));
    srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.add(context));
    log.debug("Creating new FwdObj for termination NextObj with id={} for tunnel {}", nextId, l2Tunnel.tunnelId());
    return SUCCESS;
}
Also used : DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) NextObjective(org.onosproject.net.flowobjective.NextObjective) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) ConsistentMap(org.onosproject.store.service.ConsistentMap) REV(org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Direction.REV) PortNumber(org.onosproject.net.PortNumber) LoggerFactory(org.slf4j.LoggerFactory) DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) Link(org.onosproject.net.Link) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) ConnectPoint(org.onosproject.net.ConnectPoint) PwaasUtil(org.onosproject.segmentrouting.pwaas.PwaasUtil) ObjectiveError(org.onosproject.net.flowobjective.ObjectiveError) Ethernet(org.onlab.packet.Ethernet) FWD(org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Direction.FWD) NextObjective(org.onosproject.net.flowobjective.NextObjective) KryoNamespaces(org.onosproject.store.serializers.KryoNamespaces) Result(org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Result) DefaultLink(org.onosproject.net.DefaultLink) Serializer(org.onosproject.store.service.Serializer) ImmutableMap(com.google.common.collect.ImmutableMap) DefaultFilteringObjective(org.onosproject.net.flowobjective.DefaultFilteringObjective) SRLinkWeigher(org.onosproject.segmentrouting.SRLinkWeigher) FilteringObjective(org.onosproject.net.flowobjective.FilteringObjective) Set(java.util.Set) DefaultForwardingObjective(org.onosproject.net.flowobjective.DefaultForwardingObjective) Collectors(java.util.stream.Collectors) Versioned(org.onosproject.store.service.Versioned) List(java.util.List) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) Path(org.onosproject.net.Path) TERMINATION(org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.TERMINATION) DeviceId(org.onosproject.net.DeviceId) DistributedLock(org.onosproject.store.service.DistributedLock) RandomUtils(org.apache.commons.lang3.RandomUtils) Iterables(com.google.common.collect.Iterables) StorageException(org.onosproject.store.service.StorageException) CompletableFuture(java.util.concurrent.CompletableFuture) KryoNamespace(org.onlab.util.KryoNamespace) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SegmentRoutingService(org.onosproject.segmentrouting.SegmentRoutingService) Lists(com.google.common.collect.Lists) TrafficSelector(org.onosproject.net.flow.TrafficSelector) VERSATILE(org.onosproject.net.flowobjective.ForwardingObjective.Flag.VERSATILE) Criteria(org.onosproject.net.flow.criteria.Criteria) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) SegmentRoutingManager(org.onosproject.segmentrouting.SegmentRoutingManager) Logger(org.slf4j.Logger) MplsLabel(org.onlab.packet.MplsLabel) INITIATION(org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.INITIATION) VlanId(org.onlab.packet.VlanId) Objective(org.onosproject.net.flowobjective.Objective) MacAddress(org.onlab.packet.MacAddress) LinkWeigher(org.onosproject.net.topology.LinkWeigher) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) DefaultForwardingObjective(org.onosproject.net.flowobjective.DefaultForwardingObjective) ConnectPoint(org.onosproject.net.ConnectPoint)

Example 13 with NextObjective

use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.

the class NextObjectiveCodec method decode.

@Override
public NextObjective decode(ObjectNode json, CodecContext context) {
    if (json == null || !json.isObject()) {
        return null;
    }
    CoreService coreService = context.getService(CoreService.class);
    final JsonCodec<TrafficSelector> trafficSelectorCodec = context.codec(TrafficSelector.class);
    final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class);
    ObjectiveCodecHelper och = new ObjectiveCodecHelper();
    DefaultNextObjective.Builder baseBuilder = DefaultNextObjective.builder();
    final DefaultNextObjective.Builder builder = (DefaultNextObjective.Builder) och.decode(json, baseBuilder, context);
    // decode id
    JsonNode idJson = json.get(ID);
    checkNotNull(idJson);
    builder.withId(idJson.asInt());
    // decode application id
    JsonNode appIdJson = json.get(APP_ID);
    String appId = appIdJson != null ? appIdJson.asText() : REST_APP_ID;
    builder.fromApp(coreService.registerApplication(appId));
    // decode type
    String typeStr = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asText();
    switch(typeStr) {
        case "HASHED":
            builder.withType(NextObjective.Type.HASHED);
            break;
        case "BROADCAST":
            builder.withType(NextObjective.Type.BROADCAST);
            break;
        case "FAILOVER":
            builder.withType(NextObjective.Type.FAILOVER);
            break;
        case "SIMPLE":
            builder.withType(NextObjective.Type.SIMPLE);
            break;
        default:
            throw new IllegalArgumentException("The requested type " + typeStr + " is not defined for NextObjective.");
    }
    // decode treatments
    JsonNode treatmentsJson = json.get(TREATMENTS);
    checkNotNull(treatmentsJson);
    if (treatmentsJson != null) {
        IntStream.range(0, treatmentsJson.size()).forEach(i -> {
            ObjectNode treatmentJson = get(treatmentsJson, i);
            JsonNode weightJson = treatmentJson.get(WEIGHT);
            int weight = (weightJson != null) ? weightJson.asInt() : NextTreatment.DEFAULT_WEIGHT;
            builder.addTreatment(DefaultNextTreatment.of(trafficTreatmentCodec.decode(treatmentJson, context), weight));
        });
    }
    // decode meta
    JsonNode metaJson = json.get(META);
    if (metaJson != null) {
        TrafficSelector trafficSelector = trafficSelectorCodec.decode((ObjectNode) metaJson, context);
        builder.withMeta(trafficSelector);
    }
    // decode operation
    String opStr = nullIsIllegal(json.get(OPERATION), OPERATION + MISSING_MEMBER_MESSAGE).asText();
    NextObjective nextObjective;
    switch(opStr) {
        case "ADD":
            nextObjective = builder.add();
            break;
        case "REMOVE":
            nextObjective = builder.remove();
            break;
        default:
            throw new IllegalArgumentException("The requested operation " + opStr + " is not defined for NextObjective.");
    }
    return nextObjective;
}
Also used : DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) NextObjective(org.onosproject.net.flowobjective.NextObjective) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) CoreService(org.onosproject.core.CoreService) JsonNode(com.fasterxml.jackson.databind.JsonNode) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) TrafficSelector(org.onosproject.net.flow.TrafficSelector)

Example 14 with NextObjective

use of org.onosproject.net.flowobjective.NextObjective in project onos by opennetworkinglab.

the class Ofdpa2GroupHandler method verifyGroup.

/**
 *  Checks existing buckets in {@link NextGroup}  to verify if they match
 *  the buckets in the given {@link NextObjective}. Adds or removes buckets
 *  to ensure that the buckets match up.
 *
 * @param nextObjective the next objective to verify
 * @param next the representation of the existing group which has to be
 *             modified to match the given next objective
 */
protected void verifyGroup(NextObjective nextObjective, NextGroup next) {
    if (nextObjective.type() == NextObjective.Type.SIMPLE) {
        log.warn("verification not supported for indirect group");
        fail(nextObjective, ObjectiveError.UNSUPPORTED);
        return;
    }
    log.trace("Call to verify device:{} nextId:{}", deviceId, nextObjective.id());
    List<Deque<GroupKey>> allActiveKeys = appKryo.deserialize(next.data());
    List<TrafficTreatment> bucketsToCreate = Lists.newArrayList();
    List<Integer> indicesToRemove = Lists.newArrayList();
    // to detect missing buckets and/or duplicate buckets (to be removed)
    for (TrafficTreatment bkt : nextObjective.next()) {
        PortNumber portNumber = readOutPortFromTreatment(bkt);
        int label = readLabelFromTreatment(bkt);
        if (portNumber == null) {
            log.warn("treatment {} of next objective {} has no outport.. " + "cannot remove bucket from group in dev: {}", bkt, nextObjective.id(), deviceId);
            fail(nextObjective, ObjectiveError.BADPARAMS);
            return;
        }
        List<Integer> existing = existingPortAndLabel(allActiveKeys, groupService, deviceId, portNumber, label);
        if (existing.isEmpty()) {
            // if it doesn't exist, mark this bucket for creation
            bucketsToCreate.add(bkt);
        }
        if (existing.size() > 1) {
            // if it exists but there are duplicates, mark the others for removal
            existing.remove(0);
            indicesToRemove.addAll(existing);
        }
    }
    // (not duplicates) respect to the next objective
    if (allActiveKeys.size() > nextObjective.next().size() && // ignore specific case of empty group
    !(nextObjective.next().size() == 0 && allActiveKeys.size() == 1 && allActiveKeys.get(0).size() == 1)) {
        log.warn("Mismatch detected between next and flowobjstore for device {}: " + "nextId:{}, nextObjective-size:{} next-size:{} .. correcting", deviceId, nextObjective.id(), nextObjective.next().size(), allActiveKeys.size());
        List<Integer> otherIndices = indicesToRemoveFromNextGroup(allActiveKeys, nextObjective, groupService, deviceId);
        // Filter out the indices not present
        otherIndices = otherIndices.stream().filter(index -> !indicesToRemove.contains(index)).collect(Collectors.toList());
        // Add all to the final list
        indicesToRemove.addAll(otherIndices);
    }
    log.trace("Buckets to create {}", bucketsToCreate);
    log.trace("Indices to remove {}", indicesToRemove);
    if (!bucketsToCreate.isEmpty()) {
        log.info("creating {} buckets as part of nextId: {} verification", bucketsToCreate.size(), nextObjective.id());
        // create a nextObjective only with these buckets
        NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(nextObjective.id()).withType(nextObjective.type()).withMeta(nextObjective.meta()).fromApp(nextObjective.appId());
        bucketsToCreate.forEach(nextObjBuilder::addTreatment);
        // According to the next type we call the proper add function
        if (nextObjective.type() == NextObjective.Type.HASHED) {
            if (isL2Hash(nextObjective)) {
                addBucketToL2HashGroup(nextObjBuilder.addToExisting(), allActiveKeys);
            } else {
                addBucketToEcmpHashGroup(nextObjBuilder.addToExisting(), allActiveKeys);
            }
        } else {
            addBucketToBroadcastGroup(nextObjBuilder.addToExisting(), allActiveKeys);
        }
    }
    if (!indicesToRemove.isEmpty()) {
        log.info("removing {} buckets as part of nextId: {} verification", indicesToRemove.size(), nextObjective.id());
        List<Deque<GroupKey>> chainsToRemove = Lists.newArrayList();
        indicesToRemove.forEach(index -> chainsToRemove.add(allActiveKeys.get(index)));
        removeBucket(chainsToRemove, nextObjective);
    }
    log.trace("Checking mismatch with GroupStore device:{} nextId:{}", deviceId, nextObjective.id());
    if (bucketsToCreate.isEmpty() && indicesToRemove.isEmpty()) {
        // flowObjective store record is in-sync with nextObjective passed-in
        // Nevertheless groupStore may not be in sync due to bug in the store
        // - see CORD-1844. XXX When this bug is fixed, the rest of this verify
        // method will not be required.
        GroupKey topGroupKey = allActiveKeys.get(0).peekFirst();
        Group topGroup = groupService.getGroup(deviceId, topGroupKey);
        // topGroup should not be null - adding guard
        if (topGroup == null) {
            log.warn("topGroup {} not found in GroupStore device:{}, nextId:{}", topGroupKey, deviceId, nextObjective.id());
            fail(nextObjective, ObjectiveError.GROUPMISSING);
            return;
        }
        int actualGroupSize = topGroup.buckets().buckets().size();
        int objGroupSize = nextObjective.next().size();
        if (actualGroupSize != objGroupSize) {
            log.warn("Mismatch detected in device:{}, nextId:{}, nextObjective-size" + ":{} group-size:{} .. correcting", deviceId, nextObjective.id(), objGroupSize, actualGroupSize);
        }
        if (actualGroupSize > objGroupSize) {
            // Group in the device has more chains
            List<GroupBucket> bucketsToRemove = Lists.newArrayList();
            // check every bucket in the actual group
            for (GroupBucket bucket : topGroup.buckets().buckets()) {
                GroupInstruction g = (GroupInstruction) bucket.treatment().allInstructions().iterator().next();
                // the group pointed to
                GroupId gidToCheck = g.groupId();
                boolean matches = false;
                for (Deque<GroupKey> validChain : allActiveKeys) {
                    if (validChain.size() < 2) {
                        continue;
                    }
                    GroupKey pointedGroupKey = validChain.stream().collect(Collectors.toList()).get(1);
                    Group pointedGroup = groupService.getGroup(deviceId, pointedGroupKey);
                    if (pointedGroup != null && gidToCheck.equals(pointedGroup.id())) {
                        matches = true;
                        break;
                    }
                }
                if (!matches) {
                    log.warn("Removing bucket pointing to groupId:{}", gidToCheck);
                    bucketsToRemove.add(bucket);
                }
            }
            // remove buckets for which there was no record in the obj store
            if (bucketsToRemove.isEmpty()) {
                log.warn("Mismatch detected but could not determine which" + "buckets to remove");
            } else {
                GroupBuckets removeBuckets = new GroupBuckets(bucketsToRemove);
                groupService.removeBucketsFromGroup(deviceId, topGroupKey, removeBuckets, topGroupKey, nextObjective.appId());
            }
        } else if (actualGroupSize < objGroupSize) {
            // Group in the device has less chains
            // should also add buckets not in group-store but in obj-store
            List<GroupBucket> bucketsToAdd = Lists.newArrayList();
            // check every bucket in the obj
            for (Deque<GroupKey> validChain : allActiveKeys) {
                if (validChain.size() < 2) {
                    continue;
                }
                GroupKey pointedGroupKey = validChain.stream().collect(Collectors.toList()).get(1);
                Group pointedGroup = groupService.getGroup(deviceId, pointedGroupKey);
                if (pointedGroup == null) {
                    // group should exist, otherwise cannot be added as bucket
                    continue;
                }
                boolean matches = false;
                for (GroupBucket bucket : topGroup.buckets().buckets()) {
                    GroupInstruction g = (GroupInstruction) bucket.treatment().allInstructions().iterator().next();
                    // the group pointed to
                    GroupId gidToCheck = g.groupId();
                    if (pointedGroup.id().equals(gidToCheck)) {
                        matches = true;
                        break;
                    }
                }
                if (!matches) {
                    log.warn("Adding bucket pointing to groupId:{}", pointedGroup);
                    TrafficTreatment t = DefaultTrafficTreatment.builder().group(pointedGroup.id()).build();
                    // Create the proper bucket according to the next type
                    if (nextObjective.type() == NextObjective.Type.HASHED) {
                        bucketsToAdd.add(DefaultGroupBucket.createSelectGroupBucket(t));
                    } else {
                        bucketsToAdd.add(DefaultGroupBucket.createAllGroupBucket(t));
                    }
                }
            }
            if (bucketsToAdd.isEmpty()) {
                log.warn("Mismatch detected but could not determine which " + "buckets to add");
            } else {
                GroupBuckets addBuckets = new GroupBuckets(bucketsToAdd);
                groupService.addBucketsToGroup(deviceId, topGroupKey, addBuckets, topGroupKey, nextObjective.appId());
            }
        }
    }
    log.trace("Verify done for device:{} nextId:{}", deviceId, nextObjective.id());
    pass(nextObjective);
}
Also used : DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) NextObjective(org.onosproject.net.flowobjective.NextObjective) NextGroup(org.onosproject.net.behaviour.NextGroup) Group(org.onosproject.net.group.Group) GroupKey(org.onosproject.net.group.GroupKey) DefaultGroupKey(org.onosproject.net.group.DefaultGroupKey) OfdpaGroupHandlerUtility.l2MulticastGroupKey(org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.l2MulticastGroupKey) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) GroupBuckets(org.onosproject.net.group.GroupBuckets) Deque(java.util.Deque) ArrayDeque(java.util.ArrayDeque) GroupId(org.onosproject.core.GroupId) GroupBucket(org.onosproject.net.group.GroupBucket) DefaultGroupBucket(org.onosproject.net.group.DefaultGroupBucket) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) PortNumber(org.onosproject.net.PortNumber) GroupInstruction(org.onosproject.net.flow.instructions.Instructions.GroupInstruction)

Example 15 with NextObjective

use of org.onosproject.net.flowobjective.NextObjective 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)

Aggregations

NextObjective (org.onosproject.net.flowobjective.NextObjective)83 DefaultNextObjective (org.onosproject.net.flowobjective.DefaultNextObjective)57 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)56 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)55 TrafficSelector (org.onosproject.net.flow.TrafficSelector)51 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)47 ForwardingObjective (org.onosproject.net.flowobjective.ForwardingObjective)36 Objective (org.onosproject.net.flowobjective.Objective)31 ObjectiveContext (org.onosproject.net.flowobjective.ObjectiveContext)30 DeviceId (org.onosproject.net.DeviceId)29 PortNumber (org.onosproject.net.PortNumber)24 FilteringObjective (org.onosproject.net.flowobjective.FilteringObjective)24 DefaultObjectiveContext (org.onosproject.net.flowobjective.DefaultObjectiveContext)23 Set (java.util.Set)22 Test (org.junit.Test)22 List (java.util.List)21 Collectors (java.util.stream.Collectors)20 GroupBucket (org.onosproject.net.group.GroupBucket)19 GroupBuckets (org.onosproject.net.group.GroupBuckets)19 Lists (com.google.common.collect.Lists)18