Skip to content

Commit

Permalink
Importing pfSense patch pf_match.diff
Browse files Browse the repository at this point in the history
  • Loading branch information
loos-br committed Apr 15, 2016
1 parent 5f8f9db commit ffc6c6b
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 27 deletions.
4 changes: 3 additions & 1 deletion sbin/pfctl/parse.y
Expand Up @@ -448,7 +448,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
Expand Down Expand Up @@ -2625,6 +2625,7 @@ probability : STRING {


action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
| MATCH { $$.b1 = PF_MATCH; $$.b2 = $$.w = 0; }
| BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; }
;

Expand Down Expand Up @@ -5540,6 +5541,7 @@ lookup(char *s)
{ "load", LOAD},
{ "log", LOG},
{ "loginterface", LOGINTERFACE},
{ "match", MATCH},
{ "max", MAXIMUM},
{ "max-mss", MAXMSS},
{ "max-src-conn", MAXSRCCONN},
Expand Down
4 changes: 3 additions & 1 deletion sbin/pfctl/pfctl_parser.c
Expand Up @@ -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] == '_') {
Expand Down
16 changes: 14 additions & 2 deletions sys/net/pfvar.h
Expand Up @@ -468,6 +468,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;
Expand Down Expand Up @@ -524,8 +531,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
Expand Down Expand Up @@ -767,6 +774,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;
Expand Down Expand Up @@ -1138,6 +1149,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 */

Expand Down
126 changes: 104 additions & 22 deletions sys/netpfil/pf/pf.c
Expand Up @@ -230,6 +230,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 **,
Expand Down Expand Up @@ -2991,6 +2993,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)
{
Expand Down Expand Up @@ -3503,10 +3520,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);
Expand All @@ -3525,6 +3552,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);
Expand Down Expand Up @@ -3698,6 +3728,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) {
Expand Down Expand Up @@ -3959,10 +3994,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);
Expand All @@ -3981,6 +4026,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);
Expand Down Expand Up @@ -6308,6 +6356,13 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
M_SETFIB(m, r->rtableid);

#ifdef ALTQ
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 && r->qid) {
if (pd.pf_mtag == NULL &&
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
Expand All @@ -6332,15 +6387,25 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
action = PF_DROP;
REASON_SET(&reason, PFRES_MEMORY);
}
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;
Expand Down Expand Up @@ -6835,7 +6900,14 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
M_SETFIB(m, r->rtableid);

#ifdef ALTQ
if (action == PF_PASS && r->qid) {
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 (pd.pf_mtag == NULL &&
((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
action = PF_DROP;
Expand All @@ -6844,9 +6916,9 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
if (s != NULL)
pd.pf_mtag->qid_hash = pf_state_hash(s);
if (pd.tos & IPTOS_LOWDELAY)
pd.pf_mtag->qid = r->pqid;
pd.pf_mtag->qid = pd.act.pqid;
else
pd.pf_mtag->qid = r->qid;
pd.pf_mtag->qid = pd.act.qid;
/* Add hints for ecn. */
pd.pf_mtag->hdr = h;
}
Expand All @@ -6858,15 +6930,25 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
action = PF_DROP;
REASON_SET(&reason, PFRES_MEMORY);
}
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;
Expand Down
3 changes: 2 additions & 1 deletion sys/netpfil/pf/pf.h
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions sys/netpfil/pf/pf_ruleset.c
Expand Up @@ -121,6 +121,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;
Expand Down

0 comments on commit ffc6c6b

Please sign in to comment.