From owner-svn-src-head@freebsd.org Mon Oct 16 15:01:51 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 50329E3C97C; Mon, 16 Oct 2017 15:01:51 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0E3C683A1B; Mon, 16 Oct 2017 15:01:50 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v9GF1obH065616; Mon, 16 Oct 2017 15:01:50 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v9GF1oYg065613; Mon, 16 Oct 2017 15:01:50 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201710161501.v9GF1oYg065613@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Mon, 16 Oct 2017 15:01:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r324662 - head/tests/sys/netpfil/pf X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: head/tests/sys/netpfil/pf X-SVN-Commit-Revision: 324662 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Oct 2017 15:01:51 -0000 Author: kp Date: Mon Oct 16 15:01:49 2017 New Revision: 324662 URL: https://svnweb.freebsd.org/changeset/base/324662 Log: pf: test set-tos Introduce tests for the set-tos feature of pf. Teach pft_ping.py to send and verify ToS flags. Added: head/tests/sys/netpfil/pf/set_tos.sh (contents, props changed) Modified: head/tests/sys/netpfil/pf/Makefile head/tests/sys/netpfil/pf/pft_ping.py Modified: head/tests/sys/netpfil/pf/Makefile ============================================================================== --- head/tests/sys/netpfil/pf/Makefile Mon Oct 16 12:54:53 2017 (r324661) +++ head/tests/sys/netpfil/pf/Makefile Mon Oct 16 15:01:49 2017 (r324662) @@ -5,7 +5,8 @@ PACKAGE= tests TESTSDIR= ${TESTSBASE}/sys/netpfil/pf ATF_TESTS_SH+= pass_block \ - forward + forward \ + set_tos ${PACKAGE}FILES+= utils.subr \ pft_ping.py Modified: head/tests/sys/netpfil/pf/pft_ping.py ============================================================================== --- head/tests/sys/netpfil/pf/pft_ping.py Mon Oct 16 12:54:53 2017 (r324661) +++ head/tests/sys/netpfil/pf/pft_ping.py Mon Oct 16 15:01:49 2017 (r324662) @@ -18,7 +18,7 @@ class Sniffer(threading.Thread): def run(self): self.packets = sp.sniff(iface=self._recvif, timeout=3) -def check_ping_request(packet, dst_ip): +def check_ping_request(packet, dst_ip, args): """ Verify that the packet matches what we'd have sent """ @@ -40,13 +40,27 @@ def check_ping_request(packet, dst_ip): if raw.load != str(PAYLOAD_MAGIC): return False + # Wait to check expectations until we've established this is the packet we + # sent. + if args.expect_tos: + if ip.tos != int(args.expect_tos[0]): + print "Unexpected ToS value %d, expected %s" \ + % (ip.tos, args.expect_tos[0]) + return False + + return True -def ping(send_if, dst_ip): - req = sp.Ether() \ - / sp.IP(dst=dst_ip) \ - / sp.ICMP(type='echo-request') \ - / sp.Raw(PAYLOAD_MAGIC) +def ping(send_if, dst_ip, args): + ether = sp.Ether() + ip = sp.IP(dst=dst_ip) + icmp = sp.ICMP(type='echo-request') + raw = sp.Raw(PAYLOAD_MAGIC) + + if args.send_tos: + ip.tos = int(args.send_tos[0]) + + req = ether / ip / icmp / raw sp.sendp(req, iface=send_if, verbose=False) def main(): @@ -61,19 +75,27 @@ def main(): required=True, help='The destination IP address for the ICMP echo request') + # Packet settings + parser.add_argument('--send-tos', nargs=1, + help='Set the ToS value for the transmitted packet') + + # Expectations + parser.add_argument('--expect-tos', nargs=1, + help='The expected ToS value in the received packet') + args = parser.parse_args() sniffer = None if not args.recvif is None: sniffer = Sniffer(args.recvif[0]) - ping(args.sendif[0], args.to[0]) + ping(args.sendif[0], args.to[0], args) if sniffer: sniffer.join() for packet in sniffer.packets: - if check_ping_request(packet, args.to[0]): + if check_ping_request(packet, args.to[0], args): sys.exit(0) # We did not get the packet we expected Added: head/tests/sys/netpfil/pf/set_tos.sh ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tests/sys/netpfil/pf/set_tos.sh Mon Oct 16 15:01:49 2017 (r324662) @@ -0,0 +1,92 @@ +# $FreeBSD$ + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "v4" "cleanup" +v4_head() +{ + atf_set descr 'set-tos test' + atf_set require.user root + + # We need scapy to be installed for out test scripts to work + atf_set require.progs scapy +} + +v4_body() +{ + pft_init + + epair_send=$(pft_mkepair) + ifconfig ${epair_send}a 192.0.2.1/24 up + + epair_recv=$(pft_mkepair) + ifconfig ${epair_recv}a up + + pft_mkjail alcatraz ${epair_send}b ${epair_recv}b + jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up + jexec alcatraz ifconfig ${epair_recv}b 198.51.100.2/24 up + jexec alcatraz sysctl net.inet.ip.forwarding=1 + jexec alcatraz arp -s 198.51.100.3 00:01:02:03:04:05 + route add -net 198.51.100.0/24 192.0.2.2 + + # No change is done if not requested + printf "scrub out proto icmp\n" | jexec alcatraz pfctl -ef - + atf_check -s exit:1 -o ignore $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 42 + + # The requested ToS is set + printf "scrub out proto icmp set-tos 42\n" | jexec alcatraz pfctl -f - + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 42 + + # ToS is not changed if the scrub rule does not match + printf "scrub out proto tcp set-tos 42\n" | jexec alcatraz pfctl -f - + atf_check -s exit:1 -o ignore $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 42 + + # Multiple scrub rules match as expected + printf "scrub out proto tcp set-tos 13\nscrub out proto icmp set-tos 14\n" \ + | jexec alcatraz pfctl -f - + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --expect-tos 14 + + # And this works even if the packet already has ToS values set + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --send-tos 42 \ + --expect-tos 14 + + # ToS values are unmolested if the packets do not match a scrub rule + printf "scrub out proto tcp set-tos 13\n" \ + | jexec alcatraz pfctl -f - + atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \ + --sendif ${epair_send}a \ + --to 198.51.100.3 \ + --recvif ${epair_recv}a \ + --send-tos 42 \ + --expect-tos 42 +} + +v4_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "v4" +}