fix: (vnet) virtual flowrule provider fails
Rollback to previsous devirtualize logic and
some refactoring.
Change-Id: I6eab07f205f7ca7ad34c8af33f7226bbb448554b
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
index cb660b9..4e9c13a 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
@@ -37,7 +37,6 @@
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.VirtualNetworkService;
import org.onosproject.incubator.net.virtual.VirtualPort;
-import org.onosproject.incubator.net.virtual.VirtualLink;
import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
import org.onosproject.incubator.net.virtual.provider.InternalRoutingAlgorithm;
import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
@@ -80,7 +79,6 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.List;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -442,235 +440,165 @@
TrafficTreatment commonTreatment,
FlowRule flowRule) {
- Set<FlowRule> outRules = new HashSet<>();
-
if (ingressPoint.deviceId().equals(egressPoint.deviceId()) ||
egressPoint.port().isLogical()) {
- //Traffic is handled inside a single physical switch
-
- TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector
- .builder(commonSelector)
- .matchInPort(ingressPoint.port());
-
- TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
- .builder(commonTreatment);
-
- VirtualPort virtualIngressPort = vnService
- .getVirtualPorts(networkId, flowRule.deviceId())
- .stream()
- .filter(p -> p.realizedBy().equals(ingressPoint))
- .findFirst()
- .get();
-
- VirtualPort virtualEgressPort = vnService
- .getVirtualPorts(networkId, flowRule.deviceId())
- .stream()
- .filter(p -> p.realizedBy().equals(egressPoint))
- .findFirst()
- .get();
-
- ConnectPoint ingressCp = new ConnectPoint(virtualIngressPort.element().id(), virtualIngressPort.number());
- ConnectPoint egressCp = new ConnectPoint(virtualEgressPort.element().id(), virtualEgressPort.number());
-
- Optional<VirtualLink> optionalIngressLink = vnService
- .getVirtualLinks(networkId)
- .stream()
- .filter(l -> l.dst().equals(ingressCp))
- .findFirst();
-
- Optional<VirtualLink> optionalEgressLink = vnService
- .getVirtualLinks(networkId)
- .stream()
- .filter(l -> l.src().equals(egressCp))
- .findFirst();
-
- //Isolate traffic from different virtual networks with VLAN
- if (!optionalIngressLink.isPresent() && !optionalEgressLink.isPresent()) {
- treatmentBuilder.setOutput(egressPoint.port());
- } else if (optionalIngressLink.isPresent() && !optionalEgressLink.isPresent()) {
- selectorBuilder.matchVlanId(VlanId.vlanId(networkId.id().shortValue()));
- treatmentBuilder.popVlan();
- treatmentBuilder.setOutput(egressPoint.port());
- } else if (!optionalIngressLink.isPresent() && optionalEgressLink.isPresent()) {
- outRules.addAll(generateRulesOnPath(networkId, optionalEgressLink.get(),
- commonSelector, commonTreatment, flowRule));
- treatmentBuilder.pushVlan()
- .setVlanId(VlanId.vlanId(networkId.id().shortValue()));
- treatmentBuilder.setOutput(egressPoint.port());
- } else if (optionalIngressLink.isPresent() && optionalEgressLink.isPresent()) {
- outRules.addAll(generateRulesOnPath(networkId, optionalEgressLink.get(),
- commonSelector, commonTreatment, flowRule));
- selectorBuilder.matchVlanId(VlanId.vlanId(networkId.id().shortValue()));
- treatmentBuilder.setOutput(egressPoint.port());
- }
-
- FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
- .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
- .forDevice(ingressPoint.deviceId())
- .withSelector(selectorBuilder.build())
- .withTreatment(treatmentBuilder.build())
- .withIdleTimeout(flowRule.timeout())
- .withPriority(flowRule.priority());
-
- FlowRule rule = ruleBuilder.build();
- frm.addIngressRule(flowRule, rule, networkId);
- outRules.add(rule);
+ return generateRuleForSingle(networkId, ingressPoint, egressPoint,
+ commonSelector, commonTreatment, flowRule);
} else {
- //Traffic is handled by multiple physical switches
- //A tunnel is needed.
-
- Path internalPath = internalRoutingAlgorithm
- .findPath(ingressPoint, egressPoint);
- checkNotNull(internalPath, "No path between " +
- ingressPoint.toString() + " " + egressPoint.toString());
-
- ConnectPoint outCp = internalPath.links().get(0).src();
-
- //ingress point of tunnel
- TrafficSelector.Builder selectorBuilder =
- DefaultTrafficSelector.builder(commonSelector);
- selectorBuilder.matchInPort(ingressPoint.port());
-
- TrafficTreatment.Builder treatmentBuilder =
- DefaultTrafficTreatment.builder(commonTreatment);
- //TODO: add the logic to check host location
- treatmentBuilder.pushVlan()
- .setVlanId(VlanId.vlanId(networkId.id().shortValue()));
- treatmentBuilder.setOutput(outCp.port());
-
- FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
- .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
- .forDevice(ingressPoint.deviceId())
- .withSelector(selectorBuilder.build())
- .withIdleTimeout(flowRule.timeout())
- .withTreatment(treatmentBuilder.build())
- .withPriority(flowRule.priority());
-
- FlowRule rule = ruleBuilder.build();
- frm.addIngressRule(flowRule, rule, networkId);
- outRules.add(rule);
-
- //routing inside tunnel
- ConnectPoint inCp = internalPath.links().get(0).dst();
-
- if (internalPath.links().size() > 1) {
- for (Link l : internalPath.links()
- .subList(1, internalPath.links().size())) {
-
- outCp = l.src();
-
- selectorBuilder = DefaultTrafficSelector
- .builder(commonSelector)
- .matchVlanId(VlanId.vlanId(networkId.id().shortValue()))
- .matchInPort(inCp.port());
-
- treatmentBuilder = DefaultTrafficTreatment
- .builder(commonTreatment)
- .setOutput(outCp.port());
-
- ruleBuilder = DefaultFlowRule.builder()
- .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
- .forDevice(inCp.deviceId())
- .withSelector(selectorBuilder.build())
- .withTreatment(treatmentBuilder.build())
- .withIdleTimeout(flowRule.timeout())
- .withPriority(flowRule.priority());
-
- outRules.add(ruleBuilder.build());
- inCp = l.dst();
- }
- }
-
- //egress point of tunnel
- selectorBuilder = DefaultTrafficSelector.builder(commonSelector)
- .matchVlanId(VlanId.vlanId(networkId.id().shortValue()))
- .matchInPort(inCp.port());
-
- treatmentBuilder = DefaultTrafficTreatment.builder(commonTreatment)
- .popVlan()
- .setOutput(egressPoint.port());
-
- ruleBuilder = DefaultFlowRule.builder()
- .fromApp(appId)
- .forDevice(egressPoint.deviceId())
- .withSelector(selectorBuilder.build())
- .withTreatment(treatmentBuilder.build())
- .withIdleTimeout(flowRule.timeout())
- .withPriority(flowRule.priority());
-
- outRules.add(ruleBuilder.build());
+ return generateRuleForMulti(networkId, ingressPoint, egressPoint,
+ commonSelector, commonTreatment, flowRule);
}
-
- return outRules;
}
/**
- * Generate flow rules to the intermediate nodes on the physical path for a virtual link.
+ * Generate physical rules when a virtual flow rule can be handled inside
+ * a single physical switch.
*
* @param networkId The virtual network identifier
- * @param virtualLink A virtual link
+ * @param ingressPoint The ingress point of the physical network
+ * @param egressPoint The egress point of the physical network
* @param commonSelector A common traffic selector between the virtual
* and physical flow rules
* @param commonTreatment A common traffic treatment between the virtual
* and physical flow rules
* @param flowRule The virtual flow rule to be translated
- * @return A set of flow rules for the path on physical network
+ * @return A set of flow rules for the physical network
*/
- private Set<FlowRule> generateRulesOnPath(NetworkId networkId,
- VirtualLink virtualLink,
- TrafficSelector commonSelector,
- TrafficTreatment commonTreatment,
- FlowRule flowRule) {
+ private Set<FlowRule> generateRuleForSingle(NetworkId networkId,
+ ConnectPoint ingressPoint,
+ ConnectPoint egressPoint,
+ TrafficSelector commonSelector,
+ TrafficTreatment commonTreatment,
+ FlowRule flowRule) {
- VirtualPort srcVirtualPort = vnService
- .getVirtualPorts(networkId, virtualLink.src().deviceId())
- .stream()
- .filter(p -> p.number().equals(virtualLink.src().port()))
- .findFirst()
- .get();
-
- VirtualPort dstVirtualPort = vnService
- .getVirtualPorts(networkId, virtualLink.dst().deviceId())
- .stream()
- .filter(p -> p.number().equals(virtualLink.dst().port()))
- .findFirst()
- .get();
Set<FlowRule> outRules = new HashSet<>();
- ConnectPoint srcCp = srcVirtualPort.realizedBy();
- ConnectPoint dstCp = dstVirtualPort.realizedBy();
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector
+ .builder(commonSelector)
+ .matchInPort(ingressPoint.port());
+
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
+ .builder(commonTreatment)
+ .setOutput(egressPoint.port());
+
+ FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+ .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
+ .forDevice(ingressPoint.deviceId())
+ .withSelector(selectorBuilder.build())
+ .withTreatment(treatmentBuilder.build())
+ .withIdleTimeout(flowRule.timeout())
+ .withPriority(flowRule.priority());
+
+ FlowRule rule = ruleBuilder.build();
+ frm.addIngressRule(flowRule, rule, networkId);
+ outRules.add(rule);
+
+ return outRules;
+ }
+
+ /**
+ * Generate physical rules when a virtual flow rule can be handled with
+ * multiple physical switches.
+ *
+ * @param networkId The virtual network identifier
+ * @param ingressPoint The ingress point of the physical network
+ * @param egressPoint The egress point of the physical network
+ * @param commonSelector A common traffic selector between the virtual
+ * and physical flow rules
+ * @param commonTreatment A common traffic treatment between the virtual
+ * and physical flow rules
+ * @param flowRule The virtual flow rule to be translated
+ * @return A set of flow rules for the physical network
+ */
+ private Set<FlowRule> generateRuleForMulti(NetworkId networkId,
+ ConnectPoint ingressPoint,
+ ConnectPoint egressPoint,
+ TrafficSelector commonSelector,
+ TrafficTreatment commonTreatment,
+ FlowRule flowRule) {
+ Set<FlowRule> outRules = new HashSet<>();
Path internalPath = internalRoutingAlgorithm
- .findPath(srcCp, dstCp);
- List<Link> links = internalPath.links();
- if (internalPath != null && links.size() > 1) {
- for (int i = 0; i < links.size() - 1; i++) {
- ConnectPoint inCp = links.get(i).dst();
- ConnectPoint outCp = links.get(i + 1).src();
- TrafficSelector.Builder linkSelectorBuilder = DefaultTrafficSelector
+ .findPath(ingressPoint, egressPoint);
+ checkNotNull(internalPath, "No path between " +
+ ingressPoint.toString() + " " + egressPoint.toString());
+
+ ConnectPoint outCp = internalPath.links().get(0).src();
+
+ //ingress point of tunnel
+ TrafficSelector.Builder selectorBuilder =
+ DefaultTrafficSelector.builder(commonSelector);
+ selectorBuilder.matchInPort(ingressPoint.port());
+
+ TrafficTreatment.Builder treatmentBuilder =
+ DefaultTrafficTreatment.builder(commonTreatment);
+ //TODO: add the logic to check host location
+ treatmentBuilder.pushVlan()
+ .setVlanId(VlanId.vlanId(networkId.id().shortValue()));
+ treatmentBuilder.setOutput(outCp.port());
+
+ FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+ .fromApp(vnService.getVirtualNetworkApplicationId(networkId))
+ .forDevice(ingressPoint.deviceId())
+ .withSelector(selectorBuilder.build())
+ .withIdleTimeout(flowRule.timeout())
+ .withTreatment(treatmentBuilder.build())
+ .withPriority(flowRule.priority());
+
+ FlowRule rule = ruleBuilder.build();
+ frm.addIngressRule(flowRule, rule, networkId);
+ outRules.add(rule);
+
+ //routing inside tunnel
+ ConnectPoint inCp = internalPath.links().get(0).dst();
+
+ if (internalPath.links().size() > 1) {
+ for (Link l : internalPath.links()
+ .subList(1, internalPath.links().size())) {
+
+ outCp = l.src();
+
+ selectorBuilder = DefaultTrafficSelector
.builder(commonSelector)
.matchVlanId(VlanId.vlanId(networkId.id().shortValue()))
.matchInPort(inCp.port());
- TrafficTreatment.Builder linkTreatmentBuilder = DefaultTrafficTreatment
+ treatmentBuilder = DefaultTrafficTreatment
.builder(commonTreatment)
.setOutput(outCp.port());
- FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+ ruleBuilder = DefaultFlowRule.builder()
.fromApp(vnService.getVirtualNetworkApplicationId(networkId))
.forDevice(inCp.deviceId())
- .withSelector(linkSelectorBuilder.build())
- .withTreatment(linkTreatmentBuilder.build())
+ .withSelector(selectorBuilder.build())
+ .withTreatment(treatmentBuilder.build())
+ .withIdleTimeout(flowRule.timeout())
.withPriority(flowRule.priority());
- if (flowRule.isPermanent()) {
- ruleBuilder.makePermanent();
- } else {
- ruleBuilder.makeTemporary(flowRule.timeout());
- }
-
outRules.add(ruleBuilder.build());
+ inCp = l.dst();
}
}
+
+ //egress point of tunnel
+ selectorBuilder = DefaultTrafficSelector.builder(commonSelector)
+ .matchVlanId(VlanId.vlanId(networkId.id().shortValue()))
+ .matchInPort(inCp.port());
+
+ treatmentBuilder = DefaultTrafficTreatment.builder(commonTreatment)
+ .popVlan()
+ .setOutput(egressPoint.port());
+
+ ruleBuilder = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .forDevice(egressPoint.deviceId())
+ .withSelector(selectorBuilder.build())
+ .withTreatment(treatmentBuilder.build())
+ .withIdleTimeout(flowRule.timeout())
+ .withPriority(flowRule.priority());
+
+ outRules.add(ruleBuilder.build());
+
return outRules;
}