svn commit: r237440 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Fri Jun 22 10:25:12 UTC 2012
Author: glebius
Date: Fri Jun 22 10:25:12 2012
New Revision: 237440
URL: http://svn.freebsd.org/changeset/base/237440
Log:
Stop allocating the mbuf tag unconditionally in pf_test(), pf_test6().
We actually need tag only in case of:
- ALTQ
- "tag" rules
- "route" rules
- divert processing
In all above cases allocate tag only by the time we are sure we need it.
Modified:
projects/pf/head/sys/contrib/pf/net/pf.c
projects/pf/head/sys/contrib/pf/net/pf_lb.c
projects/pf/head/sys/contrib/pf/net/pf_norm.c
projects/pf/head/sys/contrib/pf/net/pfvar.h
Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c Fri Jun 22 08:37:33 2012 (r237439)
+++ projects/pf/head/sys/contrib/pf/net/pf.c Fri Jun 22 10:25:12 2012 (r237440)
@@ -328,7 +328,8 @@ VNET_DECLARE(int, pf_end_threads);
VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]);
-#define PACKET_LOOPED(pd) ((pd)->pf_mtag->flags & PF_PACKET_LOOPED)
+#define PACKET_LOOPED(pd) ((pd)->pf_mtag && \
+ (pd)->pf_mtag->flags & PF_PACKET_LOOPED)
#define STATE_LOOKUP(i, k, d, s, pd) \
do { \
@@ -2466,29 +2467,25 @@ pf_match_gid(u_int8_t op, gid_t a1, gid_
}
int
-pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag,
- struct pf_mtag *pf_mtag)
+pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag, int mtag)
{
if (*tag == -1)
- *tag = pf_mtag->tag;
+ *tag = mtag;
return ((!r->match_tag_not && r->match_tag == *tag) ||
(r->match_tag_not && r->match_tag != *tag));
}
int
-pf_tag_packet(struct mbuf *m, int tag, int rtableid,
- struct pf_mtag *pf_mtag)
+pf_tag_packet(struct mbuf *m, struct pf_pdesc *pd, int tag)
{
- if (tag <= 0 && rtableid < 0)
- return (0);
- if (tag > 0)
- pf_mtag->tag = tag;
- if (rtableid >= 0)
- {
- M_SETFIB(m, rtableid);
- }
+ KASSERT(tag > 0, ("%s: tag %d", __func__, tag));
+
+ if (pd->pf_mtag == NULL && ((pd->pf_mtag = pf_get_mtag(m)) == NULL))
+ return (ENOMEM);
+
+ pd->pf_mtag->tag = tag;
return (0);
}
@@ -3168,7 +3165,8 @@ pf_test_rule(struct pf_rule **rm, struct
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))
+ 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->os_fingerprint != PF_OSFP_ANY &&
(pd->proto != IPPROTO_TCP || !pf_osfp_match(
@@ -3280,10 +3278,12 @@ pf_test_rule(struct pf_rule **rm, struct
if (r->action == PF_DROP)
goto cleanup;
- if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag)) {
+ if (tag > 0 && pf_tag_packet(m, pd, tag)) {
REASON_SET(&reason, PFRES_MEMORY);
goto cleanup;
}
+ if (rtableid >= 0)
+ M_SETFIB(m, rtableid);
if (!state_icmp && (r->keep_state || nr != NULL ||
(pd->flags & PFDESC_TCP_NORM))) {
@@ -3603,7 +3603,8 @@ pf_test_fragment(struct pf_rule **rm, in
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))
+ 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) {
@@ -3635,7 +3636,7 @@ pf_test_fragment(struct pf_rule **rm, in
if (r->action != PF_PASS)
return (PF_DROP);
- if (pf_tag_packet(m, tag, -1, pd->pf_mtag)) {
+ if (tag > 0 && pf_tag_packet(m, pd, tag)) {
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
@@ -5124,7 +5125,9 @@ pf_route(struct mbuf **m, struct pf_rule
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
__func__));
- if (pd->pf_mtag->routed++ > 3) {
+ if ((pd->pf_mtag == NULL &&
+ ((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) ||
+ pd->pf_mtag->routed++ > 3) {
m0 = *m;
*m = NULL;
goto bad_locked;
@@ -5306,7 +5309,9 @@ pf_route6(struct mbuf **m, struct pf_rul
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
__func__));
- if (pd->pf_mtag->routed++ > 3) {
+ if ((pd->pf_mtag == NULL &&
+ ((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) ||
+ pd->pf_mtag->routed++ > 3) {
m0 = *m;
*m = NULL;
goto bad_locked;
@@ -5571,11 +5576,7 @@ pf_test(int dir, struct ifnet *ifp, stru
return (PF_PASS);
memset(&pd, 0, sizeof(pd));
- if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_test: pf_get_mtag returned NULL\n"));
- return (PF_DROP);
- }
+
kif = (struct pfi_kif *)ifp->if_pf_kif;
if (kif == NULL) {
@@ -5596,16 +5597,23 @@ pf_test(int dir, struct ifnet *ifp, stru
goto done;
}
+ pd.pf_mtag = pf_find_mtag(m);
+
PF_RULES_RLOCK();
if (ip_divert_ptr != NULL &&
((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) {
struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1);
if (rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) {
+ if (pd.pf_mtag == NULL &&
+ ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
+ action = PF_DROP;
+ goto done;
+ }
pd.pf_mtag->flags |= PF_PACKET_LOOPED;
m_tag_delete(m, ipfwtag);
}
- if (pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) {
+ if (pd.pf_mtag && pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) {
m->m_flags |= M_FASTFWD_OURS;
pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT;
}
@@ -5762,11 +5770,20 @@ done:
("pf: dropping packet with ip options\n"));
}
- if ((s && s->tag) || r->rtableid >= 0)
- pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag);
+ if (s && s->tag > 0 && pf_tag_packet(m, &pd, s->tag)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_MEMORY);
+ }
+ if (r->rtableid >= 0)
+ 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);
+ }
if (pqid || (pd.tos & IPTOS_LOWDELAY))
pd.pf_mtag->qid = r->pqid;
else
@@ -5804,6 +5821,14 @@ done:
m_tag_prepend(m, ipfwtag);
if (m->m_flags & M_FASTFWD_OURS) {
+ if (pd.pf_mtag == NULL &&
+ ((pd.pf_mtag = pf_get_mtag(m)) == NULL)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_MEMORY);
+ log = 1;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: failed to allocate tag\n"));
+ }
pd.pf_mtag->flags |= PF_FASTFWD_OURS_PRESENT;
m->m_flags &= ~M_FASTFWD_OURS;
}
@@ -5923,13 +5948,9 @@ pf_test6(int dir, struct ifnet *ifp, str
return (PF_PASS);
memset(&pd, 0, sizeof(pd));
- if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_test: pf_get_mtag returned NULL\n"));
- return (PF_DROP);
- }
+ pd.pf_mtag = pf_find_mtag(m);
- if (pd.pf_mtag->flags & PF_TAG_GENERATED)
+ if (pd.pf_mtag && pd.pf_mtag->flags & PF_TAG_GENERATED)
return (PF_PASS);
kif = (struct pfi_kif *)ifp->if_pf_kif;
@@ -6173,11 +6194,20 @@ done:
("pf: dropping packet with dangerous v6 headers\n"));
}
- if ((s && s->tag) || r->rtableid >= 0)
- pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag);
+ if (s && s->tag > 0 && pf_tag_packet(m, &pd, s->tag)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_MEMORY);
+ }
+ if (r->rtableid >= 0)
+ 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);
+ }
if (pd.tos & IPTOS_LOWDELAY)
pd.pf_mtag->qid = r->pqid;
else
Modified: projects/pf/head/sys/contrib/pf/net/pf_lb.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_lb.c Fri Jun 22 08:37:33 2012 (r237439)
+++ projects/pf/head/sys/contrib/pf/net/pf_lb.c Fri Jun 22 10:25:12 2012 (r237440)
@@ -227,7 +227,8 @@ pf_match_translation(struct pf_pdesc *pd
!pf_match_port(dst->port_op, dst->port[0],
dst->port[1], dport))
r = r->skip[PF_SKIP_DST_PORT].ptr;
- else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
+ 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->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
@@ -248,8 +249,12 @@ pf_match_translation(struct pf_pdesc *pd
pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
NULL, NULL);
}
- if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag))
+
+ if (tag > 0 && pf_tag_packet(m, pd, tag))
return (NULL);
+ if (rtableid >= 0)
+ M_SETFIB(m, rtableid);
+
if (rm != NULL && (rm->action == PF_NONAT ||
rm->action == PF_NORDR || rm->action == PF_NOBINAT))
return (NULL);
Modified: projects/pf/head/sys/contrib/pf/net/pf_norm.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_norm.c Fri Jun 22 08:37:33 2012 (r237439)
+++ projects/pf/head/sys/contrib/pf/net/pf_norm.c Fri Jun 22 10:25:12 2012 (r237440)
@@ -904,7 +904,8 @@ pf_normalize_ip(struct mbuf **m0, int di
(struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
r->dst.neg, NULL, M_GETFIB(m)))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
- else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
+ 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
break;
Modified: projects/pf/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pfvar.h Fri Jun 22 08:37:33 2012 (r237439)
+++ projects/pf/head/sys/contrib/pf/net/pfvar.h Fri Jun 22 10:25:12 2012 (r237440)
@@ -1902,9 +1902,8 @@ void pfi_get_ifaces(const char *, stru
int pfi_set_flags(const char *, int);
int pfi_clear_flags(const char *, int);
-int pf_match_tag(struct mbuf *, struct pf_rule *, int *,
- struct pf_mtag *);
-int pf_tag_packet(struct mbuf *, int, int, struct pf_mtag *);
+int pf_match_tag(struct mbuf *, struct pf_rule *, int *, int);
+int pf_tag_packet(struct mbuf *, struct pf_pdesc *, int);
void pf_qid2qname(u_int32_t, char *);
VNET_DECLARE(struct pf_status, pf_status);
More information about the svn-src-projects
mailing list