Send GARP packet in case floating ip is associated and gateway node is updated.
Change-Id: I9aa4172bebdc25de5998b3b3123639bce7d865a0
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/InstancePortService.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/InstancePortService.java
index d9890db..b6c99fb 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/InstancePortService.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/InstancePortService.java
@@ -64,6 +64,14 @@
InstancePort instancePort(DeviceId deviceId, PortNumber portNumber);
/**
+ * Returns instance ports with the given device identifier.
+ *
+ * @param deviceId device identifier
+ * @return set of instance ports; empty list if no port exists
+ */
+ Set<InstancePort> instancePort(DeviceId deviceId);
+
+ /**
* Returns all instance ports.
*
* @return set of instance ports; empty list if no port exists
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
index 8d346a9..2ddb181 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
@@ -226,6 +226,15 @@
}
@Override
+ public Set<InstancePort> instancePort(DeviceId deviceId) {
+ Set<InstancePort> ports = instancePortStore.instancePorts().stream()
+ .filter(port -> port.deviceId().equals(deviceId))
+ .collect(Collectors.toSet());
+
+ return ImmutableSet.copyOf(ports);
+ }
+
+ @Override
public Set<InstancePort> instancePorts() {
Set<InstancePort> ports = instancePortStore.instancePorts();
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 084e969..c711ded 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
@@ -51,6 +51,7 @@
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.openstacknetworking.api.Constants;
+import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.InstancePortAdminService;
import org.onosproject.openstacknetworking.api.InstancePortEvent;
@@ -60,10 +61,11 @@
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
-import org.onosproject.openstacknetworking.api.OpenstackRouterService;
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;
@@ -71,6 +73,7 @@
import org.openstack4j.model.network.ExternalGateway;
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.osgi.service.component.ComponentContext;
@@ -98,7 +101,9 @@
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
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.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
import static org.slf4j.LoggerFactory.getLogger;
@@ -124,7 +129,7 @@
protected OpenstackNetworkAdminService osNetworkAdminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected OpenstackRouterService osRouterService;
+ protected OpenstackRouterAdminService osRouterAdminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OpenstackNodeService osNodeService;
@@ -174,7 +179,7 @@
appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
configService.registerProperties(getClass());
localNodeId = clusterService.getLocalNode().id();
- osRouterService.addListener(osRouterListener);
+ osRouterAdminService.addListener(osRouterListener);
osNodeService.addListener(osNodeListener);
osNetworkService.addListener(osNetworkListener);
instancePortService.addListener(instPortListener);
@@ -187,7 +192,7 @@
protected void deactivate() {
packetService.removeProcessor(packetProcessor);
instancePortService.removeListener(instPortListener);
- osRouterService.removeListener(osRouterListener);
+ osRouterAdminService.removeListener(osRouterListener);
osNodeService.removeListener(osNodeListener);
osNetworkService.removeListener(osNetworkListener);
instancePortService.removeListener(instPortListener);
@@ -221,7 +226,7 @@
MacAddress targetMac = null;
- NetFloatingIP floatingIP = osRouterService.floatingIps().stream()
+ NetFloatingIP floatingIP = osRouterAdminService.floatingIps().stream()
.filter(ip -> ip.getFloatingIpAddress().equals(targetIp.toString()))
.findAny().orElse(null);
@@ -359,14 +364,14 @@
if (completedGws.contains(gateway)) {
if (completedGws.size() > 1) {
finalGws.remove(gateway);
- osRouterService.floatingIps().forEach(fip -> {
+ osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, false);
finalGws.add(gateway);
}
});
}
- osRouterService.floatingIps().forEach(fip -> {
+ osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, true);
}
@@ -377,14 +382,14 @@
} else {
if (!completedGws.contains(gateway)) {
finalGws.add(gateway);
- osRouterService.floatingIps().forEach(fip -> {
+ osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, false);
}
});
finalGws.remove(gateway);
if (completedGws.size() >= 1) {
- osRouterService.floatingIps().forEach(fip -> {
+ osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, true);
}
@@ -730,14 +735,14 @@
public void event(InstancePortEvent event) {
InstancePort instPort = event.subject();
- Set<NetFloatingIP> ips = osRouterService.floatingIps();
+ Set<NetFloatingIP> ips = osRouterAdminService.floatingIps();
NetFloatingIP fip = associatedFloatingIp(instPort, ips);
Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
switch (event.type()) {
case OPENSTACK_INSTANCE_PORT_DETECTED:
- osRouterService.floatingIps().stream()
+ osRouterAdminService.floatingIps().stream()
.filter(f -> f.getPortId() != null)
.filter(f -> f.getPortId().equals(instPort.portId()))
.forEach(f -> setFloatingIpArpRule(f, instPort.portId(), gateways, true));
@@ -803,16 +808,68 @@
case OPENSTACK_NODE_COMPLETE:
setDefaultArpRule(osNode, true);
setFloatingIpArpRuleForGateway(osNode, true);
+ sendGratuitousArpToSwitch(event.subject(), true);
break;
case OPENSTACK_NODE_INCOMPLETE:
setDefaultArpRule(osNode, false);
setFloatingIpArpRuleForGateway(osNode, false);
+ sendGratuitousArpToSwitch(event.subject(), false);
break;
+ case OPENSTACK_NODE_REMOVED:
+ sendGratuitousArpToSwitch(event.subject(), false);
+ break;
+
default:
break;
}
}
+ private void sendGratuitousArpToSwitch(OpenstackNode gatewayNode, boolean isCompleteCase) {
+ Set<OpenstackNode> completeGws = ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY));
+
+ if (isCompleteCase) {
+ osNodeService.completeNodes(COMPUTE)
+ .stream()
+ .filter(node -> isGwSelectedByComputeNode(completeGws, node, gatewayNode))
+ .forEach(node -> processGratuitousArpPacketForComputeNode(node, gatewayNode));
+
+ } else {
+ Set<OpenstackNode> oldCompleteGws = Sets.newConcurrentHashSet();
+ oldCompleteGws.addAll(ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY)));
+ oldCompleteGws.add(gatewayNode);
+
+ osNodeService.completeNodes(COMPUTE)
+ .stream()
+ .filter(node -> isGwSelectedByComputeNode(oldCompleteGws, node, gatewayNode))
+ .forEach(node -> {
+ OpenstackNode newSelectedGatewayNode = getGwByComputeDevId(completeGws, node.intgBridge());
+ processGratuitousArpPacketForComputeNode(node, newSelectedGatewayNode);
+ });
+ }
+ }
+
+ private boolean isGwSelectedByComputeNode(Set<OpenstackNode> gws,
+ OpenstackNode computeNode,
+ OpenstackNode gwNode) {
+ return OpenstackNetworkingUtil
+ .getGwByComputeDevId(gws, computeNode.intgBridge())
+ .intgBridge().equals(gwNode.intgBridge());
+ }
+
+ private void processGratuitousArpPacketForComputeNode(OpenstackNode computeNode, OpenstackNode gatewayNode) {
+ instancePortService.instancePort(computeNode.intgBridge()).forEach(instancePort -> {
+ NetFloatingIP floatingIP = OpenstackNetworkingUtil.floatingIpByInstancePort(instancePort,
+ osRouterAdminService);
+ Network network = osNetworkService.network(instancePort.networkId());
+ ExternalPeerRouter externalPeerRouter = OpenstackNetworkingUtil.externalPeerRouterForNetwork(network,
+ osNetworkService, osRouterAdminService);
+ if (floatingIP != null && externalPeerRouter != null) {
+ processGratuitousArpPacketForFloatingIp(
+ floatingIP, instancePort, externalPeerRouter.vlanId(), gatewayNode, packetService);
+ }
+ });
+ }
+
private void setDefaultArpRule(OpenstackNode osNode, boolean install) {
switch (getArpMode()) {
case ARP_PROXY_MODE:
@@ -871,7 +928,7 @@
install
);
- osRouterService.routers().stream()
+ 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/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";
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 b755017..db15e15 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
@@ -42,11 +42,21 @@
import org.apache.sshd.client.future.OpenFuture;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.util.io.NoCloseInputStream;
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.PacketService;
import org.onosproject.openstacknetworking.api.Constants.VnicType;
+import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
@@ -63,10 +73,13 @@
import org.openstack4j.core.transport.ObjectMapperSingleton;
import org.openstack4j.model.ModelEntity;
import org.openstack4j.model.common.Identifier;
+import org.openstack4j.model.network.ExternalGateway;
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.openstack4j.model.network.Subnet;
import org.openstack4j.openstack.OSFactory;
import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
import org.slf4j.Logger;
@@ -84,6 +97,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.ByteBuffer;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.HashMap;
@@ -846,11 +860,126 @@
return traceResult;
}
+ /**
+ * Returns the floating ip with supplied instance port.
+ *
+ * @param instancePort instance port
+ * @param osRouterAdminService openstack router admin service
+ * @return floating ip
+ */
+ public static NetFloatingIP floatingIpByInstancePort(InstancePort instancePort,
+ OpenstackRouterAdminService osRouterAdminService) {
+ return osRouterAdminService.floatingIps().stream()
+ .filter(netFloatingIP -> netFloatingIP.getPortId() != null)
+ .filter(netFloatingIP -> netFloatingIP.getPortId().equals(instancePort.portId()))
+ .findAny().orElse(null);
+ }
+
+ /**
+ * Sends GARP packet with supplied floating ip information.
+ *
+ * @param floatingIP floating ip
+ * @param instancePort instance port
+ * @param vlanId vlain id
+ * @param gatewayNode gateway node
+ * @param packetService packet service
+ */
+ public static void processGratuitousArpPacketForFloatingIp(NetFloatingIP floatingIP,
+ InstancePort instancePort,
+ VlanId vlanId,
+ OpenstackNode gatewayNode,
+ PacketService packetService) {
+ Ethernet ethernet = buildGratuitousArpPacket(floatingIP, instancePort, vlanId);
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(gatewayNode.uplinkPortNum()).build();
+
+ packetService.emit(new DefaultOutboundPacket(gatewayNode.intgBridge(), treatment,
+ ByteBuffer.wrap(ethernet.serialize())));
+ }
+
+ /**
+ * Returns the external peer router with supplied network information.
+ *
+ * @param network network
+ * @param osNetworkService openstack network service
+ * @param osRouterAdminService openstack router admin service
+ * @return external peer router
+ */
+ public static ExternalPeerRouter externalPeerRouterForNetwork(Network network,
+ OpenstackNetworkService osNetworkService,
+ OpenstackRouterAdminService osRouterAdminService) {
+ 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 static boolean isDirectPort(String portName) {
return portNamePrefixMap().values().stream().anyMatch(p -> portName.startsWith(p));
}
/**
+ * Returns GARP packet with supplied floating ip and instance port information.
+ *
+ * @param floatingIP floating ip
+ * @param instancePort instance port
+ * @param vlanId vlan id
+ * @return GARP packet
+ */
+ private static Ethernet buildGratuitousArpPacket(NetFloatingIP floatingIP,
+ InstancePort instancePort,
+ VlanId vlanId) {
+ Ethernet ethernet = new Ethernet();
+ ethernet.setDestinationMACAddress(MacAddress.BROADCAST);
+ ethernet.setSourceMACAddress(instancePort.macAddress());
+ ethernet.setEtherType(Ethernet.TYPE_ARP);
+ ethernet.setVlanID(vlanId.id());
+
+ ARP arp = new ARP();
+ arp.setOpCode(ARP.OP_REPLY);
+ arp.setProtocolType(ARP.PROTO_TYPE_IP);
+ arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+
+ arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
+ arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
+
+ arp.setSenderHardwareAddress(instancePort.macAddress().toBytes());
+ arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
+
+ arp.setSenderProtocolAddress(Ip4Address.valueOf(floatingIP.getFloatingIpAddress()).toInt());
+ arp.setTargetProtocolAddress(Ip4Address.valueOf(floatingIP.getFloatingIpAddress()).toInt());
+
+ ethernet.setPayload(arp);
+
+ return ethernet;
+ }
+
+ /**
* Builds up and a complete endpoint URL from gateway node.
*
* @param node gateway node
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortServiceAdapter.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortServiceAdapter.java
index d4f1d3f..7d9b75a 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortServiceAdapter.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortServiceAdapter.java
@@ -51,6 +51,11 @@
}
@Override
+ public Set<InstancePort> instancePort(DeviceId deviceId) {
+ return ImmutableSet.of();
+ }
+
+ @Override
public Set<InstancePort> instancePorts() {
return ImmutableSet.of();
}