use of org.onosproject.net.flowobjective.ObjectiveContext in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method updateFwdObj.
/**
* Update Forwarding objective for each host and IP address connected to given port.
* And create corresponding Simple Next objective if it does not exist.
* Applied only when populating Forwarding objective
* @param deviceId switch ID to set the rule
* @param portNumber port number
* @param prefix IP prefix of the route
* @param hostMac MAC address of the next hop
* @param vlanId Vlan ID of the port
* @param popVlan true to pop vlan tag in TrafficTreatment
* @param install true to populate the forwarding objective, false to revoke
* @return a completable future that completes when the fwdobj completes. In case of removal,
* the completable future completes when also the nextobj completes.
*/
CompletableFuture<Objective> updateFwdObj(DeviceId deviceId, PortNumber portNumber, IpPrefix prefix, MacAddress hostMac, VlanId vlanId, boolean popVlan, boolean install) {
ForwardingObjective.Builder fob;
TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(prefix);
MacAddress deviceMac;
try {
deviceMac = config.getDeviceMac(deviceId);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Aborting updateFwdObj.");
return CompletableFuture.completedFuture(null);
}
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
tbuilder.deferred().setEthDst(hostMac).setEthSrc(deviceMac).setOutput(portNumber);
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
if (!popVlan) {
mbuilder.matchVlanId(vlanId);
tbuilder.setVlanId(vlanId);
} else {
mbuilder.matchVlanId(vlanId);
tbuilder.popVlan();
}
// if the objective is to revoke an existing rule, and for some reason
// the next-objective does not exist, then a new one should not be created
int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNumber, tbuilder.build(), mbuilder.build(), install);
CompletableFuture<Objective> future = new CompletableFuture<>();
if (portNextObjId == -1) {
// Warning log will come from getPortNextObjective method
return CompletableFuture.completedFuture(null);
}
fob = DefaultForwardingObjective.builder().withSelector(sbuilder.build()).nextStep(portNextObjId).fromApp(srManager.appId).makePermanent().withPriority(getPriorityFromPrefix(prefix)).withFlag(ForwardingObjective.Flag.SPECIFIC);
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
log.debug("IP rule for route {} {}", prefix, install ? "installed" : "revoked");
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to {} IP rule for route {}: {}", install ? "install" : "revoke", prefix, error);
future.complete(null);
});
srManager.flowObjectiveService.forward(deviceId, install ? fob.add(context) : fob.remove(context));
if (!install) {
if (!srManager.getVlanPortMap(deviceId).containsKey(vlanId) || !srManager.getVlanPortMap(deviceId).get(vlanId).contains(portNumber)) {
DefaultGroupHandler grpHandler = srManager.getGroupHandler(deviceId);
if (grpHandler == null) {
log.warn("updateFwdObj: groupHandler for device {} not found", deviceId);
} else {
// Before moving forward we have to be sure flow has been removed;
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
log.warn("Exception caught when executing IP rule removal for route {}", prefix);
}
// Flow future has been already consumed (normally or exceptionally)
return grpHandler.removeGroupFromPort(portNumber, tbuilder.build(), mbuilder.build());
}
}
}
return future;
}
use of org.onosproject.net.flowobjective.ObjectiveContext in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method updateBridging.
/**
* Populate or revoke a bridging rule on given deviceId that matches given vlanId,
* and hostMAC connected to given port, and output to given port only when
* vlan information is valid.
*
* @param deviceId device ID that host attaches to
* @param portNum port number that host attaches to
* @param hostMac mac address of the host connected to the switch port
* @param vlanId Vlan ID configured on the switch port
* @param popVlan true to pop Vlan tag at TrafficTreatment, false otherwise
* @param install true to populate the objective, false to revoke
* @return a completable future that completes when the update of the bridging rule completes
*/
// TODO Refactor. There are a lot of duplications between this method, populateBridging,
// revokeBridging and bridgingFwdObjBuilder.
CompletableFuture<Objective> updateBridging(DeviceId deviceId, PortNumber portNum, MacAddress hostMac, VlanId vlanId, boolean popVlan, boolean install) {
// Create host selector
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
sbuilder.matchEthDst(hostMac);
// Create host meta
TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
sbuilder.matchVlanId(vlanId);
mbuilder.matchVlanId(vlanId);
// Create host treatment
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
tbuilder.immediate().setOutput(portNum);
if (popVlan) {
tbuilder.immediate().popVlan();
}
int portNextObjId = srManager.getPortNextObjectiveId(deviceId, portNum, tbuilder.build(), mbuilder.build(), install);
CompletableFuture<Objective> future = new CompletableFuture<>();
if (portNextObjId != -1) {
ForwardingObjective.Builder fob = DefaultForwardingObjective.builder().withFlag(ForwardingObjective.Flag.SPECIFIC).withSelector(sbuilder.build()).nextStep(portNextObjId).withPriority(100).fromApp(srManager.appId).makePermanent();
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
log.debug("Brigding rule for {}/{} {}", hostMac, vlanId, install ? "populated" : "revoked");
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to {} bridging rule for {}/{}: {}", install ? "populate" : "revoke", hostMac, vlanId, error);
future.complete(null);
});
srManager.flowObjectiveService.forward(deviceId, install ? fob.add(context) : fob.remove(context));
} else {
log.warn("Failed to retrieve next objective for {}/{}", hostMac, vlanId);
return CompletableFuture.completedFuture(null);
}
return future;
}
use of org.onosproject.net.flowobjective.ObjectiveContext in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method handleMpls.
/**
* Differentiates between popping and swapping labels when building an MPLS
* forwarding objective.
*
* @param targetSwId the target sw
* @param destSwId the destination sw
* @param nextHops the set of next hops
* @param segmentId the segmentId to match representing the destination
* switch
* @param routerIp the router ip representing the destination switch
* @return a collection of fwdobjective
*/
private Collection<ForwardingObjective> handleMpls(DeviceId targetSwId, DeviceId destSwId, Set<DeviceId> nextHops, int segmentId, IpAddress routerIp, boolean isMplsBos) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
List<ForwardingObjective.Builder> fwdObjBuilders = Lists.newArrayList();
// For the transport of Pwaas we can use two or three MPLS label
sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId));
sbuilder.matchMplsBos(isMplsBos);
TrafficSelector selector = sbuilder.build();
// setup metadata to pass to nextObjective - indicate the vlan on egress
// if needed by the switch pipeline. Since mpls next-hops are always to
// other neighboring routers, there is no subnet assigned on those ports.
TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector);
metabuilder.matchVlanId(srManager.getDefaultInternalVlan());
if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
// If the next hop is the destination router for the segment, do pop
log.debug("populateMplsRule: Installing MPLS forwarding objective for " + "label {} in switch {} with pop to next-hops {}", segmentId, targetSwId, nextHops);
ForwardingObjective.Builder fwdObjNoBosBuilder = getMplsForwardingObjective(targetSwId, nextHops, true, isMplsBos, metabuilder.build(), routerIp, segmentId, destSwId);
// Error case, we cannot handle, exit.
if (fwdObjNoBosBuilder == null) {
return Collections.emptyList();
}
fwdObjBuilders.add(fwdObjNoBosBuilder);
} else {
// next hop is not destination, irrespective of the number of next
// hops (1 or more) -- SR CONTINUE case (swap with self)
log.debug("Installing MPLS forwarding objective for " + "label {} in switch {} without pop to next-hops {}", segmentId, targetSwId, nextHops);
ForwardingObjective.Builder fwdObjNoBosBuilder = getMplsForwardingObjective(targetSwId, nextHops, false, isMplsBos, metabuilder.build(), routerIp, segmentId, destSwId);
// Error case, we cannot handle, exit.
if (fwdObjNoBosBuilder == null) {
return Collections.emptyList();
}
fwdObjBuilders.add(fwdObjNoBosBuilder);
}
List<ForwardingObjective> fwdObjs = Lists.newArrayList();
// We add the final property to the fwdObjs.
for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId).makePermanent()).withSelector(selector).withPriority(SegmentRoutingService.DEFAULT_PRIORITY)).withFlag(ForwardingObjective.Flag.SPECIFIC);
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("MPLS rule {} for SID {} populated in dev:{} ", objective.id(), segmentId, targetSwId), (objective, error) -> log.warn("Failed to populate MPLS rule {} for SID {}: {} in dev:{}", objective.id(), segmentId, error, targetSwId));
ForwardingObjective fob = fwdObjBuilder.add(context);
fwdObjs.add(fob);
}
return fwdObjs;
}
use of org.onosproject.net.flowobjective.ObjectiveContext in project trellis-control by opennetworkinglab.
the class AppConfigHandler method revokeVRouter.
private void revokeVRouter(DeviceId deviceId, Set<MacAddress> pendingRemove) {
if (!isEdge(deviceId)) {
return;
}
getVRouterFlowObjBuilders(pendingRemove).forEach(foBuilder -> {
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("vRouterMac filter for {} revoked", pendingRemove), (objective, error) -> log.warn("Failed to revoke vRouterMac filter for {}: {}", pendingRemove, error));
srManager.flowObjectiveService.filter(deviceId, foBuilder.remove(context));
});
}
Aggregations