From nobody Tue Jan 16 08:52:04 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TDjS55079z579jK; Tue, 16 Jan 2024 08:52:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TDjS51TlBz4Q30; Tue, 16 Jan 2024 08:52:05 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705395125; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4xFgaB6I2qRZHkVUUyq8z9LqFvuta+HRmqUHpLoiiw4=; b=HphzjkdOgIQJyzy3e8QN/TafOwjHZvnEeA/tj5sA6V64wBCPSS/a+x7p7eCIrP3b/kx6u3 9wR7mceJZSn4/36WNDIvgdJPvocbmiJKEu+2+bRpw0li2EuWqYLjwkXKdmUFNlJJMsMp+L QnyrsuOLkh/NTgG+ZPAQdtnuYnPThEcEPBJxWlKO6ILXWNDf8kFYdltD/H/vzdNAsgBRAy yPUnxjhehZe+j+mP/Ml7exfJy+ybblPddjOjOsFGHTz1EIK8RhLgNYdHBN2MFxjFeMfqla WiyollE/hA1N1d9SV2R5phoS3PE3p1EmIDiR/qQcQHlXEmwPawSSbTRZNw4BAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705395125; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4xFgaB6I2qRZHkVUUyq8z9LqFvuta+HRmqUHpLoiiw4=; b=ec9sT9g/urc99tCyljxo2WNQWDqsPoZRN4w0NMfsfRAh8Fm7CTuYVcp48/vB5xZf5vekls ZIRitjdWgHmAp5sUb4gHxILbbk3cYi9PeUpxAAXVDeZBjve0tZnqNvvOUW7bCkzW/mlgCE JXRfkelTrVMC+MyW+dUE9tBE+lDVZ1RtCVW/rPmOivEd1z20PQK9ilEALrNVl4gAkdEJ8s goBZkkedt1grgh5V2Oi7WjbIy958cAVyY+FyHyxdFt6eOaTQk5bvMPN7r4RoJkJTCqbrAk MNYuIFdiDf2FO6rSeeuk3LTMNng14tjG8uHYpd10Mr6oKMfEfBRspuvRAJ3lzw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1705395125; a=rsa-sha256; cv=none; b=fSU2msGsN/qcxhvOlcj0t5b+5LyMc6LXXMfmVKsi0F8OnYbOwvuMD1LMy5UvSLYt64sLOP +TRv1R/JSY1OGuLGyL5YtENSIm90fnFZM+0unEjRxQo63RFtdF8tlP68o9RDujqe98xWAS +lKoHYTHczpR7w5iVKBU5tNtxGQE7OW4rvBmCgbFOg4s2Vo5QwVwsSk48n36S2hNykiyJY gKxJvLwKsj/8EyyyvogYR+E6n/XsXHokew/4QbqE5e7W2rlr4lewiuctCxKFCoRdyFU797 96dVMHqCllqcrePIyKIUNQsBh90poQSxGVX7th45mDnAKL6m18NEH8FxZXi4SA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TDjS50b6PzYS7; Tue, 16 Jan 2024 08:52:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 40G8q4qB077449; Tue, 16 Jan 2024 08:52:04 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40G8q4R6077446; Tue, 16 Jan 2024 08:52:04 GMT (envelope-from git) Date: Tue, 16 Jan 2024 08:52:04 GMT Message-Id: <202401160852.40G8q4R6077446@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: c4d97a948753 - main - pf tests: test pflow NAT state information List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c4d97a94875378d69e5f87d4341b95307a241a58 Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=c4d97a94875378d69e5f87d4341b95307a241a58 commit c4d97a94875378d69e5f87d4341b95307a241a58 Author: Kristof Provost AuthorDate: 2023-12-15 16:52:56 +0000 Commit: Kristof Provost CommitDate: 2024-01-16 08:45:55 +0000 pf tests: test pflow NAT state information pflow(4) now also exports NAT session creation/destruction information. Test that this works as expected. While here improve the parsing of ipfix (i.e. pflowproto 10) a bit, and check more information for the existing state information exports. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43117 --- tests/sys/netpfil/pf/pflow.sh | 58 ++++++++++++++++++++++++++++++++-- tests/sys/netpfil/pf/pft_read_ipfix.py | 41 +++++++++++++++++++++--- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/tests/sys/netpfil/pf/pflow.sh b/tests/sys/netpfil/pf/pflow.sh index 4bed49ef6f76..88478cfbfe84 100644 --- a/tests/sys/netpfil/pf/pflow.sh +++ b/tests/sys/netpfil/pf/pflow.sh @@ -124,7 +124,7 @@ state_defaults_body() ping -c 1 192.0.2.1 # We default to version 5 - atf_check -o match:"^v=5.*" \ + atf_check -o match:".*v=5.*" \ $(atf_get_srcdir)/pft_read_ipfix.py --recvif ${epair}a --port 2055 # Switch to version 10 @@ -132,7 +132,7 @@ state_defaults_body() ping -c 1 192.0.2.1 - atf_check -o match:"^v=10.*" \ + atf_check -o match:".*v=10.*" \ $(atf_get_srcdir)/pft_read_ipfix.py --recvif ${epair}a --port 2055 } @@ -174,7 +174,7 @@ v6_body() ping -6 -c 1 2001:db8::1 - atf_check -o match:"^v=10.*" \ + atf_check -o match:".*v=10,IPv6,proto=58,src=2001:db8::2,dst=2001:db8::1.*" \ $(atf_get_srcdir)/pft_read_ipfix.py --recvif ${epair}a --port 2055 } @@ -183,9 +183,61 @@ v6_cleanup() pft_cleanup } +atf_test_case "nat" "cleanup" +nat_head() +{ + atf_set descr 'Test pflow export for NAT44' + atf_set require.user root + atf_set require.progs scapy +} + +nat_body() +{ + pflow_init + + epair=$(vnet_mkepair) + epair_srv=$(vnet_mkepair) + + vnet_mkjail srv ${epair_srv}a + vnet_mkjail rtr ${epair_srv}b ${epair}a + + ifconfig ${epair}b 192.0.2.2/24 up + + jexec srv ifconfig ${epair_srv}a 198.51.100.2/24 up + jexec srv route add default 198.51.100.1 + + jexec rtr ifconfig ${epair_srv}b 198.51.100.1/24 up + jexec rtr ifconfig ${epair}a 192.0.2.1/24 up + jexec rtr sysctl net.inet.ip.forwarding=1 + + route add -net 198.51.100.0/24 192.0.2.1 + + jexec rtr pfctl -e + pft_set_rules rtr \ + "set state-defaults pflow" \ + "nat pass on ${epair_srv}b inet from 192.0.2.0/24 to any -> (${epair_srv}b)" \ + "pass" + + pflow=$(jexec rtr pflowctl -c) + jexec rtr pflowctl -s ${pflow} dst 192.0.2.2:2055 proto 10 + + # Sanity check + atf_check -s exit:0 -o ignore \ + ping -c 1 198.51.100.2 + + atf_check -o match:".*v=10,NAT=4,proto=1,src=192.0.2.2-198.51.100.1.*" \ + $(atf_get_srcdir)/pft_read_ipfix.py --recvif ${epair}b --port 2055 +} + +nat_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "basic" atf_add_test_case "state_defaults" atf_add_test_case "v6" + atf_add_test_case "nat" } diff --git a/tests/sys/netpfil/pf/pft_read_ipfix.py b/tests/sys/netpfil/pf/pft_read_ipfix.py index 64d4fcb3c523..2c11bdfd130c 100644 --- a/tests/sys/netpfil/pf/pft_read_ipfix.py +++ b/tests/sys/netpfil/pf/pft_read_ipfix.py @@ -31,6 +31,34 @@ import logging logging.getLogger("scapy").setLevel(logging.CRITICAL) import scapy.all as sp +def parse_ipfix(p): + if not sp.NetflowDataflowsetV9 in p: + # A template? + return + + c = p + while sp.NetflowDataflowsetV9 in c: + datafl = c[sp.NetflowDataflowsetV9] + if datafl.templateID == 258: + # NAT + for r in datafl.records: + print("v=10,NAT=%d,proto=%s,src=%s-%s,dst=%s-%s" % + (int.from_bytes(r.natEvent, "big"), r.PROTOCOL, + r.IPV4_SRC_ADDR, r.postNATSourceIPv4Address, + r.IPV4_DST_ADDR, r.postNATDestinationIPv4Address)) + elif datafl.templateID == 257: + # IPv6 + for r in datafl.records: + print("v=10,IPv6,proto=%s,src=%s,dst=%s" % + (r.PROTOCOL, r.IPV6_SRC_ADDR, r.IPV6_DST_ADDR)) + elif datafl.templateID == 256: + # IPv4 + for r in datafl.records: + print("v=10,proto=%s,src=%s,dst=%s" % + (r.PROTOCOL, r.IPV4_SRC_ADDR, r.IPV4_DST_ADDR)) + + c = datafl.payload + def receive(recvif, recvport): pkts = sp.sniff(iface=recvif, timeout=65) @@ -38,6 +66,8 @@ def receive(recvif, recvport): print("No data") return + pkts = sp.ipfix_defragment(pkts) + for pkt in pkts: udp = pkt.getlayer(sp.UDP) if not udp: @@ -46,18 +76,19 @@ def receive(recvif, recvport): if udp.dport != recvport: continue - hdr = pkt.getlayer(sp.NetflowHeader) + if not sp.NetflowHeader in pkt: + continue + hdr = pkt.getlayer(sp.NetflowHeader) if hdr.version == 5: v5hdr = pkt.getlayer(sp.NetflowHeaderV5) out="" for i in range(1, v5hdr.count + 1): r = pkt.getlayer(sp.NetflowRecordV5, nb=i) - out = "%s,proto=%d,src=%s,dst=%s,srcport=%d,dstport=%d" % (out, r.prot, r.src, r.dst, r.srcport, r.dstport) - print("v=%d,count=%d%s" % (hdr.version, v5hdr.count, out)) + print("v=%d,proto=%d,src=%s,dst=%s,srcport=%d,dstport=%d" % + (hdr.version, r.prot, r.src, r.dst, r.srcport, r.dstport)) elif hdr.version == 10: - print("v=10") - return + parse_ipfix(pkt) def main(): parser = argparse.ArgumentParser("pft_read_ipfix.py",