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);
}
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);
}
}
}
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));
}
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;
}
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;
}
Aggregations