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)