Fix: provide the ICMP connectivity to external gateway
Change-Id: I893037715c93dd228fc23eb1c706abba96cd4786
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingIcmpHandler.java
index 3f8a362..1ff77a8 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingIcmpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingIcmpHandler.java
@@ -46,6 +46,7 @@
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Router;
import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.model.network.Subnet;
@@ -57,6 +58,7 @@
import org.slf4j.Logger;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@@ -71,6 +73,8 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ICMP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.ROUTING_TABLE;
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT;
+import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.FLAT;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getExternalIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValueAsBoolean;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.NXM_NX_IP_TTL;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.NXM_OF_ICMP_TYPE;
@@ -169,12 +173,42 @@
osNodeService.completeNodes(COMPUTE).stream()
.filter(cNode -> cNode.dataIp() != null)
- .forEach(cNode -> setRoutableSubnetsIcmpRules(
- cNode, segId, routableSubnets, gatewayIp, netType, install));
+ .forEach(cNode -> {
+ setRoutableSubnetsIcmpRules(cNode, segId, osSubnet,
+ routableSubnets, gatewayIp, netType, install);
+ setExtGatewayIcmpReplyRules(cNode, routerIface,
+ netType, install);
+ });
+ }
+
+ private void setExtGatewayIcmpReplyRules(OpenstackNode osNode,
+ RouterInterface routerIface,
+ Type networkType, boolean install) {
+
+ if (networkType == FLAT) {
+ return;
+ }
+
+ Optional<Router> osRouter = osRouterService.routers().stream()
+ .filter(router -> osRouterService.routerInterfaces(routerIface.getId()) != null)
+ .findAny();
+
+ if (!osRouter.isPresent()) {
+ log.error("Cannot find a router for router interface {} ", routerIface);
+ return;
+ }
+
+ IpAddress natAddress = getExternalIp(osRouter.get(), osNetworkService);
+ if (natAddress == null) {
+ return;
+ }
+
+ setGatewayIcmpReplyRule(osNode, null, natAddress, networkType, install);
}
private void setRoutableSubnetsIcmpRules(OpenstackNode osNode,
String segmentId,
+ Subnet updatedSubnet,
Set<Subnet> routableSubnets,
IpAddress gatewayIp,
Type networkType,
@@ -184,6 +218,11 @@
routableSubnets.forEach(subnet -> {
setGatewayIcmpReplyRule(osNode, segmentId,
IpAddress.valueOf(subnet.getGateway()), networkType, install);
+
+ Network network = osNetworkService.network(subnet.getNetworkId());
+
+ setGatewayIcmpReplyRule(osNode, network.getProviderSegID(),
+ IpAddress.valueOf(updatedSubnet.getGateway()), networkType, install);
});
}
@@ -208,17 +247,19 @@
.matchIcmpCode(CODE_ECHO_REQEUST)
.matchIPDst(gatewayIp.getIp4Address().toIpPrefix());
- switch (networkType) {
- case VXLAN:
- case GRE:
- case GENEVE:
- sBuilder.matchTunnelId(Long.parseLong(segmentId));
- break;
- case VLAN:
- sBuilder.matchVlanId(VlanId.vlanId(segmentId));
- break;
- default:
- break;
+ if (segmentId != null) {
+ switch (networkType) {
+ case VXLAN:
+ case GRE:
+ case GENEVE:
+ sBuilder.matchTunnelId(Long.parseLong(segmentId));
+ break;
+ case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(segmentId));
+ break;
+ default:
+ break;
+ }
}
Device device = deviceService.getDevice(osNode.intgBridge());