Date: Fri, 22 Jun 2012 10:25:12 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r237440 - projects/pf/head/sys/contrib/pf/net Message-ID: <201206221025.q5MAPCK7071251@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206221025.q5MAPCK7071251>