diff options
author | Luiz Otavio O Souza <luiz@netgate.com> | 2017-01-04 11:36:03 -0600 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2017-07-17 21:45:14 -0500 |
commit | 19578e75e06ca0c1b4127c9331a02eba3b1a66b0 (patch) | |
tree | ad66b4683633a1a41440478a940485a01744bfb5 | |
parent | 9c5e350763fb60f0a7bd25f638761d4c157d7783 (diff) | |
download | FreeBSD-src-19578e75e06ca0c1b4127c9331a02eba3b1a66b0.zip FreeBSD-src-19578e75e06ca0c1b4127c9331a02eba3b1a66b0.tar.gz |
Better support for dummynet (limiters) with binat and rdr rules.
Ticket #7050
(cherry picked from commit bf80603857ea4d11cb666429c1ec7917bbac9bf0)
-rw-r--r-- | sys/netpfil/pf/pf.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 74865a5..7b279c8 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -316,7 +316,8 @@ VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]); #define PACKET_UNDO_NAT(_m, _pd, _off, _s, _dir) \ do { \ struct pf_state_key *nk; \ - if ((_dir) == PF_OUT) \ + if ((_dir) == PF_OUT && \ + (_s)->nat_rule.ptr->action == PF_NAT) \ nk = (_s)->key[PF_SK_STACK]; \ else \ nk = (_s)->key[PF_SK_WIRE]; \ @@ -325,7 +326,8 @@ VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]); #define PACKET_REDO_NAT(_m, _pd, _off, _s, _dir) \ do { \ struct pf_state_key *nk; \ - if ((_dir) == PF_OUT) \ + if ((_dir) == PF_OUT && \ + (_s)->nat_rule.ptr->action == PF_NAT) \ nk = (_s)->key[PF_SK_WIRE]; \ else \ nk = (_s)->key[PF_SK_STACK]; \ @@ -6263,6 +6265,20 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, &reason); if (action == PF_PASS) { + if (dir == PF_IN && s != NULL && + s->nat_rule.ptr != NULL && + s->nat_rule.ptr->action == PF_NAT) { + dnflow.f_id.dst_port = + ntohs(s->key[(s->direction == PF_IN)]-> + port[(s->direction == PF_OUT)]); + } + if (dir == PF_OUT && s != NULL && + s->nat_rule.ptr != NULL && + s->nat_rule.ptr->action != PF_NAT) { + dnflow.f_id.src_port = + ntohs(s->key[(s->direction == PF_OUT)]-> + port[(s->direction == PF_IN)]); + } if (pfsync_update_state_ptr != NULL) pfsync_update_state_ptr(s); r = s->rule.ptr; @@ -6294,6 +6310,20 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) } action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); if (action == PF_PASS) { + if (dir == PF_IN && s != NULL && + s->nat_rule.ptr != NULL && + s->nat_rule.ptr->action == PF_NAT) { + dnflow.f_id.dst_port = + ntohs(s->key[(s->direction == PF_IN)]-> + port[(s->direction == PF_OUT)]); + } + if (dir == PF_OUT && s != NULL && + s->nat_rule.ptr != NULL && + s->nat_rule.ptr->action != PF_NAT) { + dnflow.f_id.src_port = + ntohs(s->key[(s->direction == PF_OUT)]-> + port[(s->direction == PF_IN)]); + } if (pfsync_update_state_ptr != NULL) pfsync_update_state_ptr(s); r = s->rule.ptr; @@ -6445,7 +6475,13 @@ done: addr[(s->direction == PF_OUT)].v4.s_addr); else dnflow.f_id.src_ip = ntohl(h->ip_src.s_addr); - dnflow.f_id.dst_ip = ntohl(h->ip_dst.s_addr); + if (dir == PF_IN && s != NULL && s->nat_rule.ptr != NULL && + s->nat_rule.ptr->action != PF_NAT) + dnflow.f_id.dst_ip = + ntohl(s->key[(s->direction == PF_OUT)]-> + addr[(s->direction == PF_IN)].v4.s_addr); + else + dnflow.f_id.dst_ip = ntohl(h->ip_dst.s_addr); dnflow.f_id.extra = dnflow.rule.info; if (m->m_flags & M_FASTFWD_OURS) { |