[ONOS-7863] Initial support GENEVE tunnel at SONA
Change-Id: Ia85d32e8068c22d59082dceccc0d911f8acb5f02
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index 98bd413..e5301e5 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -434,26 +434,31 @@
Set<String> networkIds = Sets.newConcurrentHashSet();
switch (type.toUpperCase()) {
- case "FLAT" :
+ case Constants.FLAT :
networkIds = augmentedNetworkMap.asJavaMap().entrySet().stream()
.filter(e -> e.getValue().type() == FLAT)
.map(Map.Entry::getKey).collect(Collectors.toSet());
break;
- case "VXLAN" :
+ case Constants.VXLAN :
networkIds = augmentedNetworkMap.asJavaMap().entrySet().stream()
- .filter(e -> e.getValue().type() == Type.VXLAN)
+ .filter(e -> e.getValue().type() == VXLAN)
.map(Map.Entry::getKey).collect(Collectors.toSet());
break;
- case "GRE" :
+ case Constants.GRE :
networkIds = augmentedNetworkMap.asJavaMap().entrySet().stream()
- .filter(e -> e.getValue().type() == Type.GRE)
+ .filter(e -> e.getValue().type() == GRE)
.map(Map.Entry::getKey).collect(Collectors.toSet());
break;
- case "VLAN" :
+ case Constants.VLAN :
networkIds = augmentedNetworkMap.asJavaMap().entrySet().stream()
.filter(e -> e.getValue().type() == VLAN)
.map(Map.Entry::getKey).collect(Collectors.toSet());
break;
+ case Constants.GENEVE :
+ networkIds = augmentedNetworkMap.asJavaMap().entrySet().stream()
+ .filter(e -> e.getValue().type() == GENEVE)
+ .map(Map.Entry::getKey).collect(Collectors.toSet());
+ break;
default:
break;
}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index 5a324ee..a9eef09 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -83,6 +83,7 @@
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GRE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VLAN;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VXLAN;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GENEVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterForNetwork;
@@ -341,9 +342,12 @@
return;
}
- switch (osNet.getNetworkType()) {
+ Type netType = osNetworkService.networkType(osNet.getId());
+
+ switch (netType) {
case VXLAN:
case GRE:
+ case GENEVE:
PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(),
osNetworkService, osNodeService.node(instPort.deviceId()));
@@ -406,6 +410,11 @@
final String error = String.format(errorFormat, floatingIp, cNode.hostname());
throw new IllegalStateException(error);
}
+ if (netType == GENEVE && cNode.dataIp() == null) {
+ final String errorFormat = ERR_FLOW + "GENEVE mode is not ready for %s";
+ final String error = String.format(errorFormat, floatingIp, cNode.hostname());
+ throw new IllegalStateException(error);
+ }
if (netType == VLAN && cNode.vlanIntf() == null) {
final String errorFormat = ERR_FLOW + "VLAN mode is not ready for %s";
final String error = String.format(errorFormat, floatingIp, cNode.hostname());
@@ -436,9 +445,10 @@
externalTreatmentBuilder.popVlan();
}
- switch (osNet.getNetworkType()) {
+ switch (netType) {
case VXLAN:
case GRE:
+ case GENEVE:
PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(),
osNetworkService, selectedGatewayNode);
externalTreatmentBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID()))
@@ -479,9 +489,12 @@
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPSrc(instPort.ipAddress().toIpPrefix());
- switch (osNet.getNetworkType()) {
+ Type netType = osNetworkService.networkType(osNet.getId());
+
+ switch (netType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.valueOf(osNet.getProviderSegID()));
break;
case VLAN:
@@ -494,7 +507,6 @@
}
TrafficSelector selector = sBuilder.build();
- Type netType = osNetworkService.networkType(osNet.getId());
osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index bc02119..d1864d7 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -96,7 +96,10 @@
import static org.onosproject.openstacknetworking.api.Constants.STAT_OUTBOUND_TABLE;
import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.FLAT;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GENEVE;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GRE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VLAN;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VXLAN;
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT;
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT_DEFAULT;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetType;
@@ -460,21 +463,25 @@
// take ICMP request to a subnet gateway through gateway node group
Network net = osNetworkAdminService.network(osSubnet.getNetworkId());
+ Type netType = osNetworkAdminService.networkType(osSubnet.getNetworkId());
Set<Subnet> routableSubnets = routableSubnets(osRouter, osSubnet.getId());
- switch (net.getNetworkType()) {
+ switch (netType) {
case VXLAN:
setGatewayIcmpForVxlan(osSubnet, srcNatGw, net, routableSubnets, install);
break;
case GRE:
setGatewayIcmpForGre(osSubnet, srcNatGw, net, routableSubnets, install);
break;
+ case GENEVE:
+ setGatewayIcmpForGeneve(osSubnet, srcNatGw, net, routableSubnets, install);
+ break;
case VLAN:
setGatewayIcmpForVlan(osSubnet, srcNatGw, net, routableSubnets, install);
break;
default:
final String error = String.format("%s %s", ERR_UNSUPPORTED_NET_TYPE,
- net.getNetworkType().toString());
+ netType.toString());
throw new IllegalStateException(error);
}
@@ -502,7 +509,7 @@
network.getProviderSegID(),
osSubnet,
routableSubnets,
- Type.VXLAN,
+ VXLAN,
install));
}
@@ -519,7 +526,24 @@
network.getProviderSegID(),
osSubnet,
routableSubnets,
- Type.GRE,
+ GRE,
+ install));
+ }
+
+ private void setGatewayIcmpForGeneve(Subnet osSubnet,
+ OpenstackNode srcNatGw,
+ Network network,
+ Set<Subnet> routableSubnets,
+ boolean install) {
+ osNodeService.completeNodes(COMPUTE).stream()
+ .filter(cNode -> cNode.dataIp() != null)
+ .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
+ cNode,
+ srcNatGw,
+ network.getProviderSegID(),
+ osSubnet,
+ routableSubnets,
+ GENEVE,
install));
}
@@ -629,6 +653,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
setInternalRouterRulesForTunnel(deviceId, srcSegId, dstSegId,
srcSubnet, dstSubnet, install);
break;
@@ -766,6 +791,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.parseLong(segmentId));
break;
case VLAN:
@@ -783,6 +809,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
PortNumber portNum = tunnelPortNumByNetType(networkType, osNode);
tBuilder.extension(buildExtension(
deviceService,
@@ -883,6 +910,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.parseLong(segmentId));
PortNumber portNum = tunnelPortNumByNetType(networkType, osNode);
@@ -994,6 +1022,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.parseLong(segmentId));
break;
case VLAN:
@@ -1034,6 +1063,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.parseLong(segmentId));
break;
case VLAN:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index d1072cb..9ee5f3d 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -280,6 +280,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
tBuilder.setTunnelId(Long.parseLong(segmentId));
break;
case VLAN:
@@ -334,6 +335,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
PortNumber portNum = tunnelPortNumByNetType(networkType, gNode);
tmpBuilder.extension(RulePopulatorUtil.buildExtension(
deviceService,
@@ -372,6 +374,7 @@
switch (networkType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.parseLong(segmentId));
break;
case VLAN:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
index 15920fe..140facf 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
@@ -107,6 +107,7 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_DROP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_HOOK_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_RULE;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GENEVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GRE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VLAN;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VXLAN;
@@ -585,7 +586,7 @@
if (netType == VLAN) {
sBuilder.matchVlanId(VlanId.vlanId(segId));
- } else if (netType == VXLAN || netType == GRE) {
+ } else if (netType == VXLAN || netType == GRE || netType == GENEVE) {
sBuilder.matchTunnelId(Long.valueOf(segId));
} else {
log.warn("Cannot tag the VID due to lack of support of virtual network type {}", netType);
@@ -912,6 +913,7 @@
switch (netType) {
case VXLAN:
case GRE:
+ case GENEVE:
sBuilder.matchTunnelId(Long.valueOf(segId));
break;
case VLAN:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
index 3ac0c0d..0e09b03 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
@@ -86,6 +86,7 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_REQUEST_RULE;
import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.FLAT;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GENEVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GRE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VLAN;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VXLAN;
@@ -316,7 +317,7 @@
if (netType == VLAN) {
sBuilder.matchVlanId(VlanId.vlanId(network.getProviderSegID()));
tBuilder.popVlan();
- } else if (netType == VXLAN || netType == GRE) {
+ } else if (netType == VXLAN || netType == GRE || netType == GENEVE) {
// do not remove fake gateway ARP rules, if there is another gateway
// which has the same subnet that to be removed
// this only occurs if we have duplicated subnets associated with
@@ -381,6 +382,7 @@
switch (netType) {
case VXLAN:
case GRE:
+ case GENEVE:
setRemoteArpRequestRuleForTunnel(port, install);
break;
case VLAN:
@@ -407,6 +409,9 @@
case GRE:
setArpReplyRuleForGre(port, install);
break;
+ case GENEVE:
+ setArpReplyRuleForGeneve(port, install);
+ break;
case VLAN:
setArpReplyRuleForVlan(port, install);
break;
@@ -500,6 +505,22 @@
}
/**
+ * Installs flow rules to match ARP reply packets only for GENEVE.
+ *
+ * @param port instance port
+ * @param install installation flag
+ */
+ private void setArpReplyRuleForGeneve(InstancePort port, boolean install) {
+
+ OpenstackNode localNode = osNodeService.node(port.deviceId());
+
+ TrafficSelector selector = getArpReplySelectorForGeneve(port);
+
+ setLocalArpReplyTreatmentForGeneve(selector, port, install);
+ setRemoteArpTreatmentForTunnel(selector, port, localNode, install);
+ }
+
+ /**
* Installs flow rules to match ARP reply packets only for VLAN.
*
* @param port instance port
@@ -524,6 +545,11 @@
}
// a helper method
+ private TrafficSelector getArpReplySelectorForGeneve(InstancePort port) {
+ return getArpReplySelectorForVnet(port, GENEVE);
+ }
+
+ // a helper method
private TrafficSelector getArpReplySelectorForVlan(InstancePort port) {
return getArpReplySelectorForVnet(port, VLAN);
}
@@ -562,6 +588,13 @@
}
// a helper method
+ private void setLocalArpReplyTreatmentForGeneve(TrafficSelector selector,
+ InstancePort port,
+ boolean install) {
+ setLocalArpReplyTreatmentForVnet(selector, port, GENEVE, install);
+ }
+
+ // a helper method
private void setLocalArpReplyTreatmentForVlan(TrafficSelector selector,
InstancePort port,
boolean install) {
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index e4b22b5..0fab37e 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -500,6 +500,7 @@
switch (type) {
case VXLAN:
case GRE:
+ case GENEVE:
setNetworkBlockRulesForTunnel(network.getProviderSegID(), install);
break;
case VLAN:
@@ -734,7 +735,7 @@
/**
* Configures L2 forwarding rules.
- * Currently, SONA supports Flat, VXLAN, GRE and VLAN modes.
+ * Currently, SONA supports Flat, VXLAN, GRE, GENEVE and VLAN modes.
*
* @param instPort instance port object
* @param install install flag, add the rule if true, remove it otherwise
@@ -745,6 +746,7 @@
switch (type) {
case VXLAN:
case GRE:
+ case GENEVE:
setNetworkRulesForTunnel(instPort, install);
break;
case VLAN:
@@ -794,6 +796,7 @@
switch (type) {
case VXLAN:
case GRE:
+ case GENEVE:
removeVportRulesForTunnel(instPort);
break;
case VLAN:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index c4e3803..ce12d77 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -156,9 +156,6 @@
private static final String ERR_FLOW = "Failed set flows for floating IP %s: ";
- private static final String VXLAN = "VXLAN";
- private static final String GRE = "GRE";
- private static final String VLAN = "VLAN";
private static final String DL_DST = "dl_dst=";
private static final String NW_DST = "nw_dst=";
private static final String DEFAULT_REQUEST_STRING = "sudo ovs-appctl ofproto/trace br-int ip";
@@ -770,9 +767,9 @@
.append(COMMA);
String modifiedDstIp = dstIp;
- if (osNetService.networkType(srcInstancePort.networkId()) == Type.VXLAN ||
- osNetService.networkType(srcInstancePort.networkId()) == Type.GRE ||
- osNetService.networkType(srcInstancePort.networkId()) == Type.VLAN) {
+ Type netType = osNetService.networkType(srcInstancePort.networkId());
+ if (netType == Type.VXLAN || netType == Type.GRE ||
+ netType == Type.VLAN || netType == Type.GENEVE) {
if (srcIp.equals(dstIp)) {
modifiedDstIp = osNetService.gatewayIp(srcInstancePort.portId());
requestStringBuilder.append(DL_DST)
@@ -798,9 +795,10 @@
.append(dstIp)
.append(COMMA);
- if (osNetService.networkType(srcInstancePort.networkId()) == Type.VXLAN ||
- osNetService.networkType(srcInstancePort.networkId()) == Type.GRE ||
- osNetService.networkType(srcInstancePort.networkId()) == Type.VLAN) {
+ Type netType = osNetService.networkType(srcInstancePort.networkId());
+
+ if (netType == Type.VXLAN || netType == Type.GRE ||
+ netType == Type.VLAN || netType == Type.GENEVE) {
requestStringBuilder.append(TUN_ID)
.append(osNetService.segmentId(srcInstancePort.networkId()))
.append(COMMA);
@@ -1083,6 +1081,8 @@
return osNode.vxlanTunnelPortNum();
case GRE:
return osNode.greTunnelPortNum();
+ case GENEVE:
+ return osNode.geneveTunnelPortNum();
default:
return null;
}