[ONOS-6186] Implement VLAN based virtual network provisioning and logical switching
Change-Id: I1dcee5377b3d4d9ec5fc3d6bc851a90a016074dc
diff --git a/apps/openstacknetworking/network-cfg.json b/apps/openstacknetworking/network-cfg.json
new file mode 100644
index 0000000..556de59
--- /dev/null
+++ b/apps/openstacknetworking/network-cfg.json
@@ -0,0 +1,51 @@
+{
+ "apps" : {
+ "org.onosproject.openstacknode" : {
+ "openstacknode" : {
+ "nodes" : [
+ {
+ "hostname" : "compute-01",
+ "type" : "COMPUTE",
+ "managementIp" : "172.16.130.4",
+ "vlanPort" : "eth2",
+ "dataIp" : "172.16.130.4",
+ "integrationBridge" : "of:00000000000000a1"
+ },
+ {
+ "hostname" : "compute-02",
+ "type" : "COMPUTE",
+ "managementIp" : "172.16.130.6",
+ "vlanPort" : "eth2",
+ "dataIp" : "172.16.130.6",
+ "integrationBridge" : "of:00000000000000a2"
+ },
+ {
+ "hostname" : "gateway-01",
+ "type" : "GATEWAY",
+ "managementIp" : "172.16.130.3",
+ "dataIp" : "172.16.130.3",
+ "vlanPort" : "eth2",
+ "integrationBridge" : "of:00000000000000a3",
+ "routerBridge" : "of:00000000000000b1",
+ "uplinkPort" : "quagga-router",
+ "routerController" : "172.17.0.2"
+
+ }
+ ]
+ }
+ }
+ },
+ "devices" : {
+ "of:00000000000000a1" : {
+ "basic" : {
+ "driver" : "sona"
+ }
+ },
+ "of:00000000000000a2" : {
+ "basic" : {
+ "driver" : "sona"
+ }
+ }
+ }
+}
+
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackNetworkListCommand.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackNetworkListCommand.java
index 8b489c9..a00eff9 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackNetworkListCommand.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackNetworkListCommand.java
@@ -41,7 +41,7 @@
description = "Lists all OpenStack networks")
public class OpenstackNetworkListCommand extends AbstractShellCommand {
- private static final String FORMAT = "%-40s%-20s%-20s%-8s";
+ private static final String FORMAT = "%-40s%-20s%-20s%-20s%-8s";
@Override
protected void execute() {
@@ -58,7 +58,7 @@
return;
}
- print(FORMAT, "ID", "Name", "VNI", "Subnets");
+ print(FORMAT, "ID", "Name", "Network Mode", "VNI", "Subnets");
for (Network net: networks) {
List<String> subnets = service.subnets().stream()
.filter(subnet -> subnet.getNetworkId().equals(net.getId()))
@@ -66,6 +66,7 @@
.collect(Collectors.toList());
print(FORMAT, net.getId(),
net.getName(),
+ net.getNetworkType().toString(),
net.getProviderSegID(),
subnets.isEmpty() ? "" : subnets);
}
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index b399fdf..975096f 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -23,6 +23,7 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.mastership.MastershipService;
@@ -106,8 +107,18 @@
}
private void setNetworkRules(InstancePort instPort, boolean install) {
- setTunnelTagFlowRules(instPort, install);
- setForwardingRules(instPort, install);
+ switch (osNetworkService.network(instPort.networkId()).getNetworkType()) {
+ case VXLAN:
+ setTunnelTagFlowRules(instPort, install);
+ setForwardingRules(instPort, install);
+ break;
+ case VLAN:
+ setVlanTagFlowRules(instPort, install);
+ setForwardingRulesForVlan(instPort, install);
+ break;
+ default:
+ break;
+ }
}
private void setForwardingRules(InstancePort instPort, boolean install) {
@@ -159,6 +170,53 @@
});
}
+ private void setForwardingRulesForVlan(InstancePort instPort, boolean install) {
+ // switching rules for the instPorts in the same node
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(instPort.ipAddress().toIpPrefix())
+ .matchVlanId(getVlanId(instPort))
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .popVlan()
+ .setEthDst(instPort.macAddress())
+ .setOutput(instPort.portNumber())
+ .build();
+
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ instPort.deviceId(),
+ selector,
+ treatment,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_SWITCHING_RULE,
+ install);
+
+ // switching rules for the instPorts in the remote node
+ osNodeService.completeNodes().stream()
+ .filter(osNode -> osNode.type() == COMPUTE)
+ .filter(osNode -> !osNode.intBridge().equals(instPort.deviceId()))
+ .filter(osNode -> osNode.vlanPort().isPresent())
+ .forEach(osNode -> {
+ TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
+ .setOutput(osNodeService.vlanPort(osNode.intBridge()).get())
+ .build();
+
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ osNode.intBridge(),
+ selector,
+ treatmentToRemote,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_SWITCHING_RULE,
+ install);
+ });
+
+ }
+
private void setTunnelTagFlowRules(InstancePort instPort, boolean install) {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
@@ -180,6 +238,43 @@
install);
}
+ private void setVlanTagFlowRules(InstancePort instPort, boolean install) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchInPort(instPort.portNumber())
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .pushVlan()
+ .setVlanId(getVlanId(instPort))
+ .build();
+
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ instPort.deviceId(),
+ selector,
+ treatment,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_TUNNEL_TAG_RULE,
+ install);
+
+ }
+
+ private VlanId getVlanId(InstancePort instPort) {
+ Network osNet = osNetworkService.network(instPort.networkId());
+
+ if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
+ final String error = String.format(
+ ERR_SET_FLOWS + "Failed to get VNI for %s",
+ instPort, osNet == null ? "<none>" : osNet.getName());
+ throw new IllegalStateException(error);
+ }
+
+ return VlanId.vlanId(osNet.getProviderSegID());
+ }
+
+
private Long getVni(InstancePort instPort) {
Network osNet = osNetworkService.network(instPort.networkId());
if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {