use of org.onosproject.net.flow.FlowRule in project onos by opennetworkinglab.
the class OvsOfdpaPipeline method processEgress.
/**
* In the OF-DPA 2.0 pipeline, egress forwarding objectives go to the
* egress tables.
* @param fwd the forwarding objective of type 'egress'
* @return a collection of flow rules to be sent to the switch. An empty
* collection may be returned if there is a problem in processing
* the flow rule
*/
@Override
protected Collection<FlowRule> processEgress(ForwardingObjective fwd) {
log.debug("Processing egress forwarding objective:{} in dev:{}", fwd, deviceId);
List<FlowRule> rules = new ArrayList<>();
// Build selector
TrafficSelector.Builder sb = DefaultTrafficSelector.builder();
VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID);
if (vlanIdCriterion == null) {
log.error("Egress forwarding objective:{} must include vlanId", fwd.id());
fail(fwd, ObjectiveError.BADPARAMS);
return rules;
}
Optional<Instruction> outInstr = fwd.treatment().allInstructions().stream().filter(instruction -> instruction instanceof Instructions.OutputInstruction).findFirst();
if (!outInstr.isPresent()) {
log.error("Egress forwarding objective:{} must include output port", fwd.id());
fail(fwd, ObjectiveError.BADPARAMS);
return rules;
}
PortNumber portNumber = ((Instructions.OutputInstruction) outInstr.get()).port();
sb.matchVlanId(vlanIdCriterion.vlanId());
OfdpaMatchActsetOutput actsetOutput = new OfdpaMatchActsetOutput(portNumber);
sb.extension(actsetOutput, deviceId);
// Build a flow rule for Egress VLAN Flow table
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
tb.transition(UNICAST_ROUTING_TABLE_1);
if (fwd.treatment() != null) {
for (Instruction instr : fwd.treatment().allInstructions()) {
if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
tb.immediate().add(instr);
}
if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
EthType ethType = ((L2ModificationInstruction.ModVlanHeaderInstruction) instr).ethernetType();
tb.immediate().pushVlan(ethType);
}
}
}
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sb.build()).withTreatment(tb.build()).makePermanent().forTable(EGRESS_VLAN_FLOW_TABLE_IN_INGRESS);
rules.add(ruleBuilder.build());
return rules;
}
use of org.onosproject.net.flow.FlowRule in project onos by opennetworkinglab.
the class OvsOfdpaPipeline method processDoubleVlanIdFilter.
/**
* Internal implementation of processDoubleVlanIdFilter.
*
* @param portCriterion port on device for which this filter is programmed
* @param innerVidCriterion inner vlan
* @param outerVidCriterion outer vlan
* @param popVlan true if outer vlan header needs to be removed
* @param applicationId for application programming this filter
* @return flow rules for port-vlan filters
*/
private List<FlowRule> processDoubleVlanIdFilter(PortCriterion portCriterion, VlanIdCriterion innerVidCriterion, VlanIdCriterion outerVidCriterion, boolean popVlan, ApplicationId applicationId) {
List<FlowRule> rules = new ArrayList<>();
TrafficSelector.Builder outerSelector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder outerTreatment = DefaultTrafficTreatment.builder();
TrafficSelector.Builder innerSelector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder innerTreatment = DefaultTrafficTreatment.builder();
VlanId outerVlanId = outerVidCriterion.vlanId();
VlanId innerVlanId = innerVidCriterion.vlanId();
PortNumber portNumber = portCriterion.port();
// Check arguments
if (PortNumber.ALL.equals(portNumber) || outerVlanId.equals(VlanId.NONE) || innerVlanId.equals(VlanId.NONE)) {
log.warn("Incomplete Filtering Objective. " + "VLAN Table cannot be programmed for {}", deviceId);
return ImmutableList.of();
} else {
outerSelector.matchInPort(portNumber);
innerSelector.matchInPort(portNumber);
outerTreatment.transition(VLAN_1_TABLE);
innerTreatment.transition(TMAC_TABLE);
outerTreatment.writeMetadata(outerVlanId.toShort(), 0xFFF);
outerSelector.matchVlanId(outerVlanId);
innerSelector.matchVlanId(innerVlanId);
// force recompilation
// FIXME might be issue due tu /fff mask
innerSelector.matchMetadata(outerVlanId.toShort());
if (popVlan) {
outerTreatment.popVlan();
}
}
// NOTE: for double-tagged packets, restore original outer vlan
// before sending it to the controller.
GroupKey groupKey = popVlanPuntGroupKey();
Group group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
// push outer vlan and send to controller
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder().matchInPort(portNumber).matchVlanId(innerVlanId);
Host host = handler().get(HostService.class).getConnectedHosts(ConnectPoint.deviceConnectPoint(deviceId + "/" + portNumber.toLong())).stream().filter(h -> h.vlan().equals(outerVlanId)).findFirst().orElse(null);
EthType vlanType = EthType.EtherType.VLAN.ethType();
if (host != null) {
vlanType = host.tpid();
}
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder().pushVlan(vlanType).setVlanId(outerVlanId).punt();
rules.add(DefaultFlowRule.builder().forDevice(deviceId).withSelector(sbuilder.build()).withTreatment(tbuilder.build()).withPriority(PacketPriority.CONTROL.priorityValue()).fromApp(driverId).makePermanent().forTable(PUNT_TABLE).build());
} else {
log.info("popVlanPuntGroup not found in dev:{}", deviceId);
return Collections.emptyList();
}
FlowRule outerRule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(outerSelector.build()).withTreatment(outerTreatment.build()).withPriority(DEFAULT_PRIORITY).fromApp(applicationId).makePermanent().forTable(VLAN_TABLE).build();
FlowRule innerRule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(innerSelector.build()).withTreatment(innerTreatment.build()).withPriority(DEFAULT_PRIORITY).fromApp(applicationId).makePermanent().forTable(VLAN_1_TABLE).build();
rules.add(outerRule);
rules.add(innerRule);
return rules;
}
use of org.onosproject.net.flow.FlowRule in project onos by opennetworkinglab.
the class PathIntentCompiler method compile.
@Override
public List<Intent> compile(PathIntent intent, List<Intent> installable) {
List<FlowRule> rules = new LinkedList<>();
List<DeviceId> devices = new LinkedList<>();
compile(this, intent, rules, devices);
return ImmutableList.of(new FlowRuleIntent(appId, intent.key(), rules, intent.resources(), intent.type(), intent.resourceGroup()));
}
use of org.onosproject.net.flow.FlowRule in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method createFailoverFlowRules.
/**
* Manufactures flow rule with treatment that is defined by failover
* group and traffic selector determined by ingress port of the intent.
*
* @param intent intent which is being compiled (for appId)
* @return a list of a singular flow rule with fast failover
* outport traffic treatment
*/
private List<FlowRule> createFailoverFlowRules(PointToPointIntent intent) {
List<FlowRule> flowRules = new ArrayList<>();
ConnectPoint ingress = intent.filteredIngressPoint().connectPoint();
DeviceId deviceId = ingress.deviceId();
// flow rule with failover traffic treatment
TrafficSelector trafficSelector = DefaultTrafficSelector.builder(intent.selector()).matchInPort(ingress.port()).build();
FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
flowRules.add(flowRuleBuilder.withSelector(trafficSelector).withTreatment(buildFailoverTreatment(deviceId, makeGroupKey(intent.id()))).fromApp(intent.appId()).makePermanent().forDevice(deviceId).withPriority(PRIORITY).build());
return flowRules;
}
use of org.onosproject.net.flow.FlowRule in project onos by opennetworkinglab.
the class FlowRuleIntentInstaller method prepareReallocation.
/**
* This method prepares the {@link FlowRule} required for every reallocation stage.
* <p>Stage 1: the FlowRules of the new path are installed,
* with a lower priority only on the devices shared with the old path;</p>
* <p>Stage 2: the FlowRules of the old path are removed from the ingress to the egress points,
* only in the shared devices;</p>
* <p>Stage 3: the FlowRules with a lower priority are restored to the original one;</p>
* <p>Stage 4: the remaining FlowRules of the old path are deleted.</p>
*
* @param uninstallIntents the previous FlowRuleIntent
* @param installIntents the new FlowRuleIntent to be installed
* @param firstStageBuilder the first stage operation builder
* @param secondStageFlowRules the second stage FlowRules
* @param thirdStageBuilder the third stage operation builder
* @param finalStageBuilder the last stage operation builder
*/
private void prepareReallocation(List<FlowRuleIntent> uninstallIntents, List<FlowRuleIntent> installIntents, FlowRuleOperations.Builder firstStageBuilder, List<FlowRule> secondStageFlowRules, FlowRuleOperations.Builder thirdStageBuilder, FlowRuleOperations.Builder finalStageBuilder) {
// Filter out same intents and intents with same flow rules
installIntents.forEach(installIntent -> {
uninstallIntents.forEach(uninstallIntent -> {
List<FlowRule> uninstallFlowRules = Lists.newArrayList(uninstallIntent.flowRules());
List<FlowRule> installFlowRules = Lists.newArrayList(installIntent.flowRules());
List<FlowRule> secondStageRules = Lists.newArrayList();
List<FlowRule> thirdStageRules = Lists.newArrayList();
List<DeviceId> orderedDeviceList = createIngressToEgressDeviceList(installIntent.resources());
uninstallIntent.flowRules().forEach(flowRuleToUnistall -> {
installIntent.flowRules().forEach(flowRuleToInstall -> {
if (flowRuleToInstall.exactMatch(flowRuleToUnistall)) {
// The FlowRules are in common (i.e., we are sharing the path)
uninstallFlowRules.remove(flowRuleToInstall);
installFlowRules.remove(flowRuleToInstall);
} else if (flowRuleToInstall.deviceId().equals(flowRuleToUnistall.deviceId())) {
// FlowRules that have a device in common but
// different treatment/selector (i.e., overlapping path)
FlowRule flowRuleWithLowerPriority = DefaultFlowRule.builder().withPriority(flowRuleToInstall.priority() - 1).withSelector(flowRuleToInstall.selector()).forDevice(flowRuleToInstall.deviceId()).makePermanent().withTreatment(flowRuleToInstall.treatment()).fromApp(new DefaultApplicationId(flowRuleToInstall.appId(), "org.onosproject.net.intent")).build();
// Update the FlowRule to be installed with one with a lower priority
installFlowRules.remove(flowRuleToInstall);
installFlowRules.add(flowRuleWithLowerPriority);
// Add the FlowRule to be uninstalled to the second stage of non-disruptive update
secondStageRules.add(flowRuleToUnistall);
uninstallFlowRules.remove(flowRuleToUnistall);
thirdStageRules.add(flowRuleToInstall);
uninstallFlowRules.add(flowRuleWithLowerPriority);
}
});
});
firstStageBuilder.newStage();
installFlowRules.forEach(firstStageBuilder::add);
Collections.sort(secondStageRules, new SecondStageComparator(orderedDeviceList));
secondStageFlowRules.addAll(secondStageRules);
thirdStageBuilder.newStage();
thirdStageRules.forEach(thirdStageBuilder::add);
finalStageBuilder.newStage();
uninstallFlowRules.forEach(finalStageBuilder::remove);
});
});
}
Aggregations