use of org.onosproject.net.flowobjective.NextObjective in project trellis-control by opennetworkinglab.
the class McastHandler method removeGroupFromDevice.
/**
* Removes entire group on given device.
*
* @param deviceId device ID
* @param mcastIp multicast group to be removed
* @param assignedVlan assigned VLAN ID
*/
private void removeGroupFromDevice(DeviceId deviceId, IpAddress mcastIp, VlanId assignedVlan) {
// TODO trace
log.info("Removing {} on {} and vlan {}", mcastIp, deviceId, assignedVlan);
McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId, assignedVlan);
// This device is not serving this multicast group
if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
log.debug("{} is not serving {}. Abort.", deviceId, mcastIp);
return;
}
NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("Successfully remove {} on {}, vlan {}", mcastIp, deviceId, assignedVlan), (objective, error) -> log.warn("Failed to remove {} on {}, vlan {}: {}", mcastIp, deviceId, assignedVlan, error));
if (!srManager.deviceConfiguration().isConfigured(deviceId)) {
log.debug("skip flow changes on unconfigured device: {}", deviceId);
} else {
ForwardingObjective fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
srManager.flowObjectiveService.forward(deviceId, fwdObj);
}
mcastNextObjStore.remove(mcastStoreKey);
}
use of org.onosproject.net.flowobjective.NextObjective 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.NextObjective 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.NextObjective in project trellis-control by opennetworkinglab.
the class DefaultL2TunnelHandler method tearDownPseudoWireTerm.
/**
* Deletes the pseudo wire termination.
*
* @param l2Tunnel the tunnel
* @param egress the egress connect point
* @param future the async task
* @param direction the direction of the tunnel
*/
private void tearDownPseudoWireTerm(L2Tunnel l2Tunnel, ConnectPoint egress, CompletableFuture<ObjectiveError> future, Direction direction) {
log.debug("Starting tearing down termination for pseudowire {} direction {}.", l2Tunnel.tunnelId(), direction == FWD ? "forward" : "reverse");
String key = generateKey(l2Tunnel.tunnelId(), direction);
if (!l2TerminationNextObjStore.containsKey(key)) {
log.error("Abort delete of {} for {}: next does not exist in the store", TERMINATION, key);
if (future != null) {
future.complete(null);
}
return;
}
NextObjective nextObjective = l2TerminationNextObjStore.get(key).value();
ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(l2Tunnel.pwLabel(), l2Tunnel.tunnelId(), egress.port(), nextObjective.id());
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for {} {}, " + "direction {} removed", TERMINATION, l2Tunnel.tunnelId(), direction), (objective, error) -> log.warn("Failed to remove fwdObj " + "for {} {}" + ", direction {}", TERMINATION, l2Tunnel.tunnelId(), error, direction));
srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.remove(context));
// un-comment in case you want to delete groups used by the pw
// however, this will break the update of pseudowires cause the L2 interface group can
// not be deleted (it is referenced by other groups)
/*
context = new ObjectiveContext() {
@Override
public void onSuccess(Objective objective) {
log.debug("Previous {} next for {} removed", TERMINATION, key);
if (future != null) {
future.complete(null);
}
}
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to remove previous {} next for {}: {}", TERMINATION, key, error);
if (future != null) {
future.complete(error);
}
}
};
srManager.flowObjectiveService.next(egress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
*/
l2TerminationNextObjStore.remove(key);
future.complete(null);
}
use of org.onosproject.net.flowobjective.NextObjective 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);
}
}
}
Aggregations