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 CentecV350Pipeline method processFilter.
private void processFilter(FilteringObjective filt, boolean install, ApplicationId applicationId) {
PortCriterion p;
if (!filt.key().equals(Criteria.dummy()) && filt.key().type() == Criterion.Type.IN_PORT) {
p = (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 flow rules.
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
for (Criterion c : filt.conditions()) {
// Here we do a trick to install 2 flow rules to MAC_TABLE and ROUTE_TABLE.
if (c.type() == Criterion.Type.ETH_DST) {
EthCriterion e = (EthCriterion) c;
// Install TMAC flow rule.
log.debug("adding rule for Termination MAC in Filter Table: {}", e.mac());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(e.mac());
// Add IPv4 matching explicitly since we will redirect it to ROUTE Table
// through MAC table.
selector.matchEthType(Ethernet.TYPE_IPV4);
treatment.transition(MAC_TABLE);
FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(FILTER_TABLE_TMAC_PRIORITY).fromApp(applicationId).makePermanent().forTable(FILTER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
// Must install another rule to direct the IPv4 packets that hit TMAC to
// Route table.
log.debug("adding rule for Termination MAC in MAC Table: {}", e.mac());
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
selector.matchEthDst(e.mac());
// MAC_Table must have metadata matching configured, use the default metadata.
selector.matchMetadata(DEFAULT_METADATA);
treatment.transition(ROUTE_TABLE);
rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(MAC_TABLE_PRIORITY).fromApp(applicationId).makePermanent().forTable(MAC_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else if (c.type() == Criterion.Type.VLAN_VID) {
VlanIdCriterion v = (VlanIdCriterion) c;
log.debug("adding rule for VLAN: {}", v.vlanId());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchVlanId(v.vlanId());
selector.matchInPort(p.port());
// Although the accepted packets will be sent to filter table, we must
// explicitly set goto_table instruction here.
treatment.writeMetadata(DEFAULT_METADATA, DEFAULT_METADATA_MASK);
// set default metadata written by PORT_VLAN Table.
treatment.transition(FILTER_TABLE);
// We do not support strip vlan here, treatment.deferred().popVlan();
// PORT_VLAN table only accept 0xffff priority since it does exact match only.
FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(PORT_VLAN_TABLE_PRIORITY).fromApp(applicationId).makePermanent().forTable(PORT_VLAN_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} else if (c.type() == Criterion.Type.IPV4_DST) {
IPCriterion ipaddr = (IPCriterion) c;
log.debug("adding IP filtering rules in FILTER table: {}", ipaddr.ip());
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
// router IPs to the controller
selector.matchIPDst(ipaddr.ip());
treatment.setOutput(PortNumber.CONTROLLER);
FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(FILTER_TABLE_CONTROLLER_PRIORITY).fromApp(applicationId).makePermanent().forTable(FILTER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
} 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 CentecV350Pipeline method processFilterTable.
private void processFilterTable(boolean install) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
FlowRule rule;
// Punt ARP packets to controller by default.
selector.matchEthType(Ethernet.TYPE_ARP);
treatment.punt();
rule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector.build()).withTreatment(treatment.build()).withPriority(FILTER_TABLE_CONTROLLER_PRIORITY).fromApp(appId).makePermanent().forTable(FILTER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
// Punt BGP packets to controller directly.
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4).matchIPProtocol(IPv4.PROTOCOL_TCP).matchTcpSrc(TpPort.tpPort(BGP_PORT));
treatment.punt();
rule = DefaultFlowRule.builder().forDevice(deviceId).withPriority(FILTER_TABLE_HIGHEST_PRIORITY).withSelector(selector.build()).withTreatment(treatment.build()).fromApp(appId).makePermanent().forTable(FILTER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4).matchIPProtocol(IPv4.PROTOCOL_TCP).matchTcpDst(TpPort.tpPort(BGP_PORT));
treatment.punt();
rule = DefaultFlowRule.builder().forDevice(deviceId).withPriority(FILTER_TABLE_HIGHEST_PRIORITY).withSelector(selector.build()).withTreatment(treatment.build()).fromApp(appId).makePermanent().forTable(FILTER_TABLE).build();
ops = install ? ops.add(rule) : ops.remove(rule);
// Packet will be discard in PORT_VLAN table, no need to install rule in
// filter table.
// XXX does not tell me if packets are going to be dropped by default in
// filter table or not? TTP says it will be dropped by default
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Provisioned filter table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to provision filter table");
}
}));
}
use of org.onosproject.net.flow.FlowRuleOperationsContext in project onos by opennetworkinglab.
the class JuniperQfx5100Pipeliner method forward.
@Override
public void forward(ForwardingObjective forwardObjective) {
FlowRule rule;
FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
ForwardingObjective newFwd = forwardObjective;
Device device = deviceService.getDevice(deviceId);
if (forwardObjective.treatment() != null && forwardObjective.treatment().clearedDeferred()) {
log.warn("Using 'clear actions' instruction which is not supported by {} {} {} Switch", device.id(), device.manufacturer(), device.hwVersion());
newFwd = forwardingObjectiveWithoutCleardDef(forwardObjective).orElse(forwardObjective);
}
rule = processForward(newFwd);
switch(forwardObjective.op()) {
case ADD:
flowOpsBuilder.add(rule);
break;
case REMOVE:
flowOpsBuilder.remove(rule);
break;
default:
fail(forwardObjective, ObjectiveError.UNKNOWN);
log.warn("Unknown forwarding type {}", forwardObjective.op());
}
flowRuleService.apply(flowOpsBuilder.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
pass(forwardObjective);
}
@Override
public void onError(FlowRuleOperations ops) {
fail(forwardObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
}
}));
}
Aggregations