Hiya,

* Schvberle Daniel <[EMAIL PROTECTED]> [2005-10-10 14:50]:
> Finally I got around to testing mbuf tag merging patch by Henning
> that Theo suggested.

cool.

> Some new conslusions:
>  - mbus tag merging patch helps in all cases and especially
> with the integrated NIC and i386 mp kernel -> almost the same
> performance as i386 sp kernel

wonderful. Thanks for testing that. since the diff itself never went to 
any public place before I'll include it below.

What does it do? well, it changes the way pf uses mbuf tags. now, 
pf uses 6 distinct mbuf tags for various things, like, altq, the 
tag/tagged stuff, marking redirected-to-localhost packets and so on. 
They are looked up and attached when needed.
With the diff, pf only uses one mbuf tag with a little structure in the 
data part containing the information from the previously dictinct mbuf 
tags. we look the tag up once, unconditionally and early and then just 
carry a pointer to it around. This makes the code easier, and saves 
quite some mbuf tag lookups. the lookups are not free of course, and 
the entire mbuf tags are only cheap when there are not too many in use, 
since they are just a linked list attached to an mbuf, so the fewer 
mbuf tags attached to an mbuf the better the performance.
I really wrote this diff to make the code easier, knowing that there 
should be a slight performance gain, great that the latter has been 
proven now. there is some more easyfication potential after this is in.

btw, the same should to be done for ipsec later, it uses 6 
distinct tags too.

Index: netinet/tcp_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.190
diff -u -p -r1.190 tcp_input.c
--- netinet/tcp_input.c 11 Aug 2005 11:39:36 -0000      1.190
+++ netinet/tcp_input.c 4 Oct 2005 13:00:26 -0000
@@ -604,19 +604,25 @@ findpcb:
                break;
        }
        if (inp == 0) {
+               int     inpl_flags = 0;
+#if NPF > 0
+               struct pf_mtag *t;
+
+               if ((t = pf_find_mtag(m)) != NULL &&
+                   t->flags & PF_TAG_TRANSLATE_LOCALHOST)
+                       inpl_flags = INPLOOKUP_WILDCARD;
+#endif
                ++tcpstat.tcps_pcbhashmiss;
                switch (af) {
 #ifdef INET6
                case AF_INET6:
                        inp = in6_pcblookup_listen(&tcbtable,
-                           &ip6->ip6_dst, th->th_dport, m_tag_find(m,
-                           PACKET_TAG_PF_TRANSLATE_LOCALHOST, NULL) != NULL);
+                           &ip6->ip6_dst, th->th_dport, inpl_flags);
                        break;
 #endif /* INET6 */
                case AF_INET:
                        inp = in_pcblookup_listen(&tcbtable,
-                           ip->ip_dst, th->th_dport, m_tag_find(m,
-                           PACKET_TAG_PF_TRANSLATE_LOCALHOST, NULL) != NULL);
+                           ip->ip_dst, th->th_dport, inpl_flags);
                        break;
                }
                /*
Index: netinet/ip_icmp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.68
diff -u -p -r1.68 ip_icmp.c
--- netinet/ip_icmp.c   31 Jul 2005 03:30:55 -0000      1.68
+++ netinet/ip_icmp.c   4 Oct 2005 13:00:26 -0000
@@ -134,8 +134,10 @@ icmp_do_error(struct mbuf *n, int type, 
        unsigned oiplen = oip->ip_hl << 2;
        struct icmp *icp;
        struct mbuf *m;
-       struct m_tag *mtag;
        unsigned icmplen, mblen;
+#if NPF > 0
+       struct pf_mtag  *mtag;
+#endif
 
 #ifdef ICMPPRINTFS
        if (icmpprintfs)
@@ -251,13 +253,14 @@ icmp_do_error(struct mbuf *n, int type, 
        nip->ip_p = IPPROTO_ICMP;
        nip->ip_src = oip->ip_src;
        nip->ip_dst = oip->ip_dst;
-       /* move PF_GENERATED m_tag to new packet, if it exists */
-       mtag = m_tag_find(n, PACKET_TAG_PF_GENERATED, NULL);
-       if (mtag != NULL) {
-               m_tag_unlink(n, mtag);
-               m_tag_prepend(m, mtag);
+#if NPF > 0
+       /* move PF_GENERATED to new packet, if existant XXX preserve more? */
+       if ((mtag = pf_find_mtag(n)) != NULL &&
+           mtag->flags & PF_TAG_GENERATED) {
+               mtag = pf_get_tag(m);
+               mtag->flags |= PF_TAG_GENERATED;
        }
-
+#endif
        m_freem(n);
        return (m);
 
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.104
diff -u -p -r1.104 udp_usrreq.c
--- netinet/udp_usrreq.c        27 May 2005 04:55:28 -0000      1.104
+++ netinet/udp_usrreq.c        4 Oct 2005 13:00:27 -0000
@@ -525,17 +525,23 @@ udp_input(struct mbuf *m, ...)
        inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
            ip->ip_dst, uh->uh_dport);
        if (inp == 0) {
+               int     inpl_reverse = 0;
+#if NPF > 0
+               struct pf_mtag *t;
+
+               if ((t = pf_find_mtag(m)) != NULL &&
+                   t->flags & PF_TAG_TRANSLATE_LOCALHOST)
+                       inpl_reverse = 1;
+#endif
                ++udpstat.udps_pcbhashmiss;
 #ifdef INET6
                if (ip6) {
                        inp = in6_pcblookup_listen(&udbtable,
-                           &ip6->ip6_dst, uh->uh_dport, m_tag_find(m,
-                           PACKET_TAG_PF_TRANSLATE_LOCALHOST, NULL) != NULL);
+                           &ip6->ip6_dst, uh->uh_dport, inpl_reverse);
                } else
 #endif /* INET6 */
                inp = in_pcblookup_listen(&udbtable,
-                   ip->ip_dst, uh->uh_dport, m_tag_find(m,
-                   PACKET_TAG_PF_TRANSLATE_LOCALHOST, NULL) != NULL);
+                   ip->ip_dst, uh->uh_dport, inpl_reverse);
                if (inp == 0) {
                        udpstat.udps_noport++;
                        if (m->m_flags & (M_BCAST | M_MCAST)) {
Index: sys/mbuf.h
===================================================================
RCS file: /cvs/src/sys/sys/mbuf.h,v
retrieving revision 1.82
diff -u -p -r1.82 mbuf.h
--- sys/mbuf.h  26 May 2005 01:49:15 -0000      1.82
+++ sys/mbuf.h  4 Oct 2005 13:00:27 -0000
@@ -585,12 +585,7 @@ struct m_tag *m_tag_next(struct mbuf *, 
 #define PACKET_TAG_GIF                         8  /* GIF processing done */
 #define PACKET_TAG_GRE                         9  /* GRE processing done */
 #define PACKET_TAG_IN_PACKET_CHECKSUM          10 /* NIC checksumming done */
-#define PACKET_TAG_PF_GENERATED                        11 /* PF generated, 
pass always */
-#define PACKET_TAG_PF_ROUTED                   12 /* PF routed, no route loops 
*/
-#define PACKET_TAG_PF_FRAGCACHE                        13 /* PF fragment 
cached */
-#define        PACKET_TAG_PF_QID                       14 /* PF queue id */
-#define PACKET_TAG_PF_TAG                      15 /* PF tags */
-#define PACKET_TAG_PF_TRANSLATE_LOCALHOST      16 /* translated to localhost */
+#define PACKET_TAG_PF                          11 /* PF */
 #define PACKET_TAG_DLT                         17 /* data link layer type */
 
 #ifdef MBTYPES
Index: altq/altq_cbq.c
===================================================================
RCS file: /cvs/src/sys/altq/altq_cbq.c,v
retrieving revision 1.18
diff -u -p -r1.18 altq_cbq.c
--- altq/altq_cbq.c     14 Jan 2004 08:42:23 -0000      1.18
+++ altq/altq_cbq.c     4 Oct 2005 13:00:27 -0000
@@ -441,7 +441,7 @@ cbq_enqueue(struct ifaltq *ifq, struct m
 {
        cbq_state_t     *cbqp = (cbq_state_t *)ifq->altq_disc;
        struct rm_class *cl;
-       struct m_tag    *t;
+       struct pf_mtag  *t;
        int              len;
 
        /* grab class set by classifier */
@@ -452,9 +452,9 @@ cbq_enqueue(struct ifaltq *ifq, struct m
                m_freem(m);
                return (ENOBUFS);
        }
-       t = m_tag_find(m, PACKET_TAG_PF_QID, NULL);
+       t = pf_find_mtag(m);
        if (t == NULL ||
-           (cl = clh_to_clp(cbqp, ((struct altq_tag *)(t+1))->qid)) == NULL) {
+           (cl = clh_to_clp(cbqp, t->qid)) == NULL) {
                cl = cbqp->ifnp.default_;
                if (cl == NULL) {
                        m_freem(m);
Index: altq/altq_hfsc.c
===================================================================
RCS file: /cvs/src/sys/altq/altq_hfsc.c,v
retrieving revision 1.21
diff -u -p -r1.21 altq_hfsc.c
--- altq/altq_hfsc.c    14 Jan 2004 08:42:23 -0000      1.21
+++ altq/altq_hfsc.c    4 Oct 2005 13:00:28 -0000
@@ -618,7 +618,7 @@ hfsc_enqueue(struct ifaltq *ifq, struct 
 {
        struct hfsc_if  *hif = (struct hfsc_if *)ifq->altq_disc;
        struct hfsc_class *cl;
-       struct m_tag *t;
+       struct pf_mtag *t;
        int len;
 
        /* grab class set by classifier */
@@ -629,9 +629,9 @@ hfsc_enqueue(struct ifaltq *ifq, struct 
                m_freem(m);
                return (ENOBUFS);
        }
-       t = m_tag_find(m, PACKET_TAG_PF_QID, NULL);
+       t = pf_find_mtag(m);
        if (t == NULL ||
-           (cl = clh_to_clp(hif, ((struct altq_tag *)(t+1))->qid)) == NULL ||
+           (cl = clh_to_clp(hif, t->qid)) == NULL ||
                is_a_parent_class(cl)) {
                cl = hif->hif_defaultclass;
                if (cl == NULL) {
Index: altq/altq_priq.c
===================================================================
RCS file: /cvs/src/sys/altq/altq_priq.c,v
retrieving revision 1.17
diff -u -p -r1.17 altq_priq.c
--- altq/altq_priq.c    14 Jan 2004 08:42:23 -0000      1.17
+++ altq/altq_priq.c    4 Oct 2005 13:00:28 -0000
@@ -396,7 +396,7 @@ priq_enqueue(struct ifaltq *ifq, struct 
 {
        struct priq_if  *pif = (struct priq_if *)ifq->altq_disc;
        struct priq_class *cl;
-       struct m_tag *t;
+       struct pf_mtag *t;
        int len;
 
        /* grab class set by classifier */
@@ -407,9 +407,9 @@ priq_enqueue(struct ifaltq *ifq, struct 
                m_freem(m);
                return (ENOBUFS);
        }
-       t = m_tag_find(m, PACKET_TAG_PF_QID, NULL);
+       t = pf_find_mtag(m);
        if (t == NULL ||
-           (cl = clh_to_clp(pif, ((struct altq_tag *)(t+1))->qid)) == NULL) {
+           (cl = clh_to_clp(pif, t->qid)) == NULL) {
                cl = pif->pif_default;
                if (cl == NULL) {
                        m_freem(m);
Index: altq/altq_red.c
===================================================================
RCS file: /cvs/src/sys/altq/altq_red.c,v
retrieving revision 1.11
diff -u -p -r1.11 altq_red.c
--- altq/altq_red.c     12 May 2003 00:50:12 -0000      1.11
+++ altq/altq_red.c     4 Oct 2005 13:00:28 -0000
@@ -420,39 +420,28 @@ int
 mark_ecn(struct mbuf *m, struct altq_pktattr *pktattr, int flags)
 {
        struct mbuf     *m0;
-       struct m_tag    *t;
-       struct altq_tag *at;
-       void            *hdr;
-       int              af;
+       struct pf_mtag  *t;
 
-       t = m_tag_find(m, PACKET_TAG_PF_QID, NULL);
-       if (t == NULL)
+       if ((t = pf_find_mtag(m)) == NULL)
                return (0);
-       at = (struct altq_tag *)(t + 1);
 
-       if (at == NULL)
-               return (0);
-
-       af = at->af;
-       hdr = at->hdr;
-
-       if (af != AF_INET && af != AF_INET6)
+       if (t->af != AF_INET && t->af != AF_INET6)
                return (0);
 
        /* verify that pattr_hdr is within the mbuf data */
        for (m0 = m; m0 != NULL; m0 = m0->m_next)
-               if (((caddr_t)hdr >= m0->m_data) &&
-                   ((caddr_t)hdr < m0->m_data + m0->m_len))
+               if (((caddr_t)(t->hdr) >= m0->m_data) &&
+                   ((caddr_t)(t->hdr) < m0->m_data + m0->m_len))
                        break;
        if (m0 == NULL) {
                /* ick, tag info is stale */
                return (0);
        }
 
-       switch (af) {
+       switch (t->af) {
        case AF_INET:
                if (flags & REDF_ECN4) {
-                       struct ip *ip = hdr;
+                       struct ip *ip = t->hdr;
                        u_int8_t otos;
                        int sum;
 
@@ -485,7 +474,7 @@ mark_ecn(struct mbuf *m, struct altq_pkt
 #ifdef INET6
        case AF_INET6:
                if (flags & REDF_ECN6) {
-                       struct ip6_hdr *ip6 = hdr;
+                       struct ip6_hdr *ip6 = t->hdr;
                        u_int32_t flowlabel;
 
                        flowlabel = ntohl(ip6->ip6_flow);
Index: altq/if_altq.h
===================================================================
RCS file: /cvs/src/sys/altq/if_altq.h,v
retrieving revision 1.9
diff -u -p -r1.9 if_altq.h
--- altq/if_altq.h      17 Apr 2004 00:09:00 -0000      1.9
+++ altq/if_altq.h      4 Oct 2005 13:00:28 -0000
@@ -92,16 +92,6 @@ struct altq_pktattr {
 };
 
 /*
- * mbuf tag to carry a queue id (and hints for ECN).
- */
-struct altq_tag {
-       u_int32_t       qid;            /* queue id */
-       /* hints for ecn */
-       int             af;             /* address family */
-       void            *hdr;           /* saved header position in mbuf */
-};
-
-/*
  * a token-bucket regulator limits the rate that a network driver can
  * dequeue packets from the output queue.
  * modern cards are able to buffer a large amount of packets and dequeue
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.96
diff -u -p -r1.96 if_ethersubr.c
--- net/if_ethersubr.c  8 Jun 2005 06:55:33 -0000       1.96
+++ net/if_ethersubr.c  4 Oct 2005 13:00:28 -0000
@@ -281,9 +281,14 @@ ether_output(ifp0, m0, dst, rt0)
                if (!arpresolve(ac, rt, m, dst, edst))
                        return (0);     /* if not yet resolved */
                /* If broadcasting on a simplex interface, loopback a copy */
-               if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
-                   m_tag_find(m, PACKET_TAG_PF_ROUTED, NULL) == NULL)
-                       mcopy = m_copy(m, 0, (int)M_COPYALL);
+               if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) {
+#if NPF > 0
+                       struct pf_mtag  *t;
+
+                       if ((t = pf_find_mtag(m)) == NULL || !t->routed)
+#endif
+                               mcopy = m_copy(m, 0, (int)M_COPYALL);
+               }
                etype = htons(ETHERTYPE_IP);
                break;
 #endif
Index: net/if_fddisubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_fddisubr.c,v
retrieving revision 1.46
diff -u -p -r1.46 if_fddisubr.c
--- net/if_fddisubr.c   8 Jun 2005 06:55:33 -0000       1.46
+++ net/if_fddisubr.c   4 Oct 2005 13:00:29 -0000
@@ -203,9 +203,14 @@ fddi_output(ifp0, m0, dst, rt0)
                if (!arpresolve(ac, rt, m, dst, edst))
                        return (0);     /* if not yet resolved */
                /* If broadcasting on a simplex interface, loopback a copy */
-               if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
-                   m_tag_find(m, PACKET_TAG_PF_ROUTED, NULL) == NULL)
+               if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) {
+#if NPF > 0
+                       struct pf_mtag  *t;
+
+                       if ((t = pf_find_mtag(m)) == NULL || !t->routed)
+#endif
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
+               }
                type = htons(ETHERTYPE_IP);
                break;
 #endif
Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.503
diff -u -p -r1.503 pf.c
--- net/pf.c    28 Sep 2005 01:46:32 -0000      1.503
+++ net/pf.c    4 Oct 2005 13:00:31 -0000
@@ -182,9 +182,8 @@ int                  pf_test_state_icmp(struct pf_stat
                            void *, struct pf_pdesc *, u_short *);
 int                     pf_test_state_other(struct pf_state **, int,
                            struct pfi_kif *, struct pf_pdesc *);
-struct pf_tag          *pf_get_tag(struct mbuf *);
 int                     pf_match_tag(struct mbuf *, struct pf_rule *,
-                            struct pf_tag **, int *);
+                            struct pf_mtag *, int *);
 void                    pf_hash(struct pf_addr *, struct pf_addr *,
                            struct pf_poolhashkey *, sa_family_t);
 int                     pf_map_addr(u_int8_t, struct pf_rule *,
@@ -195,9 +194,11 @@ int                         pf_get_sport(sa_family_t, 
u_int8_
                            struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
                            struct pf_src_node **);
 void                    pf_route(struct mbuf **, struct pf_rule *, int,
-                           struct ifnet *, struct pf_state *);
+                           struct ifnet *, struct pf_state *,
+                           struct pf_pdesc *);
 void                    pf_route6(struct mbuf **, struct pf_rule *, int,
-                           struct ifnet *, struct pf_state *);
+                           struct ifnet *, struct pf_state *,
+                           struct pf_pdesc *);
 int                     pf_socket_lookup(int, struct pf_pdesc *);
 u_int8_t                pf_get_wscale(struct mbuf *, int, u_int16_t,
                            sa_family_t);
@@ -211,7 +212,6 @@ int                  pf_check_proto_cksum(struct mbuf 
                            u_int8_t, sa_family_t);
 int                     pf_addr_wrap_neq(struct pf_addr_wrap *,
                            struct pf_addr_wrap *);
-static int              pf_add_mbuf_tag(struct mbuf *, u_int);
 struct pf_state                *pf_find_state_recurse(struct pfi_kif *,
                            struct pf_state_cmp *, u_int8_t);
 int                     pf_src_connlimit(struct pf_state **);
@@ -988,12 +988,13 @@ pf_src_tree_remove_state(struct pf_state
 void
 pf_unlink_state(struct pf_state *cur)
 {
-       if (cur->src.state == PF_TCPS_PROXY_DST)
+       if (cur->src.state == PF_TCPS_PROXY_DST) {
                pf_send_tcp(cur->rule.ptr, cur->af,
                    &cur->ext.addr, &cur->lan.addr,
                    cur->ext.port, cur->lan.port,
                    cur->src.seqhi, cur->src.seqlo + 1,
                    TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
+       }
        RB_REMOVE(pf_state_tree_ext_gwy,
            &cur->u.s.kif->pfik_ext_gwy, cur);
        RB_REMOVE(pf_state_tree_lan_ext,
@@ -1507,7 +1508,8 @@ pf_send_tcp(const struct pf_rule *r, sa_
        struct ip6_hdr  *h6;
 #endif /* INET6 */
        struct tcphdr   *th;
-       char *opt;
+       char            *opt;
+       struct pf_mtag  *pf_mtag;
 
        /* maximum segment size tcp option */
        tlen = sizeof(struct tcphdr);
@@ -1531,35 +1533,20 @@ pf_send_tcp(const struct pf_rule *r, sa_
        m = m_gethdr(M_DONTWAIT, MT_HEADER);
        if (m == NULL)
                return;
-       if (tag) {
-               struct m_tag    *mtag;
-
-               mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
-               if (mtag == NULL) {
-                       m_freem(m);
-                       return;
-               }
-               m_tag_prepend(m, mtag);
+       if ((pf_mtag = pf_get_mtag(m)) == NULL) {
+               m_freem(m);
+               return;
        }
-       if (rtag)
-               if (pf_tag_packet(m, NULL, rtag)) {
-                       m_freem(m);
-                       return;
-               }
+       if (tag)
+               pf_mtag->flags |= PF_TAG_GENERATED;
+       pf_mtag->tag = rtag;
+
 #ifdef ALTQ
        if (r != NULL && r->qid) {
-               struct m_tag    *mtag;
-               struct altq_tag *atag;
-
-               mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
-               if (mtag != NULL) {
-                       atag = (struct altq_tag *)(mtag + 1);
-                       atag->qid = r->qid;
-                       /* add hints for ecn */
-                       atag->af = af;
-                       atag->hdr = mtod(m, struct ip *);
-                       m_tag_prepend(m, mtag);
-               }
+               pf_mtag->qid = r->qid;
+               /* add hints for ecn */
+               pf_mtag->af = af;
+               pf_mtag->hdr = mtod(m, struct ip *);
        }
 #endif /* ALTQ */
        m->m_data += max_linkhdr;
@@ -1669,32 +1656,21 @@ void
 pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
     struct pf_rule *r)
 {
-       struct m_tag    *mtag;
+       struct pf_mtag  *pf_mtag;
        struct mbuf     *m0;
 
-       mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
-       if (mtag == NULL)
-               return;
        m0 = m_copy(m, 0, M_COPYALL);
-       if (m0 == NULL) {
-               m_tag_free(mtag);
+
+       if ((pf_mtag = pf_get_mtag(m0)) == NULL)
                return;
-       }
-       m_tag_prepend(m0, mtag);
+       pf_mtag->flags |= PF_TAG_GENERATED;
 
 #ifdef ALTQ
        if (r->qid) {
-               struct altq_tag *atag;
-
-               mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
-               if (mtag != NULL) {
-                       atag = (struct altq_tag *)(mtag + 1);
-                       atag->qid = r->qid;
-                       /* add hints for ecn */
-                       atag->af = af;
-                       atag->hdr = mtod(m0, struct ip *);
-                       m_tag_prepend(m0, mtag);
-               }
+               pf_mtag->qid = r->qid;
+               /* add hints for ecn */
+               pf_mtag->af = af;
+               pf_mtag->hdr = mtod(m0, struct ip *);
        }
 #endif /* ALTQ */
 
@@ -1809,48 +1785,55 @@ pf_match_gid(u_int8_t op, gid_t a1, gid_
        return (pf_match(op, a1, a2, g));
 }
 
-struct pf_tag *
-pf_get_tag(struct mbuf *m)
+struct pf_mtag *
+pf_find_mtag(struct mbuf *m)
 {
        struct m_tag    *mtag;
 
-       if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL)
-               return ((struct pf_tag *)(mtag + 1));
-       else
+       if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL)
                return (NULL);
+
+       return ((struct pf_mtag *)(mtag + 1));
 }
 
-int
-pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_tag **pftag, int 
*tag)
+struct pf_mtag *
+pf_get_mtag(struct mbuf *m)
 {
-       if (*tag == -1) {       /* find mbuf tag */
-               *pftag = pf_get_tag(m);
-               if (*pftag != NULL)
-                       *tag = (*pftag)->tag;
-               else
-                       *tag = 0;
+       struct m_tag    *mtag;
+
+       if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) {
+               mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag),
+                   M_NOWAIT);
+               if (mtag == NULL)
+                       return (NULL);
+               bzero(mtag + 1, sizeof(struct pf_mtag));
+               m_tag_prepend(m, mtag);
        }
 
+       return ((struct pf_mtag *)(mtag + 1));
+}
+
+int
+pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag,
+    int *tag)
+{
+       if (*tag == -1)
+               *tag = pf_mtag->tag;
+
        return ((!r->match_tag_not && r->match_tag == *tag) ||
            (r->match_tag_not && r->match_tag != *tag));
 }
 
 int
-pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag)
+pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag)
 {
-       struct m_tag    *mtag;
-
        if (tag <= 0)
                return (0);
 
-       if (pftag == NULL) {
-               mtag = m_tag_get(PACKET_TAG_PF_TAG, sizeof(*pftag), M_NOWAIT);
-               if (mtag == NULL)
+       if (pf_mtag == NULL)
+               if ((pf_mtag = pf_get_mtag(m)) == NULL)
                        return (1);
-               ((struct pf_tag *)(mtag + 1))->tag = tag;
-               m_tag_prepend(m, mtag);
-       } else
-               pftag->tag = tag;
+       pf_mtag->tag = tag;
 
        return (0);
 }
@@ -2309,7 +2292,6 @@ pf_match_translation(struct pf_pdesc *pd
 {
        struct pf_rule          *r, *rm = NULL;
        struct pf_ruleset       *ruleset = NULL;
-       struct pf_tag           *pftag = NULL;
        int                      tag = -1;
        int                      asd = 0;
 
@@ -2352,7 +2334,7 @@ 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, &pftag, &tag))
+               else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
                        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,
@@ -2369,7 +2351,7 @@ pf_match_translation(struct pf_pdesc *pd
                if (r == NULL)
                        pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, NULL);
        }
-       if (pf_tag_packet(m, pftag, tag))
+       if (pf_tag_packet(m, pd->pf_mtag, tag))
                return (NULL);
        if (rm != NULL && (rm->action == PF_NONAT ||
            rm->action == PF_NORDR || rm->action == PF_NOBINAT))
@@ -2775,7 +2757,6 @@ pf_test_tcp(struct pf_rule **rm, struct 
        struct pf_src_node      *nsn = NULL;
        u_short                  reason;
        int                      rewrite = 0;
-       struct pf_tag           *pftag = NULL;
        int                      tag = -1;
        u_int16_t                mss = tcp_mssdflt;
        int                      asd = 0;
@@ -2855,7 +2836,7 @@ pf_test_tcp(struct pf_rule **rm, struct 
                        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, &pftag, &tag))
+               else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
                        r = TAILQ_NEXT(r, entries);
                else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
                    pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
@@ -2931,7 +2912,7 @@ pf_test_tcp(struct pf_rule **rm, struct 
        if (r->action == PF_DROP)
                return (PF_DROP);
 
-       if (pf_tag_packet(m, pftag, tag)) {
+       if (pf_tag_packet(m, pd->pf_mtag, tag)) {
                REASON_SET(&reason, PFRES_MEMORY);
                return (PF_DROP);
        }
@@ -3150,7 +3131,6 @@ pf_test_udp(struct pf_rule **rm, struct 
        struct pf_src_node      *nsn = NULL;
        u_short                  reason;
        int                      rewrite = 0;
-       struct pf_tag           *pftag = NULL;
        int                      tag = -1;
        int                      asd = 0;
 
@@ -3227,7 +3207,7 @@ pf_test_udp(struct pf_rule **rm, struct 
                        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, &pftag, &tag))
+               else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
                        r = TAILQ_NEXT(r, entries);
                else if (r->os_fingerprint != PF_OSFP_ANY)
                        r = TAILQ_NEXT(r, entries);
@@ -3288,7 +3268,7 @@ pf_test_udp(struct pf_rule **rm, struct 
        if (r->action == PF_DROP)
                return (PF_DROP);
 
-       if (pf_tag_packet(m, pftag, tag)) {
+       if (pf_tag_packet(m, pd->pf_mtag, tag)) {
                REASON_SET(&reason, PFRES_MEMORY);
                return (PF_DROP);
        }
@@ -3427,7 +3407,6 @@ pf_test_icmp(struct pf_rule **rm, struct
        sa_family_t              af = pd->af;
        u_int8_t                 icmptype, icmpcode;
        int                      state_icmp = 0;
-       struct pf_tag           *pftag = NULL;
        int                      tag = -1;
 #ifdef INET6
        int                      rewrite = 0;
@@ -3553,7 +3532,7 @@ pf_test_icmp(struct pf_rule **rm, struct
                        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, &pftag, &tag))
+               else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
                        r = TAILQ_NEXT(r, entries);
                else if (r->os_fingerprint != PF_OSFP_ANY)
                        r = TAILQ_NEXT(r, entries);
@@ -3594,7 +3573,7 @@ pf_test_icmp(struct pf_rule **rm, struct
        if (r->action != PF_PASS)
                return (PF_DROP);
 
-       if (pf_tag_packet(m, pftag, tag)) {
+       if (pf_tag_packet(m, pd->pf_mtag, tag)) {
                REASON_SET(&reason, PFRES_MEMORY);
                return (PF_DROP);
        }
@@ -3730,7 +3709,6 @@ pf_test_other(struct pf_rule **rm, struc
        struct pf_addr          *saddr = pd->src, *daddr = pd->dst;
        sa_family_t              af = pd->af;
        u_short                  reason;
-       struct pf_tag           *pftag = NULL;
        int                      tag = -1;
        int                      asd = 0;
 
@@ -3807,7 +3785,7 @@ pf_test_other(struct pf_rule **rm, struc
                        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, &pftag, &tag))
+               else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
                        r = TAILQ_NEXT(r, entries);
                else if (r->os_fingerprint != PF_OSFP_ANY)
                        r = TAILQ_NEXT(r, entries);
@@ -3876,7 +3854,7 @@ pf_test_other(struct pf_rule **rm, struc
        if (r->action != PF_PASS)
                return (PF_DROP);
 
-       if (pf_tag_packet(m, pftag, tag)) {
+       if (pf_tag_packet(m, pd->pf_mtag, tag)) {
                REASON_SET(&reason, PFRES_MEMORY);
                return (PF_DROP);
        }
@@ -3994,7 +3972,6 @@ pf_test_fragment(struct pf_rule **rm, in
        struct pf_ruleset       *ruleset = NULL;
        sa_family_t              af = pd->af;
        u_short                  reason;
-       struct pf_tag           *pftag = NULL;
        int                      tag = -1;
        int                      asd = 0;
 
@@ -4021,7 +3998,7 @@ pf_test_fragment(struct pf_rule **rm, in
                        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, &pftag, &tag))
+               else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
                        r = TAILQ_NEXT(r, entries);
                else {
                        if (r->anchor == NULL) {
@@ -4052,7 +4029,7 @@ pf_test_fragment(struct pf_rule **rm, in
        if (r->action != PF_PASS)
                return (PF_DROP);
 
-       if (pf_tag_packet(m, pftag, tag)) {
+       if (pf_tag_packet(m, pd->pf_mtag, tag)) {
                REASON_SET(&reason, PFRES_MEMORY);
                return (PF_DROP);
        }
@@ -5355,7 +5332,7 @@ pf_rtlabel_match(struct pf_addr *addr, s
 #ifdef INET
 void
 pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
-    struct pf_state *s)
+    struct pf_state *s, struct pf_pdesc *pd)
 {
        struct mbuf             *m0, *m1;
        struct m_tag            *mtag;
@@ -5372,22 +5349,10 @@ pf_route(struct mbuf **m, struct pf_rule
            (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
                panic("pf_route: invalid parameters");
 
-       if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
-               if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
-                   NULL) {
-                       m0 = *m;
-                       *m = NULL;
-                       goto bad;
-               }
-               *(char *)(mtag + 1) = 1;
-               m_tag_prepend(*m, mtag);
-       } else {
-               if (*(char *)(mtag + 1) > 3) {
-                       m0 = *m;
-                       *m = NULL;
-                       goto bad;
-               }
-               (*(char *)(mtag + 1))++;
+       if (pd->pf_mtag->routed++ > 3) {
+               m0 = *m;
+               *m = NULL;
+               goto bad;
        }
 
        if (r->rt == PF_DUPTO) {
@@ -5559,10 +5524,9 @@ bad:
 #ifdef INET6
 void
 pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
-    struct pf_state *s)
+    struct pf_state *s, struct pf_pdesc *pd)
 {
        struct mbuf             *m0;
-       struct m_tag            *mtag;
        struct route_in6         ip6route;
        struct route_in6        *ro;
        struct sockaddr_in6     *dst;
@@ -5576,22 +5540,10 @@ pf_route6(struct mbuf **m, struct pf_rul
            (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
                panic("pf_route6: invalid parameters");
 
-       if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
-               if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
-                   NULL) {
-                       m0 = *m;
-                       *m = NULL;
-                       goto bad;
-               }
-               *(char *)(mtag + 1) = 1;
-               m_tag_prepend(*m, mtag);
-       } else {
-               if (*(char *)(mtag + 1) > 3) {
-                       m0 = *m;
-                       *m = NULL;
-                       goto bad;
-               }
-               (*(char *)(mtag + 1))++;
+       if (pd->pf_mtag->routed++ > 3) {
+               m0 = *m;
+               *m = NULL;
+               goto bad;
        }
 
        if (r->rt == PF_DUPTO) {
@@ -5617,12 +5569,9 @@ pf_route6(struct mbuf **m, struct pf_rul
        dst->sin6_len = sizeof(*dst);
        dst->sin6_addr = ip6->ip6_dst;
 
-       /* Cheat. */
+       /* Cheat. XXX why only in the v6 case??? */
        if (r->rt == PF_FASTROUTE) {
-               mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
-               if (mtag == NULL)
-                       goto bad;
-               m_tag_prepend(m0, mtag);
+               pd->pf_mtag->flags |= PF_TAG_GENERATED;
                ip6_output(m0, NULL, NULL, 0, NULL, NULL);
                return;
        }
@@ -5780,20 +5729,6 @@ pf_check_proto_cksum(struct mbuf *m, int
        return (0);
 }
 
-static int
-pf_add_mbuf_tag(struct mbuf *m, u_int tag)
-{
-       struct m_tag *mtag;
-
-       if (m_tag_find(m, tag, NULL) != NULL)
-               return (0);
-       mtag = m_tag_get(tag, 0, M_NOWAIT);
-       if (mtag == NULL)
-               return (1);
-       m_tag_prepend(m, mtag);
-       return (0);
-}
-
 #ifdef INET
 int
 pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
@@ -5809,8 +5744,16 @@ pf_test(int dir, struct ifnet *ifp, stru
        struct pf_pdesc          pd;
        int                      off, dirndx, pqid = 0;
 
-       if (!pf_status.running ||
-           (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL))
+       if (!pf_status.running)
+               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);
+       }
+       if (pd.pf_mtag->flags & PF_TAG_GENERATED)
                return (PF_PASS);
 
        if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
@@ -5830,7 +5773,6 @@ pf_test(int dir, struct ifnet *ifp, stru
                panic("non-M_PKTHDR is passed to pf_test");
 #endif /* DIAGNOSTIC */
 
-       memset(&pd, 0, sizeof(pd));
        if (m->m_pkthdr.len < (int)sizeof(*h)) {
                action = PF_DROP;
                REASON_SET(&reason, PFRES_SHORT);
@@ -6001,25 +5943,17 @@ done:
        }
 
        if (s && s->tag)
-               pf_tag_packet(m, pf_get_tag(m), s->tag);
+               pf_tag_packet(m, pd.pf_mtag, s->tag);
 
 #ifdef ALTQ
        if (action == PF_PASS && r->qid) {
-               struct m_tag    *mtag;
-               struct altq_tag *atag;
-
-               mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
-               if (mtag != NULL) {
-                       atag = (struct altq_tag *)(mtag + 1);
-                       if (pqid || pd.tos == IPTOS_LOWDELAY)
-                               atag->qid = r->pqid;
-                       else
-                               atag->qid = r->qid;
-                       /* add hints for ecn */
-                       atag->af = AF_INET;
-                       atag->hdr = h;
-                       m_tag_prepend(m, mtag);
-               }
+               if (pqid || pd.tos == IPTOS_LOWDELAY)
+                       pd.pf_mtag->qid = r->pqid;
+               else
+                       pd.pf_mtag->qid = r->qid;
+               /* add hints for ecn */
+               pd.pf_mtag->af = AF_INET;
+               pd.pf_mtag->hdr = h;
        }
 #endif /* ALTQ */
 
@@ -6032,11 +5966,8 @@ done:
            pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
            (s->nat_rule.ptr->action == PF_RDR ||
            s->nat_rule.ptr->action == PF_BINAT) &&
-           (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
-           pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
-               action = PF_DROP;
-               REASON_SET(&reason, PFRES_MEMORY);
-       }
+           (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+               pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST;
 
        if (log) {
                struct pf_rule *lr;
@@ -6121,7 +6052,7 @@ done:
                action = PF_PASS;
        } else if (r->rt)
                /* pf_route can free the mbuf causing *m0 to become NULL */
-               pf_route(m0, r, dir, ifp, s);
+               pf_route(m0, r, dir, ifp, s, &pd);
 
        return (action);
 }
@@ -6142,8 +6073,16 @@ pf_test6(int dir, struct ifnet *ifp, str
        struct pf_pdesc          pd;
        int                      off, terminal = 0, dirndx;
 
-       if (!pf_status.running ||
-           (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL))
+       if (!pf_status.running)
+               return (PF_PASS);
+
+       memset(&pd, 0, sizeof(pd));
+       if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
+               DPFPRINTF(PF_DEBUG_URGENT,
+                   ("pf_test6: pf_get_mtag returned NULL\n"));
+               return (PF_DROP);
+       }
+       if (pd.pf_mtag->flags & PF_TAG_GENERATED)
                return (PF_PASS);
 
        if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
@@ -6163,7 +6102,6 @@ pf_test6(int dir, struct ifnet *ifp, str
                panic("non-M_PKTHDR is passed to pf_test6");
 #endif /* DIAGNOSTIC */
 
-       memset(&pd, 0, sizeof(pd));
        if (m->m_pkthdr.len < (int)sizeof(*h)) {
                action = PF_DROP;
                REASON_SET(&reason, PFRES_SHORT);
@@ -6351,25 +6289,17 @@ done:
        /* XXX handle IPv6 options, if not allowed. not implemented. */
 
        if (s && s->tag)
-               pf_tag_packet(m, pf_get_tag(m), s->tag);
+               pf_tag_packet(m, pd.pf_mtag, s->tag);
 
 #ifdef ALTQ
        if (action == PF_PASS && r->qid) {
-               struct m_tag    *mtag;
-               struct altq_tag *atag;
-
-               mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
-               if (mtag != NULL) {
-                       atag = (struct altq_tag *)(mtag + 1);
-                       if (pd.tos == IPTOS_LOWDELAY)
-                               atag->qid = r->pqid;
-                       else
-                               atag->qid = r->qid;
-                       /* add hints for ecn */
-                       atag->af = AF_INET6;
-                       atag->hdr = h;
-                       m_tag_prepend(m, mtag);
-               }
+               if (pd.tos == IPTOS_LOWDELAY)
+                       pd.pf_mtag->qid = r->pqid;
+               else
+                       pd.pf_mtag->qid = r->qid;
+               /* add hints for ecn */
+               pd.pf_mtag->af = AF_INET6;
+               pd.pf_mtag->hdr = h;
        }
 #endif /* ALTQ */
 
@@ -6377,11 +6307,8 @@ done:
            pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
            (s->nat_rule.ptr->action == PF_RDR ||
            s->nat_rule.ptr->action == PF_BINAT) &&
-           IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) &&
-           pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
-               action = PF_DROP;
-               REASON_SET(&reason, PFRES_MEMORY);
-       }
+           IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
+               pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST;
 
        if (log) {
                struct pf_rule *lr;
@@ -6466,7 +6393,7 @@ done:
                action = PF_PASS;
        } else if (r->rt)
                /* pf_route6 can free the mbuf causing *m0 to become NULL */
-               pf_route6(m0, r, dir, ifp, s);
+               pf_route6(m0, r, dir, ifp, s, &pd);
 
        return (action);
 }
Index: net/pf_norm.c
===================================================================
RCS file: /cvs/src/sys/net/pf_norm.c,v
retrieving revision 1.102
diff -u -p -r1.102 pf_norm.c
--- net/pf_norm.c       6 Aug 2005 12:11:09 -0000       1.102
+++ net/pf_norm.c       4 Oct 2005 13:00:31 -0000
@@ -931,15 +931,13 @@ pf_normalize_ip(struct mbuf **m0, int di
                /* non-buffering fragment cache (drops or masks overlaps) */
                int     nomem = 0;
 
-               if (dir == PF_OUT) {
-                       if (m_tag_find(m, PACKET_TAG_PF_FRAGCACHE, NULL) !=
-                           NULL) {
-                               /* Already passed the fragment cache in the
-                                * input direction.  If we continued, it would
-                                * appear to be a dup and would be dropped.
-                                */
-                               goto fragment_pass;
-                       }
+               if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
+                       /*
+                        * Already passed the fragment cache in the
+                        * input direction.  If we continued, it would
+                        * appear to be a dup and would be dropped.
+                        */
+                       goto fragment_pass;
                }
 
                frag = pf_find_fragment(h, &pf_cache_tree);
@@ -960,14 +958,9 @@ pf_normalize_ip(struct mbuf **m0, int di
                        goto drop;
                }
 
-               if (dir == PF_IN) {
-                       struct m_tag    *mtag;
+               if (dir == PF_IN)
+                       pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
 
-                       mtag = m_tag_get(PACKET_TAG_PF_FRAGCACHE, 0, M_NOWAIT);
-                       if (mtag == NULL)
-                               goto no_mem;
-                       m_tag_prepend(m, mtag);
-               }
                if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
                        goto drop;
                goto fragment_pass;
Index: net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.230
diff -u -p -r1.230 pfvar.h
--- net/pfvar.h 28 Sep 2005 01:46:33 -0000      1.230
+++ net/pfvar.h 4 Oct 2005 13:00:32 -0000
@@ -936,6 +936,7 @@ struct pf_pdesc {
        struct pf_addr  *dst;
        struct ether_header
                        *eh;
+       struct pf_mtag  *pf_mtag;
        u_int16_t       *ip_sum;
        u_int32_t        p_len;         /* total length of payload */
        u_int16_t        flags;         /* Let SCRUB trigger behavior in
@@ -1139,6 +1140,19 @@ struct pf_altq {
        u_int32_t                qid;           /* return value */
 };
 
+#define        PF_TAG_GENERATED                0x01
+#define        PF_TAG_FRAGCACHE                0x02
+#define        PF_TAG_TRANSLATE_LOCALHOST      0x04
+
+struct pf_mtag {
+       void            *hdr;           /* saved hdr pos in mbuf, for ECN */
+       u_int32_t        qid;           /* queue id */
+       u_int16_t        tag;           /* tag id */
+       u_int8_t         flags;
+       u_int8_t         routed;
+       sa_family_t      af;            /* for ECN */
+};
+
 struct pf_tag {
        u_int16_t       tag;            /* tag id */
 };
@@ -1561,14 +1575,16 @@ int              pfi_get_ifaces(const char *, struc
 int             pfi_set_flags(const char *, int);
 int             pfi_clear_flags(const char *, int);
 
-u_int16_t      pf_tagname2tag(char *);
-void           pf_tag2tagname(u_int16_t, char *);
-void           pf_tag_ref(u_int16_t);
-void           pf_tag_unref(u_int16_t);
-int            pf_tag_packet(struct mbuf *, struct pf_tag *, int);
-u_int32_t      pf_qname2qid(char *);
-void           pf_qid2qname(u_int32_t, char *);
-void           pf_qid_unref(u_int32_t);
+u_int16_t       pf_tagname2tag(char *);
+void            pf_tag2tagname(u_int16_t, char *);
+void            pf_tag_ref(u_int16_t);
+void            pf_tag_unref(u_int16_t);
+int             pf_tag_packet(struct mbuf *, struct pf_mtag *, int);
+u_int32_t       pf_qname2qid(char *);
+void            pf_qid2qname(u_int32_t, char *);
+void            pf_qid_unref(u_int32_t);
+struct pf_mtag *pf_find_mtag(struct mbuf *);
+struct pf_mtag *pf_get_mtag(struct mbuf *);
 
 extern struct pf_status        pf_status;
 extern struct pool     pf_frent_pl, pf_frag_pl;

Reply via email to