use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class PolicyManager method removeTrafficMatchInDevice.
// Traffic match removal in a device
private void removeTrafficMatchInDevice(DeviceId deviceId, TrafficMatch trafficMatch) {
if (log.isDebugEnabled()) {
log.debug("Removing traffic match {} associated to policy {}", trafficMatch.trafficMatchId(), trafficMatch.policyId());
}
TrafficMatchKey trafficMatchKey = new TrafficMatchKey(deviceId, trafficMatch.trafficMatchId());
Operation operation = Versioned.valueOrNull(operations.get(trafficMatchKey.toString()));
if (operation == null || operation.objectiveOperation() == null) {
log.warn("There are no ops associated with {}", trafficMatchKey);
operation = Operation.builder().isDone(true).isInstall(false).trafficMatch(trafficMatch).build();
operations.put(trafficMatchKey.toString(), operation);
} else if (!operation.isInstall()) {
if (log.isDebugEnabled()) {
log.debug("There is already an uninstall operation for traffic match {} associated to policy {}" + " for device {}", trafficMatch.trafficMatchId(), trafficMatch.policyId(), deviceId);
}
} else {
ForwardingObjective oldObj = (ForwardingObjective) operation.objectiveOperation();
operation = Operation.builder(operation).isInstall(false).build();
operations.put(trafficMatchKey.toString(), operation);
ForwardingObjective.Builder builder = DefaultForwardingObjective.builder(oldObj);
CompletableFuture<Objective> future = new CompletableFuture<>();
if (log.isDebugEnabled()) {
log.debug("Removing forwarding objectives for dev: {}", deviceId);
}
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
if (log.isDebugEnabled()) {
log.debug("Forwarding objective for policy {} removed", trafficMatch.policyId());
}
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to remove forwarding objective for policy {}: {}", trafficMatch.policyId(), error);
future.complete(null);
});
ForwardingObjective serializableObjective = builder.remove();
flowObjectiveService.forward(deviceId, builder.remove(context));
future.whenComplete((objective, ex) -> {
if (ex != null) {
log.error("Exception removing forwarding objective", ex);
} else if (objective != null) {
operations.computeIfPresent(trafficMatchKey.toString(), (k, v) -> {
if (!v.isDone() && !v.isInstall()) {
v.isDone(true);
v.objectiveOperation(serializableObjective);
}
return v;
});
}
});
}
}
use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class PolicyManager method installTrafficMatchToDevice.
// Orchestrate traffic match installation according to the type
private void installTrafficMatchToDevice(DeviceId deviceId, TrafficMatch trafficMatch) {
if (log.isDebugEnabled()) {
log.debug("Installing traffic match {} associated to policy {}", trafficMatch.trafficMatchId(), trafficMatch.policyId());
}
TrafficMatchKey trafficMatchKey = new TrafficMatchKey(deviceId, trafficMatch.trafficMatchId());
Operation oldTrafficOperation = Versioned.valueOrNull(operations.get(trafficMatchKey.toString()));
if (oldTrafficOperation != null && oldTrafficOperation.isInstall()) {
if (trafficMatch.equals(oldTrafficOperation.trafficMatch().orElse(null))) {
if (log.isDebugEnabled()) {
log.debug("There is already an install operation for traffic match {} associated to policy {} " + "for device {}", trafficMatch.trafficMatchId(), trafficMatch.policyId(), deviceId);
}
// If we add or submit a trafficMatch multiple times
// We skip the installation and update the state directly
updateTrafficMatch(trafficMatch, true);
return;
} else {
if (log.isDebugEnabled()) {
log.debug("Starts updating traffic match {} associated to policy {} " + "for device {}", trafficMatch.trafficMatchId(), trafficMatch.policyId(), deviceId);
}
}
}
// For the DROP policy we need to set an ACL drop in the fwd objective. The other
// policies require to retrieve the next Id and sets the next step.
PolicyKey policyKey = new PolicyKey(deviceId, trafficMatch.policyId());
Operation policyOperation = Versioned.valueOrNull(operations.get(policyKey.toString()));
if (policyOperation == null || !policyOperation.isDone() || !policyOperation.isInstall() || policyOperation.policy().isEmpty() || (policyOperation.policy().get().policyType() == PolicyType.REDIRECT && policyOperation.objectiveOperation() == null)) {
log.info("Deferring traffic match {} installation on device {}. Policy {} not yet installed", trafficMatch.trafficMatchId(), deviceId, trafficMatch.policyId());
return;
}
// Updates the store and then send the versatile fwd objective to the pipeliner
Operation newTrafficOperation = Operation.builder().isInstall(true).trafficMatch(trafficMatch).build();
operations.put(trafficMatchKey.toString(), newTrafficOperation);
Policy policy = policyOperation.policy().get();
ForwardingObjective.Builder builder = trafficMatchFwdObjective(trafficMatch, policy.policyType());
if (policy.policyType() == PolicyType.DROP) {
// Firstly builds the fwd objective with the wipeDeferred action.
TrafficTreatment dropTreatment = DefaultTrafficTreatment.builder().wipeDeferred().build();
builder.withTreatment(dropTreatment);
} else if (policy.policyType() == PolicyType.REDIRECT) {
// Here we need to set only the next step
builder.nextStep(policyOperation.objectiveOperation().id());
}
// Once, the fwd objective has completed its execution, we update the policiesOps map
CompletableFuture<Objective> addNewFuture = new CompletableFuture<>();
CompletableFuture<Objective> removeOldFuture = new CompletableFuture<>();
if (log.isDebugEnabled()) {
log.debug("Installing forwarding objective for dev: {}", deviceId);
}
ObjectiveContext addNewContext = new DefaultObjectiveContext((objective) -> {
if (log.isDebugEnabled()) {
log.debug("Forwarding objective for policy {} installed", trafficMatch.policyId());
}
addNewFuture.complete(objective);
}, (objective, error) -> {
log.warn("Failed to install forwarding objective for policy {}: {}", trafficMatch.policyId(), error);
addNewFuture.complete(null);
});
ObjectiveContext removeOldContext = new DefaultObjectiveContext((objective) -> {
if (log.isDebugEnabled()) {
log.debug("Old forwarding objective for policy {} removed, update finished", trafficMatch.policyId());
}
removeOldFuture.complete(objective);
}, (objective, error) -> {
log.warn("Failed to remove old forwarding objective for policy {}: {}", trafficMatch.policyId(), error);
removeOldFuture.complete(null);
});
// Context is not serializable
ForwardingObjective serializableObjective = builder.add();
flowObjectiveService.forward(deviceId, builder.add(addNewContext));
addNewFuture.whenComplete((objective, ex) -> {
if (ex != null) {
log.error("Exception installing forwarding objective", ex);
} else if (objective != null) {
// base on priority, selector and metadata change
if (oldTrafficOperation != null && oldTrafficOperation.objectiveOperation() != null && oldTrafficOperation.isInstall() && (oldTrafficOperation.objectiveOperation().priority() != serializableObjective.priority() || !((ForwardingObjective) oldTrafficOperation.objectiveOperation()).selector().equals(serializableObjective.selector()) || !((ForwardingObjective) oldTrafficOperation.objectiveOperation()).meta().equals(serializableObjective.meta()))) {
ForwardingObjective oldFwdObj = (ForwardingObjective) oldTrafficOperation.objectiveOperation();
ForwardingObjective.Builder oldBuilder = DefaultForwardingObjective.builder(oldFwdObj);
flowObjectiveService.forward(deviceId, oldBuilder.remove(removeOldContext));
} else {
operations.computeIfPresent(trafficMatchKey.toString(), (k, v) -> {
if (!v.isDone() && v.isInstall()) {
v.isDone(true);
v.objectiveOperation(serializableObjective);
}
return v;
});
}
}
});
removeOldFuture.whenComplete((objective, ex) -> {
if (ex != null) {
log.error("Exception removing old forwarding objective", ex);
} else if (objective != null) {
operations.computeIfPresent(trafficMatchKey.toString(), (k, v) -> {
if (!v.isDone() && v.isInstall()) {
v.isDone(true);
v.objectiveOperation(serializableObjective);
}
return v;
});
}
});
}
use of org.onosproject.net.flowobjective.Objective 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;
}
use of org.onosproject.net.flowobjective.Objective in project onos by opennetworkinglab.
the class VirtualNetworkPacketManager method pushRule.
/**
* Pushes packet intercept flow rules to the device.
*
* @param device the device to push the rules to
* @param request the packet request
*/
private void pushRule(Device device, PacketRequest request) {
if (!device.type().equals(Device.Type.VIRTUAL)) {
return;
}
ForwardingObjective forwarding = createBuilder(request).add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install packet request {} to {}: {}", request, device.id(), error);
}
});
objectiveService.forward(device.id(), forwarding);
}
use of org.onosproject.net.flowobjective.Objective in project onos by opennetworkinglab.
the class InOrderFlowObjectiveManager method dequeue.
/**
* Dequeue flow objective. Execute the next flow objective in the queue, if any.
*
* @param deviceId Device ID
* @param obj Flow objective
* @param error ObjectiveError that triggers this dequeue. Null if this is not triggered by an error.
*/
private synchronized void dequeue(DeviceId deviceId, Objective obj, ObjectiveError error) {
List<Objective> remaining;
int priority = obj.priority();
LogLevel logLevel = (obj.op() == Objective.Operation.VERIFY) ? LogLevel.TRACE : LogLevel.DEBUG;
Tools.log(log, logLevel, "Dequeue {}", obj);
if (obj instanceof FilteringObjective) {
FilteringObjQueueKey k = new FilteringObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
if (!Objects.equals(ObjectiveError.INSTALLATIONTIMEOUT, error)) {
filtObjQueueHead.invalidate(k);
}
filtObjQueue.remove(k, obj);
remaining = filtObjQueue.get(k);
} else if (obj instanceof ForwardingObjective) {
ForwardingObjQueueKey k = new ForwardingObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
if (!Objects.equals(ObjectiveError.INSTALLATIONTIMEOUT, error)) {
fwdObjQueueHead.invalidate(k);
}
fwdObjQueue.remove(k, obj);
remaining = fwdObjQueue.get(k);
} else if (obj instanceof NextObjective) {
if (error != null) {
// Remove pendingForwards and pendingNexts if next objective failed
Set<PendingFlowObjective> removedForwards = pendingForwards.remove(obj.id());
List<PendingFlowObjective> removedNexts = pendingNexts.remove(obj.id());
if (removedForwards != null) {
removedForwards.stream().map(PendingFlowObjective::flowObjective).forEach(pendingObj -> pendingObj.context().ifPresent(c -> c.onError(pendingObj, error)));
}
if (removedNexts != null) {
removedNexts.stream().map(PendingFlowObjective::flowObjective).forEach(pendingObj -> pendingObj.context().ifPresent(c -> c.onError(pendingObj, error)));
}
}
NextObjQueueKey k = new NextObjQueueKey(deviceId, obj.id());
if (!Objects.equals(ObjectiveError.INSTALLATIONTIMEOUT, error)) {
nextObjQueueHead.invalidate(k);
}
nextObjQueue.remove(k, obj);
remaining = nextObjQueue.get(k);
} else {
log.error("Unknown flow objective instance: {}", obj.getClass().getName());
return;
}
log.trace("{} queue size {}", obj.getClass().getSimpleName(), remaining.size());
// Submit the next one in the queue, if any
if (remaining.size() > 0) {
execute(deviceId, remaining.get(0));
}
}
Aggregations