Added: DirectPacket test with ICMP matching
diff --git a/src/python/oftest/parse.py b/src/python/oftest/parse.py
index c8d9ad9..54b7226 100644
--- a/src/python/oftest/parse.py
+++ b/src/python/oftest/parse.py
@@ -240,8 +240,13 @@
     except:
         udp = None
 
-    # @todo arp and icmp are not yet supported
-    icmp = arp = None
+    try:
+        icmp = ether[scapy.ICMP]
+    except:
+        icmp = None
+
+    # @todo arp is not yet supported
+    arp = None
     return (dot1q, ip, tcp, udp, icmp, arp)
 
 def packet_to_flow_match(packet, pkt_format="L2"):
@@ -289,9 +294,12 @@
 
     if dot1q:
         match.dl_vlan = dot1q.vlan
-        match.wildcards &= ~OFPFW_DL_VLAN
         match.dl_vlan_pcp = dot1q.prio
-        match.wildcards &= ~OFPFW_DL_VLAN_PCP
+    else:
+        match.dl_vlan = OFP_VLAN_NONE
+        match.dl_vlan_pcp = 0
+    match.wildcards &= ~OFPFW_DL_VLAN
+    match.wildcards &= ~OFPFW_DL_VLAN_PCP
 
     if ip:
         match.nw_src = parse_ip(ip.src)
@@ -307,6 +315,11 @@
         match.tp_dst = tcp.dport
         match.wildcards &= ~OFPFW_TP_DST
 
-    #@todo Implement ICMP and ARP fields
+    if icmp:
+        match.nw_proto = 1
+        match.tp_src = icmp.type
+        match.tp_dst = icmp.code
+
+    #@todo Implement ARP fields
 
     return match
diff --git a/tests/pktact.py b/tests/pktact.py
index 4bc1de7..dd8c509 100644
--- a/tests/pktact.py
+++ b/tests/pktact.py
@@ -64,12 +64,19 @@
     Verify the packet is received at the egress port only
     """
     def runTest(self):
+        self.handleFlow()
+
+    def handleFlow(self, pkttype='TCP'):
+
         global pa_port_map
         of_ports = pa_port_map.keys()
         of_ports.sort()
         self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
 
-        pkt = simple_tcp_packet()
+        if (pkttype == 'ICMP'):
+            pkt = simple_icmp_packet()
+        else:
+            pkt = simple_tcp_packet()
         match = parse.packet_to_flow_match(pkt)
         match.wildcards &= ~ofp.OFPFW_IN_PORT
         self.assertTrue(match is not None, 
@@ -108,8 +115,21 @@
             self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
             self.assertEqual(str(pkt), str(rcv_pkt),
                              'Response packet does not match send packet')
-            
-        
+
+class DirectPacketICMP(DirectPacket):
+    """
+    Send ICMP packet to single egress port
+
+    Generate a ICMP packet
+    Generate and install a matching flow
+    Add action to direct the packet to an egress port
+    Send the packet to ingress dataplane port
+    Verify the packet is received at the egress port only
+    Difference from DirectPacket test is that sent packet is ICMP
+    """
+    def runTest(self):
+        self.handleFlow(pkttype='ICMP')
+
 
 class DirectTwoPorts(basic.SimpleDataPlane):
     """
diff --git a/tests/testutils.py b/tests/testutils.py
index 862571f..5a0be14 100644
--- a/tests/testutils.py
+++ b/tests/testutils.py
@@ -78,6 +78,52 @@
 
     return pkt
 
+def simple_icmp_packet(pktlen=60, 
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      dl_vlan=0,
+                      dl_vlan_pcp=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      icmp_type=8,
+                      icmp_code=0
+                      ):
+    """
+    Return a simple ICMP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param dl_vlan VLAN ID
+    @param dl_vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param icmp_type ICMP type
+    @param icmp_code ICMP code
+
+    Generates a simple ICMP ECHO REQUEST.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/ICMP frame.
+    """
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=dl_dst, src=dl_src)/ \
+            scapy.Dot1Q(prio=dl_vlan_pcp, id=0, vlan=dl_vlan)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos)/ \
+            scapy.ICMP(type=icmp_type, code=icmp_code)
+    else:
+        pkt = scapy.Ether(dst=dl_dst, src=dl_src)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos)/ \
+            scapy.ICMP(type=icmp_type, code=icmp_code)
+
+    pkt = pkt/("0" * (pktlen - len(pkt)))
+
+    return pkt
+
 def do_barrier(ctrl):
     b = message.barrier_request()
     ctrl.transact(b)