git: 9925aee0aaec - main - pf: carry over rule actions from route-to rules
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 02 Jun 2023 14:56:30 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=9925aee0aaeccabd26f41625694a97b64185a59d
commit 9925aee0aaeccabd26f41625694a97b64185a59d
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-05-30 19:17:54 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-06-02 14:05:30 +0000
pf: carry over rule actions from route-to rules
If we route-to (or dup-to/reply-to) we re-run pf_test(), which will also
create states for the connection.
This means that we may end up matching a different (i.e. not the state
that was created by the route-to rule) state, without the attributes
(such as dummynet pipes/queues) set by the route-to rule.
Address this by inheriting the pf_rule_actions from the route-to rule
while evaluating the connection again in pf_test(). That is, we set
default pf_rule_actions based on the route-to rule for the new
evaluation. The new rule may still overrule these, but if it does not
have such actions the route-to actions are applied.
Do the same for IPv6 rules in pf_test6()/pf_route6().
See also: https://redmine.pfsense.org/issues/14039
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D40340
---
sys/net/pfvar.h | 6 ++++--
sys/netpfil/pf/pf.c | 16 +++++++++++-----
sys/netpfil/pf/pf_ioctl.c | 9 +++++----
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 2f2cc1632edc..a658573cf6f1 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2230,13 +2230,15 @@ void pf_free_rule(struct pf_krule *);
int pf_test_eth(int, int, struct ifnet *, struct mbuf **, struct inpcb *);
#ifdef INET
-int pf_test(int, int, struct ifnet *, struct mbuf **, struct inpcb *);
+int pf_test(int, int, struct ifnet *, struct mbuf **, struct inpcb *,
+ struct pf_rule_actions *);
int pf_normalize_ip(struct mbuf **, int, struct pfi_kkif *, u_short *,
struct pf_pdesc *);
#endif /* INET */
#ifdef INET6
-int pf_test6(int, int, struct ifnet *, struct mbuf **, struct inpcb *);
+int pf_test6(int, int, struct ifnet *, struct mbuf **, struct inpcb *,
+ struct pf_rule_actions *);
int pf_normalize_ip6(struct mbuf **, int, struct pfi_kkif *, u_short *,
struct pf_pdesc *);
void pf_poolmask(struct pf_addr *, struct pf_addr*,
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 75c58609318c..78bd8b1dab12 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -6546,7 +6546,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
goto bad;
if (dir == PF_IN) {
- if (pf_test(PF_OUT, 0, ifp, &m0, inp) != PF_PASS)
+ if (pf_test(PF_OUT, 0, ifp, &m0, inp, &pd->act) != PF_PASS)
goto bad;
else if (m0 == NULL)
goto done;
@@ -6762,7 +6762,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp,
goto bad;
if (dir == PF_IN) {
- if (pf_test6(PF_OUT, 0, ifp, &m0, inp) != PF_PASS)
+ if (pf_test6(PF_OUT, 0, ifp, &m0, inp, &pd->act) != PF_PASS)
goto bad;
else if (m0 == NULL)
goto done;
@@ -7120,7 +7120,8 @@ pf_dummynet_route(struct pf_pdesc *pd, int dir, struct pf_kstate *s,
#ifdef INET
int
-pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
+pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
+ struct inpcb *inp, struct pf_rule_actions *default_actions)
{
struct pfi_kkif *kif;
u_short action, reason = 0, log = 0;
@@ -7172,6 +7173,8 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
}
memset(&pd, 0, sizeof(pd));
+ if (default_actions != NULL)
+ memcpy(&pd.act, default_actions, sizeof(pd.act));
pd.pf_mtag = pf_find_mtag(m);
if (pd.pf_mtag != NULL && (pd.pf_mtag->flags & PF_TAG_ROUTE_TO)) {
@@ -7312,7 +7315,7 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
break;
}
- action = pf_test(dir, pflags, ifp, &msyn, inp);
+ action = pf_test(dir, pflags, ifp, &msyn, inp, &pd.act);
m_freem(msyn);
if (action == PF_PASS) {
@@ -7682,7 +7685,8 @@ done:
#ifdef INET6
int
-pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
+pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp,
+ struct pf_rule_actions *default_actions)
{
struct pfi_kkif *kif;
u_short action, reason = 0, log = 0;
@@ -7733,6 +7737,8 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
}
memset(&pd, 0, sizeof(pd));
+ if (default_actions != NULL)
+ memcpy(&pd.act, default_actions, sizeof(pd.act));
pd.pf_mtag = pf_find_mtag(m);
if (pd.pf_mtag != NULL && (pd.pf_mtag->flags & PF_TAG_ROUTE_TO)) {
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index db88c7d2dc0e..cb6d22885ef4 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -6534,7 +6534,7 @@ pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
{
int chk;
- chk = pf_test(PF_IN, flags, ifp, m, inp);
+ chk = pf_test(PF_IN, flags, ifp, m, inp, NULL);
return (pf_check_return(chk, m));
}
@@ -6545,7 +6545,7 @@ pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
{
int chk;
- chk = pf_test(PF_OUT, flags, ifp, m, inp);
+ chk = pf_test(PF_OUT, flags, ifp, m, inp, NULL);
return (pf_check_return(chk, m));
}
@@ -6564,7 +6564,8 @@ pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
* filtering we have change this to lo0 as it is the case in IPv4.
*/
CURVNET_SET(ifp->if_vnet);
- chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp, m, inp);
+ chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp,
+ m, inp, NULL);
CURVNET_RESTORE();
return (pf_check_return(chk, m));
@@ -6577,7 +6578,7 @@ pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
int chk;
CURVNET_SET(ifp->if_vnet);
- chk = pf_test6(PF_OUT, flags, ifp, m, inp);
+ chk = pf_test6(PF_OUT, flags, ifp, m, inp, NULL);
CURVNET_RESTORE();
return (pf_check_return(chk, m));