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 | |
parent | ba3cfbc880a712304a0cbc8e48a8bc428a40ab50 (diff) | |
download | FreeBSD-src-2042629d2832f01aedf341b8cfdf333f39743595.zip FreeBSD-src-2042629d2832f01aedf341b8cfdf333f39743595.tar.gz |
Importing pfSense patch pf_match.diff
-rw-r--r-- | sbin/pfctl/parse.y | 4 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 4 | ||||
-rw-r--r-- | sys/net/pfvar.h | 16 | ||||
-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 |
6 files changed, 141 insertions, 55 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index a28f96e..3b95dd9 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -446,7 +446,7 @@ int parseport(char *, struct range *r, int); %} -%token PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS +%token PASS BLOCK MATCH SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS %token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE %token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF %token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL SCHEDULE @@ -2565,6 +2565,7 @@ probability : STRING { action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; } + | MATCH { $$.b1 = PF_MATCH; $$.b2 = $$.w = 0; } | BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; } ; @@ -5485,6 +5486,7 @@ lookup(char *s) { "load", LOAD}, { "log", LOG}, { "loginterface", LOGINTERFACE}, + { "match", MATCH}, { "max", MAXIMUM}, { "max-mss", MAXMSS}, { "max-src-conn", MAXSRCCONN}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index b4a6eb9..bf3fe8c 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -692,7 +692,9 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric) if (verbose) printf("@%d ", r->nr); - if (r->action > PF_NORDR) + if (r->action == PF_MATCH) + printf("match"); + else if (r->action > PF_NORDR) printf("action(%d)", r->action); else if (anchor_call[0]) { if (anchor_call[0] == '_') { diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index ba8b1d9..148ef4e 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -465,6 +465,13 @@ struct pf_osfp_ioctl { int fp_getnum; /* DIOCOSFPGET number */ }; +struct pf_rule_actions { + u_int16_t qid; + u_int16_t pqid; + u_int32_t pdnpipe; + u_int32_t dnpipe; + u_int8_t flags; +}; union pf_rule_ptr { struct pf_rule *ptr; @@ -521,8 +528,8 @@ struct pf_rule { u_int32_t limit; u_int32_t seconds; } max_src_conn_rate; - u_int32_t qid; - u_int32_t pqid; + u_int16_t qid; + u_int16_t pqid; u_int32_t dnpipe; u_int32_t pdnpipe; #define PFRULE_DN_IS_PIPE 0x00000010 @@ -766,6 +773,10 @@ struct pf_state { u_int32_t creation; u_int32_t expire; u_int32_t pfsync_time; + u_int16_t qid; + u_int16_t pqid; + u_int32_t pdnpipe; + u_int32_t dnpipe; u_int16_t tag; u_int8_t log; u_int8_t state_flags; @@ -1137,6 +1148,7 @@ struct pf_pdesc { u_int16_t *sport; u_int16_t *dport; struct pf_mtag *pf_mtag; + struct pf_rule_actions act; u_int32_t p_len; /* total length of payload */ 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; |