Page MenuHomeFreeBSD

D28694.id.diff
No OneTemporary

D28694.id.diff

diff --git a/tests/sys/netpfil/common/pft_ping.py b/tests/sys/netpfil/common/pft_ping.py
--- a/tests/sys/netpfil/common/pft_ping.py
+++ b/tests/sys/netpfil/common/pft_ping.py
@@ -115,6 +115,35 @@
return True
+def check_ping_reply(args, packet):
+ return check_ping4_reply(args, packet)
+
+def check_ping4_reply(args, packet):
+ """
+ Check that this is a reply to the ping request we sent
+ """
+ dst_ip = args.to[0]
+
+ ip = packet.getlayer(sp.IP)
+ if not ip:
+ return False
+ if ip.src != dst_ip:
+ return False
+
+ icmp = packet.getlayer(sp.ICMP)
+ if not icmp:
+ return False
+ if sp.icmptypes[icmp.type] != 'echo-reply':
+ return False
+
+ raw = packet.getlayer(sp.Raw)
+ if not raw:
+ return False
+ if raw.load != PAYLOAD_MAGIC:
+ return False
+
+ return True
+
def ping(send_if, dst_ip, args):
ether = sp.Ether()
ip = sp.IP(dst=dst_ip)
@@ -124,6 +153,9 @@
if args.send_tos:
ip.tos = int(args.send_tos[0])
+ if args.fromaddr:
+ ip.src = args.fromaddr[0]
+
req = ether / ip / icmp / raw
sp.sendp(req, iface=send_if, verbose=False)
@@ -132,6 +164,9 @@
ip6 = sp.IPv6(dst=dst_ip)
icmp = sp.ICMPv6EchoRequest(data=sp.raw(PAYLOAD_MAGIC))
+ if args.fromaddr:
+ ip.src = args.fromaddr[0]
+
req = ether / ip6 / icmp
sp.sendp(req, iface=send_if, verbose=False)
@@ -189,6 +224,8 @@
required=True,
help='The interface through which the packet(s) will be sent')
parser.add_argument('--recvif', nargs=1,
+ help='The interface on which to expect the ICMP echo request')
+ parser.add_argument('--replyif', nargs=1,
help='The interface on which to expect the ICMP echo response')
parser.add_argument('--checkdup', nargs=1,
help='The interface on which to expect the duplicated ICMP packets')
@@ -197,6 +234,8 @@
parser.add_argument('--to', nargs=1,
required=True,
help='The destination IP address for the ICMP echo request')
+ parser.add_argument('--fromaddr', nargs=1,
+ help='The source IP address for the ICMP echo request')
# TCP options
parser.add_argument('--tcpsyn', action='store_true',
@@ -225,6 +264,11 @@
sniffer = Sniffer(args, checkfn)
+ replysniffer = None
+ if not args.replyif is None:
+ checkfn=check_ping_reply
+ replysniffer = Sniffer(args, checkfn, recvif=args.replyif[0])
+
dupsniffer = None
if args.checkdup is not None:
dupsniffer = Sniffer(args, check_dup, recvif=args.checkdup[0])
@@ -250,5 +294,13 @@
else:
sys.exit(1)
+ if replysniffer:
+ replysniffer.join()
+
+ if replysniffer.foundCorrectPacket:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
if __name__ == '__main__':
main()
diff --git a/tests/sys/netpfil/pf/pass_block.sh b/tests/sys/netpfil/pf/pass_block.sh
--- a/tests/sys/netpfil/pf/pass_block.sh
+++ b/tests/sys/netpfil/pf/pass_block.sh
@@ -27,6 +27,8 @@
. $(atf_get_srcdir)/utils.subr
+common_dir=$(atf_get_srcdir)/../common
+
atf_test_case "v4" "cleanup"
v4_head()
{
@@ -189,10 +191,75 @@
pft_cleanup
}
+atf_test_case "urpf" "cleanup"
+urpf_head()
+{
+ atf_set descr "Test unicast reverse path forwarding check"
+ atf_set require.user root
+ atf_set require.progs scapy
+}
+
+urpf_body()
+{
+ pft_init
+
+ epair_one=$(vnet_mkepair)
+ epair_two=$(vnet_mkepair)
+
+ vnet_mkjail alcatraz ${epair_one}b ${epair_two}b
+
+ ifconfig ${epair_one}a 192.0.2.2/24 up
+ ifconfig ${epair_two}a 198.51.100.2/24 up
+
+ jexec alcatraz ifconfig ${epair_one}b 192.0.2.1/24 up
+ jexec alcatraz ifconfig ${epair_two}b 198.51.100.1/24 up
+ jexec alcatraz sysctl net.inet.ip.forwarding=1
+
+ # Sanity checks
+ atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
+ atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1
+ atf_check -s exit:0 ${common_dir}/pft_ping.py \
+ --sendif ${epair_one}a \
+ --to 192.0.2.1 \
+ --fromaddr 198.51.100.2 \
+ --replyif ${epair_two}a
+ atf_check -s exit:0 ${common_dir}/pft_ping.py \
+ --sendif ${epair_two}a \
+ --to 198.51.100.1 \
+ --fromaddr 192.0.2.2 \
+ --replyif ${epair_one}a
+
+ pft_set_rules alcatraz \
+ "block quick from urpf-failed"
+ jexec alcatraz pfctl -e
+
+ # Correct source still works
+ atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
+ atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1
+
+ # Unexpected source interface is blocked
+ atf_check -s exit:1 ${common_dir}/pft_ping.py \
+ --sendif ${epair_one}a \
+ --to 192.0.2.1 \
+ --fromaddr 198.51.100.2 \
+ --replyif ${epair_two}a
+ atf_check -s exit:1 ${common_dir}/pft_ping.py \
+ --sendif ${epair_two}a \
+ --to 198.51.100.1 \
+ --fromaddr 192.0.2.2 \
+ --replyif ${epair_one}a
+}
+
+urpf_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "v4"
atf_add_test_case "v6"
atf_add_test_case "noalias"
atf_add_test_case "nested_inline"
+ atf_add_test_case "urpf"
}

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 19, 2:38 PM (9 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27733023
Default Alt Text
D28694.id.diff (4 KB)

Event Timeline