summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Otavio O Souza <luiz@netgate.com>2017-01-04 11:36:03 -0600
committerLuiz Souza <luiz@netgate.com>2017-07-17 21:45:14 -0500
commit19578e75e06ca0c1b4127c9331a02eba3b1a66b0 (patch)
treead66b4683633a1a41440478a940485a01744bfb5
parent9c5e350763fb60f0a7bd25f638761d4c157d7783 (diff)
downloadFreeBSD-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.c42
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) {
OpenPOWER on IntegriCloud