use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class PolicyManager method removePolicyInDevice.
// Remove policy in a device according to the type
private void removePolicyInDevice(DeviceId deviceId, Policy policy) {
PolicyKey policyKey = new PolicyKey(deviceId, policy.policyId());
Operation operation = Versioned.valueOrNull(operations.get(policyKey.toString()));
// Policy might be still in pending or not present anymore
if (operation == null || operation.objectiveOperation() == null) {
log.warn("There are no ops associated with {}", policyKey);
operation = Operation.builder().isDone(true).isInstall(false).policy(policy).build();
operations.put(policyKey.toString(), operation);
} else {
if (log.isDebugEnabled()) {
log.debug("Removing {} policy {} in device {}", policy.policyType(), policy.policyId(), deviceId);
}
Operation.Builder operationBuilder = Operation.builder().isInstall(false).policy(policy);
if (policy.policyType() == PolicyType.DROP) {
operationBuilder.isDone(true);
operations.put(policyKey.toString(), operationBuilder.build());
} else if (policy.policyType() == PolicyType.REDIRECT) {
// REDIRECT has to remove the next objective first
NextObjective oldObj = (NextObjective) operation.objectiveOperation();
operations.put(policyKey.toString(), operationBuilder.build());
NextObjective.Builder builder = oldObj.copy();
CompletableFuture<Objective> future = new CompletableFuture<>();
if (log.isDebugEnabled()) {
log.debug("Removing REDIRECT next objective for dev: {}", deviceId);
}
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
if (log.isDebugEnabled()) {
log.debug("REDIRECT next objective for policy {} removed in dev: {}", policy.policyId(), deviceId);
}
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to remove REDIRECT next objective for policy {}: {} in dev: {}", policy.policyId(), error, deviceId);
future.complete(null);
});
NextObjective serializableObjective = builder.remove();
flowObjectiveService.next(deviceId, builder.remove(context));
future.whenComplete((objective, ex) -> {
if (ex != null) {
log.error("Exception Removing REDIRECT next objective", ex);
} else if (objective != null) {
operations.computeIfPresent(policyKey.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 installPolicyInDevice.
// Orchestrate policy installation according to the type
private void installPolicyInDevice(DeviceId deviceId, Policy policy) {
if (!SUPPORTED_POLICIES.contains(policy.policyType())) {
log.warn("Policy {} type {} not yet supported", policy.policyId(), policy.policyType());
return;
}
PolicyKey policyKey;
Operation.Builder operation;
if (log.isDebugEnabled()) {
log.debug("Installing {} policy {} for dev: {}", policy.policyType(), policy.policyId(), deviceId);
}
policyKey = new PolicyKey(deviceId, policy.policyId());
// Prevent duplicate installation of the policies. With the current
// implementation is not possible to update a policy since a change
// in the params will create a new policy. Thus, there is no need to
// check the equality like we do for the TM
Operation oldPolicyOp = Versioned.valueOrNull(operations.get(policyKey.toString()));
if (oldPolicyOp != null && oldPolicyOp.isInstall()) {
if (log.isDebugEnabled()) {
log.debug("There is already an install operation for policy {}", policy.policyId());
}
// If we add or submit a policy multiple times
// We skip the installation update the policy state directly
updatePolicy(policy.policyId(), true);
return;
}
operation = Operation.builder().isInstall(true).policy(policy);
// TODO To better handle different policy types consider the abstraction of a compiler (subtypes ?)
if (policy.policyType() == PolicyType.DROP) {
// DROP policies do not need the next objective installation phase
// we can update directly the map and signal the ops as done
operation.isDone(true);
operations.put(policyKey.toString(), operation.build());
} else if (policy.policyType() == PolicyType.REDIRECT) {
// REDIRECT Uses next objective context to update the ops as done when
// it returns successfully. In the other cases leaves the ops as undone
// and the relative policy will remain in pending.
operations.put(policyKey.toString(), operation.build());
NextObjective.Builder builder = redirectPolicyNextObjective(deviceId, (RedirectPolicy) policy);
// Handle error here - leave the operation as undone and pending
if (builder != null) {
CompletableFuture<Objective> future = new CompletableFuture<>();
if (log.isDebugEnabled()) {
log.debug("Installing REDIRECT next objective for dev: {}", deviceId);
}
ObjectiveContext context = new DefaultObjectiveContext((objective) -> {
if (log.isDebugEnabled()) {
log.debug("REDIRECT next objective for policy {} installed in dev: {}", policy.policyId(), deviceId);
}
future.complete(objective);
}, (objective, error) -> {
log.warn("Failed to install REDIRECT next objective for policy {}: {} in dev: {}", policy.policyId(), error, deviceId);
future.complete(null);
});
// Context is not serializable
NextObjective serializableObjective = builder.add();
flowObjectiveService.next(deviceId, builder.add(context));
future.whenComplete((objective, ex) -> {
if (ex != null) {
log.error("Exception installing REDIRECT next objective", ex);
} else if (objective != null) {
operations.computeIfPresent(policyKey.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 deletePolicy.
/**
* Deletes a given policy using the parameter supplied.
*
* @param tunnelId the tunnel id
* @param ingress the ingress point
* @param ingressInner the ingress inner vlan id
* @param ingressOuter the ingress outer vlan id
* @param future to perform the async operation
* @param direction the direction: forward or reverse
*/
private void deletePolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner, VlanId ingressOuter, VlanId egressVlan, CompletableFuture<ObjectiveError> future, Direction direction) {
String key = generateKey(tunnelId, direction);
if (!l2InitiationNextObjStore.containsKey(key)) {
log.error("Abort delete of policy for tunnel {}: next does not exist in the store", tunnelId);
if (future != null) {
future.complete(null);
}
return;
}
NextObjective nextObjective = l2InitiationNextObjStore.get(key).value();
int nextId = nextObjective.id();
List<Objective> objectives = Lists.newArrayList();
// We create the forwarding objective.
ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(tunnelId, ingress.port(), nextId);
ObjectiveContext context = new ObjectiveContext() {
@Override
public void onSuccess(Objective objective) {
log.debug("Previous fwdObj for policy {} removed", tunnelId);
if (future != null) {
future.complete(null);
}
}
@Override
public void onError(Objective objective, ObjectiveError error) {
log.error("Failed to remove previous fwdObj for policy {}: {}", tunnelId, error);
if (future != null) {
future.complete(error);
}
}
};
objectives.add(fwdBuilder.remove(context));
// We create the filtering objective to define the
// permit traffic in the switch
FilteringObjective.Builder filtBuilder = createFiltObjective(ingress.port(), ingressInner, ingressOuter);
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder().setTunnelId(tunnelId).setVlanId(egressVlan);
filtBuilder.withMeta(treatment.build());
context = new DefaultObjectiveContext((objective) -> log.debug("FilterObj for policy {} revoked", tunnelId), (objective, error) -> log.warn("Failed to revoke filterObj for policy {}", tunnelId, error));
objectives.add(filtBuilder.remove(context));
for (Objective objective : objectives) {
if (objective instanceof ForwardingObjective) {
srManager.flowObjectiveService.forward(ingress.deviceId(), (ForwardingObjective) objective);
} else {
srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
}
}
}
use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class DefaultL2TunnelHandler method deployPolicy.
/**
* Handles the policy establishment which consists in
* create the filtering and forwarding objectives related
* to the initiation and termination.
*
* @param tunnelId the tunnel id
* @param ingress the ingress point
* @param ingressInner the ingress inner tag
* @param ingressOuter the ingress outer tag
* @param egressVlan Vlan-id to set, depends on ingress vlan
* combinations. For example, if pw is double tagged
* then this is the value of the outer vlan, if single
* tagged then it is the new value of the single tag.
* Should be None for untagged traffic.
* @param nextId the next objective id
* @return the result of the operation
*/
private Result deployPolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner, VlanId ingressOuter, VlanId egressVlan, int nextId) {
log.debug("Starting deploying policy for pseudowire {}.", tunnelId);
List<Objective> objectives = Lists.newArrayList();
// We create the forwarding objective for supporting
// the l2 tunnel.
ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(tunnelId, ingress.port(), nextId);
// We create and add objective context.
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for tunnel {} populated", tunnelId), (objective, error) -> log.warn("Failed to populate fwdObj " + "for tunnel {} : {}", tunnelId, error));
objectives.add(fwdBuilder.add(context));
// We create the filtering objective to define the
// permit traffic in the switch
FilteringObjective.Builder filtBuilder = createFiltObjective(ingress.port(), ingressInner, ingressOuter);
// We add the metadata.
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder().setTunnelId(tunnelId).setVlanId(egressVlan);
filtBuilder.withMeta(treatment.build());
// We create and add objective context.
context = new DefaultObjectiveContext((objective) -> log.debug("FilterObj for tunnel {} populated", tunnelId), (objective, error) -> log.warn("Failed to populate filterObj for " + "tunnel {} : {}", tunnelId, error));
objectives.add(filtBuilder.add(context));
for (Objective objective : objectives) {
if (objective instanceof ForwardingObjective) {
srManager.flowObjectiveService.forward(ingress.deviceId(), (ForwardingObjective) objective);
log.debug("Creating new FwdObj for initiation NextObj with id={} for tunnel {}", nextId, tunnelId);
} else {
srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
log.debug("Creating new FiltObj for tunnel {}", tunnelId);
}
}
return SUCCESS;
}
use of org.onosproject.net.flowobjective.Objective in project trellis-control by opennetworkinglab.
the class XconnectManager method revokeFilter.
/**
* Revokes filtering objectives for given XConnect.
*
* @param key XConnect store key
* @param endpoints XConnect endpoints
*/
private void revokeFilter(XconnectKey key, Set<XconnectEndpoint> endpoints) {
// FIXME Improve the logic
// If port load balancer is not involved, use filtered port. Otherwise, use unfiltered port.
// The purpose is to make sure existing XConnect logic can still work on a configured port.
boolean filtered = endpoints.stream().map(ep -> getNextTreatment(key.deviceId(), ep, false)).allMatch(t -> t.type().equals(NextTreatment.Type.TREATMENT));
endpoints.stream().map(ep -> getPhysicalPorts(key.deviceId(), ep)).flatMap(Set::stream).forEach(port -> {
FilteringObjective.Builder filtObjBuilder = filterObjBuilder(key, port, filtered);
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("XConnect FilterObj for {} on port {} revoked", key, port), (objective, error) -> log.warn("Failed to revoke XConnect FilterObj for {} on port {}: {}", key, port, error));
flowObjectiveService.filter(key.deviceId(), filtObjBuilder.remove(context));
});
}
Aggregations