Send GARP packet in case floating ip is associated and gateway node is updated.
Change-Id: I9aa4172bebdc25de5998b3b3123639bce7d865a0
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 60b924b..731a115 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
@@ -38,6 +38,7 @@
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.PacketService;
import org.onosproject.openstacknetworking.api.Constants;
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.InstancePort;
@@ -56,14 +57,10 @@
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
-import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.NetFloatingIP;
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.openstack4j.openstack.networking.domain.NeutronFloatingIP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -84,8 +81,11 @@
import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
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;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGratuitousArpPacketForFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -131,6 +131,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PreCommitPortService preCommitPortService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PacketService packetService;
+
private final ExecutorService eventExecutor = newSingleThreadExecutor(
groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
private final OpenstackRouterListener floatingIpListener = new InternalFloatingIpListener();
@@ -180,15 +183,8 @@
Network osNet = osNetworkService.network(instPort.networkId());
- if (osNet == null) {
- final String errorFormat = ERR_FLOW + "no network(%s) exists";
- final String error = String.format(errorFormat,
- floatingIp.getFloatingIpAddress(),
- instPort.networkId());
- throw new IllegalStateException(error);
- }
-
- ExternalPeerRouter externalPeerRouter = externalPeerRouter(osNet);
+ ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
+ osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
final String errorFormat = ERR_FLOW + "no external peer router found";
throw new IllegalStateException(errorFormat);
@@ -491,36 +487,6 @@
log.trace("Succeeded to set flow rules for upstream on gateway nodes");
}
- private ExternalPeerRouter externalPeerRouter(Network network) {
- if (network == null) {
- return null;
- }
-
- Subnet subnet = osNetworkService.subnets(network.getId()).stream().findAny().orElse(null);
-
- if (subnet == null) {
- return null;
- }
-
- RouterInterface osRouterIface = osRouterAdminService.routerInterfaces().stream()
- .filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
- .findAny().orElse(null);
- if (osRouterIface == null) {
- return null;
- }
-
- Router osRouter = osRouterAdminService.router(osRouterIface.getId());
- if (osRouter == null) {
- return null;
- }
- if (osRouter.getExternalGatewayInfo() == null) {
- return null;
- }
-
- ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
- return osNetworkService.externalPeerRouter(exGatewayInfo);
- }
-
private void associateFloatingIp(NetFloatingIP osFip) {
InstancePort instPort = instancePortService.instancePort(osFip.getPortId());
@@ -533,9 +499,31 @@
// set floating IP rules only if the port is associated to a VM
if (!Strings.isNullOrEmpty(instPort.deviceId().toString())) {
setFloatingIpRules(osFip, instPort, null, true);
+ processGratuitousArpPacket(osFip, instPort);
+
}
}
+ private void processGratuitousArpPacket(NetFloatingIP floatingIP,
+ InstancePort instancePort) {
+ Set<OpenstackNode> gws = ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY));
+
+ Network osNet = osNetworkService.network(instancePort.networkId());
+
+
+ OpenstackNode selectedGw = getGwByInstancePort(gws, instancePort);
+ ExternalPeerRouter externalPeerRouter =
+ externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
+ if (externalPeerRouter == null) {
+ log.error("Failed to process GARP packet for floating ip {} because no external peer router found");
+ return;
+ }
+
+ processGratuitousArpPacketForFloatingIp(floatingIP, instancePort, externalPeerRouter.vlanId(),
+ selectedGw, packetService);
+
+ }
+
private void disassociateFloatingIp(NetFloatingIP osFip, String portId) {
InstancePort instPort = instancePortService.instancePort(portId);
@@ -701,7 +689,8 @@
throw new IllegalStateException(error);
}
- ExternalPeerRouter externalPeerRouter = externalPeerRouter(osNet);
+ ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
+ osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
final String errorFormat = ERR_FLOW + "no external peer router found";
throw new IllegalStateException(errorFormat);
@@ -776,7 +765,7 @@
osPort = osNetworkService.port(fip.getPortId());
osNet = osNetworkService.network(osPort.getNetworkId());
- externalPeerRouter = externalPeerRouter(osNet);
+ externalPeerRouter = externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
final String errorFormat = ERR_FLOW + "no external peer router found";
@@ -809,7 +798,7 @@
osPort = osNetworkService.port(fip.getPortId());
osNet = osNetworkService.network(osPort.getNetworkId());
- externalPeerRouter = externalPeerRouter(osNet);
+ externalPeerRouter = externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
final String errorFormat = ERR_FLOW + "no external peer router found";