aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Cowie <brad@wand.net.nz>2020-01-17 15:52:32 +1300
committerGitHub <noreply@github.com>2020-01-17 15:52:32 +1300
commitf33c97a1c08a3338fc469e528d1066f411da876e (patch)
treec91d7131b2d82c9d0b42818e2061f612a5c449b0
parent5e22429f4d9e752e56cda839a14c497674aeb199 (diff)
parent4b4f9b2e57edb51b7c1306dfc63448e173a069d1 (diff)
downloadfaucet-master.tar.gz
faucet-master.tar.bz2
faucet-master.zip
Merge pull request #3426 from brandonchau-github/setFieldTestsHEADmaster
Need test verifying set_field action for ICMPV4_TYPE, IPV4_DST, IPV4_…
-rw-r--r--clib/mininet_test_base.py18
-rw-r--r--tests/integration/mininet_tests.py103
2 files changed, 121 insertions, 0 deletions
diff --git a/clib/mininet_test_base.py b/clib/mininet_test_base.py
index 80be9f81..81c92424 100644
--- a/clib/mininet_test_base.py
+++ b/clib/mininet_test_base.py
@@ -802,6 +802,15 @@ class FaucetTestBase(unittest.TestCase):
return ('python3 -c \"from scapy.all import * ; sendp(%s, iface=\'%s\', count=%u)"' % (
packet, iface, count))
+ def scapy_base_udp(self, mac, iface, src_ip, dst_ip, dport, sport, count=1, dst=None):
+ if dst is None:
+ dst = 'ff:ff:ff:ff:ff:ff'
+ return self.scapy_template(
+ ('Ether(dst=\'%s\', src=\'%s\', type=%u) / '
+ 'IP(src=\'%s\', dst=\'%s\') / UDP(dport=%s,sport=%s) ' % (
+ dst, mac, IPV4_ETH, src_ip, dst_ip, dport, sport)),
+ iface, count)
+
def scapy_dhcp(self, mac, iface, count=1, dst=None):
if dst is None:
dst = 'ff:ff:ff:ff:ff:ff'
@@ -812,6 +821,15 @@ class FaucetTestBase(unittest.TestCase):
dst, mac, IPV4_ETH),
iface, count)
+ def scapy_icmp(self, mac, iface, src_ip, dst_ip, count=1, dst=None):
+ if dst is None:
+ dst = 'ff:ff:ff:ff:ff:ff'
+ return self.scapy_template(
+ ('Ether(dst=\'%s\', src=\'%s\', type=%u) / '
+ 'IP(src=\'%s\', dst=\'%s\') / ICMP()') % (
+ dst, mac, IPV4_ETH, src_ip, dst_ip),
+ iface, count)
+
def scapy_dscp(self, src_mac, dst_mac, dscp_value, iface, count=1):
# creates a packet with L2-L4 headers using scapy
return self.scapy_template(
diff --git a/tests/integration/mininet_tests.py b/tests/integration/mininet_tests.py
index f40246b6..194746f6 100644
--- a/tests/integration/mininet_tests.py
+++ b/tests/integration/mininet_tests.py
@@ -6755,6 +6755,109 @@ acls:
source_host, overridden_host, rewrite_host, overridden_host)
+class FaucetSetFieldsTest(FaucetUntaggedTest):
+ # A generic test to verify that a flow will set fields specified for
+ # matching packets
+ OUTPUT_MAC = '0f:00:12:23:48:03'
+ SRC_MAC = '0f:12:00:00:00:ff'
+
+ IP_DSCP_VAL = 46
+ # this is the converted DSCP value that is displayed
+ NW_TOS_VAL = 184
+ IPV4_SRC_VAL = "192.0.2.0"
+ IPV4_DST_VAL = "198.51.100.0"
+ # ICMP echo request
+ ICMPV4_TYPE_VAL = 8
+ UDP_SRC_PORT = 68
+ UDP_DST_PORT = 67
+
+ CONFIG_GLOBAL = """
+vlans:
+ 100:
+ description: "untagged"
+
+acls:
+ 1:
+ - rule:
+ eth_type: 0x0800
+ actions:
+ allow: 1
+ output:
+ set_fields:
+ - ipv4_src: '%s'
+ - ipv4_dst: '%s'
+ - ip_dscp: %d
+ - rule:
+ eth_type: 0x0800
+ ip_proto: 1
+ actions:
+ allow: 1
+ output:
+ set_fields:
+ - icmpv4_type: %d
+""" % (IPV4_SRC_VAL, IPV4_DST_VAL, IP_DSCP_VAL, ICMPV4_TYPE_VAL)
+ CONFIG = """
+ interfaces:
+ %(port_1)d:
+ native_vlan: 100
+ acl_in: 1
+ %(port_2)d:
+ native_vlan: 100
+ %(port_3)d:
+ native_vlan: 100
+ %(port_4)d:
+ native_vlan: 100
+ """
+
+ def test_set_fields_generic_udp(self):
+ # Send a basic UDP packet through the faucet pipeline and verify that
+ # the expected fields were updated via tcpdump output
+ source_host, dest_host = self.hosts_name_ordered()[0:2]
+ dest_host.setMAC(self.OUTPUT_MAC)
+
+ # scapy command to create and send a UDP packet
+ scapy_pkt = self.scapy_base_udp(
+ self.SRC_MAC, source_host.defaultIntf(), source_host.IP(),
+ dest_host.IP(), self.UDP_DST_PORT, self.UDP_SRC_PORT,
+ dst=self.OUTPUT_MAC)
+
+ tcpdump_filter = "ether dst %s" % self.OUTPUT_MAC
+ tcpdump_txt = self.tcpdump_helper(
+ dest_host, tcpdump_filter, [lambda: source_host.cmd(scapy_pkt)],
+ root_intf=True, packets=1)
+
+ # verify that the packet we've received on the dest_host has the
+ # overwritten values
+ self.assertTrue(
+ re.search("%s.%s > %s.%s" % (self.IPV4_SRC_VAL, self.UDP_SRC_PORT,
+ self.IPV4_DST_VAL, self.UDP_DST_PORT),
+ tcpdump_txt))
+ # check the packet's converted dscp value
+ self.assertTrue(re.search("tos %s" % hex(self.NW_TOS_VAL), tcpdump_txt))
+
+ def test_set_fields_icmp(self):
+ # Send a basic ICMP packet through the faucet pipeline and verify that
+ # the expected fields were updated via tcpdump output
+ source_host, dest_host = self.hosts_name_ordered()[0:2]
+ dest_host.setMAC(self.OUTPUT_MAC)
+
+ # scapy command to create and send an ICMP packet
+ scapy_pkt = self.scapy_icmp(
+ self.SRC_MAC, source_host.defaultIntf(), source_host.IP(),
+ dest_host.IP(), dst=self.OUTPUT_MAC)
+
+ tcpdump_filter = "ether dst %s" % self.OUTPUT_MAC
+ tcpdump_txt = self.tcpdump_helper(
+ dest_host, tcpdump_filter, [lambda: source_host.cmd(scapy_pkt)],
+ root_intf=True, packets=1)
+
+ # verify that the packet we've received on the dest_host has been
+ # overwritten to be an ICMP echo request
+ self.assertTrue(re.search("ICMP echo request", tcpdump_txt))
+
+ def test_untagged(self):
+ pass
+
class FaucetDscpMatchTest(FaucetUntaggedTest):
# Match all packets with this IP_DSP and eth_type, based on the ryu API def
# e.g {"ip_dscp": 3, "eth_type": 2048}