use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class McastHandler method getSinks.
/**
* Gets sink(s) of given multicast group.
*
* @param mcastIp multicast IP
* @return set of connect point or empty set if not found
*/
private Set<ConnectPoint> getSinks(IpAddress mcastIp, DeviceId device, ConnectPoint source) {
McastPathStoreKey pathStoreKey = new McastPathStoreKey(mcastIp, source);
Collection<? extends List<Link>> storedPaths = Versioned.valueOrElse(mcastPathStore.get(pathStoreKey), Lists.newArrayList());
VlanId assignedVlan = mcastUtils.assignedVlan(device.equals(source.deviceId()) ? source : null);
McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, device, assignedVlan);
NextObjective nextObjective = Versioned.valueOrNull(mcastNextObjStore.get(mcastStoreKey));
ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
if (nextObjective != null) {
Set<PortNumber> outputPorts = mcastUtils.getPorts(nextObjective.next());
outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(device, portNumber)));
}
Set<ConnectPoint> egressCp = cpBuilder.build();
return egressCp.stream().filter(connectPoint -> !mcastUtils.isInfraPort(connectPoint, storedPaths)).collect(Collectors.toSet());
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class McastHandler method isSinkForGroup.
/**
* Verify if a given connect point is sink for this group.
*
* @param mcastIp group address
* @param connectPoint connect point to be verified
* @param source source connect point
* @return true if the connect point is sink of the group
*/
private boolean isSinkForGroup(IpAddress mcastIp, ConnectPoint connectPoint, ConnectPoint source) {
VlanId assignedVlan = mcastUtils.assignedVlan(connectPoint.deviceId().equals(source.deviceId()) ? source : null);
McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, connectPoint.deviceId(), assignedVlan);
if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
return false;
}
NextObjective mcastNext = mcastNextObjStore.get(mcastStoreKey).value();
return mcastUtils.getPorts(mcastNext.next()).contains(connectPoint.port());
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class McastHandler method removePortFromDevice.
/**
* Removes a port from given multicast group on given device.
* This involves the update of L3 multicast group and multicast routing
* table entry.
*
* @param deviceId device ID
* @param port port to be added
* @param mcastIp multicast group
* @param assignedVlan assigned VLAN ID
* @return true if this is the last sink on this device
*/
private boolean removePortFromDevice(DeviceId deviceId, PortNumber port, IpAddress mcastIp, VlanId assignedVlan) {
// TODO trace
log.info("Removing {} on {}/{} and vlan {}", mcastIp, deviceId, port, assignedVlan);
McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId, assignedVlan);
// This device is not serving this multicast group
if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
return true;
}
NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
Set<PortNumber> existingPorts = mcastUtils.getPorts(nextObj.next());
// This port does not serve this multicast group
if (!existingPorts.contains(port)) {
if (!existingPorts.isEmpty()) {
log.debug("{} is not serving {} on port {}. Abort.", deviceId, mcastIp, port);
return false;
}
return true;
}
// Copy and modify the ImmutableSet
existingPorts = Sets.newHashSet(existingPorts);
existingPorts.remove(port);
NextObjective newNextObj;
ObjectiveContext context;
ForwardingObjective fwdObj;
if (existingPorts.isEmpty()) {
context = new DefaultObjectiveContext((objective) -> log.debug("Successfully remove {} on {}/{}, vlan {}", mcastIp, deviceId, port.toLong(), assignedVlan), (objective, error) -> log.warn("Failed to remove {} on {}/{}, vlan {}: {}", mcastIp, deviceId, port.toLong(), assignedVlan, error));
fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
if (!srManager.deviceConfiguration().isConfigured(deviceId)) {
log.debug("skip forward flowobjective removal for device: {}", deviceId);
} else {
srManager.flowObjectiveService.forward(deviceId, fwdObj);
}
mcastNextObjStore.remove(mcastStoreKey);
} else {
// Here we store the next objective with the remaining port
newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan, existingPorts, nextObj.id()).removeFromExisting();
mcastNextObjStore.put(mcastStoreKey, newNextObj);
// Let's modify the next objective removing the bucket
newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan, ImmutableSet.of(port), nextObj.id()).removeFromExisting();
if (!srManager.deviceConfiguration().isConfigured(deviceId)) {
log.debug("skip next flowobjective update for device: {}", deviceId);
} else {
// no need to update the flow here since we have updated the next objective + group
// the existing flow will keep pointing to the updated nextobj
srManager.flowObjectiveService.next(deviceId, newNextObj);
}
}
return existingPorts.isEmpty();
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class DefaultGroupHandler method updateL3UcastGroupBucket.
/**
* Updates the next objective for the given nextId .
*
* @param hostMac mac of host for which Next obj is to be updated.
* @param hostVlanId vlan of host for which Next obj is to be updated.
* @param port port with which to update the Next Obj.
* @param nextId of Next Obj which needs to be updated.
*/
public void updateL3UcastGroupBucket(MacAddress hostMac, VlanId hostVlanId, PortNumber port, int nextId) {
MacAddress deviceMac;
try {
deviceMac = deviceConfig.getDeviceMac(deviceId);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " in updateL3UcastGroupBucket");
return;
}
ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
VlanId untaggedVlan = srManager.interfaceService.getUntaggedVlanId(connectPoint);
Set<VlanId> taggedVlans = srManager.interfaceService.getTaggedVlanId(connectPoint);
VlanId nativeVlan = srManager.interfaceService.getNativeVlanId(connectPoint);
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder().deferred().setEthDst(hostMac).setEthSrc(deviceMac).setOutput(port);
if (taggedVlans.contains(hostVlanId)) {
mbuilder.matchVlanId(hostVlanId);
tbuilder.setVlanId(hostVlanId);
} else if (hostVlanId.equals(VlanId.NONE)) {
if (untaggedVlan != null) {
mbuilder.matchVlanId(untaggedVlan);
tbuilder.popVlan();
} else if (nativeVlan != null) {
mbuilder.matchVlanId(nativeVlan);
tbuilder.popVlan();
} else {
log.warn("Untagged nexthop {}/{} is not allowed on {} without untagged or native vlan", hostMac, hostVlanId, connectPoint);
return;
}
} else {
log.warn("Tagged nexthop {}/{} is not allowed on {} without VLAN listed" + " in tagged vlan", hostMac, hostVlanId, connectPoint);
return;
}
log.debug(" update L3Ucast : deviceMac {}, port {}, host {}/{}, nextid {}, Treatment {} Meta {}", deviceMac, port, hostMac, hostVlanId, nextId, tbuilder.build(), mbuilder.build());
NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(nextId).withType(NextObjective.Type.SIMPLE).fromApp(appId).addTreatment(tbuilder.build()).withMeta(mbuilder.build());
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug(" NextId {} successfully updated host {} vlan {} with port {}", nextId, hostMac, hostVlanId, port), (objective, error) -> {
log.warn(" NextId {} failed to update host {} vlan {} with port {}, error : {}", nextId, hostMac, hostVlanId, port, error);
srManager.invalidateNextObj(objective.id());
});
NextObjective nextObj = nextObjBuilder.modify(context);
flowObjectiveService.next(deviceId, nextObj);
}
use of org.onlab.packet.VlanId in project trellis-control by opennetworkinglab.
the class RouteHandler method processRouteRemovedInternal.
private void processRouteRemovedInternal(Collection<ResolvedRoute> routes) {
if (!isReady()) {
log.info("System is not ready. Skip removing route for {}", routes);
return;
}
log.info("processRouteRemovedInternal. routes={}", routes);
Set<IpPrefix> allPrefixes = Sets.newHashSet();
routes.forEach(route -> {
allPrefixes.add(route.prefix());
});
log.debug("RouteRemoved. revokeSubnet {}", allPrefixes);
// FIXME remove routes more precisely by memorizing the old locations
srManager.defaultRoutingHandler.revokeSubnet(allPrefixes, null);
routes.forEach(route -> {
IpPrefix prefix = route.prefix();
MacAddress nextHopMac = route.nextHopMac();
VlanId nextHopVlan = route.nextHopVlan();
Set<ConnectPoint> locations = srManager.nextHopLocations(route);
locations.forEach(location -> {
log.debug("RouteRemoved. removeSubnet {}, {}", location, prefix);
srManager.deviceConfiguration.removeSubnet(location, prefix);
// We don't need to call revokeRoute again since revokeSubnet will remove the prefix
// from all devices, including the ones that next hop attaches to.
// revokeSubnet will also remove flow on the pair device (if exist) pointing to current location.
});
});
}
Aggregations