Page MenuHomeFreeBSD

D47783.diff
No OneTemporary

D47783.diff

diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -174,7 +174,12 @@
char overload_tblname[PF_TABLE_NAME_SIZE];
TAILQ_ENTRY(pfctl_rule) entries;
- struct pfctl_pool rpool;
+ struct pfctl_pool nat;
+ union {
+ /* Alias old and new names. */
+ struct pfctl_pool rpool;
+ struct pfctl_pool rdr;
+ };
uint64_t evaluations;
uint64_t packets[2];
@@ -521,7 +526,7 @@
int pfctl_set_limit(struct pfctl_handle *h, const int index, const uint limit);
int pfctl_get_limit(struct pfctl_handle *h, const int index, uint *limit);
int pfctl_begin_addrs(struct pfctl_handle *h, uint32_t *ticket);
-int pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa);
+int pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa, int which);
int pfctl_get_addrs(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
uint8_t r_action, const char *anchor, uint32_t *nr);
int pfctl_get_addr(struct pfctl_handle *h, uint32_t ticket, uint32_t r_num,
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -731,7 +731,7 @@
strlcpy(rule->overload_tblname, nvlist_get_string(nvl, "overload_tblname"),
PF_TABLE_NAME_SIZE);
- pf_nvpool_to_pool(nvlist_get_nvlist(nvl, "rpool"), &rule->rpool);
+ pf_nvpool_to_pool(nvlist_get_nvlist(nvl, "rpool"), &rule->rdr);
rule->evaluations = nvlist_get_number(nvl, "evaluations");
pf_nvuint_64_array(nvl, "packets", 2, rule->packets, NULL);
@@ -1226,7 +1226,8 @@
snl_add_msg_attr_string(nw, PF_RT_TAGNAME, r->tagname);
snl_add_msg_attr_string(nw, PF_RT_MATCH_TAGNAME, r->match_tagname);
snl_add_msg_attr_string(nw, PF_RT_OVERLOAD_TBLNAME, r->overload_tblname);
- snl_add_msg_attr_rpool(nw, PF_RT_RPOOL, &r->rpool);
+ snl_add_msg_attr_rpool(nw, PF_RT_RPOOL_RDR, &r->rdr);
+ snl_add_msg_attr_rpool(nw, PF_RT_RPOOL_NAT, &r->nat);
snl_add_msg_attr_u32(nw, PF_RT_OS_FINGERPRINT, r->os_fingerprint);
snl_add_msg_attr_u32(nw, PF_RT_RTABLEID, r->rtableid);
snl_add_msg_attr_timeouts(nw, PF_RT_TIMEOUT, r->timeout);
@@ -1596,7 +1597,7 @@
{ .type = PF_RT_TAGNAME, .off = _OUT(r.tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = snl_attr_copy_string },
{ .type = PF_RT_MATCH_TAGNAME, .off = _OUT(r.match_tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = snl_attr_copy_string },
{ .type = PF_RT_OVERLOAD_TBLNAME, .off = _OUT(r.overload_tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = snl_attr_copy_string },
- { .type = PF_RT_RPOOL, .off = _OUT(r.rpool), .arg = &pool_parser, .cb = snl_attr_get_nested },
+ { .type = PF_RT_RPOOL_RDR, .off = _OUT(r.rdr), .arg = &pool_parser, .cb = snl_attr_get_nested },
{ .type = PF_RT_OS_FINGERPRINT, .off = _OUT(r.os_fingerprint), .cb = snl_attr_get_uint32 },
{ .type = PF_RT_RTABLEID, .off = _OUT(r.rtableid), .cb = snl_attr_get_uint32 },
{ .type = PF_RT_TIMEOUT, .off = _OUT(r.timeout), .arg = &timeout_parser, .cb = snl_attr_get_nested_timeouts },
@@ -1660,6 +1661,7 @@
{ .type = PF_RT_ANCHOR_CALL, .off = _OUT(anchor_call), .arg = (void*)MAXPATHLEN, .cb = snl_attr_copy_string },
{ .type = PF_RT_RCV_IFNAME, .off = _OUT(r.rcv_ifname), .arg = (void*)IFNAMSIZ, .cb = snl_attr_copy_string },
{ .type = PF_RT_MAX_SRC_CONN, .off = _OUT(r.max_src_conn), .cb = snl_attr_get_uint32 },
+ { .type = PF_RT_RPOOL_NAT, .off = _OUT(r.nat), .arg = &pool_parser, .cb = snl_attr_get_nested },
};
static struct snl_field_parser fp_getrule[] = {};
#undef _OUT
@@ -2771,7 +2773,7 @@
}
int
-pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa)
+pfctl_add_addr(struct pfctl_handle *h, const struct pfioc_pooladdr *pa, int which __unused)
{
struct snl_writer nw;
struct snl_errmsg_data e = {};
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1687,7 +1687,7 @@
/* callbacks for rule/nat/rdr/addr */
int
-pfctl_add_pool(struct pfctl *pf, struct pfctl_pool *p, sa_family_t af)
+pfctl_add_pool(struct pfctl *pf, struct pfctl_pool *p, sa_family_t af, int which)
{
struct pf_pooladdr *pa;
int ret;
@@ -1701,7 +1701,7 @@
TAILQ_FOREACH(pa, &p->list, entries) {
memcpy(&pf->paddr.addr, pa, sizeof(struct pf_pooladdr));
if ((pf->opts & PF_OPT_NOACTION) == 0) {
- if ((ret = pfctl_add_addr(pf->h, &pf->paddr)) != 0)
+ if ((ret = pfctl_add_addr(pf->h, &pf->paddr, which)) != 0)
errc(1, ret, "DIOCADDADDR");
}
}
@@ -2045,7 +2045,7 @@
was_present = false;
if ((pf->opts & PF_OPT_NOACTION) == 0) {
- if (pfctl_add_pool(pf, &r->rpool, r->af))
+ if (pfctl_add_pool(pf, &r->rpool, r->af, PF_RDR))
return (1);
error = pfctl_add_rule_h(pf->h, r, anchor, name, ticket,
pf->paddr.ticket);
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -281,7 +281,7 @@
int pfctl_append_eth_rule(struct pfctl *, struct pfctl_eth_rule *,
const char *);
int pfctl_add_altq(struct pfctl *, struct pf_altq *);
-int pfctl_add_pool(struct pfctl *, struct pfctl_pool *, sa_family_t);
+int pfctl_add_pool(struct pfctl *, struct pfctl_pool *, sa_family_t, int);
void pfctl_move_pool(struct pfctl_pool *, struct pfctl_pool *);
void pfctl_clear_pool(struct pfctl_pool *);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -785,7 +785,8 @@
char overload_tblname[PF_TABLE_NAME_SIZE];
TAILQ_ENTRY(pf_krule) entries;
- struct pf_kpool rpool;
+ struct pf_kpool nat;
+ struct pf_kpool rdr;
struct pf_counter_u64 evaluations;
struct pf_counter_u64 packets[2];
@@ -1604,8 +1605,10 @@
struct pf_addr *src; /* src address */
struct pf_addr *dst; /* dst address */
- u_int16_t *sport;
- u_int16_t *dport;
+ u_int16_t *sport;
+ u_int16_t *dport;
+ u_int16_t osport;
+ u_int16_t odport;
struct pf_mtag *pf_mtag;
struct pf_rule_actions act;
@@ -2192,7 +2195,7 @@
TAILQ_HEAD(pf_altqqueue, pf_altq);
VNET_DECLARE(struct pf_altqqueue, pf_altqs[4]);
#define V_pf_altqs VNET(pf_altqs)
-VNET_DECLARE(struct pf_kpalist, pf_pabuf);
+VNET_DECLARE(struct pf_kpalist, pf_pabuf[2]);
#define V_pf_pabuf VNET(pf_pabuf)
VNET_DECLARE(u_int32_t, ticket_altqs_active);
@@ -2527,6 +2530,20 @@
#endif /* _KERNEL */
#ifdef _KERNEL
+struct pf_nl_pooladdr {
+ u_int32_t action;
+ u_int32_t ticket;
+ u_int32_t nr;
+ u_int32_t r_num;
+ u_int8_t r_action;
+ u_int8_t r_last;
+ u_int8_t af;
+ char anchor[MAXPATHLEN];
+ struct pf_pooladdr addr;
+ /* Above this is identical to pfioc_pooladdr */
+ int which;
+};
+
VNET_DECLARE(struct pf_kanchor_global, pf_anchors);
#define V_pf_anchors VNET(pf_anchors)
VNET_DECLARE(struct pf_kanchor, pf_main_anchor);
@@ -2579,9 +2596,9 @@
int pf_ioctl_get_limit(int, unsigned int *);
int pf_ioctl_set_limit(int, unsigned int, unsigned int *);
int pf_ioctl_begin_addrs(uint32_t *);
-int pf_ioctl_add_addr(struct pfioc_pooladdr *);
-int pf_ioctl_get_addrs(struct pfioc_pooladdr *);
-int pf_ioctl_get_addr(struct pfioc_pooladdr *);
+int pf_ioctl_add_addr(struct pf_nl_pooladdr *);
+int pf_ioctl_get_addrs(struct pf_nl_pooladdr *);
+int pf_ioctl_get_addr(struct pf_nl_pooladdr *);
int pf_ioctl_get_rulesets(struct pfioc_ruleset *);
int pf_ioctl_get_ruleset(struct pfioc_ruleset *);
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -582,7 +582,7 @@
* give up, as we can't be sure that we will pick the
* same one as the pfsync peer did.
*/
- rpool_first = TAILQ_FIRST(&(r->rpool.list));
+ rpool_first = TAILQ_FIRST(&(r->rdr.list));
if ((rpool_first == NULL) ||
(TAILQ_NEXT(rpool_first, entries) != NULL)) {
DPFPRINTF(PF_DEBUG_MISC,
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -157,7 +157,7 @@
/* state tables */
VNET_DEFINE(struct pf_altqqueue, pf_altqs[4]);
-VNET_DEFINE(struct pf_kpalist, pf_pabuf);
+VNET_DEFINE(struct pf_kpalist, pf_pabuf[2]);
VNET_DEFINE(struct pf_altqqueue *, pf_altqs_active);
VNET_DEFINE(struct pf_altqqueue *, pf_altq_ifs_active);
VNET_DEFINE(struct pf_altqqueue *, pf_altqs_inactive);
@@ -332,8 +332,7 @@
struct pf_kruleset **, struct inpcb *);
static int pf_create_state(struct pf_krule *, struct pf_krule *,
struct pf_krule *, struct pf_pdesc *,
- struct pf_state_key *, struct pf_state_key *,
- u_int16_t, u_int16_t, int *,
+ struct pf_state_key *, struct pf_state_key *, int *,
struct pf_kstate **, int, u_int16_t, u_int16_t,
struct pf_krule_slist *, struct pf_udp_mapping *);
static int pf_state_key_addr_setup(struct pf_pdesc *,
@@ -1027,7 +1026,7 @@
u_short reason = 0;
KASSERT((rule->rule_flag & PFRULE_SRCTRACK ||
- rule->rpool.opts & PF_POOL_STICKYADDR),
+ rule->rdr.opts & PF_POOL_STICKYADDR),
("%s for non-tracking rule %p", __func__, rule));
/*
@@ -1242,7 +1241,8 @@
TAILQ_INIT(&V_pf_altqs[1]);
TAILQ_INIT(&V_pf_altqs[2]);
TAILQ_INIT(&V_pf_altqs[3]);
- TAILQ_INIT(&V_pf_pabuf);
+ TAILQ_INIT(&V_pf_pabuf[0]);
+ TAILQ_INIT(&V_pf_pabuf[1]);
V_pf_altqs_active = &V_pf_altqs[0];
V_pf_altq_ifs_active = &V_pf_altqs[1];
V_pf_altqs_inactive = &V_pf_altqs[2];
@@ -4979,6 +4979,8 @@
sport = dport = 0;
break;
}
+ pd->osport = sport;
+ pd->odport = dport;
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
@@ -5327,7 +5329,7 @@
(pd->flags & PFDESC_TCP_NORM)))) {
int action;
action = pf_create_state(r, nr, a, pd, nk, sk,
- sport, dport, &rewrite, sm, tag, bproto_sum, bip_sum,
+ &rewrite, sm, tag, bproto_sum, bip_sum,
&match_rules, udp_mapping);
if (action != PF_PASS) {
pf_udp_mapping_release(udp_mapping);
@@ -5382,9 +5384,9 @@
static int
pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
struct pf_pdesc *pd, struct pf_state_key *nk, struct pf_state_key *sk,
- u_int16_t sport, u_int16_t dport, int *rewrite, struct pf_kstate **sm,
- int tag, u_int16_t bproto_sum, u_int16_t bip_sum,
- struct pf_krule_slist *match_rules, struct pf_udp_mapping *udp_mapping)
+ int *rewrite, struct pf_kstate **sm, int tag, u_int16_t bproto_sum,
+ u_int16_t bip_sum, struct pf_krule_slist *match_rules,
+ struct pf_udp_mapping *udp_mapping)
{
struct pf_kstate *s = NULL;
struct pf_ksrc_node *sn = NULL;
@@ -5405,14 +5407,14 @@
}
/* src node for filter rule */
if ((r->rule_flag & PFRULE_SRCTRACK ||
- r->rpool.opts & PF_POOL_STICKYADDR) &&
+ r->rdr.opts & PF_POOL_STICKYADDR) &&
(sn_reason = pf_insert_src_node(&sn, &snh, r, pd->src, pd->af,
&pd->act.rt_addr, pd->act.rt_kif)) != 0) {
REASON_SET(&reason, sn_reason);
goto csfailed;
}
/* src node for translation rule */
- if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
+ if (nr != NULL && (nr->rdr.opts & PF_POOL_STICKYADDR) &&
(sn_reason = pf_insert_src_node(&nsn, &nsnh, nr, &sk->addr[pd->sidx],
pd->af, &nk->addr[1], NULL)) != 0 ) {
REASON_SET(&reason, sn_reason);
@@ -5535,7 +5537,9 @@
if (nr == NULL) {
KASSERT((sk == NULL && nk == NULL), ("%s: nr %p sk %p, nk %p",
__func__, nr, sk, nk));
- sk = pf_state_key_setup(pd, pd->src, pd->dst, sport, dport);
+ MPASS(pd->sport == NULL || (pd->osport == *pd->sport));
+ MPASS(pd->dport == NULL || (pd->odport == *pd->dport));
+ sk = pf_state_key_setup(pd, pd->src, pd->dst, pd->osport, pd->odport);
if (sk == NULL)
goto csfailed;
nk = sk;
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -100,7 +100,7 @@
SDT_PROBE_DEFINE2(pf, ioctl, nvchk, error, "int", "int");
static struct pf_kpool *pf_get_kpool(const char *, u_int32_t, u_int8_t,
- u_int32_t, u_int8_t, u_int8_t, u_int8_t);
+ u_int32_t, u_int8_t, u_int8_t, u_int8_t, int);
static void pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *);
static void pf_empty_kpool(struct pf_kpalist *);
@@ -430,12 +430,14 @@
static struct pf_kpool *
pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action,
u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
- u_int8_t check_ticket)
+ u_int8_t check_ticket, int which)
{
struct pf_kruleset *ruleset;
struct pf_krule *rule;
int rs_num;
+ MPASS(which == PF_RDR || which == PF_NAT);
+
ruleset = pf_find_kruleset(anchor);
if (ruleset == NULL)
return (NULL);
@@ -468,7 +470,10 @@
if (rule == NULL)
return (NULL);
- return (&rule->rpool);
+ if (which == PF_NAT)
+ return (&rule->nat);
+ else
+ return (&rule->rdr);
}
static void
@@ -605,7 +610,7 @@
if (rule->rcv_kif)
pfi_kkif_unref(rule->rcv_kif);
pf_kanchor_remove(rule);
- pf_empty_kpool(&rule->rpool.list);
+ pf_empty_kpool(&rule->rdr.list);
pf_krule_free(rule);
}
@@ -1824,7 +1829,8 @@
struct pf_krule *rule;
rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO);
- mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF);
+ mtx_init(&rule->nat.mtx, "pf_krule_nat_pool", NULL, MTX_DEF);
+ mtx_init(&rule->rdr.mtx, "pf_krule_rdr_pool", NULL, MTX_DEF);
rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
M_WAITOK | M_ZERO);
return (rule);
@@ -1862,7 +1868,8 @@
counter_u64_free(rule->src_nodes);
uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
- mtx_destroy(&rule->rpool.mtx);
+ mtx_destroy(&rule->nat.mtx);
+ mtx_destroy(&rule->rdr.mtx);
free(rule, M_PFRULE);
}
@@ -1966,7 +1973,7 @@
if (ret != 0)
return (ret);
- pf_pool_to_kpool(&rule->rpool, &krule->rpool);
+ pf_pool_to_kpool(&rule->rpool, &krule->rdr);
/* Don't allow userspace to set evaluations, packets or bytes. */
/* kif, anchor, overload_tbl are not copied over. */
@@ -2096,7 +2103,8 @@
rule->src_nodes = counter_u64_alloc(M_WAITOK);
rule->cuid = uid;
rule->cpid = pid;
- TAILQ_INIT(&rule->rpool.list);
+ TAILQ_INIT(&rule->rdr.list);
+ TAILQ_INIT(&rule->nat.list);
PF_CONFIG_LOCK();
PF_RULES_WLOCK();
@@ -2194,13 +2202,15 @@
(rule->set_prio[0] > PF_PRIO_MAX ||
rule->set_prio[1] > PF_PRIO_MAX))
error = EINVAL;
- TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
- if (pa->addr.type == PF_ADDR_TABLE) {
- pa->addr.p.tbl = pfr_attach_table(ruleset,
- pa->addr.v.tblname);
- if (pa->addr.p.tbl == NULL)
- error = ENOMEM;
- }
+ for (int i = 0; i < 2; i++) {
+ TAILQ_FOREACH(pa, &V_pf_pabuf[i], entries)
+ if (pa->addr.type == PF_ADDR_TABLE) {
+ pa->addr.p.tbl = pfr_attach_table(ruleset,
+ pa->addr.v.tblname);
+ if (pa->addr.p.tbl == NULL)
+ error = ENOMEM;
+ }
+ }
rule->overload_tbl = NULL;
if (rule->overload_tblname[0]) {
@@ -2212,14 +2222,15 @@
PFR_TFLAG_ACTIVE;
}
- pf_mv_kpool(&V_pf_pabuf, &rule->rpool.list);
+ pf_mv_kpool(&V_pf_pabuf[0], &rule->nat.list);
+ pf_mv_kpool(&V_pf_pabuf[1], &rule->rdr.list);
if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
(rule->action == PF_BINAT)) && rule->anchor == NULL) ||
(rule->rt > PF_NOPFROUTE)) &&
- (TAILQ_FIRST(&rule->rpool.list) == NULL))
+ (TAILQ_FIRST(&rule->rdr.list) == NULL))
error = EINVAL;
- if (rule->action == PF_PASS && rule->rpool.opts & PF_POOL_STICKYADDR &&
+ if (rule->action == PF_PASS && rule->rdr.opts & PF_POOL_STICKYADDR &&
!rule->keep_state) {
error = EINVAL;
}
@@ -2230,7 +2241,8 @@
ERROUT(error);
}
- rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
+ rule->nat.cur = TAILQ_FIRST(&rule->nat.list);
+ rule->rdr.cur = TAILQ_FIRST(&rule->rdr.list);
TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
rule, entries);
ruleset->rules[rs_num].inactive.rcount++;
@@ -2538,7 +2550,8 @@
pf_ioctl_begin_addrs(uint32_t *ticket)
{
PF_RULES_WLOCK();
- pf_empty_kpool(&V_pf_pabuf);
+ pf_empty_kpool(&V_pf_pabuf[0]);
+ pf_empty_kpool(&V_pf_pabuf[1]);
*ticket = ++V_ticket_pabuf;
PF_RULES_WUNLOCK();
@@ -2546,12 +2559,14 @@
}
int
-pf_ioctl_add_addr(struct pfioc_pooladdr *pp)
+pf_ioctl_add_addr(struct pf_nl_pooladdr *pp)
{
struct pf_kpooladdr *pa = NULL;
struct pfi_kkif *kif = NULL;
int error;
+ MPASS(pp->which == PF_RDR || pp->which == PF_NAT);
+
#ifndef INET
if (pp->af == AF_INET)
return (EAFNOSUPPORT);
@@ -2596,7 +2611,8 @@
PF_RULES_WUNLOCK();
goto out;
}
- TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
+ TAILQ_INSERT_TAIL(&V_pf_pabuf[pp->which == PF_RDR ? 1 : 0],
+ pa, entries);
PF_RULES_WUNLOCK();
return (0);
@@ -2607,19 +2623,21 @@
}
int
-pf_ioctl_get_addrs(struct pfioc_pooladdr *pp)
+pf_ioctl_get_addrs(struct pf_nl_pooladdr *pp)
{
struct pf_kpool *pool;
struct pf_kpooladdr *pa;
PF_RULES_RLOCK_TRACKER;
+ MPASS(pp->which == PF_RDR || pp->which == PF_NAT);
+
pp->anchor[sizeof(pp->anchor) - 1] = 0;
pp->nr = 0;
PF_RULES_RLOCK();
pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
- pp->r_num, 0, 1, 0);
+ pp->r_num, 0, 1, 0, pp->which);
if (pool == NULL) {
PF_RULES_RUNLOCK();
return (EBUSY);
@@ -2632,19 +2650,21 @@
}
int
-pf_ioctl_get_addr(struct pfioc_pooladdr *pp)
+pf_ioctl_get_addr(struct pf_nl_pooladdr *pp)
{
struct pf_kpool *pool;
struct pf_kpooladdr *pa;
u_int32_t nr = 0;
+ MPASS(pp->which == PF_RDR || pp->which == PF_NAT);
+
PF_RULES_RLOCK_TRACKER;
pp->anchor[sizeof(pp->anchor) - 1] = 0;
PF_RULES_RLOCK();
pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
- pp->r_num, 0, 1, 1);
+ pp->r_num, 0, 1, 1, pp->which);
if (pool == NULL) {
PF_RULES_RUNLOCK();
return (EBUSY);
@@ -3626,7 +3646,8 @@
newrule->src_nodes = counter_u64_alloc(M_WAITOK);
newrule->cuid = td->td_ucred->cr_ruid;
newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
- TAILQ_INIT(&newrule->rpool.list);
+ TAILQ_INIT(&newrule->nat.list);
+ TAILQ_INIT(&newrule->rdr.list);
}
#define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x)
@@ -3723,14 +3744,16 @@
error = ENOMEM;
if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
error = EINVAL;
- TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
- if (pa->addr.type == PF_ADDR_TABLE) {
- pa->addr.p.tbl =
- pfr_attach_table(ruleset,
- pa->addr.v.tblname);
- if (pa->addr.p.tbl == NULL)
- error = ENOMEM;
- }
+ for (int i = 0; i < 2; i++) {
+ TAILQ_FOREACH(pa, &V_pf_pabuf[i], entries)
+ if (pa->addr.type == PF_ADDR_TABLE) {
+ pa->addr.p.tbl =
+ pfr_attach_table(ruleset,
+ pa->addr.v.tblname);
+ if (pa->addr.p.tbl == NULL)
+ error = ENOMEM;
+ }
+ }
newrule->overload_tbl = NULL;
if (newrule->overload_tblname[0]) {
@@ -3743,13 +3766,14 @@
PFR_TFLAG_ACTIVE;
}
- pf_mv_kpool(&V_pf_pabuf, &newrule->rpool.list);
+ pf_mv_kpool(&V_pf_pabuf[0], &newrule->nat.list);
+ pf_mv_kpool(&V_pf_pabuf[1], &newrule->rdr.list);
if (((((newrule->action == PF_NAT) ||
(newrule->action == PF_RDR) ||
(newrule->action == PF_BINAT) ||
(newrule->rt > PF_NOPFROUTE)) &&
!newrule->anchor)) &&
- (TAILQ_FIRST(&newrule->rpool.list) == NULL))
+ (TAILQ_FIRST(&newrule->rdr.list) == NULL))
error = EINVAL;
if (error) {
@@ -3759,9 +3783,11 @@
break;
}
- newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
+ newrule->nat.cur = TAILQ_FIRST(&newrule->nat.list);
+ newrule->rdr.cur = TAILQ_FIRST(&newrule->rdr.list);
}
- pf_empty_kpool(&V_pf_pabuf);
+ pf_empty_kpool(&V_pf_pabuf[0]);
+ pf_empty_kpool(&V_pf_pabuf[1]);
if (pcr->action == PF_CHANGE_ADD_HEAD)
oldrule = TAILQ_FIRST(
@@ -4390,22 +4416,35 @@
case DIOCADDADDR: {
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+ struct pf_nl_pooladdr npp = {};
- error = pf_ioctl_add_addr(pp);
+ npp.which = PF_RDR;
+ memcpy(&npp, pp, sizeof(*pp));
+ error = pf_ioctl_add_addr(&npp);
break;
}
case DIOCGETADDRS: {
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+ struct pf_nl_pooladdr npp = {};
+
+ npp.which = PF_RDR;
+ memcpy(&npp, pp, sizeof(*pp));
+ error = pf_ioctl_get_addrs(&npp);
+ memcpy(pp, &npp, sizeof(*pp));
- error = pf_ioctl_get_addrs(pp);
break;
}
case DIOCGETADDR: {
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+ struct pf_nl_pooladdr npp = {};
+
+ npp.which = PF_RDR;
+ memcpy(&npp, pp, sizeof(*pp));
+ error = pf_ioctl_get_addr(&npp);
+ memcpy(pp, &npp, sizeof(*pp));
- error = pf_ioctl_get_addr(pp);
break;
}
@@ -4460,7 +4499,7 @@
ERROUT(EBUSY);
pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action,
- pca->r_num, pca->r_last, 1, 1);
+ pca->r_num, pca->r_last, 1, 1, PF_RDR);
if (pool == NULL)
ERROUT(EBUSY);
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -149,8 +149,8 @@
if (r->action == PF_BINAT && pd->dir == PF_IN) {
src = &r->dst;
- if (r->rpool.cur != NULL)
- xdst = &r->rpool.cur->addr;
+ if (r->rdr.cur != NULL)
+ xdst = &r->rdr.cur->addr;
} else {
src = &r->src;
dst = &r->dst;
@@ -240,7 +240,7 @@
* from the mapping. In this case we have to look up the src_node as
* pf_map_addr would.
*/
- if (proto == IPPROTO_UDP && (r->rpool.opts & PF_POOL_ENDPI)) {
+ if (proto == IPPROTO_UDP && (r->rdr.opts & PF_POOL_ENDPI)) {
struct pf_udp_endpoint_cmp udp_source;
bzero(&udp_source, sizeof(udp_source));
@@ -252,8 +252,8 @@
PF_ACPY(naddr, &(*udp_mapping)->endpoints[1].addr, af);
*nport = (*udp_mapping)->endpoints[1].port;
/* Try to find a src_node as per pf_map_addr(). */
- if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
- (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
+ if (*sn == NULL && r->rdr.opts & PF_POOL_STICKYADDR &&
+ (r->rdr.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
*sn = pf_find_src_node(saddr, r, af, sh, false);
if (*sn != NULL)
PF_SRC_NODE_UNLOCK(*sn);
@@ -363,7 +363,7 @@
tmp = cut;
for (tmp -= 1; tmp >= low && tmp <= 0xffff; --tmp) {
if (proto == IPPROTO_UDP &&
- (r->rpool.opts & PF_POOL_ENDPI)) {
+ (r->rdr.opts & PF_POOL_ENDPI)) {
(*udp_mapping)->endpoints[1].port = htons(tmp);
if (pf_udp_mapping_insert(*udp_mapping) == 0) {
*nport = htons(tmp);
@@ -379,7 +379,7 @@
}
}
- switch (r->rpool.opts & PF_POOL_TYPEMASK) {
+ switch (r->rdr.opts & PF_POOL_TYPEMASK) {
case PF_POOL_RANDOM:
case PF_POOL_ROUNDROBIN:
/*
@@ -423,13 +423,13 @@
uint16_t i, ahigh, cut;
int ashift, psidshift;
- ashift = 16 - r->rpool.mape.offset;
- psidshift = ashift - r->rpool.mape.psidlen;
- psmask = r->rpool.mape.psid & ((1U << r->rpool.mape.psidlen) - 1);
+ ashift = 16 - r->rdr.mape.offset;
+ psidshift = ashift - r->rdr.mape.psidlen;
+ psmask = r->rdr.mape.psid & ((1U << r->rdr.mape.psidlen) - 1);
psmask = psmask << psidshift;
highmask = (1U << psidshift) - 1;
- ahigh = (1U << r->rpool.mape.offset) - 1;
+ ahigh = (1U << r->rdr.mape.offset) - 1;
cut = arc4random() & ahigh;
if (cut == 0)
cut = 1;
@@ -454,7 +454,7 @@
struct pf_addr *naddr, struct pfi_kkif **nkif, struct pf_addr *init_addr)
{
u_short reason = PFRES_MATCH;
- struct pf_kpool *rpool = &r->rpool;
+ struct pf_kpool *rpool = &r->rdr;
struct pf_addr *raddr = NULL, *rmask = NULL;
mtx_lock(&rpool->mtx);
@@ -629,7 +629,7 @@
struct pf_ksrc_node **sn, struct pf_srchash **sh)
{
u_short reason = 0;
- struct pf_kpool *rpool = &r->rpool;
+ struct pf_kpool *rpool = &r->rdr;
KASSERT(*sn == NULL, ("*sn not NULL"));
@@ -638,8 +638,8 @@
* Request the sh to be unlocked if sn was not found, as we never
* insert a new sn when parsing the ruleset.
*/
- if (r->rpool.opts & PF_POOL_STICKYADDR &&
- (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
+ if (r->rdr.opts & PF_POOL_STICKYADDR &&
+ (r->rdr.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
*sn = pf_find_src_node(saddr, r, af, sh, false);
if (*sn != NULL) {
@@ -763,19 +763,19 @@
low = 1;
high = 65535;
} else {
- low = r->rpool.proxy_port[0];
- high = r->rpool.proxy_port[1];
+ low = r->rdr.proxy_port[0];
+ high = r->rdr.proxy_port[1];
}
- if (r->rpool.mape.offset > 0) {
+ if (r->rdr.mape.offset > 0) {
if (pf_get_mape_sport(pd->af, pd->proto, r, saddr,
sport, daddr, dport, naddr, nportp, &sn, &sh,
udp_mapping)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: MAP-E port allocation (%u/%u/%u)"
" failed\n",
- r->rpool.mape.offset,
- r->rpool.mape.psidlen,
- r->rpool.mape.psid));
+ r->rdr.mape.offset,
+ r->rdr.mape.psidlen,
+ r->rdr.mape.psid));
reason = PFRES_MAPFAILED;
goto notrans;
}
@@ -784,7 +784,7 @@
udp_mapping)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: NAT proxy port allocation (%u-%u) failed\n",
- r->rpool.proxy_port[0], r->rpool.proxy_port[1]));
+ r->rdr.proxy_port[0], r->rdr.proxy_port[1]));
reason = PFRES_MAPFAILED;
goto notrans;
}
@@ -792,41 +792,41 @@
case PF_BINAT:
switch (pd->dir) {
case PF_OUT:
- if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
+ if (r->rdr.cur->addr.type == PF_ADDR_DYNIFTL){
switch (pd->af) {
#ifdef INET
case AF_INET:
- if (r->rpool.cur->addr.p.dyn->
+ if (r->rdr.cur->addr.p.dyn->
pfid_acnt4 < 1) {
reason = PFRES_MAPFAILED;
goto notrans;
}
PF_POOLMASK(naddr,
- &r->rpool.cur->addr.p.dyn->
+ &r->rdr.cur->addr.p.dyn->
pfid_addr4,
- &r->rpool.cur->addr.p.dyn->
+ &r->rdr.cur->addr.p.dyn->
pfid_mask4, saddr, AF_INET);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if (r->rpool.cur->addr.p.dyn->
+ if (r->rdr.cur->addr.p.dyn->
pfid_acnt6 < 1) {
reason = PFRES_MAPFAILED;
goto notrans;
}
PF_POOLMASK(naddr,
- &r->rpool.cur->addr.p.dyn->
+ &r->rdr.cur->addr.p.dyn->
pfid_addr6,
- &r->rpool.cur->addr.p.dyn->
+ &r->rdr.cur->addr.p.dyn->
pfid_mask6, saddr, AF_INET6);
break;
#endif /* INET6 */
}
} else
PF_POOLMASK(naddr,
- &r->rpool.cur->addr.v.a.addr,
- &r->rpool.cur->addr.v.a.mask, saddr,
+ &r->rdr.cur->addr.v.a.addr,
+ &r->rdr.cur->addr.v.a.mask, saddr,
pd->af);
break;
case PF_IN:
@@ -871,27 +871,27 @@
reason = pf_map_addr_sn(pd->af, r, saddr, naddr, NULL, NULL, &sn, &sh);
if (reason != 0)
goto notrans;
- if ((r->rpool.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
- PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask,
+ if ((r->rdr.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
+ PF_POOLMASK(naddr, naddr, &r->rdr.cur->addr.v.a.mask,
daddr, pd->af);
/* Do not change SCTP ports. */
if (pd->proto == IPPROTO_SCTP)
break;
- if (r->rpool.proxy_port[1]) {
+ if (r->rdr.proxy_port[1]) {
uint32_t tmp_nport;
tmp_nport = ((ntohs(dport) - ntohs(r->dst.port[0])) %
- (r->rpool.proxy_port[1] - r->rpool.proxy_port[0] +
- 1)) + r->rpool.proxy_port[0];
+ (r->rdr.proxy_port[1] - r->rdr.proxy_port[0] +
+ 1)) + r->rdr.proxy_port[0];
/* Wrap around if necessary. */
if (tmp_nport > 65535)
tmp_nport -= 65535;
nport = htons((uint16_t)tmp_nport);
- } else if (r->rpool.proxy_port[0])
- nport = htons(r->rpool.proxy_port[0]);
+ } else if (r->rdr.proxy_port[0])
+ nport = htons(r->rdr.proxy_port[0]);
else
nport = dport;
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -198,7 +198,7 @@
PF_RT_TAGNAME = 8, /* string */
PF_RT_MATCH_TAGNAME = 9, /* string */
PF_RT_OVERLOAD_TBLNAME = 10, /* string */
- PF_RT_RPOOL = 11, /* nested, pf_rpool_type_t */
+ PF_RT_RPOOL_RDR = 11, /* nested, pf_rpool_type_t */
PF_RT_OS_FINGERPRINT = 12, /* u32 */
PF_RT_RTABLEID = 13, /* u32 */
PF_RT_TIMEOUT = 14, /* nested, pf_timeout_type_t */
@@ -262,6 +262,7 @@
PF_RT_ANCHOR_CALL = 72, /* string */
PF_RT_RCV_IFNAME = 73, /* string */
PF_RT_MAX_SRC_CONN = 74, /* u32 */
+ PF_RT_RPOOL_NAT = 75, /* nested, pf_rpool_type_t */
};
enum pf_addrule_type_t {
@@ -381,6 +382,7 @@
PF_AA_AF = 7, /* u8 */
PF_AA_ANCHOR = 8, /* string */
PF_AA_ADDR = 9, /* nested, pf_pooladdr */
+ PF_AA_WHICH = 10, /* u32 */
};
enum pf_get_rulesets_types_t {
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -678,7 +678,7 @@
{ .type = PF_RT_TAGNAME, .off = _OUT(tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = nlattr_get_chara },
{ .type = PF_RT_MATCH_TAGNAME, .off = _OUT(match_tagname), .arg = (void *)PF_TAG_NAME_SIZE, .cb = nlattr_get_chara },
{ .type = PF_RT_OVERLOAD_TBLNAME, .off = _OUT(overload_tblname), .arg = (void *)PF_TABLE_NAME_SIZE, .cb = nlattr_get_chara },
- { .type = PF_RT_RPOOL, .off = _OUT(rpool), .arg = &pool_parser, .cb = nlattr_get_nested },
+ { .type = PF_RT_RPOOL_RDR, .off = _OUT(rdr), .arg = &pool_parser, .cb = nlattr_get_nested },
{ .type = PF_RT_OS_FINGERPRINT, .off = _OUT(os_fingerprint), .cb = nlattr_get_uint32 },
{ .type = PF_RT_RTABLEID, .off = _OUT(rtableid), .cb = nlattr_get_uint32 },
{ .type = PF_RT_TIMEOUT, .off = _OUT(timeout), .arg = &timeout_parser, .cb = nlattr_get_nested_timeouts },
@@ -732,6 +732,7 @@
{ .type = PF_RT_DIVERT_PORT, .off = _OUT(divert.port), .cb = nlattr_get_uint16 },
{ .type = PF_RT_RCV_IFNAME, .off = _OUT(rcv_ifname), .arg = (void *)IFNAMSIZ, .cb = nlattr_get_chara },
{ .type = PF_RT_MAX_SRC_CONN, .off = _OUT(max_src_conn), .cb = nlattr_get_uint32 },
+ { .type = PF_RT_RPOOL_NAT, .off = _OUT(nat), .arg = &pool_parser, .cb = nlattr_get_nested },
};
NL_DECLARE_ATTR_PARSER(rule_parser, nla_p_rule);
#undef _OUT
@@ -915,7 +916,8 @@
nlattr_add_string(nw, PF_RT_TAGNAME, rule->tagname);
nlattr_add_string(nw, PF_RT_MATCH_TAGNAME, rule->match_tagname);
nlattr_add_string(nw, PF_RT_OVERLOAD_TBLNAME, rule->overload_tblname);
- nlattr_add_pool(nw, PF_RT_RPOOL, &rule->rpool);
+ nlattr_add_pool(nw, PF_RT_RPOOL_RDR, &rule->rdr);
+ nlattr_add_pool(nw, PF_RT_RPOOL_NAT, &rule->nat);
nlattr_add_u32(nw, PF_RT_OS_FINGERPRINT, rule->os_fingerprint);
nlattr_add_u32(nw, PF_RT_RTABLEID, rule->rtableid);
nlattr_add_timeout(nw, PF_RT_TIMEOUT, rule->timeout);
@@ -1528,7 +1530,7 @@
NL_DECLARE_ATTR_PARSER(pool_addr_parser, nla_p_pool_addr);
#undef _OUT
-#define _OUT(_field) offsetof(struct pfioc_pooladdr, _field)
+#define _OUT(_field) offsetof(struct pf_nl_pooladdr, _field)
static const struct nlattr_parser nla_p_add_addr[] = {
{ .type = PF_AA_ACTION, .off = _OUT(action), .cb = nlattr_get_uint32 },
{ .type = PF_AA_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
@@ -1539,6 +1541,7 @@
{ .type = PF_AA_AF, .off = _OUT(af), .cb = nlattr_get_uint8 },
{ .type = PF_AA_ANCHOR, .off = _OUT(anchor), .arg = (void *)MAXPATHLEN, .cb = nlattr_get_chara },
{ .type = PF_AA_ADDR, .off = _OUT(addr), .arg = &pool_addr_parser, .cb = nlattr_get_nested },
+ { .type = PF_AA_WHICH, .off = _OUT(which), .cb = nlattr_get_uint32 },
};
static const struct nlfield_parser nlf_p_add_addr[] = {};
#undef _OUT
@@ -1547,13 +1550,16 @@
static int
pf_handle_add_addr(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
- struct pfioc_pooladdr attrs = { 0 };
+ struct pf_nl_pooladdr attrs = { 0 };
int error;
error = nl_parse_nlmsg(hdr, &add_addr_parser, npt, &attrs);
if (error != 0)
return (error);
+ if (attrs.which == 0)
+ attrs.which = PF_RDR;
+
error = pf_ioctl_add_addr(&attrs);
return (error);
@@ -1562,7 +1568,7 @@
static int
pf_handle_get_addrs(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
- struct pfioc_pooladdr attrs = { 0 };
+ struct pf_nl_pooladdr attrs = { 0 };
struct nl_writer *nw = npt->nw;
struct genlmsghdr *ghdr_new;
int error;
@@ -1571,6 +1577,9 @@
if (error != 0)
return (error);
+ if (attrs.which == 0)
+ attrs.which = PF_RDR;
+
error = pf_ioctl_get_addrs(&attrs);
if (error != 0)
return (error);
@@ -1596,7 +1605,7 @@
static int
pf_handle_get_addr(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
- struct pfioc_pooladdr attrs = { 0 };
+ struct pf_nl_pooladdr attrs = { 0 };
struct nl_writer *nw = npt->nw;
struct genlmsghdr *ghdr_new;
int error;
@@ -1605,6 +1614,9 @@
if (error != 0)
return (error);
+ if (attrs.which == 0)
+ attrs.which = PF_RDR;
+
error = pf_ioctl_get_addr(&attrs);
if (error != 0)
return (error);
diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -563,7 +563,7 @@
if (! nvlist_exists_nvlist(nvl, "rpool"))
ERROUT(EINVAL);
PFNV_CHK(pf_nvpool_to_pool(nvlist_get_nvlist(nvl, "rpool"),
- &rule->rpool));
+ &rule->rdr));
PFNV_CHK(pf_nvuint32(nvl, "os_fingerprint", &rule->os_fingerprint));
@@ -721,7 +721,7 @@
nvlist_add_string(nvl, "match_tagname", rule->match_tagname);
nvlist_add_string(nvl, "overload_tblname", rule->overload_tblname);
- tmp = pf_pool_to_nvpool(&rule->rpool);
+ tmp = pf_pool_to_nvpool(&rule->rdr);
if (tmp == NULL)
goto error;
nvlist_add_nvlist(nvl, "rpool", tmp);

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 28, 2:54 AM (10 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17824821
Default Alt Text
D47783.diff (32 KB)

Event Timeline