--- 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" }