CORD-416 Implemented ARP proxy for service IPs
Added ARP proxy which sends fake ARP reply for service IPs.
Change-Id: I0583ee994def2a429701c0375af5203bdfaa39c5
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
index 127c7c9..5b3f8aa 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
@@ -23,6 +23,7 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.util.ItemNotFoundException;
import org.onlab.packet.IpAddress;
@@ -56,6 +57,9 @@
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
import org.onosproject.openstackswitching.OpenstackNetwork;
import org.onosproject.openstackswitching.OpenstackPort;
import org.onosproject.openstackswitching.OpenstackSubnet;
@@ -135,6 +139,9 @@
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PacketService packetService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OvsdbController controller;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -154,6 +161,7 @@
private final DeviceListener deviceListener = new InternalDeviceListener();
private final HostListener hostListener = new InternalHostListener();
+ private final PacketProcessor packetProcessor = new InternalPacketProcessor();
private final OvsdbHandler ovsdbHandler = new OvsdbHandler();
private final BridgeHandler bridgeHandler = new BridgeHandler();
@@ -163,6 +171,7 @@
private ConsistentMap<CordVtnNode, NodeState> nodeStore;
private Map<HostId, OpenstackNetwork> hostNetMap = Maps.newHashMap();
private CordVtnRuleInstaller ruleInstaller;
+ private CordVtnArpProxy arpProxy;
private enum NodeState {
@@ -223,6 +232,10 @@
mastershipService,
DEFAULT_TUNNEL);
+ arpProxy = new CordVtnArpProxy(appId, packetService);
+ packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
+ arpProxy.requestPacket();
+
deviceService.addListener(deviceListener);
hostService.addListener(hostListener);
@@ -233,6 +246,7 @@
protected void deactivate() {
deviceService.removeListener(deviceListener);
hostService.removeListener(hostListener);
+ packetService.removeProcessor(packetProcessor);
eventExecutor.shutdown();
nodeStore.clear();
@@ -920,17 +934,18 @@
log.info("VM {} is detected", host.id());
hostNetMap.put(host.id(), vNet);
+ CordService service = getCordService(vNet);
+ if (service != null) {
+ // TODO check if the service needs an update on its group buckets after done CORD-433
+ ruleInstaller.updateServiceGroup(service);
+ arpProxy.addServiceIp(service.serviceIp());
+ }
+
ruleInstaller.populateBasicConnectionRules(
host,
hostIp,
checkNotNull(getRemoteIp(host.location().deviceId())).getIp4Address(),
vNet);
-
- CordService service = getCordService(vNet);
- // TODO check if the service needs an update on its group buckets after done CORD-433
- if (service != null) {
- ruleInstaller.updateServiceGroup(service);
- }
}
@Override
@@ -950,12 +965,37 @@
ruleInstaller.removeBasicConnectionRules(host);
CordService service = getCordService(vNet);
- // TODO check if the service needs an update on its group buckets after done CORD-433
if (service != null) {
+ // TODO check if the service needs an update on its group buckets after done CORD-433
ruleInstaller.updateServiceGroup(service);
+
+ if (getHostsWithOpenstackNetwork(vNet).isEmpty()) {
+ arpProxy.removeServiceIp(service.serviceIp());
+ }
}
hostNetMap.remove(host.id());
}
}
+
+ private class InternalPacketProcessor implements PacketProcessor {
+
+ @Override
+ public void process(PacketContext context) {
+ if (context.isHandled()) {
+ return;
+ }
+
+ Ethernet ethPacket = context.inPacket().parsed();
+ if (ethPacket == null) {
+ return;
+ }
+
+ if (ethPacket.getEtherType() != Ethernet.TYPE_ARP) {
+ return;
+ }
+
+ arpProxy.processArpPacket(context, ethPacket);
+ }
+ }
}