summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2015-08-17 13:53:06 -0300
committerRenato Botelho <renato@netgate.com>2015-08-17 13:53:06 -0300
commit2042629d2832f01aedf341b8cfdf333f39743595 (patch)
tree6e22eb34609a9bd0fc3a18ea508b3377cdef4b7c /sys/netpfil
parentba3cfbc880a712304a0cbc8e48a8bc428a40ab50 (diff)
downloadFreeBSD-src-2042629d2832f01aedf341b8cfdf333f39743595.zip
FreeBSD-src-2042629d2832f01aedf341b8cfdf333f39743595.tar.gz
Importing pfSense patch pf_match.diff
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/pf/pf.c168
-rw-r--r--sys/netpfil/pf/pf.h3
-rw-r--r--sys/netpfil/pf/pf_ruleset.c1
3 files changed, 121 insertions, 51 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index c5f26f9..0bba638 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -228,6 +228,8 @@ static int pf_state_key_attach(struct pf_state_key *,
static void pf_state_key_detach(struct pf_state *, int);
static int pf_state_key_ctor(void *, int, void *, int);
static u_int32_t pf_tcp_iss(struct pf_pdesc *);
+void pf_rule_to_actions(struct pf_rule *,
+ struct pf_rule_actions *);
static int pf_test_rule(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
struct pf_pdesc *, struct pf_rule **,
@@ -2950,6 +2952,21 @@ pf_addr_inc(struct pf_addr *addr, sa_family_t af)
}
#endif /* INET6 */
+void
+pf_rule_to_actions(struct pf_rule *r, struct pf_rule_actions *a)
+{
+ if (r->qid)
+ a->qid = r->qid;
+ if (r->pqid)
+ a->pqid = r->pqid;
+ if (r->pdnpipe)
+ a->pdnpipe = r->pdnpipe;
+ if (r->dnpipe)
+ a->dnpipe = r->dnpipe;
+ if (r->free_flags & PFRULE_DN_IS_PIPE)
+ a->flags |= PFRULE_DN_IS_PIPE;
+}
+
int
pf_socket_lookup(int direction, struct pf_pdesc *pd, struct mbuf *m)
{
@@ -3476,10 +3493,20 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->rtableid >= 0)
rtableid = r->rtableid;
if (r->anchor == NULL) {
- match = 1;
- *rm = r;
- *am = a;
- *rsm = ruleset;
+ if (r->action == PF_MATCH) {
+ r->packets[direction == PF_OUT]++;
+ r->bytes[direction == PF_OUT] += pd->tot_len;
+ pf_rule_to_actions(r, &pd->act);
+ if (r->log)
+ PFLOG_PACKET(kif, m, af,
+ direction, PFRES_MATCH, r,
+ a, ruleset, pd, 1);
+ } else {
+ match = 1;
+ *rm = r;
+ *am = a;
+ *rsm = ruleset;
+ }
if ((*rm)->quick)
break;
r = TAILQ_NEXT(r, entries);
@@ -3498,6 +3525,9 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
REASON_SET(&reason, PFRES_MATCH);
+ /* apply actions for last matching pass/block rule */
+ pf_rule_to_actions(r, &pd->act);
+
if (r->log || (nr != NULL && nr->log)) {
if (rewrite)
m_copyback(m, off, hdrlen, pd->hdr.any);
@@ -3671,6 +3701,11 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
s->state_flags |= PFSTATE_SLOPPY;
s->log = r->log & PF_LOG_ALL;
s->sync_state = PFSYNC_S_NONE;
+ s->qid = pd->act.qid;
+ s->pqid = pd->act.pqid;
+ s->pdnpipe = pd->act.pdnpipe;
+ s->dnpipe = pd->act.dnpipe;
+ s->state_flags |= pd->act.flags;
if (nr != NULL)
s->log |= nr->log & PF_LOG_ALL;
switch (pd->proto) {
@@ -3932,10 +3967,20 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
r = TAILQ_NEXT(r, entries);
else {
if (r->anchor == NULL) {
- match = 1;
- *rm = r;
- *am = a;
- *rsm = ruleset;
+ if (r->action == PF_MATCH) {
+ r->packets[direction == PF_OUT]++;
+ r->bytes[direction == PF_OUT] += pd->tot_len;
+ pf_rule_to_actions(r, &pd->act);
+ if (r->log)
+ PFLOG_PACKET(kif, m, af,
+ direction, PFRES_MATCH, r,
+ a, ruleset, pd, 1);
+ } else {
+ match = 1;
+ *rm = r;
+ *am = a;
+ *rsm = ruleset;
+ }
if ((*rm)->quick)
break;
r = TAILQ_NEXT(r, entries);
@@ -3954,6 +3999,9 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
REASON_SET(&reason, PFRES_MATCH);
+ /* apply actions for last matching pass/block rule */
+ pf_rule_to_actions(r, &pd->act);
+
if (r->log)
PFLOG_PACKET(kif, m, af, direction, reason, r, a, ruleset, pd,
1);
@@ -6219,34 +6267,44 @@ done:
M_SETFIB(m, r->rtableid);
#ifdef ALTQ
- if (action == PF_PASS && r->qid) {
- if (pd.pf_mtag == NULL &&
- ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_MEMORY);
- } else {
- if (s != NULL)
- pd.pf_mtag->qid_hash = pf_state_hash(s);
- if (pqid || (pd.tos & IPTOS_LOWDELAY))
- pd.pf_mtag->qid = r->pqid;
- else
- pd.pf_mtag->qid = r->qid;
- /* Add hints for ecn. */
- pd.pf_mtag->hdr = h;
- }
-
+ if (s && s->qid) {
+ pd.act.pqid = s->pqid;
+ pd.act.qid = s->qid;
+ } else if (r->qid) {
+ pd.act.pqid = r->pqid;
+ pd.act.qid = r->qid;
+ }
+ if (action == PF_PASS && pd.act.qid) {
+ if (s != NULL)
+ pd.pf_mtag->qid_hash = pf_state_hash(s);
+ if (pqid || (pd.tos & IPTOS_LOWDELAY))
+ pd.pf_mtag->qid = pd.act.pqid;
+ else
+ pd.pf_mtag->qid = pd.act.qid;
+ /* Add hints for ecn. */
+ pd.pf_mtag->hdr = h;
}
#endif /* ALTQ */
- if (r->dnpipe && ip_dn_io_ptr != NULL && loopedfrom != 1) {
- if (dir != r->direction && r->pdnpipe) {
- dnflow.rule.info = r->pdnpipe;
+ if (s && (s->dnpipe || s->pdnpipe)) {
+ pd.act.dnpipe = s->dnpipe;
+ pd.act.pdnpipe = s->pdnpipe;
+ pd.act.flags = s->state_flags;
+ } else if (r->dnpipe || r->pdnpipe) {
+ pd.act.dnpipe = r->dnpipe;
+ pd.act.dnpipe = r->pdnpipe;
+ pd.act.flags = r->free_flags;
+ }
+
+ if (pd.act.dnpipe && ip_dn_io_ptr != NULL && loopedfrom != 1) {
+ if (dir != r->direction && pd.act.pdnpipe) {
+ dnflow.rule.info = pd.act.pdnpipe;
} else if (dir == r->direction) {
- dnflow.rule.info = r->dnpipe;
+ dnflow.rule.info = pd.act.dnpipe;
} else
goto continueprocessing;
- if (r->free_flags & PFRULE_DN_IS_PIPE)
+ if (pd.act.flags & PFRULE_DN_IS_PIPE)
dnflow.rule.info |= IPFW_IS_PIPE;
dnflow.f_id.addr_type = 4; /* IPv4 type */
dnflow.f_id.proto = pd.proto;
@@ -6724,33 +6782,43 @@ done:
M_SETFIB(m, r->rtableid);
#ifdef ALTQ
- if (action == PF_PASS && r->qid) {
- if (pd.pf_mtag == NULL &&
- ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_MEMORY);
- } else {
- if (s != NULL)
- pd.pf_mtag->qid_hash = pf_state_hash(s);
- if (pd.tos & IPTOS_LOWDELAY)
- pd.pf_mtag->qid = r->pqid;
- else
- pd.pf_mtag->qid = r->qid;
- /* Add hints for ecn. */
- pd.pf_mtag->hdr = h;
- }
+ if (s && s->qid) {
+ pd.act.pqid = s->pqid;
+ pd.act.qid = s->qid;
+ } else if (r->qid) {
+ pd.act.pqid = r->pqid;
+ pd.act.qid = r->qid;
+ }
+ if (action == PF_PASS && pd.act.qid) {
+ if (s != NULL)
+ pd.pf_mtag->qid_hash = pf_state_hash(s);
+ if (pd.tos & IPTOS_LOWDELAY)
+ pd.pf_mtag->qid = pd.act.pqid;
+ else
+ pd.pf_mtag->qid = pd.act.qid;
+ /* Add hints for ecn. */
+ pd.pf_mtag->hdr = h;
}
#endif /* ALTQ */
- if (r->dnpipe && ip_dn_io_ptr != NULL && loopedfrom != 1) {
- if (dir != r->direction && r->pdnpipe) {
- dnflow.rule.info = r->pdnpipe;
- } else if (dir == r->direction) {
- dnflow.rule.info = r->dnpipe;
+ if (s && (s->dnpipe || s->pdnpipe)) {
+ pd.act.dnpipe = s->dnpipe;
+ pd.act.pdnpipe = s->pdnpipe;
+ pd.act.flags = s->state_flags;
+ } else if (r->dnpipe || r->pdnpipe) {
+ pd.act.dnpipe = r->dnpipe;
+ pd.act.dnpipe = r->pdnpipe;
+ pd.act.flags = r->free_flags;
+ }
+ if ((pd.act.dnpipe || pd.act.pdnpipe) && ip_dn_io_ptr != NULL && loopedfrom != 1) {
+ if (dir != r->direction && pd.act.pdnpipe) {
+ dnflow.rule.info = pd.act.pdnpipe;
+ } else if (dir == r->direction && pd.act.dnpipe) {
+ dnflow.rule.info = pd.act.dnpipe;
} else
goto continueprocessing6;
- if (r->free_flags & PFRULE_DN_IS_PIPE)
+ if (pd.act.flags & PFRULE_DN_IS_PIPE)
dnflow.rule.info |= IPFW_IS_PIPE;
dnflow.f_id.addr_type = 6; /* IPv4 type */
dnflow.f_id.proto = pd.proto;
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
index 3a5d2aa..e588eb1 100644
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -45,7 +45,8 @@
enum { PF_INOUT, PF_IN, PF_OUT, PF_FWD };
enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
- PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER };
+ PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER,
+ PF_MATCH };
enum { PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
PF_RULESET_BINAT, PF_RULESET_RDR, PF_RULESET_MAX };
enum { PF_OP_NONE, PF_OP_IRG, PF_OP_EQ, PF_OP_NE, PF_OP_LT,
diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c
index 384e42b..2274359 100644
--- a/sys/netpfil/pf/pf_ruleset.c
+++ b/sys/netpfil/pf/pf_ruleset.c
@@ -120,6 +120,7 @@ pf_get_ruleset_number(u_int8_t action)
return (PF_RULESET_SCRUB);
break;
case PF_PASS:
+ case PF_MATCH:
case PF_DROP:
return (PF_RULESET_FILTER);
break;
OpenPOWER on IntegriCloud