aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2025-01-20 13:11:20 +0000
committerKristof Provost <kp@FreeBSD.org>2025-01-24 10:20:29 +0000
commit5cb08fddef998b5e6452df3f52474e00883e06c4 (patch)
tree2d7a46fc2172bbfff08598140ee78da8c319be06
parent096efeb658b5a6d63068bd90f3c6508f74767bba (diff)
pfctl: improve NAT pool handling
Ensure we always free the NAT pool (as well as the rdr pool) and actually handle it in the optimiser. Sponsored by: Rubicon Communications, LLC ("Netgate")
-rw-r--r--sbin/pfctl/parse.y1
-rw-r--r--sbin/pfctl/pfctl.c5
-rw-r--r--sbin/pfctl/pfctl_optimize.c13
3 files changed, 18 insertions, 1 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 2bd8e16b535b..e66d3cdd295e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -5171,6 +5171,7 @@ binatrule : no BINAT natpasslog interface af proto FROM ipspec toipspec tag
}
TAILQ_INIT(&binat.rdr.list);
+ TAILQ_INIT(&binat.nat.list);
pa = calloc(1, sizeof(struct pf_pooladdr));
if (pa == NULL)
err(1, "binat: calloc");
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 9da13daee063..7b54bc1c7c7a 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1324,6 +1324,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
break;
}
pfctl_clear_pool(&rule.rdr);
+ pfctl_clear_pool(&rule.nat);
}
ret = pfctl_get_rules_info_h(pfh, &ri, PF_PASS, path);
if (ret != 0) {
@@ -1410,6 +1411,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
break;
}
pfctl_clear_pool(&rule.rdr);
+ pfctl_clear_pool(&rule.nat);
}
error:
@@ -1757,6 +1759,8 @@ pfctl_append_rule(struct pfctl *pf, struct pfctl_rule *r,
bcopy(r, rule, sizeof(*rule));
TAILQ_INIT(&rule->rdr.list);
pfctl_move_pool(&r->rdr, &rule->rdr);
+ TAILQ_INIT(&rule->nat.list);
+ pfctl_move_pool(&r->nat, &rule->nat);
TAILQ_INSERT_TAIL(rs->rules[rs_num].active.ptr, rule, entries);
return (0);
@@ -2086,6 +2090,7 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth)
}
path[len] = '\0';
pfctl_clear_pool(&r->rdr);
+ pfctl_clear_pool(&r->nat);
return (0);
}
diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c
index 48b9a9caa82d..a97664e0c929 100644
--- a/sbin/pfctl/pfctl_optimize.c
+++ b/sbin/pfctl/pfctl_optimize.c
@@ -136,6 +136,7 @@ static struct pf_rule_field {
PF_RULE_FIELD(overload_tblname, BREAK),
PF_RULE_FIELD(flush, BREAK),
PF_RULE_FIELD(rdr, BREAK),
+ PF_RULE_FIELD(nat, BREAK),
PF_RULE_FIELD(logif, BREAK),
/*
@@ -296,7 +297,12 @@ pfctl_optimize_ruleset(struct pfctl *pf, struct pfctl_ruleset *rs)
} else
bzero(&por->por_rule.rdr,
sizeof(por->por_rule.rdr));
-
+ if (TAILQ_FIRST(&r->nat.list) != NULL) {
+ TAILQ_INIT(&por->por_rule.nat.list);
+ pfctl_move_pool(&r->nat, &por->por_rule.nat);
+ } else
+ bzero(&por->por_rule.nat,
+ sizeof(por->por_rule.nat));
TAILQ_INSERT_TAIL(&opt_queue, por, por_entry);
}
@@ -327,6 +333,8 @@ pfctl_optimize_ruleset(struct pfctl *pf, struct pfctl_ruleset *rs)
memcpy(r, &por->por_rule, sizeof(*r));
TAILQ_INIT(&r->rdr.list);
pfctl_move_pool(&por->por_rule.rdr, &r->rdr);
+ TAILQ_INIT(&r->nat.list);
+ pfctl_move_pool(&por->por_rule.nat, &r->nat);
TAILQ_INSERT_TAIL(
rs->rules[PF_RULESET_FILTER].active.ptr,
r, entries);
@@ -915,6 +923,9 @@ load_feedback_profile(struct pfctl *pf, struct superblocks *superblocks)
if (TAILQ_EMPTY(&por->por_rule.rdr.list))
memset(&por->por_rule.rdr, 0,
sizeof(por->por_rule.rdr));
+ if (TAILQ_EMPTY(&por->por_rule.nat.list))
+ memset(&por->por_rule.nat, 0,
+ sizeof(por->por_rule.nat));
TAILQ_INSERT_TAIL(&queue, por, por_entry);
/* XXX pfctl_get_pool(pf->dev, &rule.rdr, nr, pr.ticket,