Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F96563832
D46705.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D46705.diff
View Options
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -6073,10 +6073,10 @@
LOOP_THROUGH(struct node_proto, proto, protos,
LOOP_THROUGH(struct node_icmp, icmp_type, icmp_types,
LOOP_THROUGH(struct node_host, src_host, src_hosts,
- LOOP_THROUGH(struct node_port, src_port, src_ports,
- LOOP_THROUGH(struct node_os, src_os, src_oses,
LOOP_THROUGH(struct node_host, dst_host, dst_hosts,
+ LOOP_THROUGH(struct node_port, src_port, src_ports,
LOOP_THROUGH(struct node_port, dst_port, dst_ports,
+ LOOP_THROUGH(struct node_os, src_os, src_oses,
LOOP_THROUGH(struct node_uid, uid, uids,
LOOP_THROUGH(struct node_gid, gid, gids,
diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c
--- a/sbin/pfctl/pfctl_optimize.c
+++ b/sbin/pfctl/pfctl_optimize.c
@@ -249,8 +249,8 @@
{ "af", PF_SKIP_AF, skip_cmp_af }, \
{ "proto", PF_SKIP_PROTO, skip_cmp_proto }, \
{ "saddr", PF_SKIP_SRC_ADDR, skip_cmp_src_addr }, \
- { "sport", PF_SKIP_SRC_PORT, skip_cmp_src_port }, \
{ "daddr", PF_SKIP_DST_ADDR, skip_cmp_dst_addr }, \
+ { "sport", PF_SKIP_SRC_PORT, skip_cmp_src_port }, \
{ "dport", PF_SKIP_DST_PORT, skip_cmp_dst_port } \
}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1634,6 +1634,8 @@
* state code. Easier than tags */
#define PFDESC_TCP_NORM 0x0001 /* TCP shall be statefully scrubbed */
#define PFDESC_IP_REAS 0x0002 /* IP frags would've been reassembled */
+ u_int16_t virtual_proto;
+#define PF_VPROTO_FRAGMENT 256
pf_af_t af;
u_int8_t proto;
u_int8_t tos;
@@ -2371,7 +2373,8 @@
struct pf_pdesc *, struct mbuf *,
u_short *, u_short *, struct pfi_kkif *,
struct pf_krule **, struct pf_krule **,
- struct pf_kruleset **, int *, int *,
+ struct pf_kstate **, struct pf_kruleset **,
+ int *, int *, struct inpcb *,
struct pf_rule_actions *);
int pf_test_eth(int, int, struct ifnet *, struct mbuf **, struct inpcb *);
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -491,8 +491,8 @@
#define PF_SKIP_AF 2
#define PF_SKIP_PROTO 3
#define PF_SKIP_SRC_ADDR 4
-#define PF_SKIP_SRC_PORT 5
-#define PF_SKIP_DST_ADDR 6
+#define PF_SKIP_DST_ADDR 5
+#define PF_SKIP_SRC_PORT 6
#define PF_SKIP_DST_PORT 7
#define PF_SKIP_COUNT 8
union pf_rule_ptr skip[PF_SKIP_COUNT];
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -333,9 +333,6 @@
static int pf_state_key_addr_setup(struct pf_pdesc *, struct mbuf *,
int, struct pf_state_key_cmp *, int, struct pf_addr *,
int, struct pf_addr *, int);
-static int pf_test_fragment(struct pf_krule **, struct pfi_kkif *,
- struct mbuf *, struct pf_pdesc *,
- struct pf_krule **, struct pf_kruleset **);
static int pf_tcp_track_full(struct pf_kstate **,
struct pfi_kkif *, struct mbuf *, int,
struct pf_pdesc *, u_short *, int *);
@@ -2972,13 +2969,13 @@
if (cur->src.neg != prev->src.neg ||
pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
+ if (cur->dst.neg != prev->dst.neg ||
+ pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
+ PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
if (cur->src.port[0] != prev->src.port[0] ||
cur->src.port[1] != prev->src.port[1] ||
cur->src.port_op != prev->src.port_op)
PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
- if (cur->dst.neg != prev->dst.neg ||
- pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
- PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
if (cur->dst.port[0] != prev->dst.port[0] ||
cur->dst.port[1] != prev->dst.port[1] ||
cur->dst.port_op != prev->dst.port_op)
@@ -4887,6 +4884,14 @@
return (action);
}
+#define PF_TEST_ATTRIB(t, a)\
+ do { \
+ if (t) { \
+ r = a; \
+ goto nextrule; \
+ } \
+ } while (0)
+
static int
pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif,
struct mbuf *m, int off, struct pf_pdesc *pd, struct pf_krule **am,
@@ -4926,7 +4931,7 @@
pd->lookup.done = 1;
}
- switch (pd->proto) {
+ switch (pd->virtual_proto) {
case IPPROTO_TCP:
sport = th->th_sport;
dport = th->th_dport;
@@ -5141,108 +5146,136 @@
while (r != NULL) {
pf_counter_u64_add(&r->evaluations, 1);
- if (pfi_kkif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != pd->dir)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != af)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != pd->proto)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- /* tcp/udp only. port_op always 0 in other cases */
- else if (r->src.port_op && !pf_match_port(r->src.port_op,
- r->src.port[0], r->src.port[1], sport))
- r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- /* tcp/udp only. port_op always 0 in other cases */
- else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
- r->dst.port[0], r->dst.port[1], dport))
- r = r->skip[PF_SKIP_DST_PORT].ptr;
- /* icmp only. type always 0 in other cases */
- else if (r->type && r->type != icmptype + 1)
- r = TAILQ_NEXT(r, entries);
- /* icmp only. type always 0 in other cases */
- else if (r->code && r->code != icmpcode + 1)
- r = TAILQ_NEXT(r, entries);
- else if (r->tos && !(r->tos == pd->tos))
- r = TAILQ_NEXT(r, entries);
- else if (r->rule_flag & PFRULE_FRAGMENT)
- r = TAILQ_NEXT(r, entries);
- else if (pd->proto == IPPROTO_TCP &&
- (r->flagset & th->th_flags) != r->flags)
- r = TAILQ_NEXT(r, entries);
- /* tcp/udp only. uid.op always 0 in other cases */
- else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
- pf_socket_lookup(pd, m), 1)) &&
- !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
- pd->lookup.uid))
- r = TAILQ_NEXT(r, entries);
- /* tcp/udp only. gid.op always 0 in other cases */
- else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
- pf_socket_lookup(pd, m), 1)) &&
- !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
- pd->lookup.gid))
- r = TAILQ_NEXT(r, entries);
- else if (r->prio &&
- !pf_match_ieee8021q_pcp(r->prio, m))
- r = TAILQ_NEXT(r, entries);
- else if (r->prob &&
- r->prob <= arc4random())
- r = TAILQ_NEXT(r, entries);
- else if (r->match_tag && !pf_match_tag(m, r, &tag,
- pd->pf_mtag ? pd->pf_mtag->tag : 0))
- r = TAILQ_NEXT(r, entries);
- else if (r->rcv_kif && !pf_match_rcvif(m, r))
- r = TAILQ_NEXT(r, entries);
- else if (r->os_fingerprint != PF_OSFP_ANY &&
- (pd->proto != IPPROTO_TCP || !pf_osfp_match(
+ PF_TEST_ATTRIB(pfi_kkif_match(r->kif, kif) == r->ifnot,
+ r->skip[PF_SKIP_IFP].ptr);
+ PF_TEST_ATTRIB(r->direction && r->direction != pd->dir,
+ r->skip[PF_SKIP_DIR].ptr);
+ PF_TEST_ATTRIB(r->af && r->af != af,
+ r->skip[PF_SKIP_AF].ptr);
+ PF_TEST_ATTRIB(r->proto && r->proto != pd->proto,
+ r->skip[PF_SKIP_PROTO].ptr);
+ PF_TEST_ATTRIB(PF_MISMATCHAW(&r->src.addr, saddr, af,
+ r->src.neg, kif, M_GETFIB(m)),
+ r->skip[PF_SKIP_SRC_ADDR].ptr);
+ PF_TEST_ATTRIB(PF_MISMATCHAW(&r->dst.addr, daddr, af,
+ r->dst.neg, NULL, M_GETFIB(m)),
+ r->skip[PF_SKIP_DST_ADDR].ptr);
+ switch (pd->virtual_proto) {
+ case PF_VPROTO_FRAGMENT:
+ /* tcp/udp only. port_op always 0 in other cases */
+ PF_TEST_ATTRIB((r->src.port_op || r->dst.port_op),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB((pd->proto == IPPROTO_TCP && r->flagset),
+ TAILQ_NEXT(r, entries));
+ /* icmp only. type/code always 0 in other cases */
+ PF_TEST_ATTRIB((r->type || r->code),
+ TAILQ_NEXT(r, entries));
+ /* tcp/udp only. {uid|gid}.op always 0 in other cases */
+ PF_TEST_ATTRIB((r->gid.op || r->uid.op),
+ TAILQ_NEXT(r, entries));
+ break;
+
+ case IPPROTO_TCP:
+ PF_TEST_ATTRIB((r->flagset & th->th_flags) != r->flags,
+ TAILQ_NEXT(r, entries));
+ /* FALLTHROUGH */
+ case IPPROTO_SCTP:
+ case IPPROTO_UDP:
+ /* tcp/udp only. port_op always 0 in other cases */
+ PF_TEST_ATTRIB(r->src.port_op && !pf_match_port(r->src.port_op,
+ r->src.port[0], r->src.port[1], sport),
+ r->skip[PF_SKIP_SRC_PORT].ptr);
+ /* tcp/udp only. port_op always 0 in other cases */
+ PF_TEST_ATTRIB(r->dst.port_op && !pf_match_port(r->dst.port_op,
+ r->dst.port[0], r->dst.port[1], dport),
+ r->skip[PF_SKIP_DST_PORT].ptr);
+ /* tcp/udp only. uid.op always 0 in other cases */
+ PF_TEST_ATTRIB(r->uid.op && (pd->lookup.done || (pd->lookup.done =
+ pf_socket_lookup(pd, m), 1)) &&
+ !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
+ pd->lookup.uid),
+ TAILQ_NEXT(r, entries));
+ /* tcp/udp only. gid.op always 0 in other cases */
+ PF_TEST_ATTRIB(r->gid.op && (pd->lookup.done || (pd->lookup.done =
+ pf_socket_lookup(pd, m), 1)) &&
+ !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
+ pd->lookup.gid),
+ TAILQ_NEXT(r, entries));
+ break;
+
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
+ /* icmp only. type always 0 in other cases */
+ PF_TEST_ATTRIB(r->type && r->type != icmptype + 1,
+ TAILQ_NEXT(r, entries));
+ /* icmp only. type always 0 in other cases */
+ PF_TEST_ATTRIB(r->code && r->code != icmpcode + 1,
+ TAILQ_NEXT(r, entries));
+ break;
+
+ default:
+ break;
+ }
+ PF_TEST_ATTRIB(r->tos && !(r->tos == pd->tos),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB(r->prio &&
+ !pf_match_ieee8021q_pcp(r->prio, m),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB(r->prob &&
+ r->prob <= arc4random(),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB(r->match_tag && !pf_match_tag(m, r, &tag,
+ pd->pf_mtag ? pd->pf_mtag->tag : 0),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB(r->rcv_kif && !pf_match_rcvif(m, r),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB((r->rule_flag & PFRULE_FRAGMENT &&
+ pd->virtual_proto != PF_VPROTO_FRAGMENT),
+ TAILQ_NEXT(r, entries));
+ PF_TEST_ATTRIB(r->os_fingerprint != PF_OSFP_ANY &&
+ (pd->virtual_proto != IPPROTO_TCP || !pf_osfp_match(
pf_osfp_fingerprint(pd, m, off, th),
- r->os_fingerprint)))
- r = TAILQ_NEXT(r, entries);
- else {
- if (r->tag)
- tag = r->tag;
- if (r->anchor == NULL) {
- if (r->action == PF_MATCH) {
- ri = malloc(sizeof(struct pf_krule_item), M_PF_RULE_ITEM, M_NOWAIT | M_ZERO);
- if (ri == NULL) {
- REASON_SET(&reason, PFRES_MEMORY);
- goto cleanup;
- }
- ri->r = r;
- SLIST_INSERT_HEAD(&match_rules, ri, entry);
- pf_counter_u64_critical_enter();
- pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
- pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
- pf_counter_u64_critical_exit();
- pf_rule_to_actions(r, &pd->act);
- if (r->log || pd->act.log & PF_LOG_MATCHES)
- PFLOG_PACKET(kif, m,
- r->action, PFRES_MATCH, r,
- a, ruleset, pd, 1);
- } else {
- match = 1;
- *rm = r;
- *am = a;
- *rsm = ruleset;
- if (pd->act.log & PF_LOG_MATCHES)
- PFLOG_PACKET(kif, m,
- r->action, PFRES_MATCH, r,
- a, ruleset, pd, 1);
+ r->os_fingerprint)),
+ TAILQ_NEXT(r, entries));
+ /* FALLTHROUGH */
+ if (r->tag)
+ tag = r->tag;
+ if (r->anchor == NULL) {
+ if (r->action == PF_MATCH) {
+ ri = malloc(sizeof(struct pf_krule_item), M_PF_RULE_ITEM, M_NOWAIT | M_ZERO);
+ if (ri == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
}
- if ((*rm)->quick)
- break;
- r = TAILQ_NEXT(r, entries);
- } else
- pf_step_into_anchor(anchor_stack, &asd,
- &ruleset, PF_RULESET_FILTER, &r, &a,
- &match);
- }
+ ri->r = r;
+ SLIST_INSERT_HEAD(&match_rules, ri, entry);
+ pf_counter_u64_critical_enter();
+ pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
+ pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
+ pf_counter_u64_critical_exit();
+ pf_rule_to_actions(r, &pd->act);
+ if (r->log || pd->act.log & PF_LOG_MATCHES)
+ PFLOG_PACKET(kif, m,
+ r->action, PFRES_MATCH, r,
+ a, ruleset, pd, 1);
+ } else {
+ match = 1;
+ *rm = r;
+ *am = a;
+ *rsm = ruleset;
+ if (pd->act.log & PF_LOG_MATCHES)
+ PFLOG_PACKET(kif, m,
+ r->action, PFRES_MATCH, r,
+ a, ruleset, pd, 1);
+ }
+ if ((*rm)->quick)
+ break;
+ r = TAILQ_NEXT(r, entries);
+ } else
+ pf_step_into_anchor(anchor_stack, &asd,
+ &ruleset, PF_RULESET_FILTER, &r, &a,
+ &match);
+nextrule:
if (r == NULL && pf_step_out_of_anchor(anchor_stack, &asd,
&ruleset, PF_RULESET_FILTER, &r, &a, &match))
break;
@@ -5262,7 +5295,8 @@
PFLOG_PACKET(kif, m, r->action, reason, r, a, ruleset, pd, 1);
}
- if ((r->action == PF_DROP) &&
+ if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
+ (r->action == PF_DROP) &&
((r->rule_flag & PFRULE_RETURNRST) ||
(r->rule_flag & PFRULE_RETURNICMP) ||
(r->rule_flag & PFRULE_RETURN))) {
@@ -5280,8 +5314,9 @@
if (pd->act.rtableid >= 0)
M_SETFIB(m, pd->act.rtableid);
- if (!state_icmp && (r->keep_state || nr != NULL ||
- (pd->flags & PFDESC_TCP_NORM))) {
+ if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
+ (!state_icmp && (r->keep_state || nr != NULL ||
+ (pd->flags & PFDESC_TCP_NORM)))) {
int action;
action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off,
sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum,
@@ -5605,133 +5640,6 @@
return (PF_DROP);
}
-static int
-pf_test_fragment(struct pf_krule **rm, struct pfi_kkif *kif,
- struct mbuf *m, struct pf_pdesc *pd, struct pf_krule **am,
- struct pf_kruleset **rsm)
-{
- struct pf_krule *r, *a = NULL;
- struct pf_kruleset *ruleset = NULL;
- struct pf_krule_slist match_rules;
- struct pf_krule_item *ri;
- sa_family_t af = pd->af;
- u_short reason;
- int tag = -1;
- int asd = 0;
- int match = 0;
- struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE];
-
- PF_RULES_RASSERT();
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
- SLIST_INIT(&match_rules);
- while (r != NULL) {
- pf_counter_u64_add(&r->evaluations, 1);
- if (pfi_kkif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != pd->dir)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != af)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != pd->proto)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- else if (r->tos && !(r->tos == pd->tos))
- r = TAILQ_NEXT(r, entries);
- else if (r->os_fingerprint != PF_OSFP_ANY)
- r = TAILQ_NEXT(r, entries);
- else if (pd->proto == IPPROTO_UDP &&
- (r->src.port_op || r->dst.port_op))
- r = TAILQ_NEXT(r, entries);
- else if (pd->proto == IPPROTO_TCP &&
- (r->src.port_op || r->dst.port_op || r->flagset))
- r = TAILQ_NEXT(r, entries);
- else if ((pd->proto == IPPROTO_ICMP ||
- pd->proto == IPPROTO_ICMPV6) &&
- (r->type || r->code))
- r = TAILQ_NEXT(r, entries);
- else if (r->prio &&
- !pf_match_ieee8021q_pcp(r->prio, m))
- r = TAILQ_NEXT(r, entries);
- else if (r->prob && r->prob <=
- (arc4random() % (UINT_MAX - 1) + 1))
- r = TAILQ_NEXT(r, entries);
- else if (r->match_tag && !pf_match_tag(m, r, &tag,
- pd->pf_mtag ? pd->pf_mtag->tag : 0))
- r = TAILQ_NEXT(r, entries);
- else {
- if (r->anchor == NULL) {
- if (r->action == PF_MATCH) {
- ri = malloc(sizeof(struct pf_krule_item), M_PF_RULE_ITEM, M_NOWAIT | M_ZERO);
- if (ri == NULL) {
- REASON_SET(&reason, PFRES_MEMORY);
- goto cleanup;
- }
- ri->r = r;
- SLIST_INSERT_HEAD(&match_rules, ri, entry);
- pf_counter_u64_critical_enter();
- pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
- pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
- pf_counter_u64_critical_exit();
- pf_rule_to_actions(r, &pd->act);
- if (r->log)
- PFLOG_PACKET(kif, m,
- r->action, 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);
- } else
- pf_step_into_anchor(anchor_stack, &asd,
- &ruleset, PF_RULESET_FILTER, &r, &a,
- &match);
- }
- if (r == NULL && pf_step_out_of_anchor(anchor_stack, &asd,
- &ruleset, PF_RULESET_FILTER, &r, &a, &match))
- break;
- }
- r = *rm;
- a = *am;
- ruleset = *rsm;
-
- 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, r->action, reason, r, a, ruleset, pd, 1);
-
- if (r->action != PF_PASS)
- return (PF_DROP);
-
- if (tag > 0 && pf_tag_packet(m, pd, tag)) {
- REASON_SET(&reason, PFRES_MEMORY);
- goto cleanup;
- }
-
- return (PF_PASS);
-
-cleanup:
- while ((ri = SLIST_FIRST(&match_rules))) {
- SLIST_REMOVE_HEAD(&match_rules, entry);
- free(ri, M_PF_RULE_ITEM);
- }
-
- return (PF_DROP);
-}
-
static int
pf_tcp_track_full(struct pf_kstate **state, struct pfi_kkif *kif,
struct mbuf *m, int off, struct pf_pdesc *pd, u_short *reason,
@@ -8569,7 +8477,8 @@
int
pf_setup_pdesc(pf_af_t af, int dir, struct pf_pdesc *pd, struct mbuf *m,
u_short *action, u_short *reason, struct pfi_kkif *kif, struct pf_krule **a,
- struct pf_krule **r, struct pf_kruleset **ruleset, int *off, int *hdrlen,
+ struct pf_krule **r, struct pf_kstate **s, struct pf_kruleset **ruleset,
+ int *off, int *hdrlen, struct inpcb *inp,
struct pf_rule_actions *default_actions)
{
@@ -8602,7 +8511,7 @@
pd->sport = pd->dport = NULL;
pd->ip_sum = &h->ip_sum;
pd->proto_sum = NULL;
- pd->proto = h->ip_p;
+ pd->virtual_proto = pd->proto = h->ip_p;
pd->dir = dir;
pd->sidx = (dir == PF_IN) ? 0 : 1;
pd->didx = (dir == PF_IN) ? 1 : 0;
@@ -8613,9 +8522,21 @@
if (h->ip_hl > 5) /* has options */
pd->badopts++;
- /* fragments not reassembled handled later */
- if (h->ip_off & htons(IP_MF | IP_OFFMASK))
- return (0);
+ if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
+ /*
+ * handle fragments that aren't reassembled by
+ * normalization
+ */
+ pd->virtual_proto = PF_VPROTO_FRAGMENT;
+ if (kif == NULL || r == NULL) /* pflog */
+ *action = PF_DROP;
+ else
+ *action = pf_test_rule(r, s, kif, m, *off,
+ pd, a, ruleset, inp, *hdrlen);
+ if (*action != PF_PASS)
+ REASON_SET(reason, PFRES_FRAG);
+ return (-1);
+ }
break;
}
@@ -8637,17 +8558,19 @@
pd->tos = IPV6_DSCP(h);
pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
*off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
- pd->proto = h->ip6_nxt;
+ pd->virtual_proto = pd->proto = h->ip6_nxt;
pd->act.rtableid = -1;
do {
switch (pd->proto) {
case IPPROTO_FRAGMENT:
+ pd->virtual_proto = PF_VPROTO_FRAGMENT;
if (kif == NULL || r == NULL) /* pflog */
*action = PF_DROP;
else
- *action = pf_test_fragment(r, kif,
- m, pd, a, ruleset);
+ *action = pf_test_rule(r, s, kif, m, *off,
+ pd, a, ruleset, inp,
+ *hdrlen);
if (*action == PF_DROP)
REASON_SET(reason, PFRES_FRAG);
return (-1);
@@ -8695,7 +8618,7 @@
*off += (opt6.ip6e_len + 2) * 4;
else
*off += (opt6.ip6e_len + 1) * 8;
- pd->proto = opt6.ip6e_nxt;
+ pd->virtual_proto = pd->proto = opt6.ip6e_nxt;
/* goto the next header */
break;
}
@@ -9020,7 +8943,7 @@
}
if (pf_setup_pdesc(af, dir, &pd, m, &action, &reason, kif, &a, &r,
- &ruleset, &off, &hdrlen, default_actions) == -1) {
+ &s, &ruleset, &off, &hdrlen, inp, default_actions) == -1) {
if (action != PF_PASS)
pd.act.log |= PF_LOG_FORCE;
goto done;
@@ -9080,30 +9003,17 @@
m_tag_delete(m, mtag);
}
- switch (af) {
-#ifdef INET
- case AF_INET:
- /* handle fragments that didn't get reassembled by normalization */
- if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
- action = pf_test_fragment(&r, kif, m, &pd, &a, &ruleset);
- goto done;
- }
- break;
-#endif
#ifdef INET6
- case AF_INET6:
- /*
- * we do not support jumbogram. if we keep going, zero ip6_plen
- * will do something bad, so drop the packet for now.
- */
- if (htons(h6->ip6_plen) == 0) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_NORM); /*XXX*/
- goto done;
- }
- break;
-#endif
+ /*
+ * we do not support jumbogram. if we keep going, zero ip6_plen
+ * will do something bad, so drop the packet for now.
+ */
+ if (af == AF_INET6 && htons(h6->ip6_plen) == 0) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_NORM); /*XXX*/
+ goto done;
}
+#endif
switch (pd.proto) {
case IPPROTO_TCP: {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 26, 12:30 PM (22 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12820526
Default Alt Text
D46705.diff (20 KB)
Attached To
Mode
D46705: pf: fold pf_test_fragment() into pf_test_rule()
Attached
Detach File
Event Timeline
Log In to Comment