From nobody Tue Dec 17 10:07:39 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YCCDC6KVMz5h0F1; Tue, 17 Dec 2024 10:07:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YCCDC5y1Rz49N8; Tue, 17 Dec 2024 10:07:39 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734430059; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Daq0NDQMva/RgioUTcCJVjGFYzbuH4q6zwVbsFWRnLA=; b=WnMAnd1q3yjeu0k/lTAr2qiHq3O2Q4h7DvjDc7PIQC51RFS2CskpZ8mL1RdK35EfK7kHv9 xFLZoEObbEFg30oI2jwJ2mYb/5NxyA62eiBq6qs0Oc8rdKy+iRq/jRvLmqjSbjLp4Pn92A ZXciXkmx6Ot+ifMU63PHXFaPhjVTfWu7nWPZO7YTj1Z4cjLxnZWJB0oyy3xe8+/+iSgkvO xLe1zWCzkPnYpvJvuE0TrvTEEhaMy7MryrmIx2/UxKhbt30qrzoWRnKEzDGQyDT1D+Pjoc P+PPDxX7K0U90mtUZq0BD/fL/JGRQ2zQ8syD3PlW1JA2vWKiOdkXeBsRdy1Ivw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734430059; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Daq0NDQMva/RgioUTcCJVjGFYzbuH4q6zwVbsFWRnLA=; b=xThljCtXl0He++4+RU8pbZdWMjqVPfJap1Wqjy7yk7dTdgRuH4CAqEQgYVjyUSuUWy+2sZ OfdMcaHrEq/BMIse94rqmz4Rk/e87R2olzevnSLNxNJDWporuZdQlIF23hHoJgIAGERYMN UBvaTCvks42FjoNI9k993N7YaFUdZ0laQMwTI+fR3q99Vz7mFj86+K2LCnmNL2yJP8KTam /eH+pv8tQP5zc+IFepa59xfUPsqYXUFDgJxGIStNrigB++qR/iDq2Rt2iV9Yh19xSsV907 Zc+TrjBL7GRYlMElZQp9+oML3L7Wy5LPhcVlHGDMMewGa3RrGcvGVQr8L4/YBw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1734430059; a=rsa-sha256; cv=none; b=OwVwKmAkwZoTwtYfzoJJkHUe+xnTKttvmxZkZzcnx6Ex8dxXEzIOGBMRy/IcaiH0r5cOMa FUfwxITYYJmrLGDPd+Aq1gXno1cwC/dkcBW/zMSZlH/aBV7YorlXOshIc2i2l847JXtvTZ dIw0ZrS4JesG06AzMYEU2sYio5NeNWO2vKGj0IIv+g6xOv4jSNrvOmZer+2P9Xs+zNgxra 5jA1mIMyP5cnqW5zzW9oHrRKTCxmuSuNMXn23k5dbqVcci0PHCvnwdI0ejp2B++I1bw2nB dp7YcEyWnTrV1+QLsAzf1T0poARwlGv6t4hmLzcATHnE8Mn/Nr83i54cm3pnxQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YCCDC5VrXzJ1q; Tue, 17 Dec 2024 10:07:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4BHA7dut023254; Tue, 17 Dec 2024 10:07:39 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BHA7dPM023251; Tue, 17 Dec 2024 10:07:39 GMT (envelope-from git) Date: Tue, 17 Dec 2024 10:07:39 GMT Message-Id: <202412171007.4BHA7dPM023251@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: e11dacbf8484 - main - pf: partially import OpenBSD's NAT rewrite List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e11dacbf8484adc7bbb61b20fee3ab8385745925 Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=e11dacbf8484adc7bbb61b20fee3ab8385745925 commit e11dacbf8484adc7bbb61b20fee3ab8385745925 Author: Kristof Provost AuthorDate: 2024-10-11 12:15:48 +0000 Commit: Kristof Provost CommitDate: 2024-12-17 10:07:12 +0000 pf: partially import OpenBSD's NAT rewrite We won't follow this fully, because it involves breaking syntax changes (removing nat/rdr rules and moving this functionality into regular rules) as well as behaviour changes because NAT is now done after the rules evaluation, rather than before it. We import some related changes anyway, because it paves the way for nat64 support. This change introduces a new pf_kpool in struct pf_krule, for nat. It is not yet used (but will be for nat64) and renames the existing 'rpool' to 'rdr'. Obtained from: OpenBSD, henning , 0ef3d4febe Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D47783 --- lib/libpfctl/libpfctl.c | 10 ++-- lib/libpfctl/libpfctl.h | 9 +++- sbin/pfctl/pfctl.c | 6 +-- sbin/pfctl/pfctl_parser.h | 2 +- sys/net/pfvar.h | 31 ++++++++--- sys/netpfil/pf/if_pfsync.c | 2 +- sys/netpfil/pf/pf.c | 28 +++++----- sys/netpfil/pf/pf_ioctl.c | 125 +++++++++++++++++++++++++++++---------------- sys/netpfil/pf/pf_lb.c | 76 +++++++++++++-------------- sys/netpfil/pf/pf_nl.c | 24 ++++++--- sys/netpfil/pf/pf_nl.h | 4 +- sys/netpfil/pf/pf_nv.c | 4 +- 12 files changed, 201 insertions(+), 120 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 4634fa99cb19..21d0b24601a4 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -731,7 +731,7 @@ pf_nvrule_to_rule(const nvlist_t *nvl, struct pfctl_rule *rule) 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_pf_rule(struct snl_writer *nw, uint32_t type, const struct pfct 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 @@ static struct snl_attr_parser ap_getrule[] = { { .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 @@ static struct snl_attr_parser ap_getrule[] = { { .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 @@ pfctl_begin_addrs(struct pfctl_handle *h, uint32_t *ticket) } 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/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 5c3f1376960c..7b4aa0555758 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -174,7 +174,12 @@ struct pfctl_rule { 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_get_timeout(struct pfctl_handle *h, uint32_t timeout, uint32_t *second 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/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index aa3db4619972..4d77c7937a74 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1687,7 +1687,7 @@ pfctl_show_creators(int opts) /* 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 @@ pfctl_add_pool(struct pfctl *pf, struct pfctl_pool *p, sa_family_t af) 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 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth) 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 index 498027f5968c..551f2ff7537c 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -281,7 +281,7 @@ int pfctl_append_rule(struct pfctl *, struct pfctl_rule *, const char *); 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 index 100775347143..8cee1de14cb5 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -785,7 +785,8 @@ struct pf_krule { 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_pdesc { 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 @@ VNET_DECLARE(struct unrhdr64, pf_stateid); 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 @@ VNET_DECLARE(struct pf_limit, pf_limits[PF_LIMIT_MAX]); #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_set_timeout(int, int, int *); 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 index 5923675ff144..60bfb05d1570 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -582,7 +582,7 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version) * 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 index d0ddff9f38a2..806800174f03 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -157,7 +157,7 @@ SDT_PROBE_DEFINE2(pf, purge, state, rowcount, "int", "size_t"); /* 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 @@ static int pf_test_rule(struct pf_krule **, struct pf_kstate **, 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 @@ pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_srchash **sh, 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 @@ pf_initialize(void) 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 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, 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 @@ nextrule: (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 @@ cleanup: 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 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, } /* 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 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, 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 index 0fdf41a9811f..35af04eda837 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -100,7 +100,7 @@ SDT_PROBE_DEFINE2(pf, ioctl, addrule, error, "int", "int"); 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 @@ pfattach_vnet(void) 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 @@ pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action, 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 @@ pf_free_rule(struct pf_krule *rule) 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 @@ pf_krule_alloc(void) 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 @@ pf_krule_free(struct pf_krule *rule) 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 @@ pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule) 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 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, 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 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, (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 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, 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 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, 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 @@ int 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 @@ pf_ioctl_begin_addrs(uint32_t *ticket) } 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_ioctl_add_addr(struct pfioc_pooladdr *pp) 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 @@ out: } 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 @@ pf_ioctl_get_addrs(struct pfioc_pooladdr *pp) } 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 @@ DIOCGETRULENV_error: 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 @@ DIOCGETRULENV_error: 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 @@ DIOCGETRULENV_error: 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 @@ DIOCGETRULENV_error: 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 @@ DIOCGETSTATESV2_full: 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 @@ DIOCGETSTATESV2_full: 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 index 8087546683af..10129a5fab46 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -149,8 +149,8 @@ pf_match_translation(struct pf_pdesc *pd, 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 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, * 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_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, 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 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, 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 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, } } - 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 @@ pf_get_mape_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r, 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 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, 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 @@ pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, 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 @@ pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, * 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 @@ pf_get_translation(struct pf_pdesc *pd, int off, 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 @@ pf_get_translation(struct pf_pdesc *pd, int off, 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 @@ pf_get_translation(struct pf_pdesc *pd, int off, 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 @@ pf_get_translation(struct pf_pdesc *pd, int off, 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.c b/sys/netpfil/pf/pf_nl.c index ad7dc97cbc1a..52d77034c4b7 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -678,7 +678,7 @@ static const struct nlattr_parser nla_p_rule[] = { { .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 @@ static const struct nlattr_parser nla_p_rule[] = { { .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 @@ pf_handle_getrule(struct nlmsghdr *hdr, struct nl_pstate *npt) 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 @@ static const struct nlattr_parser nla_p_pool_addr[] = { 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 @@ static const struct nlattr_parser nla_p_add_addr[] = { { .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 @@ NL_DECLARE_PARSER(add_addr_parser, struct genlmsghdr, nlf_p_add_addr, nla_p_add_ 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 @@ pf_handle_add_addr(struct nlmsghdr *hdr, struct nl_pstate *npt) 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 @@ pf_handle_get_addrs(struct nlmsghdr *hdr, struct nl_pstate *npt) if (error != 0) return (error); + if (attrs.which == 0) + attrs.which = PF_RDR; + *** 73 LINES SKIPPED ***