testutils: add simple_{tcp,udp,icmp}v6_packet()
These are simplified and IPv6-ified versions of the existing functions.
Also added IPv6 packets to the OF 1.3 ethertype tests.
diff --git a/src/python/oftest/testutils.py b/src/python/oftest/testutils.py
index 7e1b2c8..33a4cc1 100644
--- a/src/python/oftest/testutils.py
+++ b/src/python/oftest/testutils.py
@@ -122,6 +122,53 @@
return pkt
+def simple_tcpv6_packet(pktlen=100,
+ eth_dst='00:01:02:03:04:05',
+ eth_src='00:06:07:08:09:0a',
+ dl_vlan_enable=False,
+ vlan_vid=0,
+ vlan_pcp=0,
+ ipv6_src='2001:db8:85a3::8a2e:370:7334',
+ ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+ ipv6_tc=0,
+ ipv6_hlim=64,
+ ipv6_fl=0,
+ tcp_sport=1234,
+ tcp_dport=80):
+ """
+ Return a simple IPv6/TCP packet
+
+ Supports a few parameters:
+ @param len Length of packet in bytes w/o CRC
+ @param eth_dst Destination MAC
+ @param eth_src Source MAC
+ @param dl_vlan_enable True if the packet is with vlan, False otherwise
+ @param vlan_vid VLAN ID
+ @param vlan_pcp VLAN priority
+ @param ipv6_src IPv6 source
+ @param ipv6_dst IPv6 destination
+ @param ipv6_tc IPv6 traffic class
+ @param ipv6_ttl IPv6 hop limit
+ @param ipv6_fl IPv6 flow label
+ @param tcp_dport TCP destination port
+ @param tcp_sport TCP source port
+
+ Generates a simple TCP request. Users shouldn't assume anything about this
+ packet other than that it is a valid ethernet/IPv6/TCP frame.
+ """
+
+ if MINSIZE > pktlen:
+ pktlen = MINSIZE
+
+ pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+ if dl_vlan_enable or vlan_vid or vlan_pcp:
+ pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+ pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+ pkt /= scapy.TCP(sport=tcp_sport, dport=tcp_dport)
+ pkt /= ("D" * (pktlen - len(pkt)))
+
+ return pkt
+
def simple_udp_packet(pktlen=100,
eth_dst='00:01:02:03:04:05',
eth_src='00:06:07:08:09:0a',
@@ -182,6 +229,53 @@
return pkt
+def simple_udpv6_packet(pktlen=100,
+ eth_dst='00:01:02:03:04:05',
+ eth_src='00:06:07:08:09:0a',
+ dl_vlan_enable=False,
+ vlan_vid=0,
+ vlan_pcp=0,
+ ipv6_src='2001:db8:85a3::8a2e:370:7334',
+ ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+ ipv6_tc=0,
+ ipv6_hlim=64,
+ ipv6_fl=0,
+ udp_sport=1234,
+ udp_dport=80):
+ """
+ Return a simple IPv6/UDP packet
+
+ Supports a few parameters:
+ @param len Length of packet in bytes w/o CRC
+ @param eth_dst Destination MAC
+ @param eth_src Source MAC
+ @param dl_vlan_enable True if the packet is with vlan, False otherwise
+ @param vlan_vid VLAN ID
+ @param vlan_pcp VLAN priority
+ @param ipv6_src IPv6 source
+ @param ipv6_dst IPv6 destination
+ @param ipv6_tc IPv6 traffic class
+ @param ipv6_ttl IPv6 hop limit
+ @param ipv6_fl IPv6 flow label
+ @param udp_dport UDP destination port
+ @param udp_sport UDP source port
+
+ Generates a simple UDP request. Users shouldn't assume anything about this
+ packet other than that it is a valid ethernet/IPv6/UDP frame.
+ """
+
+ if MINSIZE > pktlen:
+ pktlen = MINSIZE
+
+ pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+ if dl_vlan_enable or vlan_vid or vlan_pcp:
+ pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+ pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+ pkt /= scapy.UDP(sport=udp_sport, dport=udp_dport)
+ pkt /= ("D" * (pktlen - len(pkt)))
+
+ return pkt
+
def simple_icmp_packet(pktlen=60,
eth_dst='00:01:02:03:04:05',
eth_src='00:06:07:08:09:0a',
@@ -234,6 +328,53 @@
return pkt
+def simple_icmpv6_packet(pktlen=100,
+ eth_dst='00:01:02:03:04:05',
+ eth_src='00:06:07:08:09:0a',
+ dl_vlan_enable=False,
+ vlan_vid=0,
+ vlan_pcp=0,
+ ipv6_src='2001:db8:85a3::8a2e:370:7334',
+ ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+ ipv6_tc=0,
+ ipv6_hlim=64,
+ ipv6_fl=0,
+ icmp_type=8,
+ icmp_code=0):
+ """
+ Return a simple ICMPv6 packet
+
+ Supports a few parameters:
+ @param len Length of packet in bytes w/o CRC
+ @param eth_dst Destination MAC
+ @param eth_src Source MAC
+ @param dl_vlan_enable True if the packet is with vlan, False otherwise
+ @param vlan_vid VLAN ID
+ @param vlan_pcp VLAN priority
+ @param ipv6_src IPv6 source
+ @param ipv6_dst IPv6 destination
+ @param ipv6_tc IPv6 traffic class
+ @param ipv6_ttl IPv6 hop limit
+ @param ipv6_fl IPv6 flow label
+ @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/IPv6/ICMP frame.
+ """
+
+ if MINSIZE > pktlen:
+ pktlen = MINSIZE
+
+ pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+ if dl_vlan_enable or vlan_vid or vlan_pcp:
+ pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+ pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+ pkt /= scapy.ICMPv6Unknown(type=icmp_type, code=icmp_code)
+ pkt /= ("D" * (pktlen - len(pkt)))
+
+ return pkt
+
def simple_arp_packet(pktlen=60,
eth_dst='ff:ff:ff:ff:ff:ff',
eth_src='00:06:07:08:09:0a',
diff --git a/tests-1.3/match.py b/tests-1.3/match.py
index 8a46118..c81fc38 100644
--- a/tests-1.3/match.py
+++ b/tests-1.3/match.py
@@ -301,7 +301,30 @@
nonmatching = {
"arp": simple_arp_packet(),
"llc": llc_pkt,
- # TODO ipv6
+ "ipv6/tcp": simple_tcpv6_packet(),
+ }
+
+ self.verify_match(match, matching, nonmatching)
+
+class EthTypeIPv6(MatchTest):
+ """
+ Match on ethertype (IPv6)
+ """
+ def runTest(self):
+ match = ofp.match([
+ ofp.oxm.eth_type(0x86dd)
+ ])
+
+ matching = {
+ "ipv6/tcp": simple_tcpv6_packet(),
+ "ipv6/udp": simple_udpv6_packet(),
+ "ipv6/icmp": simple_icmpv6_packet(),
+ "vlan tagged": simple_tcpv6_packet(vlan_vid=2, vlan_pcp=3),
+ }
+
+ nonmatching = {
+ "ipv4/tcp": simple_tcp_packet(),
+ "arp": simple_arp_packet(),
}
self.verify_match(match, matching, nonmatching)
@@ -322,6 +345,7 @@
nonmatching = {
"ipv4/tcp": simple_tcp_packet(),
+ "ipv6/tcp": simple_tcpv6_packet(),
}
self.verify_match(match, matching, nonmatching)
@@ -352,6 +376,7 @@
nonmatching = {
"ipv4/tcp": simple_tcp_packet(),
+ "ipv6/tcp": simple_tcpv6_packet(),
"llc/snap": snap_pkt,
}