use of org.onosproject.net.flow.FlowRuleOperationsContext in project onos by opennetworkinglab.
the class DefaultVirtualFlowRuleProvider method executeBatch.
@Override
public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
checkNotNull(batch);
for (FlowRuleBatchEntry fop : batch.getOperations()) {
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
switch(fop.operator()) {
case ADD:
devirtualize(networkId, fop.target()).forEach(builder::add);
break;
case REMOVE:
devirtualize(networkId, fop.target()).forEach(builder::remove);
break;
case MODIFY:
devirtualize(networkId, fop.target()).forEach(builder::modify);
break;
default:
break;
}
flowRuleService.apply(builder.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
CompletedBatchOperation status = new CompletedBatchOperation(true, Sets.newConcurrentHashSet(), batch.deviceId());
VirtualFlowRuleProviderService providerService = (VirtualFlowRuleProviderService) providerRegistryService.getProviderService(networkId, VirtualFlowRuleProvider.class);
providerService.batchOperationCompleted(batch.id(), status);
}
@Override
public void onError(FlowRuleOperations ops) {
Set<FlowRule> failures = ImmutableSet.copyOf(Lists.transform(batch.getOperations(), BatchOperationEntry::target));
CompletedBatchOperation status = new CompletedBatchOperation(false, failures, batch.deviceId());
VirtualFlowRuleProviderService providerService = (VirtualFlowRuleProviderService) providerRegistryService.getProviderService(networkId, VirtualFlowRuleProvider.class);
providerService.batchOperationCompleted(batch.id(), status);
}
}));
}
}
use of org.onosproject.net.flow.FlowRuleOperationsContext in project onos by opennetworkinglab.
the class AbstractCorsaPipeline method processFilter.
private void processFilter(FilteringObjective filt, boolean install, ApplicationId applicationId) {
// This driver only processes filtering criteria defined with switch
// ports as the key
PortCriterion port;
if (!filt.key().equals(Criteria.dummy()) && filt.key().type() == Criterion.Type.IN_PORT) {
port = (PortCriterion) filt.key();
} else {
log.warn("No key defined in filtering objective from app: {}. Not" + "processing filtering objective", applicationId);
fail(filt, ObjectiveError.UNKNOWN);
return;
}
// convert filtering conditions for switch-intfs into flowrules
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
for (Criterion c : filt.conditions()) {
if (c.type() == Criterion.Type.ETH_DST) {
EthCriterion eth = (EthCriterion) c;
FlowRule.Builder rule = processEthFiler(filt, eth, port);
rule.forDevice(deviceId).fromApp(applicationId);
ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
} else if (c.type() == Criterion.Type.VLAN_VID) {
VlanIdCriterion vlan = (VlanIdCriterion) c;
FlowRule.Builder rule = processVlanFiler(filt, vlan, port);
rule.forDevice(deviceId).fromApp(applicationId);
ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
} else if (c.type() == Criterion.Type.IPV4_DST) {
IPCriterion ip = (IPCriterion) c;
FlowRule.Builder rule = processIpFilter(filt, ip, port);
rule.forDevice(deviceId).fromApp(applicationId);
ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
} else {
log.warn("Driver does not currently process filtering condition" + " of type: {}", c.type());
fail(filt, ObjectiveError.UNSUPPORTED);
}
}
// apply filtering flow rules
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
pass(filt);
log.info("Applied filtering rules");
}
@Override
public void onError(FlowRuleOperations ops) {
fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
log.info("Failed to apply filtering rules");
}
}));
}
use of org.onosproject.net.flow.FlowRuleOperationsContext in project onos by opennetworkinglab.
the class FlowRuleIntentInstaller method reallocate.
private void reallocate(IntentOperationContext<FlowRuleIntent> context) {
Optional<IntentData> toUninstall = context.toUninstall();
Optional<IntentData> toInstall = context.toInstall();
// TODO: Update the Intent store with this information
toInstall.get().setState(REALLOCATING);
store.write(toInstall.get());
List<FlowRuleIntent> uninstallIntents = Lists.newArrayList(context.intentsToUninstall());
List<FlowRuleIntent> installIntents = Lists.newArrayList(context.intentsToInstall());
FlowRuleOperations.Builder firstStageOperationsBuilder = FlowRuleOperations.builder();
List<FlowRule> secondStageFlowRules = Lists.newArrayList();
FlowRuleOperations.Builder thirdStageOperationsBuilder = FlowRuleOperations.builder();
FlowRuleOperations.Builder finalStageOperationsBuilder = FlowRuleOperations.builder();
prepareReallocation(uninstallIntents, installIntents, firstStageOperationsBuilder, secondStageFlowRules, thirdStageOperationsBuilder, finalStageOperationsBuilder);
trackIntentResources(toUninstall.get(), uninstallIntents, REMOVE);
trackIntentResources(toInstall.get(), installIntents, ADD);
CountDownLatch stageCompleteLatch = new CountDownLatch(1);
FlowRuleOperations firstStageOperations = firstStageOperationsBuilder.build(new StageOperation(context, stageCompleteLatch));
flowRuleService.apply(firstStageOperations);
try {
stageCompleteLatch.await(nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
if (isReallocationStageFailed) {
log.error("Reallocation FAILED in stage one: the following FlowRuleOperations are not executed {}", firstStageOperations);
return;
} else {
log.debug("Reallocation stage one completed");
}
} catch (Exception e) {
log.warn("Latch exception in the reallocation stage one");
}
for (FlowRule flowRule : secondStageFlowRules) {
stageCompleteLatch = new CountDownLatch(1);
FlowRuleOperations operations = FlowRuleOperations.builder().newStage().remove(flowRule).build(new StageOperation(context, stageCompleteLatch));
nonDisruptiveIntentInstaller.schedule(new NonDisruptiveInstallation(operations), nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
try {
stageCompleteLatch.await(nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
if (isReallocationStageFailed) {
log.error("Reallocation FAILED in stage two: " + "the following FlowRuleOperations are not executed {}", operations);
return;
} else {
log.debug("Reallocation stage two completed");
}
} catch (Exception e) {
log.warn("Latch exception in the reallocation stage two");
}
}
stageCompleteLatch = new CountDownLatch(1);
FlowRuleOperations thirdStageOperations = thirdStageOperationsBuilder.build(new StageOperation(context, stageCompleteLatch));
nonDisruptiveIntentInstaller.schedule(new NonDisruptiveInstallation(thirdStageOperations), nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
try {
stageCompleteLatch.await(nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
if (isReallocationStageFailed) {
log.error("Reallocation FAILED in stage three: " + "the following FlowRuleOperations are not executed {}", thirdStageOperations);
return;
} else {
log.debug("Reallocation stage three completed");
}
} catch (Exception e) {
log.warn("Latch exception in the reallocation stage three");
}
FlowRuleOperationsContext flowRuleOperationsContext = new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
intentInstallCoordinator.intentInstallSuccess(context);
log.info("Non-disruptive reallocation completed for intent {}", toInstall.get().key());
}
@Override
public void onError(FlowRuleOperations ops) {
intentInstallCoordinator.intentInstallFailed(context);
}
};
FlowRuleOperations finalStageOperations = finalStageOperationsBuilder.build(flowRuleOperationsContext);
flowRuleService.apply(finalStageOperations);
}
use of org.onosproject.net.flow.FlowRuleOperationsContext in project onos by opennetworkinglab.
the class FlowRuleIntentInstaller method apply.
@Override
public void apply(IntentOperationContext<FlowRuleIntent> context) {
Optional<IntentData> toUninstall = context.toUninstall();
Optional<IntentData> toInstall = context.toInstall();
if (toInstall.isPresent() && toUninstall.isPresent()) {
Intent intentToInstall = toInstall.get().intent();
if (requireNonDisruptive(intentToInstall) && INSTALLED.equals(toUninstall.get().state())) {
reallocate(context);
return;
}
}
if (!toInstall.isPresent() && !toUninstall.isPresent()) {
// Nothing to do.
intentInstallCoordinator.intentInstallSuccess(context);
return;
}
List<FlowRuleIntent> uninstallIntents = context.intentsToUninstall();
List<FlowRuleIntent> installIntents = context.intentsToInstall();
List<FlowRule> flowRulesToUninstall;
List<FlowRule> flowRulesToInstall;
if (toUninstall.isPresent()) {
// Remove tracked resource from both Intent and installable Intents.
trackIntentResources(toUninstall.get(), uninstallIntents, REMOVE);
// Retrieves all flow rules from all flow rule Intents.
flowRulesToUninstall = uninstallIntents.stream().map(FlowRuleIntent::flowRules).flatMap(Collection::stream).filter(flowRule -> flowRuleService.getFlowEntry(flowRule) != null).collect(Collectors.toList());
} else {
// No flow rules to be uninstalled.
flowRulesToUninstall = Collections.emptyList();
}
if (toInstall.isPresent()) {
// Track resource from both Intent and installable Intents.
trackIntentResources(toInstall.get(), installIntents, ADD);
// Retrieves all flow rules from all flow rule Intents.
flowRulesToInstall = installIntents.stream().map(FlowRuleIntent::flowRules).flatMap(Collection::stream).collect(Collectors.toList());
} else {
// No flow rules to be installed.
flowRulesToInstall = Collections.emptyList();
}
List<FlowRule> flowRuleToModify;
List<FlowRule> dontTouch;
// If both uninstall/install list contained equal (=match conditions are equal) FlowRules,
// omit it from remove list, since it will/should be overwritten by install
flowRuleToModify = flowRulesToInstall.stream().filter(flowRule -> flowRulesToUninstall.stream().anyMatch(flowRule::equals)).collect(Collectors.toList());
// If both contained exactMatch-ing FlowRules, remove from both list,
// since it will result in no-op.
dontTouch = flowRulesToInstall.stream().filter(flowRule -> flowRulesToUninstall.stream().anyMatch(flowRule::exactMatch)).collect(Collectors.toList());
flowRulesToUninstall.removeAll(flowRuleToModify);
flowRulesToUninstall.removeAll(dontTouch);
flowRulesToInstall.removeAll(flowRuleToModify);
flowRulesToInstall.removeAll(dontTouch);
flowRuleToModify.removeAll(dontTouch);
if (flowRulesToInstall.isEmpty() && flowRulesToUninstall.isEmpty() && flowRuleToModify.isEmpty()) {
// There is no flow rules to install/uninstall
intentInstallCoordinator.intentInstallSuccess(context);
return;
}
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
// Add flows
flowRulesToInstall.forEach(builder::add);
// Modify flows
flowRuleToModify.forEach(builder::modify);
// Remove flows
flowRulesToUninstall.forEach(builder::remove);
FlowRuleOperationsContext flowRuleOperationsContext = new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
intentInstallCoordinator.intentInstallSuccess(context);
}
@Override
public void onError(FlowRuleOperations ops) {
intentInstallCoordinator.intentInstallFailed(context);
}
};
FlowRuleOperations operations = builder.build(flowRuleOperationsContext);
log.debug("applying intent {} -> {} with {} rules: {}", toUninstall.map(x -> x.key().toString()).orElse("<empty>"), toInstall.map(x -> x.key().toString()).orElse("<empty>"), operations.stages().stream().mapToLong(Set::size).sum(), operations.stages());
flowRuleService.apply(operations);
}
use of org.onosproject.net.flow.FlowRuleOperationsContext in project onos by opennetworkinglab.
the class Ofdpa3Pipeline method processDoubleTaggedFilter.
/**
* Configure filtering rules of outer and inner VLAN IDs, and a MAC address.
* Filtering happens in three tables (VLAN_TABLE, VLAN_1_TABLE, TMAC_TABLE).
*
* @param filteringObjective the filtering objective
* @param install true to add, false to remove
* @param applicationId for application programming this filter
*/
private void processDoubleTaggedFilter(FilteringObjective filteringObjective, boolean install, ApplicationId applicationId) {
PortCriterion portCriterion = null;
EthCriterion ethCriterion = null;
VlanIdCriterion innervidCriterion = null;
VlanIdCriterion outerVidCriterion = null;
boolean popVlan = false;
boolean removeDoubleTagged = true;
if (filteringObjective.meta().writeMetadata() != null) {
removeDoubleTagged = shouldRemoveDoubleTagged(filteringObjective.meta().writeMetadata());
}
log.info("HERE , removeDoubleTagged {}", removeDoubleTagged);
TrafficTreatment meta = filteringObjective.meta();
if (!filteringObjective.key().equals(Criteria.dummy()) && filteringObjective.key().type() == Criterion.Type.IN_PORT) {
portCriterion = (PortCriterion) filteringObjective.key();
}
if (portCriterion == null) {
log.warn("No IN_PORT defined in filtering objective from app: {}" + "Failed to program VLAN tables.", applicationId);
return;
} else {
log.debug("Received filtering objective for dev/port: {}/{}", deviceId, portCriterion.port());
}
// meta should have only one instruction, popVlan.
if (meta != null && meta.allInstructions().size() == 1) {
L2ModificationInstruction l2Inst = (L2ModificationInstruction) meta.allInstructions().get(0);
if (l2Inst.subtype().equals(L2SubType.VLAN_POP)) {
popVlan = true;
} else {
log.warn("Filtering objective can have only VLAN_POP instruction.");
return;
}
} else {
log.warn("Filtering objective should have one instruction.");
return;
}
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
for (Criterion criterion : filteringObjective.conditions()) {
switch(criterion.type()) {
case ETH_DST:
case ETH_DST_MASKED:
ethCriterion = (EthCriterion) criterion;
break;
case VLAN_VID:
outerVidCriterion = (VlanIdCriterion) criterion;
break;
case INNER_VLAN_VID:
innervidCriterion = (VlanIdCriterion) criterion;
break;
default:
log.warn("Unsupported filter {}", criterion);
fail(filteringObjective, ObjectiveError.UNSUPPORTED);
return;
}
}
if (innervidCriterion == null || outerVidCriterion == null) {
log.warn("filtering objective should have two vidCriterion.");
return;
}
if (ethCriterion == null || ethCriterion.mac().equals(NONE)) {
// NOTE: it is possible that a filtering objective only has vidCriterion
log.warn("filtering objective missing dstMac, cannot program TMAC table");
return;
} else {
MacAddress unicastMac = readEthDstFromTreatment(filteringObjective.meta());
List<List<FlowRule>> allStages = processEthDstFilter(portCriterion, ethCriterion, innervidCriterion, innervidCriterion.vlanId(), unicastMac, applicationId);
for (List<FlowRule> flowRules : allStages) {
log.trace("Starting a new flow rule stage for TMAC table flow");
ops.newStage();
for (FlowRule flowRule : flowRules) {
log.trace("{} flow rules in TMAC table: {} for dev: {}", (install) ? "adding" : "removing", flowRules, deviceId);
if (install) {
ops = ops.add(flowRule);
} else {
// same VLAN on this device if TMAC doesn't support matching on in_port.
if (matchInPortTmacTable() || (filteringObjective.meta() != null && filteringObjective.meta().clearedDeferred())) {
// if metadata instruction not null and not removeDoubleTagged move on.
if ((filteringObjective.meta().writeMetadata() != null) && (!removeDoubleTagged)) {
log.info("Skipping removal of tmac rule for device {}", deviceId);
continue;
} else {
ops = ops.remove(flowRule);
}
} else {
log.debug("Abort TMAC flow removal on {}. Some other ports still share this TMAC flow");
}
}
}
}
}
List<FlowRule> rules;
rules = processDoubleVlanIdFilter(portCriterion, innervidCriterion, outerVidCriterion, popVlan, applicationId);
for (FlowRule flowRule : rules) {
log.trace("{} flow rule in VLAN table: {} for dev: {}", (install) ? "adding" : "removing", flowRule, deviceId);
// if context is remove, table is vlan_1 and removeDoubleTagged is false, continue.
if (flowRule.table().equals(IndexTableId.of(VLAN_TABLE)) && !removeDoubleTagged && !install) {
log.info("Skipping removal of vlan table rule for now!");
continue;
}
ops = install ? ops.add(flowRule) : ops.remove(flowRule);
}
// apply filtering flow rules
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.debug("Applied {} filtering rules in device {}", ops.stages().get(0).size(), deviceId);
pass(filteringObjective);
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to apply all filtering rules in dev {}", deviceId);
fail(filteringObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
}
}));
}
Aggregations