From nobody Tue Dec 03 13:10:17 2024 X-Original-To: dev-commits-src-main@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 4Y2gxQ1jdzz5g2pp; Tue, 03 Dec 2024 13:10:18 +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 4Y2gxQ158dz3y2d; Tue, 3 Dec 2024 13:10:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733231418; 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=bcf9kPTceuxE0jvXn0fioJ9ftUXfrdZ8MFTYefcyWn0=; b=QIQU5MdW4y+mVzfzRTZWYwsPeFS+SIk16xUCScgDxPonynWA6alx9sx2sKyggI72lt51/y diVnMARd9rV4tjMCdjQnV85dFe7ynjZXEDW8oPamUtfINJaMj84CPKtNxIhIvy7HDkTxb+ MIWJ1uWcFVZ6XDguB0niUcMrqwjR43lnp7kc7me0RKT3ePFffyF9+dpqcAZdDmGIK3ljZj svWkXdyy/WWcuoUNd4xnXj7DLOznS9fiOdiuhwK9QZ0aSaVDhFTiaTqgk8IHXczqjqgpUB jfkGkFs7/NV78BQlWOXnkO5iPzcpGOg3avJyBAkxx8zypBKAh2QLqTLZCGSAgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733231418; 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=bcf9kPTceuxE0jvXn0fioJ9ftUXfrdZ8MFTYefcyWn0=; b=we/Gonf3x0+oGMgQ9pW5c8ewRKZIwKj3easWbPUN9COAh432EAhq5z6BZ4Sv0k7jpuGMKp 4pDV35I/ESOolHPJarp+dNqDw/1CxIgWhfrxzTzLXmV4FDLitUh24d2jhii683NwFqUL0W u7UKkeOy2asOw8EIvN/743nslapOmK2cPe2pIOjaoavcEl4c0h++5171X9tJ1oLDd4Ec1z uEbTrmG1hsVzaPDmV9TNGA2JCTQgQOSEWWQT533jPXl8+/qTNwX28QFqsgWNPUiYUuiDg3 TOrJ/cHywiaKcq8hn9v4+GRp1pPlZ+8O9RufNi9p4QxrqLsruKtp3nOpfYOT3A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1733231418; a=rsa-sha256; cv=none; b=tfanhkr/RXpRlRY8CjGzgzBo7ALJmYVKnqegzWYSbpaevB1TtSEEA8dLfFaPnI73yqB/wl r295FNyKs39SE5oJUzLTp4TFRVxNHHHo1rTLD4trXJIQ8ITz2QA4jbzYbc1JL5LNku3b9b hN1cNhxxQyDa9+qHNSW1jXFYOQnzLQHkFFOuHkzE8niBCrxM/yjT5itFln2NU8hnNZfhx2 /cKHWi3aa2raRQNwy9ErxYLxlmwyIZVVpYkhS7CFGlhELlemvyUmW5ZPNaNsA/XURaxyUi d/nuo1BRGEoy8D7WNmJNUkET2kTLOzGKoT1YIQeMP/Gl7bBB3S6TytHhwUnHJA== 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 4Y2gxQ0R2FzNn1; Tue, 3 Dec 2024 13:10:18 +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 4B3DAHn2091202; Tue, 3 Dec 2024 13:10:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4B3DAHT0091183; Tue, 3 Dec 2024 13:10:17 GMT (envelope-from git) Date: Tue, 3 Dec 2024 13:10:17 GMT Message-Id: <202412031310.4B3DAHT0091183@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kajetan Staszkiewicz Subject: git: c49c9da239ca - main - pf: Move route-to information to rule actions List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ks X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c49c9da239ca59722f104a64d9128e4b6052885a Auto-Submitted: auto-generated The branch main has been updated by ks: URL: https://cgit.FreeBSD.org/src/commit/?id=c49c9da239ca59722f104a64d9128e4b6052885a commit c49c9da239ca59722f104a64d9128e4b6052885a Author: Kajetan Staszkiewicz AuthorDate: 2024-11-28 13:08:15 +0000 Commit: Kajetan Staszkiewicz CommitDate: 2024-12-03 12:46:34 +0000 pf: Move route-to information to rule actions Route-to redirection information (rt, rt_kif, rt_addr) can be considered an action of a rule. This information is duplicated in struct pf_kstate which means that the pf_route() function must always figure out where to get this information from: state for stateful forwarding, or rule for stateless. Create the necessary members in struct pf_rule_action. Fill them in right after parsing the ruleset, similar for how NAT redirection is applied right after parsing the NAT ruleset. Remove the logic for finding the right source for route-to redirection from pf_route(). As a bonus simplify pf_map_addr_sn() and source node handling. Both for the NAT and the filter ruleset there is now only one path: 1. parse the rules 2. apply redirection either from an existing source node or by load balancing for the last matching rule 3. create the source node using the redirection if the node does not yet exist Reviewed by: kp Approved by: kp (mentor) Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D47827 --- sys/net/pfvar.h | 12 ++-- sys/netpfil/pf/if_pfsync.c | 6 +- sys/netpfil/pf/pf.c | 153 +++++++++++++++++---------------------------- sys/netpfil/pf/pf_ioctl.c | 18 +++--- sys/netpfil/pf/pf_lb.c | 32 +++------- sys/netpfil/pf/pf_nl.c | 8 +-- sys/netpfil/pf/pf_nv.c | 2 +- 7 files changed, 91 insertions(+), 140 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 0a0a17d2c754..30229cca2e74 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -648,17 +648,20 @@ struct pf_kpool { }; struct pf_rule_actions { + struct pf_addr rt_addr; + struct pfi_kkif *rt_kif; int32_t rtableid; + uint32_t flags; uint16_t qid; uint16_t pqid; uint16_t max_mss; + uint16_t dnpipe; + uint16_t dnrpipe; /* Reverse direction pipe */ uint8_t log; uint8_t set_tos; uint8_t min_ttl; - uint16_t dnpipe; - uint16_t dnrpipe; /* Reverse direction pipe */ - uint32_t flags; uint8_t set_prio[2]; + uint8_t rt; }; union pf_keth_rule_ptr { @@ -1089,12 +1092,10 @@ struct pf_kstate { struct pf_krule *rule; struct pf_krule *anchor; struct pf_krule *nat_rule; - struct pf_addr rt_addr; struct pf_state_key *key[2]; /* addresses stack and wire */ struct pf_udp_mapping *udp_mapping; struct pfi_kkif *kif; struct pfi_kkif *orig_kif; /* The real kif, even if we're a floating state (i.e. if == V_pfi_all). */ - struct pfi_kkif *rt_kif; struct pf_ksrc_node *src_node; struct pf_ksrc_node *nat_src_node; u_int64_t packets[2]; @@ -1104,7 +1105,6 @@ struct pf_kstate { u_int32_t pfsync_time; struct pf_rule_actions act; u_int16_t tag; - u_int8_t rt; u_int16_t if_index_in; u_int16_t if_index_out; }; diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 0dd1b480b313..8dd3d875dc0b 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -611,7 +611,7 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version) } /* copy to state */ - bcopy(&sp->pfs_1301.rt_addr, &st->rt_addr, sizeof(st->rt_addr)); + bcopy(&sp->pfs_1301.rt_addr, &st->act.rt_addr, sizeof(st->act.rt_addr)); st->creation = (time_uptime - ntohl(sp->pfs_1301.creation)) * 1000; st->expire = pf_get_uptime(); if (sp->pfs_1301.expire) { @@ -680,8 +680,8 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version) st->act.max_mss = ntohs(sp->pfs_1400.max_mss); st->act.set_prio[0] = sp->pfs_1400.set_prio[0]; st->act.set_prio[1] = sp->pfs_1400.set_prio[1]; - st->rt = sp->pfs_1400.rt; - if (st->rt && (st->rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) { + st->act.rt = sp->pfs_1400.rt; + if (st->act.rt && (st->act.rt_kif = pfi_kkif_find(sp->pfs_1400.rt_ifname)) == NULL) { if (V_pf_status.debug >= PF_DEBUG_MISC) printf("%s: unknown route interface: %s\n", __func__, sp->pfs_1400.rt_ifname); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index db23559774d0..fa656f92f79b 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -379,7 +379,8 @@ static void pf_counters_inc(int, struct pf_pdesc *, static void pf_overload_task(void *v, int pending); static u_short pf_insert_src_node(struct pf_ksrc_node **, struct pf_srchash **, struct pf_krule *, - struct pf_addr *, sa_family_t); + struct pf_addr *, sa_family_t, struct pf_addr *, + struct pfi_kkif *); static u_int pf_purge_expired_states(u_int, int); static void pf_purge_unlinked_rules(void); static int pf_mtag_uminit(void *, int, int); @@ -453,11 +454,11 @@ BOUND_IFACE(struct pf_kstate *st, struct pfi_kkif *k) return (k); /* No route-to, so don't overrule. */ - if (st->rt != PF_ROUTETO) + if (st->act.rt != PF_ROUTETO) return (k); /* Bind to the route-to interface. */ - return (st->rt_kif); + return (st->act.rt_kif); } #define STATE_INC_COUNTERS(s) \ @@ -1020,7 +1021,8 @@ pf_free_src_node(struct pf_ksrc_node *sn) static u_short pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_srchash **sh, - struct pf_krule *rule, struct pf_addr *src, sa_family_t af) + struct pf_krule *rule, struct pf_addr *src, sa_family_t af, + struct pf_addr *raddr, struct pfi_kkif *rkif) { u_short reason = 0; @@ -1071,6 +1073,8 @@ pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_srchash **sh, (*sn)->af = af; (*sn)->rule = rule; PF_ACPY(&(*sn)->addr, src, af); + PF_ACPY(&(*sn)->raddr, raddr, af); + (*sn)->rkif = rkif; LIST_INSERT_HEAD(&(*sh)->nodes, *sn, entry); (*sn)->creation = time_uptime; (*sn)->ruletype = rule->action; @@ -2709,8 +2713,8 @@ relock: s->kif->pfik_flags |= PFI_IFLAG_REFS; SLIST_FOREACH(mrm, &s->match_rules, entry) mrm->r->rule_ref |= PFRULE_REFS; - if (s->rt_kif) - s->rt_kif->pfik_flags |= PFI_IFLAG_REFS; + if (s->act.rt_kif) + s->act.rt_kif->pfik_flags |= PFI_IFLAG_REFS; count++; } PF_HASHROW_UNLOCK(ih); @@ -5307,6 +5311,21 @@ nextrule: if (pd->act.rtableid >= 0) M_SETFIB(pd->m, pd->act.rtableid); + if (r->rt) { + struct pf_ksrc_node *sn = NULL; + struct pf_srchash *snh = NULL; + /* + * Set act.rt here instead of in pf_rule_to_actions() because + * it is applied only from the last pass rule. + */ + pd->act.rt = r->rt; + /* Don't use REASON_SET, pf_map_addr increases the reason counters */ + reason = pf_map_addr_sn(pd->af, r, pd->src, &pd->act.rt_addr, + &pd->act.rt_kif, NULL, &sn, &snh); + if (reason != 0) + goto cleanup; + } + if (pd->virtual_proto != PF_VPROTO_FRAGMENT && (!state_icmp && (r->keep_state || nr != NULL || (pd->flags & PFDESC_TCP_NORM)))) { @@ -5391,14 +5410,15 @@ 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) && - (sn_reason = pf_insert_src_node(&sn, &snh, r, pd->src, pd->af)) != 0) { + (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) && (sn_reason = pf_insert_src_node(&nsn, &nsnh, nr, &sk->addr[pd->sidx], - pd->af)) != 0 ) { + pd->af, &nk->addr[1], NULL)) != 0 ) { REASON_SET(&reason, sn_reason); goto csfailed; } @@ -5488,14 +5508,6 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, s->timeout = PFTM_OTHER_FIRST_PACKET; } - if (r->rt) { - /* pf_map_addr increases the reason counters */ - if ((reason = pf_map_addr_sn(pd->af, r, pd->src, &s->rt_addr, - &s->rt_kif, NULL, &sn, &snh)) != 0) - goto csfailed; - s->rt = r->rt; - } - s->creation = s->expire = pf_get_uptime(); if (pd->proto == IPPROTO_TCP) { @@ -5552,8 +5564,6 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, PF_HASHROW_UNLOCK(snh); } if (pf_src_node_exists(&nsn, nsnh)) { - /* XXX We only modify one side for now. */ - PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af); s->nat_src_node = nsn; PF_HASHROW_UNLOCK(nsnh); } @@ -7686,23 +7696,20 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, struct mbuf *m0, *m1, *md; struct sockaddr_in dst; struct ip *ip; - struct pfi_kkif *nkif = NULL; struct ifnet *ifp = NULL; struct pf_addr naddr; int error = 0; uint16_t ip_len, ip_off; uint16_t tmp; - int r_rt, r_dir; + int r_dir; KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); SDT_PROBE4(pf, ip, route_to, entry, *m, pd, s, oifp); if (s) { - r_rt = s->rt; r_dir = s->direction; } else { - r_rt = r->rt; r_dir = r->direction; } @@ -7719,17 +7726,14 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, goto bad_locked; } - if (r_rt == PF_DUPTO) { + if (pd->act.rt == PF_DUPTO) { if ((pd->pf_mtag->flags & PF_MTAG_FLAG_DUPLICATED)) { - if (s == NULL) { + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; + /* If pfsync'd from FreeBSD < 14 */ + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; - } else { - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - /* If pfsync'd */ - if (ifp == NULL && r->rpool.cur != NULL) - ifp = r->rpool.cur->kif ? - r->rpool.cur->kif->pfik_ifp : NULL; + if (s != NULL) { PF_STATE_UNLOCK(s); } if (ifp == oifp) { @@ -7750,7 +7754,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } } } else { - if ((r_rt == PF_REPLYTO) == (r_dir == pd->dir)) { + if ((pd->act.rt == PF_REPLYTO) == (r_dir == pd->dir)) { pf_dummynet(pd, s, r, m); if (s) PF_STATE_UNLOCK(s); @@ -7765,30 +7769,16 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, dst.sin_family = AF_INET; dst.sin_len = sizeof(dst); dst.sin_addr = ip->ip_dst; + dst.sin_addr.s_addr = pd->act.rt_addr.v4.s_addr; + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; bzero(&naddr, sizeof(naddr)); - if (s == NULL) { - if (TAILQ_EMPTY(&r->rpool.list)) { - DPFPRINTF(PF_DEBUG_URGENT, - ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); - SDT_PROBE1(pf, ip, route_to, drop, __LINE__); - goto bad_locked; - } - pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, - &naddr, &nkif, NULL); - if (!PF_AZERO(&naddr, AF_INET)) - dst.sin_addr.s_addr = naddr.v4.s_addr; - ifp = nkif ? nkif->pfik_ifp : NULL; - } else { + if (s != NULL){ struct pfi_kkif *kif; - if (!PF_AZERO(&s->rt_addr, AF_INET)) - dst.sin_addr.s_addr = - s->rt_addr.v4.s_addr; - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - kif = s->rt_kif; - /* If pfsync'd */ + kif = pd->act.rt_kif; + /* If pfsync'd from FreeBSD < 14 */ if (ifp == NULL && r->rpool.cur != NULL) { ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; @@ -7796,7 +7786,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } if (ifp != NULL && kif != NULL && r->rule_flag & PFRULE_IFBOUND && - r->rt == PF_REPLYTO && + pd->act.rt == PF_REPLYTO && s->kif == V_pfi_all) { s->kif = kif; s->orig_kif = oifp->if_pf_kif; @@ -7892,7 +7882,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) { error = EMSGSIZE; KMOD_IPSTAT_INC(ips_cantfrag); - if (r_rt != PF_DUPTO) { + if (pd->act.rt != PF_DUPTO) { if (s && s->nat_rule != NULL) PACKET_UNDO_NAT(m0, pd, (ip->ip_hl << 2) + (ip_off & IP_OFFMASK), @@ -7936,7 +7926,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, KMOD_IPSTAT_INC(ips_fragmented); done: - if (r_rt != PF_DUPTO) + if (pd->act.rt != PF_DUPTO) *m = NULL; return; @@ -7958,20 +7948,17 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, struct m_tag *mtag; struct sockaddr_in6 dst; struct ip6_hdr *ip6; - struct pfi_kkif *nkif = NULL; struct ifnet *ifp = NULL; struct pf_addr naddr; - int r_rt, r_dir; + int r_dir; KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); SDT_PROBE4(pf, ip6, route_to, entry, *m, pd, s, oifp); if (s) { - r_rt = s->rt; r_dir = s->direction; } else { - r_rt = r->rt; r_dir = r->direction; } @@ -7988,17 +7975,14 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, goto bad_locked; } - if (r_rt == PF_DUPTO) { + if (pd->act.rt == PF_DUPTO) { if ((pd->pf_mtag->flags & PF_MTAG_FLAG_DUPLICATED)) { - if (s == NULL) { + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; + /* If pfsync'd from FreeBSD < 14 */ + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; - } else { - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - /* If pfsync'd */ - if (ifp == NULL && r->rpool.cur != NULL) - ifp = r->rpool.cur->kif ? - r->rpool.cur->kif->pfik_ifp : NULL; + if (s != NULL) { PF_STATE_UNLOCK(s); } if (ifp == oifp) { @@ -8019,7 +8003,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } } } else { - if ((r_rt == PF_REPLYTO) == (r_dir == pd->dir)) { + if ((pd->act.rt == PF_REPLYTO) == (r_dir == pd->dir)) { pf_dummynet(pd, s, r, m); if (s) PF_STATE_UNLOCK(s); @@ -8034,31 +8018,15 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, dst.sin6_family = AF_INET6; dst.sin6_len = sizeof(dst); dst.sin6_addr = ip6->ip6_dst; - + PF_ACPY((struct pf_addr *)&dst.sin6_addr, &pd->act.rt_addr, AF_INET6); bzero(&naddr, sizeof(naddr)); + ifp = pd->act.rt_kif ? pd->act.rt_kif->pfik_ifp : NULL; - if (s == NULL) { - if (TAILQ_EMPTY(&r->rpool.list)) { - DPFPRINTF(PF_DEBUG_URGENT, - ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); - SDT_PROBE1(pf, ip6, route_to, drop, __LINE__); - goto bad_locked; - } - pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, - &naddr, &nkif, NULL); - if (!PF_AZERO(&naddr, AF_INET6)) - PF_ACPY((struct pf_addr *)&dst.sin6_addr, - &naddr, AF_INET6); - ifp = nkif ? nkif->pfik_ifp : NULL; - } else { + if (s != NULL) { struct pfi_kkif *kif; - if (!PF_AZERO(&s->rt_addr, AF_INET6)) - PF_ACPY((struct pf_addr *)&dst.sin6_addr, - &s->rt_addr, AF_INET6); - ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; - kif = s->rt_kif; - /* If pfsync'd */ + kif = pd->act.rt_kif; + /* If pfsync'd from FreeBSD < 14 */ if (ifp == NULL && r->rpool.cur != NULL) { ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; @@ -8066,7 +8034,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } if (ifp != NULL && kif != NULL && r->rule_flag & PFRULE_IFBOUND && - r->rt == PF_REPLYTO && + pd->act.rt == PF_REPLYTO && s->kif == V_pfi_all) { s->kif = kif; s->orig_kif = oifp->if_pf_kif; @@ -8135,7 +8103,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } else { in6_ifstat_inc(ifp, ifs6_in_toobig); - if (r_rt != PF_DUPTO) { + if (pd->act.rt != PF_DUPTO) { if (s && s->nat_rule != NULL) PACKET_UNDO_NAT(m0, pd, ((caddr_t)ip6 - m0->m_data) + @@ -8150,7 +8118,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } done: - if (r_rt != PF_DUPTO) + if (pd->act.rt != PF_DUPTO) *m = NULL; return; @@ -9036,7 +9004,6 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0 struct pf_pdesc pd; int use_2nd_queue = 0; uint16_t tag; - uint8_t rt; PF_RULES_RLOCK_TRACKER; KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir)); @@ -9328,10 +9295,8 @@ done: memcpy(&pd.act, &s->act, sizeof(struct pf_rule_actions)); pd.act.log |= log; tag = s->tag; - rt = s->rt; } else { tag = r->tag; - rt = r->rt; } if (tag > 0 && pf_tag_packet(&pd, tag)) { @@ -9474,7 +9439,7 @@ done: *m0 = NULL; break; default: - if (rt) { + if (pd.act.rt) { switch (af) { #ifdef INET case AF_INET: diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 59c442698b95..0fdf41a9811f 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2341,7 +2341,7 @@ relock_DIOCKILLSTATES: if (! PF_MATCHA(psk->psk_rt_addr.neg, &psk->psk_rt_addr.addr.v.a.addr, &psk->psk_rt_addr.addr.v.a.mask, - &s->rt_addr, sk->af)) + &s->act.rt_addr, sk->af)) continue; if (psk->psk_src.port_op != 0 && @@ -5587,7 +5587,7 @@ pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_ /* copy from state */ strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname)); - bcopy(&st->rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr)); + bcopy(&st->act.rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr)); sp->pfs_1301.creation = htonl(time_uptime - (st->creation / 1000)); sp->pfs_1301.expire = pf_state_expires(st); if (sp->pfs_1301.expire <= time_uptime) @@ -5615,10 +5615,10 @@ pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_ sp->pfs_1400.max_mss = htons(st->act.max_mss); sp->pfs_1400.set_prio[0] = st->act.set_prio[0]; sp->pfs_1400.set_prio[1] = st->act.set_prio[1]; - sp->pfs_1400.rt = st->rt; - if (st->rt_kif) + sp->pfs_1400.rt = st->act.rt; + if (st->act.rt_kif) strlcpy(sp->pfs_1400.rt_ifname, - st->rt_kif->pfik_name, + st->act.rt_kif->pfik_name, sizeof(sp->pfs_1400.rt_ifname)); break; default: @@ -5678,7 +5678,7 @@ pf_state_export(struct pf_state_export *sp, struct pf_kstate *st) strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname)); strlcpy(sp->orig_ifname, st->orig_kif->pfik_name, sizeof(sp->orig_ifname)); - bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); + bcopy(&st->act.rt_addr, &sp->rt_addr, sizeof(sp->rt_addr)); sp->creation = htonl(time_uptime - (st->creation / 1000)); sp->expire = pf_state_expires(st); if (sp->expire <= time_uptime) @@ -5728,9 +5728,9 @@ pf_state_export(struct pf_state_export *sp, struct pf_kstate *st) sp->min_ttl = st->act.min_ttl; sp->set_tos = st->act.set_tos; sp->max_mss = htons(st->act.max_mss); - sp->rt = st->rt; - if (st->rt_kif) - strlcpy(sp->rt_ifname, st->rt_kif->pfik_name, + sp->rt = st->act.rt; + if (st->act.rt_kif) + strlcpy(sp->rt_ifname, st->act.rt_kif->pfik_name, sizeof(sp->rt_ifname)); sp->set_prio[0] = st->act.set_prio[0]; sp->set_prio[1] = st->act.set_prio[1]; diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index e180f87d2998..8087546683af 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -631,24 +631,18 @@ pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, u_short reason = 0; struct pf_kpool *rpool = &r->rpool; + KASSERT(*sn == NULL, ("*sn not NULL")); + /* - * Try to find a src_node if none was given and this is - * a sticky-address rule. Request the sh to be unlocked if - * sn was not found, as here we never insert a new sn. + * If this is a sticky-address rule, try to find an existing src_node. + * Request the sh to be unlocked if sn was not found, as we never + * insert a new sn when parsing the ruleset. */ - if (*sn == NULL) { - if (r->rpool.opts & PF_POOL_STICKYADDR && - (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) - *sn = pf_find_src_node(saddr, r, af, sh, false); - } else { - pf_src_node_exists(sn, *sh); - } + if (r->rpool.opts & PF_POOL_STICKYADDR && + (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) + *sn = pf_find_src_node(saddr, r, af, sh, false); - /* If a src_node was found or explicitly given and it has a non-zero - route address, use this address. A zeroed address is found if the - src node was created just a moment ago in pf_create_state and it - needs to be filled in with routing decision calculated here. */ - if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { + if (*sn != NULL) { PF_SRC_NODE_LOCK_ASSERT(*sn); /* If the supplied address is the same as the current one we've @@ -683,14 +677,6 @@ pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, goto done; } - if (*sn != NULL) { - PF_SRC_NODE_LOCK_ASSERT(*sn); - - PF_ACPY(&(*sn)->raddr, naddr, af); - if (nkif) - (*sn)->rkif = *nkif; - } - if (V_pf_status.debug >= PF_DEBUG_NOISY && (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { printf("pf_map_addr: selected address "); diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index bdfa9a60faa4..68b3659b0ed2 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -173,7 +173,7 @@ dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr, struct pf_kstate *s, nlattr_add_string(nw, PF_ST_IFNAME, s->kif->pfik_name); nlattr_add_string(nw, PF_ST_ORIG_IFNAME, s->orig_kif->pfik_name); - dump_addr(nw, PF_ST_RT_ADDR, &s->rt_addr, af); + dump_addr(nw, PF_ST_RT_ADDR, &s->act.rt_addr, af); nlattr_add_u32(nw, PF_ST_CREATION, time_uptime - (s->creation / 1000)); uint32_t expire = pf_state_expires(s); if (expire > time_uptime) @@ -205,9 +205,9 @@ dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr, struct pf_kstate *s, nlattr_add_u16(nw, PF_ST_MAX_MSS, s->act.max_mss); nlattr_add_u16(nw, PF_ST_DNPIPE, s->act.dnpipe); nlattr_add_u16(nw, PF_ST_DNRPIPE, s->act.dnrpipe); - nlattr_add_u8(nw, PF_ST_RT, s->rt); - if (s->rt_kif != NULL) - nlattr_add_string(nw, PF_ST_RT_IFNAME, s->rt_kif->pfik_name); + nlattr_add_u8(nw, PF_ST_RT, s->act.rt); + if (s->act.rt_kif != NULL) + nlattr_add_string(nw, PF_ST_RT_IFNAME, s->act.rt_kif->pfik_name); if (!dump_state_peer(nw, PF_ST_PEER_SRC, &s->src)) goto enomem; diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c index 87c2211a84e0..b24d274db85d 100644 --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -963,7 +963,7 @@ pf_state_to_nvstate(const struct pf_kstate *s) nvlist_add_nvlist(nvl, "dst", tmp); nvlist_destroy(tmp); - tmp = pf_addr_to_nvaddr(&s->rt_addr); + tmp = pf_addr_to_nvaddr(&s->act.rt_addr); if (tmp == NULL) goto errout; nvlist_add_nvlist(nvl, "rt_addr", tmp);