diff options
author | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:06 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:06 -0300 |
commit | 2042629d2832f01aedf341b8cfdf333f39743595 (patch) | |
tree | 6e22eb34609a9bd0fc3a18ea508b3377cdef4b7c /sys/netpfil | |
parent | ba3cfbc880a712304a0cbc8e48a8bc428a40ab50 (diff) | |
download | FreeBSD-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.c | 168 | ||||
-rw-r--r-- | sys/netpfil/pf/pf.h | 3 | ||||
-rw-r--r-- | sys/netpfil/pf/pf_ruleset.c | 1 |
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; |