--- sbin/pfctl/pfctl.c.orig
+++ sbin/pfctl/pfctl.c
@@ -2189,13 +2189,13 @@
 		}
 	}
 
-	if (pf->opts & PF_OPT_VERBOSE) {
+	if (pf->opts & PF_OPT_VERBOSE || was_present) {
 		INDENT(depth, !(pf->opts & PF_OPT_VERBOSE2));
 		print_rule(r, name,
 		    pf->opts & PF_OPT_VERBOSE2,
 		    pf->opts & PF_OPT_NUMERIC);
 		if (was_present)
-			printf(" -- rule was already present");
+			printf(" -- rule was already present\n");
 	}
 	path[len] = '\0';
 	pfctl_clear_pool(&r->rdr);
--- sys/netpfil/pf/pf_ioctl.c.orig
+++ sys/netpfil/pf/pf_ioctl.c
@@ -1350,10 +1350,18 @@
 				PF_MD5_UPD(pfr, addr.v.tblname);
 			break;
 		case PF_ADDR_ADDRMASK:
+		case PF_ADDR_RANGE:
 			/* XXX ignore af? */
 			PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
 			PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
 			break;
+		case PF_ADDR_NONE:
+		case PF_ADDR_NOROUTE:
+		case PF_ADDR_URPFFAILED:
+			/* These do not use any address data. */
+			break;
+		default:
+			panic("Unknown address type %d", pfr->addr.type);
 	}
 
 	PF_MD5_UPD(pfr, port[0]);
@@ -1362,6 +1370,30 @@
 	PF_MD5_UPD(pfr, port_op);
 }
 
+static void
+pf_hash_pool(MD5_CTX *ctx, struct pf_kpool *pool)
+{
+	uint16_t x;
+	int y;
+
+	if (pool->cur) {
+		PF_MD5_UPD(pool, cur->addr);
+		PF_MD5_UPD_STR(pool, cur->ifname);
+		PF_MD5_UPD(pool, cur->af);
+	}
+	PF_MD5_UPD(pool, key);
+	PF_MD5_UPD(pool, counter);
+
+	PF_MD5_UPD(pool, mape.offset);
+	PF_MD5_UPD(pool, mape.psidlen);
+	PF_MD5_UPD_HTONS(pool, mape.psid, x);
+	PF_MD5_UPD_HTONL(pool, tblidx, y);
+	PF_MD5_UPD_HTONS(pool, proxy_port[0], x);
+	PF_MD5_UPD_HTONS(pool, proxy_port[1], x);
+	PF_MD5_UPD(pool, opts);
+	PF_MD5_UPD(pool, ipv6_nexthop_af);
+}
+
 static void
 pf_hash_rule_rolling(MD5_CTX *ctx, struct pf_krule *rule)
 {
@@ -1372,39 +1404,92 @@
 	pf_hash_rule_addr(ctx, &rule->dst);
 	for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
 		PF_MD5_UPD_STR(rule, label[i]);
+	PF_MD5_UPD_HTONL(rule, ridentifier, y);
 	PF_MD5_UPD_STR(rule, ifname);
 	PF_MD5_UPD_STR(rule, rcv_ifname);
+	PF_MD5_UPD_STR(rule, qname);
+	PF_MD5_UPD_STR(rule, pqname);
+	PF_MD5_UPD_STR(rule, tagname);
 	PF_MD5_UPD_STR(rule, match_tagname);
-	PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
+
+	PF_MD5_UPD_STR(rule, overload_tblname);
+
+	pf_hash_pool(ctx, &rule->nat);
+	pf_hash_pool(ctx, &rule->rdr);
+	pf_hash_pool(ctx, &rule->route);
+	PF_MD5_UPD_HTONL(rule, pktrate.limit, y);
+	PF_MD5_UPD_HTONL(rule, pktrate.seconds, y);
+
 	PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
+
+	PF_MD5_UPD_HTONL(rule, rtableid, y);
+	for (int i = 0; i < PFTM_MAX; i++)
+		PF_MD5_UPD_HTONL(rule, timeout[i], y);
+	PF_MD5_UPD_HTONL(rule, max_states, y);
+	PF_MD5_UPD_HTONL(rule, max_src_nodes, y);
+	PF_MD5_UPD_HTONL(rule, max_src_states, y);
+	PF_MD5_UPD_HTONL(rule, max_src_conn, y);
+	PF_MD5_UPD_HTONL(rule, max_src_conn_rate.limit, y);
+	PF_MD5_UPD_HTONL(rule, max_src_conn_rate.seconds, y);
+	PF_MD5_UPD_HTONS(rule, max_pkt_size, y);
+	PF_MD5_UPD_HTONS(rule, qid, x);
+	PF_MD5_UPD_HTONS(rule, pqid, x);
+	PF_MD5_UPD_HTONS(rule, dnpipe, x);
+	PF_MD5_UPD_HTONS(rule, dnrpipe, x);
+	PF_MD5_UPD_HTONL(rule, free_flags, y);
 	PF_MD5_UPD_HTONL(rule, prob, y);
+
+	PF_MD5_UPD_HTONS(rule, return_icmp, x);
+	PF_MD5_UPD_HTONS(rule, return_icmp6, x);
+	PF_MD5_UPD_HTONS(rule, max_mss, x);
+	PF_MD5_UPD_HTONS(rule, tag, x); /* dup? */
+	PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
+	PF_MD5_UPD_HTONS(rule, scrub_flags, x);
+
+	PF_MD5_UPD(rule, uid.op);
 	PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
 	PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
-	PF_MD5_UPD(rule, uid.op);
+	PF_MD5_UPD(rule, gid.op);
 	PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
 	PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
-	PF_MD5_UPD(rule, gid.op);
+
 	PF_MD5_UPD_HTONL(rule, rule_flag, y);
+	PF_MD5_UPD_HTONL(rule, rule_ref, y);
 	PF_MD5_UPD(rule, action);
 	PF_MD5_UPD(rule, direction);
-	PF_MD5_UPD(rule, af);
+	PF_MD5_UPD(rule, log);
+	PF_MD5_UPD(rule, logif);
 	PF_MD5_UPD(rule, quick);
 	PF_MD5_UPD(rule, ifnot);
-	PF_MD5_UPD(rule, rcvifnot);
 	PF_MD5_UPD(rule, match_tag_not);
 	PF_MD5_UPD(rule, natpass);
+
 	PF_MD5_UPD(rule, keep_state);
+	PF_MD5_UPD(rule, af);
 	PF_MD5_UPD(rule, proto);
-	PF_MD5_UPD(rule, type);
-	PF_MD5_UPD(rule, code);
+	PF_MD5_UPD_HTONS(rule, type, x);
+	PF_MD5_UPD_HTONS(rule, code, x);
 	PF_MD5_UPD(rule, flags);
 	PF_MD5_UPD(rule, flagset);
+	PF_MD5_UPD(rule, min_ttl);
 	PF_MD5_UPD(rule, allow_opts);
 	PF_MD5_UPD(rule, rt);
+	PF_MD5_UPD(rule, return_ttl);
 	PF_MD5_UPD(rule, tos);
-	PF_MD5_UPD(rule, scrub_flags);
-	PF_MD5_UPD(rule, min_ttl);
 	PF_MD5_UPD(rule, set_tos);
+	PF_MD5_UPD(rule, anchor_relative);
+	PF_MD5_UPD(rule, anchor_wildcard);
+
+	PF_MD5_UPD(rule, flush);
+	PF_MD5_UPD(rule, prio);
+	PF_MD5_UPD(rule, set_prio[0]);
+	PF_MD5_UPD(rule, set_prio[1]);
+	PF_MD5_UPD(rule, naf);
+	PF_MD5_UPD(rule, rcvifnot);
+
+	PF_MD5_UPD(rule, divert.addr);
+	PF_MD5_UPD_HTONS(rule, divert.port, x);
+
 	if (rule->anchor != NULL)
 		PF_MD5_UPD_STR(rule, anchor->path);
 }
--- tests/sys/netpfil/pf/pass_block.sh.orig
+++ tests/sys/netpfil/pf/pass_block.sh
@@ -451,6 +451,43 @@
 	pft_cleanup
 }
 
+atf_test_case "addr_range" "cleanup"
+addr_range_head()
+{
+	atf_set descr 'Test rulesets with multiple address ranges'
+	atf_set require.user root
+}
+
+addr_range_body()
+{
+	pft_init
+
+	epair=$(vnet_mkepair)
+	ifconfig ${epair}b 192.0.2.2/24 up
+
+	vnet_mkjail alcatraz ${epair}a
+	jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up
+
+	# Sanity check
+	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
+
+	jexec alcatraz pfctl -e
+	pft_set_rules alcatraz \
+	    "block" \
+	    "pass inet from any to 10.100.100.1 - 10.100.100.20" \
+	    "pass inet from any to 192.0.2.1 - 192.0.2.10"
+
+jexec alcatraz pfctl -sr -vv
+
+	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
+jexec alcatraz pfctl -sr -vv
+}
+
+addr_range_cleanup()
+{
+	pft_cleanup
+}
+
 atf_init_test_cases()
 {
 	atf_add_test_case "enable_disable"
@@ -462,4 +499,5 @@
 	atf_add_test_case "received_on"
 	atf_add_test_case "optimize_any"
 	atf_add_test_case "any_if"
+	atf_add_test_case "addr_range"
 }
