- decrease the TTL correctly
 - buffer IP packets and send out them when ARP responses arrive unless they are ping to routers

Change-Id: Ib2f0f7a28198cc1092ef45a91a3b2feedaa7a2eb
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
index 21b197b..b35f402 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
@@ -1,7 +1,18 @@
+
+/*******************************************************************************
+ * Copyright (c) 2014 Open Networking Laboratory.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ ******************************************************************************/
+
 package net.onrc.onos.apps.segmentrouting;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Queue;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
@@ -51,6 +62,8 @@
     private IFlowPusherService flowPusher;
     private boolean controllerPortAllowed = false;
 
+    private Queue<IPv4> icmpQueue = new LinkedList<IPv4>();
+
     private static final int TABLE_VLAN = 0;
     private static final int TABLE_TMAC = 1;
     private static final int TABLE_IPv4_UNICAST = 2;
@@ -78,6 +91,18 @@
         this.srManager = manager;
     }
 
+    /**
+     * handle ICMP packets
+     * If it is for ICMP echo to router IP or any subnet GW IP,
+     * then send ICMP response on behalf of the switch.
+     * If it is for any hosts in subnets of the switches, but if the MAC
+     * address is not known, then send an ARP request to the subent.
+     * If the MAC address is known, then set the routing rule to the switch
+     *
+     * @param sw
+     * @param inPort
+     * @param payload
+     */
     public void processPacketIn(Switch sw, Port inPort, Ethernet payload) {
 
         if (payload.getEtherType() == Ethernet.TYPE_IPV4) {
@@ -88,8 +113,8 @@
 
                 log.debug("ICMPHandler: Received a ICMP packet {} from sw {} ",
                         payload.toString(), sw.getDpid());
-                int destinationAddress = ipv4.getDestinationAddress();
-                String destAddressStr = IPv4Address.of(destinationAddress).toString();
+                IPv4Address destinationAddress =
+                        IPv4Address.of(ipv4.getDestinationAddress());
 
                 // Check if it is ICMP request to the switch
                 String switchIpAddressSlash = sw.getStringAttribute("routerIp");
@@ -99,11 +124,12 @@
                     IPv4Address switchIpAddress = IPv4Address.of(switchIpAddressStr);
                     List<String> gatewayIps = getSubnetGatewayIps(sw);
                     if (((ICMP)ipv4.getPayload()).getIcmpType() == ICMP_TYPE_ECHO &&
-                            (destinationAddress == switchIpAddress.getInt() ||
-                             gatewayIps.contains(destAddressStr))) {
+                            (destinationAddress.getInt() == switchIpAddress.getInt() ||
+                             gatewayIps.contains(destinationAddress.toString()))) {
                         log.debug("ICMPHandler: ICMP packet for sw {} and "
                                 + "sending ICMP response ", sw.getDpid());
                         sendICMPResponse(sw, inPort, payload);
+                        srManager.getIpPacketFromQueue(destinationAddress.getBytes());
                         return;
                     }
                 }
@@ -122,19 +148,21 @@
                                          hostIpAddress);
                         byte[] destinationMacAddress = host.getMacAddress().toBytes();
                         srManager.addRouteToHost(sw,
-                                destinationAddress, destinationMacAddress);
+                                destinationAddress.getInt(), destinationMacAddress);
                         return;
                     }
                 }
                 /* ICMP for an unknown host */
                 log.debug("ICMPHandler: ICMP request for unknown host {}"
                         + " and sending ARP request", destinationAddress);
-                srManager.sendArpRequest(sw, destinationAddress, inPort);
+                srManager.sendArpRequest(sw, destinationAddress.getInt(), inPort);
             }
 
         }
     }
 
+
+
     /**
      * Retrieve Gateway IP address of all subnets defined in net config file
      *
@@ -164,7 +192,6 @@
     }
 
 
-
     /**
      * Send ICMP reply back
      *