summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c80
1 files changed, 44 insertions, 36 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 594f73ceea5..dd409468abd 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.743 2011/05/13 14:31:16 oga Exp $ */
+/* $OpenBSD: pf.c,v 1.744 2011/05/22 13:21:24 claudio Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -175,7 +175,7 @@ void pf_rule_to_actions(struct pf_rule *,
int pf_test_rule(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
struct pf_pdesc *, struct pf_rule **,
- struct pf_ruleset **, struct ifqueue *, int);
+ struct pf_ruleset **, int);
static __inline int pf_create_state(struct pf_rule *, struct pf_rule *,
struct pf_pdesc *, struct pf_state_key **,
struct pf_state_key **, struct mbuf *, int,
@@ -2716,7 +2716,7 @@ int
pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off,
struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
- struct ifqueue *ifq, int hdrlen)
+ int hdrlen)
{
struct pf_rule *lastr = NULL;
sa_family_t af = pd->af;
@@ -2728,6 +2728,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
struct tcphdr *th = pd->hdr.tcp;
struct pf_state_key *skw = NULL, *sks = NULL;
struct pf_rule_actions act;
+ struct ifqueue *ifq = &ipintrq;
u_short reason;
int rewrite = 0;
int tag = -1;
@@ -2745,6 +2746,9 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
act.rtableid = pd->rdomain;
SLIST_INIT(&rules);
+ if (af == AF_INET6)
+ ifq = &ip6intrq;
+
if (direction == PF_IN && pf_check_congestion(ifq)) {
REASON_SET(&reason, PFRES_CONGEST);
return (PF_DROP);
@@ -2885,7 +2889,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
goto cleanup;
}
if (r->log || act.log & PF_LOG_MATCHES)
- PFLOG_PACKET(kif, h, m, af,
+ PFLOG_PACKET(kif, h, m,
direction, reason, r,
a, ruleset, pd);
} else {
@@ -2894,7 +2898,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
*am = a;
*rsm = ruleset;
if (act.log & PF_LOG_MATCHES)
- PFLOG_PACKET(kif, h, m, af,
+ PFLOG_PACKET(kif, h, m,
direction, reason, r,
a, ruleset, pd);
}
@@ -2923,7 +2927,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
REASON_SET(&reason, PFRES_MATCH);
if (r->log || act.log & PF_LOG_MATCHES)
- PFLOG_PACKET(kif, h, m, af, direction, reason,
+ PFLOG_PACKET(kif, h, m, direction, reason,
r, a, ruleset, pd);
if ((r->action == PF_DROP) &&
@@ -3447,8 +3451,7 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
REASON_SET(&reason, PFRES_MATCH);
if (r->log)
- PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
- pd);
+ PFLOG_PACKET(kif, h, m, direction, reason, r, a, ruleset, pd);
if (r->action == PF_DROP)
return (PF_DROP);
@@ -5798,9 +5801,15 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED_PACKET)
return (PF_PASS);
+ if (m->m_pkthdr.pf.flags & PF_TAG_REFRAGMENTED) {
+ m->m_pkthdr.pf.flags &= ~PF_TAG_REFRAGMENTED;
+ return (PF_PASS);
+ }
+
/* packet reassembly here if 1) enabled 2) we deal with a fragment */
h = mtod(m, struct ip *);
- if (pf_status.reass && (h->ip_off & htons(IP_MF | IP_OFFMASK)) &&
+ if (pf_status.reass &&
+ (h->ip_off & htons(IP_MF | IP_OFFMASK)) &&
pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
action = PF_DROP;
goto done;
@@ -5825,7 +5834,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
goto done;
}
- switch (h->ip_p) {
+ switch (pd.proto) {
case IPPROTO_TCP: {
if ((pd.hdr.tcp->th_flags & TH_ACK) && pd.p_len == 0)
@@ -5844,7 +5853,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif,
- m, off, &pd, &a, &ruleset, &ipintrq, hdrlen);
+ m, off, &pd, &a, &ruleset, hdrlen);
if (s) {
if (s->max_mss)
@@ -5866,7 +5875,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif,
- m, off, &pd, &a, &ruleset, &ipintrq, hdrlen);
+ m, off, &pd, &a, &ruleset, hdrlen);
break;
}
@@ -5882,7 +5891,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif,
- m, off, &pd, &a, &ruleset, &ipintrq, hdrlen);
+ m, off, &pd, &a, &ruleset, hdrlen);
break;
}
@@ -5904,7 +5913,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif, m, off,
- &pd, &a, &ruleset, &ipintrq, hdrlen);
+ &pd, &a, &ruleset, hdrlen);
break;
}
@@ -5982,12 +5991,12 @@ done:
struct pf_rule_item *ri;
if (pd.pflog & PF_LOG_FORCE || r->log & PF_LOG_ALL)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a,
+ PFLOG_PACKET(kif, h, m, dir, reason, r, a,
ruleset, &pd);
if (s) {
SLIST_FOREACH(ri, &s->match_rules, entry)
if (ri->r->log & PF_LOG_ALL)
- PFLOG_PACKET(kif, h, m, AF_INET, dir,
+ PFLOG_PACKET(kif, h, m, dir,
reason, ri->r, a, ruleset, &pd);
}
}
@@ -6128,7 +6137,7 @@ pf_test6(int fwdir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif,
- m, off, &pd, &a, &ruleset, &ip6intrq, hdrlen);
+ m, off, &pd, &a, &ruleset, hdrlen);
if (s) {
if (s->max_mss)
@@ -6150,7 +6159,7 @@ pf_test6(int fwdir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif,
- m, off, &pd, &a, &ruleset, &ip6intrq, hdrlen);
+ m, off, &pd, &a, &ruleset, hdrlen);
break;
}
@@ -6162,8 +6171,8 @@ pf_test6(int fwdir, struct ifnet *ifp, struct mbuf **m0,
}
case IPPROTO_ICMPV6: {
- action = pf_test_state_icmp(&s, dir, kif,
- m, off, &pd, &reason);
+ action = pf_test_state_icmp(&s, dir, kif, m, off, &pd,
+ &reason);
if (action == PF_PASS) {
#if NPFSYNC > 0
pfsync_update_state(s);
@@ -6173,7 +6182,7 @@ pf_test6(int fwdir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif,
- m, off, &pd, &a, &ruleset, &ip6intrq, hdrlen);
+ m, off, &pd, &a, &ruleset, hdrlen);
break;
}
@@ -6188,24 +6197,25 @@ pf_test6(int fwdir, struct ifnet *ifp, struct mbuf **m0,
pd.pflog |= s->log;
} else if (s == NULL)
action = pf_test_rule(&r, &s, dir, kif, m, off,
- &pd, &a, &ruleset, &ip6intrq, hdrlen);
+ &pd, &a, &ruleset, hdrlen);
break;
}
done:
- /* handle dangerous IPv6 extension headers. */
- if (action == PF_PASS && pd.rh_cnt &&
- !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_IPOPTIONS);
- pd.pflog |= PF_LOG_FORCE;
- DPFPRINTF(LOG_NOTICE,
- "dropping packet with dangerous v6 headers");
- }
-
if (action != PF_DROP) {
if (s) {
+ /* handle dangerous IPv6 extension headers. */
+ if (action == PF_PASS && pd.rh_cnt &&
+ !(s->state_flags & PFSTATE_ALLOWOPTS)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_IPOPTIONS);
+ pd.pflog |= PF_LOG_FORCE;
+ DPFPRINTF(LOG_NOTICE, "dropping packet with "
+ "dangerous v6 headers");
+ }
+
pf_scrub_ip6(m, s->min_ttl);
+ pf_tag_packet(m, s->tag, s->rtableid[pd.didx]);
if (pqid || (pd.tos & IPTOS_LOWDELAY))
qid = s->pqid;
else
@@ -6218,8 +6228,6 @@ done:
qid = r->qid;
}
}
- if (s && s->tag)
- pf_tag_packet(m, s ? s->tag : 0, s->rtableid[pd.didx]);
if (dir == PF_IN && s && s->key[PF_SK_STACK])
m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK];
@@ -6262,12 +6270,12 @@ done:
struct pf_rule_item *ri;
if (pd.pflog & PF_LOG_FORCE || r->log & PF_LOG_ALL)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a,
+ PFLOG_PACKET(kif, h, m, dir, reason, r, a,
ruleset, &pd);
if (s) {
SLIST_FOREACH(ri, &s->match_rules, entry)
if (ri->r->log & PF_LOG_ALL)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir,
+ PFLOG_PACKET(kif, h, m, dir,
reason, ri->r, a, ruleset, &pd);
}
}