Search in sources :

Example 11 with PortNumber

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

the class DefaultGroupHandler method portDownForLink.

/**
 * Updates local stores for link-src-device/port to neighbor (link-dst) for
 * link that has gone down.
 *
 * @param link the infrastructure link
 */
public void portDownForLink(Link link) {
    PortNumber port = link.src().port();
    if (portDeviceMap.get(port) == null) {
        log.warn("portDown: unknown port");
        return;
    }
    log.debug("Device {} portDown {} to neighbor {}", deviceId, port, portDeviceMap.get(port));
    devicePortMap.get(portDeviceMap.get(port)).remove(port);
    portDeviceMap.remove(port);
}
Also used : PortNumber(org.onosproject.net.PortNumber)

Example 12 with PortNumber

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

the class DefaultGroupHandler method retryHash.

/**
 * Checks all groups in the src-device of link for neighbor sets that include
 * the dst-device of link, and edits the hash groups according to link up
 * or down. Should only be called by the instance leading the programming of
 * the src-switch of link. Typically used when there are no route-path
 * changes due to the link up or down, as the ECMPspg does not change.
 *
 * @param link the infrastructure link that has gone down or come up
 * @param linkDown true if link has gone down
 * @param firstTime true if link has come up for the first time i.e a link
 *                  not seen-before
 */
public void retryHash(Link link, boolean linkDown, boolean firstTime) {
    MacAddress neighborMac;
    try {
        neighborMac = deviceConfig.getDeviceMac(link.dst().deviceId());
    } catch (DeviceConfigNotFoundException e) {
        log.warn(e.getMessage() + " Aborting retryHash.");
        return;
    }
    // find all the destinationSets related to link
    Set<DestinationSetNextObjectiveStoreKey> dsKeySet = dsNextObjStore.entrySet().stream().filter(entry -> entry.getKey().deviceId().equals(deviceId)).filter(entry -> !entry.getKey().destinationSet().notBos() || (entry.getKey().destinationSet().notBos() && srManager.getMplsEcmp())).filter(entry -> !entry.getKey().destinationSet().swap() || (entry.getKey().destinationSet().swap() && srManager.getMplsEcmp())).filter(entry -> entry.getValue().containsNextHop(link.dst().deviceId())).map(entry -> entry.getKey()).collect(Collectors.toSet());
    log.debug("retryHash: dsNextObjStore contents for linkSrc {} -> linkDst {}: {}", deviceId, link.dst().deviceId(), dsKeySet);
    for (DestinationSetNextObjectiveStoreKey dsKey : dsKeySet) {
        NextNeighbors nextHops = dsNextObjStore.get(dsKey);
        if (nextHops == null) {
            log.warn("retryHash in device {}, but global store has no record " + "for dsKey:{}", deviceId, dsKey);
            continue;
        }
        int nextId = nextHops.nextId();
        Set<DeviceId> dstSet = nextHops.getDstForNextHop(link.dst().deviceId());
        if (!linkDown) {
            List<PortLabel> pl = Lists.newArrayList();
            if (firstTime) {
                // to the same hash group are avoided by the driver.
                for (PortNumber p : devicePortMap.get(link.dst().deviceId())) {
                    dstSet.forEach(dst -> {
                        int edgeLabel = dsKey.destinationSet().getEdgeLabel(dst);
                        pl.add(new PortLabel(p, edgeLabel, popVlanInHashGroup(dsKey.destinationSet())));
                    });
                }
                addToHashedNextObjective(pl, neighborMac, nextId);
            } else {
                // handle only the port that came up
                dstSet.forEach(dst -> {
                    int edgeLabel = dsKey.destinationSet().getEdgeLabel(dst);
                    pl.add(new PortLabel(link.src().port(), edgeLabel, popVlanInHashGroup(dsKey.destinationSet())));
                });
                addToHashedNextObjective(pl, neighborMac, nextId);
            }
        } else {
            // linkdown
            List<PortLabel> pl = Lists.newArrayList();
            dstSet.forEach(dst -> {
                int edgeLabel = dsKey.destinationSet().getEdgeLabel(dst);
                pl.add(new PortLabel(link.src().port(), edgeLabel, popVlanInHashGroup(dsKey.destinationSet())));
            });
            removeFromHashedNextObjective(pl, neighborMac, nextId);
        }
    }
}
Also used : DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) PortNumber(org.onosproject.net.PortNumber) Tools.groupedThreads(org.onlab.util.Tools.groupedThreads) DeviceConfiguration(org.onosproject.segmentrouting.DeviceConfiguration) DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) Link(org.onosproject.net.Link) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) ConnectPoint(org.onosproject.net.ConnectPoint) Executors.newScheduledThreadPool(java.util.concurrent.Executors.newScheduledThreadPool) Map(java.util.Map) ApplicationId(org.onosproject.core.ApplicationId) NextObjective(org.onosproject.net.flowobjective.NextObjective) URI(java.net.URI) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) List(java.util.List) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) LinkService(org.onosproject.net.link.LinkService) DeviceId(org.onosproject.net.DeviceId) RandomUtils(org.apache.commons.lang3.RandomUtils) MacVlanNextObjectiveStoreKey(org.onosproject.segmentrouting.storekey.MacVlanNextObjectiveStoreKey) Iterables(com.google.common.collect.Iterables) VlanNextObjectiveStoreKey(org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey) DefaultRoutingHandler(org.onosproject.segmentrouting.DefaultRoutingHandler) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) KryoNamespace(org.onlab.util.KryoNamespace) FlowObjectiveService(org.onosproject.net.flowobjective.FlowObjectiveService) HashSet(java.util.HashSet) Lists(com.google.common.collect.Lists) TrafficSelector(org.onosproject.net.flow.TrafficSelector) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) EventuallyConsistentMap(org.onosproject.store.service.EventuallyConsistentMap) 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) VlanId(org.onlab.packet.VlanId) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) TimeUnit(java.util.concurrent.TimeUnit) DestinationSetNextObjectiveStoreKey(org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey) LoggerFactory.getLogger(org.slf4j.LoggerFactory.getLogger) Objective(org.onosproject.net.flowobjective.Objective) MacAddress(org.onlab.packet.MacAddress) DeviceProperties(org.onosproject.segmentrouting.config.DeviceProperties) Collections(java.util.Collections) PortNextObjectiveStoreKey(org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey) DestinationSetNextObjectiveStoreKey(org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey) DeviceId(org.onosproject.net.DeviceId) MacAddress(org.onlab.packet.MacAddress) PortNumber(org.onosproject.net.PortNumber) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) ConnectPoint(org.onosproject.net.ConnectPoint)

Example 13 with PortNumber

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

the class DefaultGroupHandler method createGroupFromDestinationSet.

/**
 * Creates a NextObjective for a hash group in this device from a given
 * DestinationSet. If the parameter simple is true, a simple next objective
 * is created instead.
 *
 * @param ds the DestinationSet
 * @param neighbors a map for each destination and its next-hops
 * @param meta metadata passed into the creation of a Next Objective
 * @param simple if true, a simple next objective will be created instead of
 *            a hashed next objective
 */
public void createGroupFromDestinationSet(DestinationSet ds, Map<DeviceId, Set<DeviceId>> neighbors, TrafficSelector meta, boolean simple) {
    int nextId = flowObjectiveService.allocateNextId();
    NextObjective.Type type = (simple) ? NextObjective.Type.SIMPLE : NextObjective.Type.HASHED;
    if (neighbors == null || neighbors.isEmpty()) {
        log.warn("createGroupsFromDestinationSet: needs at least one neighbor" + "to create group in dev:{} for ds: {} with next-hops {}", deviceId, ds, neighbors);
        return;
    }
    NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(nextId).withType(type).fromApp(appId);
    if (meta != null) {
        // Udate the meta VLAN id to match the PW transport label
        if (!popVlanInHashGroup(ds)) {
            TrafficSelector newMeta = DefaultTrafficSelector.builder(meta).matchVlanId(srManager.getPwTransportVlan()).build();
            meta = newMeta;
        }
        nextObjBuilder.withMeta(meta);
    }
    // create treatment buckets for each neighbor for each dst Device
    // except in the special case where we only want to pick a single
    // neighbor/port for a simple nextObj
    boolean foundSingleNeighbor = false;
    boolean treatmentAdded = false;
    Map<DeviceId, Set<DeviceId>> dstNextHops = new ConcurrentHashMap<>();
    for (DeviceId dst : ds.getDestinationSwitches()) {
        Set<DeviceId> nextHops = neighbors.get(dst);
        if (nextHops == null || nextHops.isEmpty()) {
            continue;
        }
        if (foundSingleNeighbor) {
            break;
        }
        for (DeviceId neighborId : nextHops) {
            if (devicePortMap.get(neighborId) == null) {
                log.warn("Neighbor {} is not in the port map yet for dev:{}", neighborId, deviceId);
                return;
            } else if (devicePortMap.get(neighborId).isEmpty()) {
                log.warn("There are no ports for " + "the Device {} in the port map yet", neighborId);
                return;
            }
            MacAddress neighborMac;
            try {
                neighborMac = deviceConfig.getDeviceMac(neighborId);
            } catch (DeviceConfigNotFoundException e) {
                log.warn(e.getMessage() + " Aborting createGroupsFromDestinationset.");
                return;
            }
            // For each port to the neighbor, we create a new treatment
            Set<PortNumber> neighborPorts = devicePortMap.get(neighborId);
            // In this case we need a SIMPLE nextObj. We randomly pick a port
            if (simple) {
                int size = devicePortMap.get(neighborId).size();
                int index = RandomUtils.nextInt(0, size);
                neighborPorts = Collections.singleton(Iterables.get(devicePortMap.get(neighborId), index));
                foundSingleNeighbor = true;
            }
            for (PortNumber sp : neighborPorts) {
                TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
                tBuilder.setEthDst(neighborMac).setEthSrc(nodeMacAddr);
                int edgeLabel = ds.getEdgeLabel(dst);
                if (edgeLabel != DestinationSet.NO_EDGE_LABEL) {
                    if (simple) {
                        // swap label case
                        tBuilder.setMpls(MplsLabel.mplsLabel(edgeLabel));
                    } else {
                        // ecmp with label push case
                        tBuilder.pushMpls().copyTtlOut().setMpls(MplsLabel.mplsLabel(edgeLabel));
                    }
                }
                // Set VLAN ID for PW transport. Otherwise pop vlan
                if (!popVlanInHashGroup(ds)) {
                    tBuilder.setVlanId(srManager.getPwTransportVlan());
                } else {
                    tBuilder.popVlan();
                }
                tBuilder.setOutput(sp);
                nextObjBuilder.addTreatment(tBuilder.build());
                treatmentAdded = true;
                // update store
                Set<DeviceId> existingNeighbors = dstNextHops.get(dst);
                if (existingNeighbors == null) {
                    existingNeighbors = new HashSet<>();
                }
                existingNeighbors.add(neighborId);
                dstNextHops.put(dst, existingNeighbors);
                log.debug("creating treatment for port/label {}/{} in next:{}", sp, edgeLabel, nextId);
            }
            if (foundSingleNeighbor) {
                break;
            }
        }
    }
    if (!treatmentAdded) {
        log.warn("Could not createGroup from DestinationSet {} without any" + "next hops {}", ds, neighbors);
        return;
    }
    ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("createGroupsFromDestinationSet installed " + "NextObj {} on {}", nextId, deviceId), (objective, error) -> {
        log.warn("createGroupsFromDestinationSet failed to install NextObj {} on {}: {}", nextId, deviceId, error);
        srManager.invalidateNextObj(objective.id());
    });
    NextObjective nextObj = nextObjBuilder.add(context);
    log.debug(".. createGroupsFromDestinationSet: Submitted " + "next objective {} in device {}", nextId, deviceId);
    flowObjectiveService.next(deviceId, nextObj);
    // update store
    dsNextObjStore.put(new DestinationSetNextObjectiveStoreKey(deviceId, ds), new NextNeighbors(dstNextHops, nextId));
}
Also used : DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) NextObjective(org.onosproject.net.flowobjective.NextObjective) Set(java.util.Set) HashSet(java.util.HashSet) DeviceId(org.onosproject.net.DeviceId) MacAddress(org.onlab.packet.MacAddress) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) ConnectPoint(org.onosproject.net.ConnectPoint) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) DestinationSetNextObjectiveStoreKey(org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey) 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) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PortNumber(org.onosproject.net.PortNumber)

Example 14 with PortNumber

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

the class DefaultGroupHandler method updateAllPortsToNextHop.

/**
 * Adds or removes buckets for all ports to a set of neighbor devices. Caller
 * needs to ensure that the  given neighbors are all next hops towards the
 * same destination (represented by the given edgeLabel).
 *
 * @param neighbors set of neighbor device ids
 * @param edgeLabel MPLS label to use in buckets
 * @param nextId the nextObjective to change
 * @param popVlan this hash group bucket shuold includes a popVlan action
 * @param revoke true if buckets need to be removed, false if they need to
 *          be added
 * @return true if successful in adding or removing buckets for all ports
 *                  to the neighbors
 */
private boolean updateAllPortsToNextHop(Set<DeviceId> neighbors, int edgeLabel, int nextId, boolean popVlan, boolean revoke) {
    for (DeviceId neighbor : neighbors) {
        MacAddress neighborMac;
        try {
            neighborMac = deviceConfig.getDeviceMac(neighbor);
        } catch (DeviceConfigNotFoundException e) {
            log.warn(e.getMessage() + " Aborting updateAllPortsToNextHop" + " for nextId:" + nextId);
            return false;
        }
        Collection<PortNumber> portsToNeighbor = devicePortMap.get(neighbor);
        if (portsToNeighbor == null || portsToNeighbor.isEmpty()) {
            log.warn("No ports found in dev:{} for neighbor:{} .. cannot " + "updateAllPortsToNextHop for nextId: {}", deviceId, neighbor, nextId);
            return false;
        }
        List<PortLabel> pl = Lists.newArrayList();
        portsToNeighbor.forEach(p -> pl.add(new PortLabel(p, edgeLabel, popVlan)));
        if (revoke) {
            log.debug("updateAllPortsToNextHops in device {}: Removing Bucket(s) " + "with Port/Label:{} to next object id {}", deviceId, pl, nextId);
            removeFromHashedNextObjective(pl, neighborMac, nextId);
        } else {
            log.debug("fixHashGroup in device {}: Adding Bucket(s) " + "with Port/Label: {} to next object id {}", deviceId, pl, nextId);
            addToHashedNextObjective(pl, neighborMac, nextId);
        }
    }
    return true;
}
Also used : DeviceId(org.onosproject.net.DeviceId) MacAddress(org.onlab.packet.MacAddress) PortNumber(org.onosproject.net.PortNumber) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException)

Example 15 with PortNumber

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

the class PolicyGroupHandler method createPolicyGroupChain.

/**
 * Creates policy group chain.
 *
 * @param id unique identifier associated with the policy group
 * @param params a list of policy group params
 * @return policy group identifier
 */
public PolicyGroupIdentifier createPolicyGroupChain(String id, List<PolicyGroupParams> params) {
    List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
    for (PolicyGroupParams param : params) {
        List<PortNumber> ports = param.getPorts();
        if (ports == null) {
            log.warn("createPolicyGroupChain in sw {} with wrong " + "input parameters", deviceId);
            return null;
        }
        int labelStackSize = (param.getLabelStack() != null) ? param.getLabelStack().size() : 0;
        if (labelStackSize > 1) {
            for (PortNumber sp : ports) {
                PolicyGroupIdentifier previousGroupkey = null;
                DeviceId neighbor = portDeviceMap.get(sp);
                for (int idx = 0; idx < param.getLabelStack().size(); idx++) {
                    int label = param.getLabelStack().get(idx);
                    if (idx == (labelStackSize - 1)) {
                        // Innermost Group
                        GroupBucketIdentifier bucketId = new GroupBucketIdentifier(label, previousGroupkey);
                        bucketIds.add(bucketId);
                    } else if (idx == 0) {
                        // Outermost Group
                        List<GroupBucket> outBuckets = new ArrayList<>();
                        GroupBucketIdentifier bucketId = new GroupBucketIdentifier(label, sp);
                        PolicyGroupIdentifier key = new PolicyGroupIdentifier(id, Collections.singletonList(param), Collections.singletonList(bucketId));
                        MacAddress neighborEthDst;
                        try {
                            neighborEthDst = deviceConfig.getDeviceMac(neighbor);
                        } catch (DeviceConfigNotFoundException e) {
                            log.warn(e.getMessage() + " Skipping createPolicyGroupChain for this label.");
                            continue;
                        }
                        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
                        tBuilder.setOutput(sp).setEthDst(neighborEthDst).setEthSrc(nodeMacAddr).pushMpls().setMpls(MplsLabel.mplsLabel(label));
                        /*outBuckets.add(DefaultGroupBucket.
                                           createSelectGroupBucket(tBuilder.build()));
                            GroupDescription desc = new
                                    DefaultGroupDescription(deviceId,
                                                            GroupDescription.Type.INDIRECT,
                                                            new GroupBuckets(outBuckets));
                            //TODO: BoS*/
                        previousGroupkey = key;
                    // groupService.addGroup(desc);
                    // TODO: Use nextObjective APIs here
                    } else {
                        // Intermediate Groups
                        GroupBucketIdentifier bucketId = new GroupBucketIdentifier(label, previousGroupkey);
                        PolicyGroupIdentifier key = new PolicyGroupIdentifier(id, Collections.singletonList(param), Collections.singletonList(bucketId));
                        // Add to group dependency list
                        dependentGroups.put(previousGroupkey, key);
                        previousGroupkey = key;
                    }
                }
            }
        } else {
            int label = -1;
            if (labelStackSize == 1) {
                label = param.getLabelStack().get(0);
            }
            for (PortNumber sp : ports) {
                GroupBucketIdentifier bucketId = new GroupBucketIdentifier(label, sp);
                bucketIds.add(bucketId);
            }
        }
    }
    PolicyGroupIdentifier innermostGroupkey = null;
    if (!bucketIds.isEmpty()) {
        innermostGroupkey = new PolicyGroupIdentifier(id, params, bucketIds);
        // Add to group dependency list
        boolean fullyResolved = true;
        for (GroupBucketIdentifier bucketId : bucketIds) {
            if (bucketId.type() == BucketOutputType.GROUP) {
                dependentGroups.put(bucketId.outGroup(), innermostGroupkey);
                fullyResolved = false;
            }
        }
        if (fullyResolved) {
            List<GroupBucket> outBuckets = new ArrayList<>();
            for (GroupBucketIdentifier bucketId : bucketIds) {
                DeviceId neighbor = portDeviceMap.get(bucketId.outPort());
                MacAddress neighborEthDst;
                try {
                    neighborEthDst = deviceConfig.getDeviceMac(neighbor);
                } catch (DeviceConfigNotFoundException e) {
                    log.warn(e.getMessage() + " Skipping createPolicyGroupChain for this bucketId.");
                    continue;
                }
                TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
                tBuilder.setOutput(bucketId.outPort()).setEthDst(neighborEthDst).setEthSrc(nodeMacAddr);
                if (bucketId.label() != DestinationSet.NO_EDGE_LABEL) {
                    tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(bucketId.label()));
                }
            // TODO: BoS
            /*outBuckets.add(DefaultGroupBucket.
                                   createSelectGroupBucket(tBuilder.build()));*/
            }
        /*GroupDescription desc = new
                        DefaultGroupDescription(deviceId,
                                                GroupDescription.Type.SELECT,
                                                new GroupBuckets(outBuckets));
                groupService.addGroup(desc);*/
        // TODO: Use nextObjective APIs here
        }
    }
    return innermostGroupkey;
}
Also used : DeviceId(org.onosproject.net.DeviceId) ArrayList(java.util.ArrayList) MacAddress(org.onlab.packet.MacAddress) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) GroupBucket(org.onosproject.net.group.GroupBucket) ArrayList(java.util.ArrayList) List(java.util.List) PortNumber(org.onosproject.net.PortNumber)

Aggregations

PortNumber (org.onosproject.net.PortNumber)336 DeviceId (org.onosproject.net.DeviceId)136 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)109 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)103 ConnectPoint (org.onosproject.net.ConnectPoint)82 TrafficSelector (org.onosproject.net.flow.TrafficSelector)80 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)74 Port (org.onosproject.net.Port)67 ArrayList (java.util.ArrayList)64 Set (java.util.Set)64 List (java.util.List)59 Logger (org.slf4j.Logger)58 Collectors (java.util.stream.Collectors)51 DeviceService (org.onosproject.net.device.DeviceService)49 VlanId (org.onlab.packet.VlanId)42 MacAddress (org.onlab.packet.MacAddress)41 Device (org.onosproject.net.Device)40 FlowRule (org.onosproject.net.flow.FlowRule)40 Optional (java.util.Optional)39 Sets (com.google.common.collect.Sets)35