Altering ARPHandler and SimpleBroadcastHandler to forward traffic immediately. 13/2413/3
authorColin Dixon <ckd@us.ibm.com>
Tue, 5 Nov 2013 02:30:42 +0000 (20:30 -0600)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 6 Nov 2013 14:55:55 +0000 (14:55 +0000)
This change modifies how ARPHandler handles punted IPv4 packets so that
they are immediately forwarded if the destination is known. This allows
for the first ARP response to come back to the requestor.

Change-Id: I278762c4048cb169bb9513e7237cac562bdc40ca
Signed-off-by: Colin Dixon <ckd@us.ibm.com>
opendaylight/arphandler/pom.xml
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleBroadcastHandlerImpl.java

index 0ee88895263488ff3c0fcb9584831c689f35d233..4c22b4a74b08a8bf23793dd8ba4f7a6496fbbddf 100644 (file)
@@ -28,6 +28,7 @@
           <instructions>
             <Import-Package>
               org.opendaylight.controller.connectionmanager,
+              org.opendaylight.controller.sal.connection,
               org.opendaylight.controller.sal.core,
               org.opendaylight.controller.sal.utils,
               org.opendaylight.controller.sal.packet,
index e345d65f7e527754981de650e8c75e47a72b47d8..7925c05f59466a5c3de3e4fa517f12e4d8368db8 100644 (file)
@@ -41,6 +41,7 @@ import org.opendaylight.controller.hosttracker.IfHostListener;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.hosttracker.hostAware.IHostFinder;
+import org.opendaylight.controller.sal.connection.ConnectionLocality;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -253,7 +254,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
          */
         if ((targetIP.equals(subnet.getNetworkAddress()))
                 && (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(targetMAC, getControllerMAC()))) {
-            if (connectionManager.isLocal(p.getNode())){
+            if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL){
                 if (log.isTraceEnabled()){
                     log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}",
                             HexEncode.bytesToHexString(getControllerMAC()));
@@ -292,7 +293,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
              */
             if (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(host.getDataLayerAddressBytes(), targetMAC)) {
                 log.trace("Received ARP req. for known host {}, sending reply...", targetIP);
-                if (connectionManager.isLocal(p.getNode())) {
+                if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) {
                     sendARPReply(p,
                             host.getDataLayerAddressBytes(),
                             host.getNetworkAddress(),
@@ -317,7 +318,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
     }
 
-    /*
+    /**
      *  Send a broadcast ARP Request to the switch/ ports  using
      *  the networkAddress of the subnet as sender IP
      *  the controller's MAC as sender MAC
@@ -335,9 +336,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             nodeConnectors = subnet.getNodeConnectors();
         }
         byte[] targetHardwareAddress = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+
+        //TODO: should use IBroadcastHandler instead
         for (NodeConnector p : nodeConnectors) {
-            //fiter out any non-local or internal ports
-            if (! connectionManager.isLocal(p.getNode()) || topologyManager.isInternal(p)) {
+            //filter out any non-local or internal ports
+            if (!(connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) || topologyManager.isInternal(p)) {
                 continue;
             }
             log.trace("Sending toward nodeConnector:{}", p);
@@ -357,7 +360,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
     }
 
-    /*
+    /**
      * Send a unicast ARP Request to the known host on a specific switch/port as
      * defined in the host.
      * The sender IP is the networkAddress of the subnet
@@ -418,7 +421,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             return;
         }
 
-        if (connectionManager.isLocal(host.getnodeconnectorNode())){
+        if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
             log.trace("Send a ucast ARP req. to: {}", host);
             sendUcastARPRequest(host, subnet);
         } else {
@@ -427,10 +430,13 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
     }
 
-    /*
+    /**
      * An IP packet is punted to the controller, this means that the
      * destination host is not known to the controller.
      * Need to discover it by sending a Broadcast ARP Request
+     *
+     * @param pkt
+     * @param p
      */
     protected void handlePuntedIPPacket(IPv4 pkt, NodeConnector p) {
 
@@ -439,6 +445,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
            return;
         }
 
+        // try to find a matching subnet
         Subnet subnet = null;
         if (switchManager != null) {
             subnet = switchManager.getSubnetByNetworkAddress(dIP);
@@ -447,12 +454,28 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             log.debug("Can't find subnet matching {}, drop packet", dIP);
             return;
         }
-        log.trace("Punted IP pkt from {}, sending bcast ARP event...", dIP);
-        /*
-         * unknown destination host, initiate bcast ARP request
-         */
-        arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false);
-        return;
+
+        // see if we know about the host
+        HostNodeConnector host = hostTracker.hostFind(dIP);
+
+        if (host == null) {
+            // if we don't, know about the host, try to find it
+            log.trace("Punted IP pkt from {}, sending bcast ARP event...",
+                      dIP);
+            /*
+             * unknown destination host, initiate bcast ARP request
+             */
+            arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false);
+        }else{
+
+            // we know about the host, send the packet the right place
+            NodeConnector nc = host.getnodeConnector();
+
+            // re-encode the Ethernet packet (the parent of the IPv4 packet)
+            RawPacket rp = this.dataPacketService.encodeDataPacket(pkt.getParent());
+            rp.setOutgoingNodeConnector(nc);
+            this.dataPacketService.transmitDataPacket(rp);
+        }
     }
 
     public byte[] getControllerMAC() {
@@ -476,7 +499,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         retrieveCaches();
     }
 
-    @SuppressWarnings({ "unchecked", "deprecation" })
+    @SuppressWarnings({ "unchecked" })
     private void retrieveCaches() {
         ConcurrentMap<?,?> map;
 
@@ -493,7 +516,6 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
     }
 
-    @SuppressWarnings("deprecation")
     private void allocateCaches() {
         if (clusterContainerService == null){
             nonClusterObjectCreate();
@@ -610,7 +632,6 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
     private void startPeriodicTimer() {
         this.periodicTimer = new Timer("ArpHandler Periodic Timer");
         this.periodicTimer.scheduleAtFixedRate(new TimerTask() {
-            @SuppressWarnings("deprecation")
             @Override
             public void run() {
                 Set<InetAddress> targetIPs = countDownTimers.keySet();
@@ -670,7 +691,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
                               HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
                               host.getNetworkAddress() });
             }
-            if (connectionManager.isLocal(host.getnodeconnectorNode())){
+            if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
                 sendARPReply(host.getnodeConnector(),
                         sourceMAC,
                         sourceIP,
@@ -740,7 +761,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
                             sendBcastARPRequest(req.getTargetIP(), req.getSubnet());
 
                         //If unicast and local, send reply
-                        } else if (connectionManager.isLocal(req.getHost().getnodeconnectorNode())) {
+                        } else if (connectionManager.getLocalityStatus(req.getHost().getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
                             log.trace("ARPCacheEventHandler - sendUcatARPRequest upon receipt of {}", req);
                             sendUcastARPRequest(req.getHost(), req.getSubnet());
                         }
@@ -751,7 +772,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
                             log.trace("Trigger a generateAndSendReply in response to {}", rep);
                             generateAndSendReply(rep.getTargetIP(), rep.getTargetMac());
                         // Otherwise, a specific reply. If local, send out.
-                        } else if (connectionManager.isLocal(rep.getPort().getNode())) {
+                        } else if (connectionManager.getLocalityStatus(rep.getPort().getNode()) == ConnectionLocality.LOCAL) {
                             log.trace("ARPCacheEventHandler - sendUcatARPReply locally in response to {}", rep);
                             sendARPReply(rep.getPort(),
                                     rep.getSourceMac(),
index d2016b1f6337b6923662268ae7d8029d34ae85b0..fec6bbe6b466519f9c5e8ed3cc5d89aa2558b66e 100644 (file)
@@ -48,7 +48,7 @@ public class SimpleBroadcastHandlerImpl implements IBroadcastHandler, IListenDat
 
     protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
 
-    BroadcastMode mode = BroadcastMode.DISABLED;
+    BroadcastMode mode = BroadcastMode.BROADCAST_TO_NONINTERNAL;
 
     @Override
     public PacketResult receiveDataPacket(RawPacket inPkt) {