Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Jan 2024 08:52:04 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: c4d97a948753 - main - pf tests: test pflow NAT state information
Message-ID:  <202401160852.40G8q4R6077446@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=c4d97a94875378d69e5f87d4341b95307a241a58

commit c4d97a94875378d69e5f87d4341b95307a241a58
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-12-15 16:52:56 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
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",



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202401160852.40G8q4R6077446>