Fix: correct the logic of obtaining ext ip address from ext GW
Change-Id: I681a05eff40067c0b945022d16f2db9e514291d3
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index ec7204e..7e65524 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -58,17 +58,14 @@
import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
import org.onosproject.openstacknetworking.api.PreCommitPortService;
-import org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
-import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.NetFloatingIP;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.Router;
-import org.openstack4j.model.network.RouterInterface;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@@ -99,6 +96,7 @@
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterForNetwork;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.floatingIpByInstancePort;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getExternalIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
@@ -530,65 +528,43 @@
}
private void setFakeGatewayArpRuleByRouter(Router router, boolean install) {
- setFakeGatewayArpRuleByGateway(router.getId(), install);
- }
-
- private Set<IP> getExternalGatewaySnatIps(String routerId) {
- if (routerId == null) {
- return ImmutableSet.of();
- }
-
- Set<String> portIds = osRouterAdminService.routerInterfaces(routerId)
- .stream()
- .map(RouterInterface::getPortId)
- .collect(Collectors.toSet());
-
- return portIds.stream()
- .map(pid -> osNetworkAdminService.port(pid))
- .filter(p -> Objects.equals(p.getDeviceOwner(), DEVICE_OWNER_ROUTER_GW))
- .flatMap(p -> p.getFixedIps().stream())
- .collect(Collectors.toSet());
- }
-
- private void setFakeGatewayArpRuleByGateway(String routerId, boolean install) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
- setFakeGatewayArpRuleByIps(getExternalGatewaySnatIps(routerId), install);
+ setFakeGatewayArpRuleByExternalIp(getExternalIp(router, osNetworkService), install);
}
}
- private void setFakeGatewayArpRuleByIps(Set<IP> ips, boolean install) {
- ips.forEach(ip -> {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(EthType.EtherType.ARP.ethType().toShort())
- .matchArpOp(ARP.OP_REQUEST)
- .matchArpTpa(Ip4Address.valueOf(ip.getIpAddress()))
- .build();
+ private void setFakeGatewayArpRuleByExternalIp(IpAddress ipAddress, boolean install) {
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setArpOp(ARP.OP_REPLY)
- .setArpSha(MacAddress.valueOf(gatewayMac))
- .setArpSpa(Ip4Address.valueOf(ip.getIpAddress()))
- .setOutput(PortNumber.IN_PORT)
- .build();
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REQUEST)
+ .matchArpTpa(ipAddress.getIp4Address())
+ .build();
- osNodeService.completeNodes(GATEWAY).forEach(n ->
- osFlowRuleService.setRule(
- appId,
- n.intgBridge(),
- selector,
- treatment,
- PRIORITY_ARP_GATEWAY_RULE,
- GW_COMMON_TABLE,
- install
- )
- );
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setArpOp(ARP.OP_REPLY)
+ .setArpSha(MacAddress.valueOf(gatewayMac))
+ .setArpSpa(ipAddress.getIp4Address())
+ .setOutput(PortNumber.IN_PORT)
+ .build();
- if (install) {
- log.info("Install ARP Rule for Gateway Snat {}", ip.getIpAddress());
- } else {
- log.info("Uninstall ARP Rule for Gateway Snat {}", ip.getIpAddress());
- }
- });
+ osNodeService.completeNodes(GATEWAY).forEach(n ->
+ osFlowRuleService.setRule(
+ appId,
+ n.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_GATEWAY_RULE,
+ GW_COMMON_TABLE,
+ install
+ )
+ );
+
+ if (install) {
+ log.info("Install ARP Rule for Gateway Snat {}", ipAddress);
+ } else {
+ log.info("Uninstall ARP Rule for Gateway Snat {}", ipAddress);
+ }
}
/**
@@ -617,14 +593,18 @@
case OPENSTACK_PORT_CREATED:
case OPENSTACK_PORT_UPDATED:
eventExecutor.execute(() ->
- setFakeGatewayArpRuleByIps(
- (Set<IP>) event.port().getFixedIps(), true)
+ setFakeGatewayArpRuleByExternalIp(
+ IpAddress.valueOf(event.port().getFixedIps()
+ .stream().findAny().get().getIpAddress()),
+ true)
);
break;
case OPENSTACK_PORT_REMOVED:
eventExecutor.execute(() ->
- setFakeGatewayArpRuleByIps(
- (Set<IP>) event.port().getFixedIps(), false)
+ setFakeGatewayArpRuleByExternalIp(
+ IpAddress.valueOf(event.port().getFixedIps()
+ .stream().findAny().get().getIpAddress()),
+ false)
);
break;
default:
@@ -654,27 +634,20 @@
switch (event.type()) {
case OPENSTACK_ROUTER_CREATED:
+ // add a router with external gateway
+ case OPENSTACK_ROUTER_GATEWAY_ADDED:
+ // add a gateway manually after adding a router
eventExecutor.execute(() ->
- // add a router with external gateway
- setFakeGatewayArpRuleByRouter(event.subject(), true)
+ // add a router with external gateway
+ setFakeGatewayArpRuleByRouter(event.subject(), true)
);
break;
case OPENSTACK_ROUTER_REMOVED:
- eventExecutor.execute(() ->
- // remove a router with external gateway
- setFakeGatewayArpRuleByRouter(event.subject(), false)
- );
- break;
- case OPENSTACK_ROUTER_GATEWAY_ADDED:
- eventExecutor.execute(() ->
- // add a gateway manually after adding a router
- setFakeGatewayArpRuleByGateway(event.subject().getId(), true)
- );
- break;
+ // remove a router with external gateway
case OPENSTACK_ROUTER_GATEWAY_REMOVED:
+ // remove a gateway from an existing router
eventExecutor.execute(() ->
- // remove a gateway from an existing router
- setFakeGatewayArpRuleByGateway(event.subject().getId(), false)
+ setFakeGatewayArpRuleByRouter(event.subject(), false)
);
break;
case OPENSTACK_FLOATING_IP_ASSOCIATED:
@@ -884,8 +857,7 @@
private boolean isGwSelectedByComputeNode(Set<OpenstackNode> gws,
OpenstackNode computeNode,
OpenstackNode gwNode) {
- return OpenstackNetworkingUtil
- .getGwByComputeDevId(gws, computeNode.intgBridge())
+ return getGwByComputeDevId(gws, computeNode.intgBridge())
.intgBridge().equals(gwNode.intgBridge());
}
@@ -912,6 +884,7 @@
if (getArpMode() == null) {
return;
}
+ log.info("ARP mode is {}", getArpMode());
switch (getArpMode()) {
case ARP_PROXY_MODE:
@@ -972,6 +945,7 @@
install
);
+ log.info("calling setFakeGatewayArpRuleByRouter.. ");
osRouterAdminService.routers().stream()
.filter(router -> router.getExternalGatewayInfo() != null)
.forEach(router -> setFakeGatewayArpRuleByRouter(router, install));
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
index 3e4b5ab..f4947f0 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
@@ -55,12 +55,10 @@
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
-import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.Router;
import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.model.network.Subnet;
-import org.openstack4j.openstack.networking.domain.NeutronIP;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@@ -70,7 +68,6 @@
import java.nio.ByteBuffer;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@@ -85,6 +82,8 @@
import static org.onosproject.openstacknetworking.api.Constants.GW_COMMON_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_INTERNAL_ROUTING_RULE;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalIpFromSubnet;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterFromSubnet;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
import static org.slf4j.LoggerFactory.getLogger;
@@ -320,30 +319,19 @@
// this is a request to an external network
log.trace("Icmp request to external {} from {}", dstIp, srcIp);
- RouterInterface routerInterface = routerInterface(srcSubnet);
- if (routerInterface == null) {
- log.warn(ERR_REQ + "failed to get router interface");
- return false;
- }
-
- ExternalGateway externalGateway = externalGateway(routerInterface);
- if (externalGateway == null) {
- log.warn(ERR_REQ + "failed to get external gateway");
- return false;
- }
-
- ExternalPeerRouter externalPeerRouter = osNetworkService.externalPeerRouter(externalGateway);
- if (externalPeerRouter == null) {
- log.warn(ERR_REQ + "failed to get external peer router");
- return false;
- }
-
- IpAddress externalIp = getExternalIp(externalGateway, routerInterface);
+ IpAddress externalIp = externalIpFromSubnet(srcSubnet, osRouterService, osNetworkService);
if (externalIp == null) {
log.warn(ERR_REQ + "failed to get external ip");
return false;
}
+ ExternalPeerRouter externalPeerRouter =
+ externalPeerRouterFromSubnet(srcSubnet, osRouterService, osNetworkService);
+ if (externalPeerRouter == null) {
+ log.warn(ERR_REQ + "failed to get external peer router");
+ return false;
+ }
+
String icmpInfoKey = icmpInfoKey(icmp,
externalIp.toString(),
IPv4.fromIPv4Address(ipPacket.getDestinationAddress()));
@@ -369,24 +357,6 @@
.concat(srcIp)
.concat(dstIp);
}
- private RouterInterface routerInterface(Subnet subnet) {
- checkNotNull(subnet);
- return osRouterService.routerInterfaces().stream()
- .filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
- .findAny().orElse(null);
- }
-
- private ExternalGateway externalGateway(RouterInterface osRouterIface) {
- checkNotNull(osRouterIface);
- Router osRouter = osRouterService.router(osRouterIface.getId());
- if (osRouter == null) {
- return null;
- }
- if (osRouter.getExternalGatewayInfo() == null) {
- return null;
- }
- return osRouter.getExternalGatewayInfo();
- }
private boolean handleEchoReply(IPv4 ipPacket, ICMP icmp) {
String icmpInfoKey = icmpInfoKey(icmp,
@@ -432,38 +402,6 @@
return routableGateways.contains(dstIp);
}
- private IpAddress getExternalIp(ExternalGateway externalGateway, RouterInterface osRouterIface) {
- checkNotNull(externalGateway);
- checkNotNull(osRouterIface);
-
- Router osRouter = osRouterService.router(osRouterIface.getId());
- if (osRouter == null) {
- return null;
- }
-
- Port exGatewayPort = osNetworkService.ports(externalGateway.getNetworkId())
- .stream()
- .filter(port -> Objects.equals(port.getDeviceId(), osRouter.getId()))
- .findAny().orElse(null);
- if (exGatewayPort == null) {
- final String error = String.format(ERR_REQ +
- "no external gateway port for router (ID:%s, name:%s)",
- osRouter.getId(), osRouter.getName());
- throw new IllegalStateException(error);
- }
- Optional<NeutronIP> externalIpAddress =
- (Optional<NeutronIP>) exGatewayPort.getFixedIps().stream().findFirst();
- if (!externalIpAddress.isPresent() || externalIpAddress.get().getIpAddress() == null) {
- final String error = String.format(ERR_REQ +
- "no external gateway IP address for router (ID:%s, name:%s)",
- osRouter.getId(), osRouter.getName());
- log.warn(error);
- return null;
- }
-
- return IpAddress.valueOf(externalIpAddress.get().getIpAddress());
- }
-
private void processRequestForGateway(IPv4 ipPacket, InstancePort instPort) {
ICMP icmpReq = (ICMP) ipPacket.getPayload();
icmpReq.setChecksum((short) 0);
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 4695338..23333c4 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
@@ -15,11 +15,6 @@
*/
package org.onosproject.openstacknetworking.impl;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
@@ -56,18 +51,19 @@
import org.onosproject.store.service.DistributedSet;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
-import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Router;
-import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.model.network.Subnet;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@@ -78,6 +74,8 @@
import static org.onosproject.openstacknetworking.api.Constants.GW_COMMON_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SNAT_RULE;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalIpFromSubnet;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterFromSubnet;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
import static org.slf4j.LoggerFactory.getLogger;
@@ -187,13 +185,15 @@
IpAddress srcIp = IpAddress.valueOf(iPacket.getSourceAddress());
Subnet srcSubnet = getSourceSubnet(srcInstPort, srcIp);
- IpAddress externalGatewayIp = getExternalIp(srcSubnet);
+ IpAddress externalGatewayIp =
+ externalIpFromSubnet(srcSubnet, osRouterService, osNetworkService);
if (externalGatewayIp == null) {
return;
}
- ExternalPeerRouter externalPeerRouter = externalPeerRouter(srcSubnet);
+ ExternalPeerRouter externalPeerRouter =
+ externalPeerRouterFromSubnet(srcSubnet, osRouterService, osNetworkService);
if (externalPeerRouter == null) {
return;
}
@@ -210,26 +210,6 @@
externalGatewayIp, externalPeerRouter);
}
- private ExternalPeerRouter externalPeerRouter(Subnet subnet) {
- RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
- .filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
- .findAny().orElse(null);
- if (osRouterIface == null) {
- return null;
- }
-
- Router osRouter = osRouterService.router(osRouterIface.getId());
- if (osRouter == null) {
- return null;
- }
- if (osRouter.getExternalGatewayInfo() == null) {
- return null;
- }
-
- ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
- return osNetworkService.externalPeerRouter(exGatewayInfo);
- }
-
private Subnet getSourceSubnet(InstancePort instance, IpAddress srcIp) {
Port osPort = osNetworkService.port(instance.portId());
IP fixedIp = osPort.getFixedIps().stream()
@@ -241,47 +221,6 @@
return osNetworkService.subnet(fixedIp.getSubnetId());
}
- private IpAddress getExternalIp(Subnet srcSubnet) {
- RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
- .filter(i -> Objects.equals(i.getSubnetId(), srcSubnet.getId()))
- .findAny().orElse(null);
- if (osRouterIface == null) {
- // this subnet is not connected to the router
- log.trace(ERR_PACKETIN + "source subnet(ID:{}, CIDR:{}) has no router",
- srcSubnet.getId(), srcSubnet.getCidr());
- return null;
- }
-
- Router osRouter = osRouterService.router(osRouterIface.getId());
- if (osRouter.getExternalGatewayInfo() == null) {
- // this router does not have external connectivity
- log.trace(ERR_PACKETIN + "router({}) has no external gateway",
- osRouter.getName());
- return null;
- }
-
- ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
- if (!exGatewayInfo.isEnableSnat()) {
- // SNAT is disabled in this router
- log.trace(ERR_PACKETIN + "router({}) SNAT is disabled", osRouter.getName());
- return null;
- }
-
- // TODO fix openstack4j for ExternalGateway provides external fixed IP list
- Port exGatewayPort = osNetworkService.ports(exGatewayInfo.getNetworkId())
- .stream()
- .filter(port -> Objects.equals(port.getDeviceId(), osRouter.getId()))
- .findAny().orElse(null);
- if (exGatewayPort == null) {
- log.trace(ERR_PACKETIN + "no external gateway port for router({})",
- osRouter.getName());
- return null;
- }
-
- return IpAddress.valueOf(exGatewayPort.getFixedIps().stream()
- .findFirst().get().getIpAddress());
- }
-
private void populateSnatFlowRules(InboundPacket packetIn, InstancePort srcInstPort,
TpPort patPort, IpAddress externalIp, ExternalPeerRouter externalPeerRouter) {
Network osNet = osNetworkService.network(srcInstPort.networkId());
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 25a7e41..27e122d 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
@@ -60,6 +60,7 @@
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterService;
import org.onosproject.openstacknetworking.impl.DefaultInstancePort;
import org.onosproject.openstacknode.api.OpenstackAuth;
import org.onosproject.openstacknode.api.OpenstackAuth.Perspective;
@@ -939,6 +940,98 @@
}
+ /**
+ * Returns the external peer router with specified subnet information.
+ *
+ * @param subnet openstack subnet
+ * @param osRouterService openstack router service
+ * @param osNetworkService openstack network service
+ * @return external peer router
+ */
+ public static ExternalPeerRouter externalPeerRouterFromSubnet(Subnet subnet, OpenstackRouterService osRouterService,
+ OpenstackNetworkService osNetworkService) {
+ Router osRouter = getRouterFromSubnet(subnet, osRouterService);
+ if (osRouter == null) {
+ return null;
+ }
+ if (osRouter.getExternalGatewayInfo() == null) {
+ // this router does not have external connectivity
+ log.trace("router({}) has no external gateway",
+ osRouter.getName());
+ return null;
+ }
+
+ return osNetworkService.externalPeerRouter(osRouter.getExternalGatewayInfo());
+ }
+
+ /**
+ * Returns the external ip address with specified router information.
+ *
+ * @param srcSubnet source subnet
+ * @param osRouterService openstack router service
+ * @param osNetworkService openstack network service
+ * @return external ip address
+ */
+ public static IpAddress externalIpFromSubnet(Subnet srcSubnet,
+ OpenstackRouterService osRouterService,
+ OpenstackNetworkService osNetworkService) {
+
+ Router osRouter = getRouterFromSubnet(srcSubnet, osRouterService);
+
+ if (osRouter.getExternalGatewayInfo() == null) {
+ // this router does not have external connectivity
+ log.trace("router({}) has no external gateway",
+ osRouter.getName());
+ return null;
+ }
+
+ return getExternalIp(osRouter, osNetworkService);
+ }
+
+ /**
+ * Returns the external ip address with specified router information.
+ *
+ * @param router openstack router
+ * @param osNetworkService openstack network service
+ * @return external ip address
+ */
+ public static IpAddress getExternalIp(Router router, OpenstackNetworkService osNetworkService) {
+ if (router == null) {
+ return null;
+ }
+
+ ExternalGateway externalGateway = router.getExternalGatewayInfo();
+ if (externalGateway == null || !externalGateway.isEnableSnat()) {
+ log.trace("Failed to get externalIp for router {} because externalGateway is null or SNAT is disabled",
+ router.getId());
+ return null;
+ }
+
+ // TODO fix openstack4j for ExternalGateway provides external fixed IP list
+ Port exGatewayPort = osNetworkService.ports(externalGateway.getNetworkId())
+ .stream()
+ .filter(port -> Objects.equals(port.getDeviceId(), router.getId()))
+ .findAny().orElse(null);
+
+ if (exGatewayPort == null) {
+ return null;
+ }
+
+ return IpAddress.valueOf(exGatewayPort.getFixedIps().stream()
+ .findAny().get().getIpAddress());
+ }
+
+ private static Router getRouterFromSubnet(Subnet subnet, OpenstackRouterService osRouterService) {
+ RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
+ .filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
+ .findAny().orElse(null);
+ if (osRouterIface == null) {
+ return null;
+ }
+
+ return osRouterService.router(osRouterIface.getId());
+ }
+
private static boolean isDirectPort(String portName) {
return portNamePrefixMap().values().stream().anyMatch(p -> portName.startsWith(p));
}