Fix: do not install unnecessary rules for stateful SNAT case
Change-Id: I4493db87193982e5d02f77711bca96ba4f7daa69
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 96a2c5b..0e2b46b 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
@@ -22,6 +22,8 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cfg.ConfigProperty;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
@@ -65,6 +67,7 @@
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ADMIN_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ICMP_RULE;
@@ -72,10 +75,10 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
import static org.onosproject.openstacknetworking.api.Constants.ROUTING_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.STAT_OUTBOUND_TABLE;
-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.ARP_MODE;
+import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValueAsBoolean;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetType;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
@@ -103,6 +106,9 @@
protected ClusterService clusterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected ComponentConfigService configService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
protected OpenstackNodeService osNodeService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -191,7 +197,7 @@
}
setInternalRoutes(osRouter, osSubnet, true);
- setGatewayIcmp(osSubnet, osRouter, true);
+ setGatewayRules(osSubnet, osRouter, true);
log.info("Connected subnet({}) to {}", osSubnet.getCidr(), osRouter.getName());
}
@@ -212,11 +218,11 @@
}
setInternalRoutes(osRouter, osSubnet, false);
- setGatewayIcmp(osSubnet, osRouter, false);
+ setGatewayRules(osSubnet, osRouter, false);
log.info("Disconnected subnet({}) from {}", osSubnet.getCidr(), osRouter.getName());
}
- private void setGatewayIcmp(Subnet osSubnet, Router osRouter, boolean install) {
+ private void setGatewayRules(Subnet osSubnet, Router osRouter, boolean install) {
OpenstackNode srcNatGw = osNodeService.completeNodes(GATEWAY)
.stream().findFirst().orElse(null);
@@ -229,107 +235,33 @@
return;
}
- // 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 (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,
- netType.toString());
- throw new IllegalStateException(error);
+ // install rules to each compute node for routing IP packets to gateways
+ osNodeService.completeNodes(COMPUTE).stream()
+ .filter(cNode -> cNode.dataIp() != null)
+ .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
+ cNode,
+ srcNatGw,
+ net.getProviderSegID(),
+ osSubnet,
+ routableSubnets,
+ netType,
+ install));
+
+ if (!getStatefulSnatFlag()) {
+ // install rules to punt ICMP packets to controller at gateway node
+ // this rule is only valid for stateless ICMP SNAT case
+ osNodeService.completeNodes(GATEWAY).forEach(gNode ->
+ setReactiveGatewayIcmpRule(
+ IpAddress.valueOf(osSubnet.getGateway()),
+ gNode.intgBridge(), install));
}
- IpAddress gatewayIp = IpAddress.valueOf(osSubnet.getGateway());
- osNodeService.completeNodes(GATEWAY).forEach(gNode ->
- setGatewayIcmpRule(
- gatewayIp,
- gNode.intgBridge(),
- install));
-
final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
- log.debug(updateStr + "ICMP to {}", osSubnet.getGateway());
- }
-
- private void setGatewayIcmpForVxlan(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,
- VXLAN,
- install));
- }
-
- private void setGatewayIcmpForGre(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,
- 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));
- }
-
- private void setGatewayIcmpForVlan(Subnet osSubnet,
- OpenstackNode srcNatGw,
- Network network,
- Set<Subnet> routableSubnets,
- boolean install) {
- osNodeService.completeNodes(COMPUTE).stream()
- .filter(cNode -> cNode.vlanPortNum() != null)
- .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
- cNode,
- srcNatGw,
- network.getProviderSegID(),
- osSubnet,
- routableSubnets,
- VLAN,
- install));
+ log.debug(updateStr + "IP to {}", osSubnet.getGateway());
}
private void setInternalRoutes(Router osRouter, Subnet updatedSubnet, boolean install) {
@@ -393,7 +325,17 @@
return osNetworkAdminService.network(osSubnet.getNetworkId()).getProviderSegID();
}
- private void setGatewayIcmpRule(IpAddress gatewayIp, DeviceId deviceId, boolean install) {
+ private boolean getStatefulSnatFlag() {
+ Set<ConfigProperty> properties = configService.getProperties(OpenstackRoutingSnatHandler.class.getName());
+ return getPropertyValueAsBoolean(properties, USE_STATEFUL_SNAT);
+ }
+
+ private String getArpMode() {
+ Set<ConfigProperty> properties = configService.getProperties(OpenstackRoutingArpHandler.class.getName());
+ return getPropertyValue(properties, ARP_MODE);
+ }
+
+ private void setReactiveGatewayIcmpRule(IpAddress gatewayIp, DeviceId deviceId, boolean install) {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
@@ -546,7 +488,12 @@
Set<Subnet> routableSubnets,
Type networkType,
boolean install) {
- //At first we install flow rules to gateway with segId and gatewayIp of updated subnet
+
+ if (getStatefulSnatFlag() && ARP_BROADCAST_MODE.equals(getArpMode())) {
+ return;
+ }
+
+ // at first we install flow rules to gateway with segId and gatewayIp of updated subnet
setRulesToGatewayWithDstIp(osNode, sourceNatGateway, segmentId,
IpAddress.valueOf(updatedSubnet.getGateway()), networkType, install);