8 queues, 8 priority levels, 0 - 7 (just like basically any better
switch, the vlan header, ...) always, unconditional. pf is being used
as classifier, like
  pass in proto tcp to port 22 prio 6
and the old trick of a second queue or rather prio level for empty
acks and IPTOS_LOWDELAY is still there, aka
  pass in proto tcp to port 22 prio (5, 6)

now having this next to altq is a bit weird, but this is the only way
we see to move forward. for interfaces where you enable altq the prios
are silently reset so that this doens;t interfere with altq.

the current 5-year-plan sez:
-the "altq on $foo bandwidth $bar" which limits a given interface's
 bandwidth has no place in pf. that is an interface property. so
 that'll become something like "ifconfig $foo bwlimit $bar" or the like.
-bandwidth shaping, some open questions there, but that is supposed to
 come back in an easier to use and less intrusive in sys/ (ESPECIALLY
 if.h. ugh.) as well. that is going to be kenjiro's hfsc that we
 already have in altq/, the glue needs to be re-done. no more
 pluggable disciplines, less indirections, hopefully some speed gains.
 once that is all cleaned up there might be some new cool things
 possible, but that is really blue sky talk and irrelevant for a long
 time, we first need to provide sth equivalent-enough to the current
 cbq/hfsc (cbq can be expressed in hfsc, so it goes away, internally. we
 don't want "hfsc" or "cbq" to be user-visible at all, it is just
 bandwidth shaping, queueing, you name it. the internals are that: internals.)
-once these two - of which the bandwidth shaper is the really hard
 part - are done, we remove the current altq stuff.

and yeah, we wanna priorize a couple of things by default later on.
like carp.

Index: sys/altq/if_altq.h
===================================================================
RCS file: /cvs/src/sys/altq/if_altq.h,v
retrieving revision 1.13
diff -u -p -r1.13 if_altq.h
--- sys/altq/if_altq.h  3 Jul 2011 22:39:12 -0000       1.13
+++ sys/altq/if_altq.h  7 Jul 2011 01:24:34 -0000
@@ -31,13 +31,17 @@
 
 struct altq_pktattr; struct tb_regulator;
 
+#define ALTQ_IFQ_NQUEUES       8
+
 /*
  * Structure defining a queue for a network interface.
  */
 struct ifaltq {
        /* fields compatible with struct ifqueue */
-       struct  mbuf *ifq_head;
-       struct  mbuf *ifq_tail;
+       struct {
+               struct  mbuf *head;
+               struct  mbuf *tail;
+       }       ifq_q[ALTQ_IFQ_NQUEUES];
        int     ifq_len;
        int     ifq_maxlen;
        int     ifq_drops;
@@ -61,7 +65,6 @@ struct        ifaltq {
        /* token bucket regulator */
        struct  tb_regulator *altq_tbr;
 };
-
 
 #ifdef _KERNEL
 
Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.159
diff -u -p -r1.159 uipc_mbuf.c
--- sys/kern/uipc_mbuf.c        5 Jul 2011 05:53:17 -0000       1.159
+++ sys/kern/uipc_mbuf.c        7 Jul 2011 01:24:35 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_mbuf.c,v 1.159 2011/07/05 05:53:17 claudio Exp $ */
+/*     $OpenBSD: uipc_mbuf.c,v 1.157 2011/05/04 16:05:49 blambert Exp $        
*/
 /*     $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $   */
 
 /*
@@ -246,6 +246,7 @@ m_gethdr(int nowait, int type)
                m->m_data = m->m_pktdat;
                m->m_flags = M_PKTHDR;
                bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
+               m->m_pkthdr.pf.prio = IFQ_DEFPRIO;
        }
        return (m);
 }
@@ -259,6 +260,7 @@ m_inithdr(struct mbuf *m)
        m->m_data = m->m_pktdat;
        m->m_flags = M_PKTHDR;
        bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
+       m->m_pkthdr.pf.prio = IFQ_DEFPRIO;
 
        return (m);
 }
@@ -1352,6 +1354,8 @@ m_print(void *v, int (*pr)(const char *,
                    m->m_pkthdr.pf.hdr, m->m_pkthdr.pf.statekey);
                (*pr)("m_pkthdr.pf.qid:\t%u m_pkthdr.pf.tag: %hu\n",
                    m->m_pkthdr.pf.qid, m->m_pkthdr.pf.tag);
+               (*pr)("m_pkthdr.pf.prio:\t%u m_pkthdr.pf.tag: %hu\n",
+                   m->m_pkthdr.pf.prio, m->m_pkthdr.pf.tag);
                (*pr)("m_pkthdr.pf.routed: %hhx\n", m->m_pkthdr.pf.routed);
        }
        if (m->m_flags & M_EXT) {
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.237
diff -u -p -r1.237 if.c
--- sys/net/if.c        6 Jul 2011 02:42:28 -0000       1.237
+++ sys/net/if.c        7 Jul 2011 01:24:36 -0000
@@ -652,33 +652,35 @@ do { \
 void
 if_detach_queues(struct ifnet *ifp, struct ifqueue *q)
 {
-       struct mbuf *m, *prev, *next;
+       struct mbuf *m, *prev = NULL, *next;
+       u_int8_t prio = IFQ_MAXPRIO;
 
-       prev = NULL;
-       for (m = q->ifq_head; m; m = next) {
-               next = m->m_nextpkt;
+       for (; prio > 0; prio--) {
+               for (m = q->ifq_q[prio - 1].head; m; m = next) {
+                       next = m->m_nextpkt;
 #ifdef DIAGNOSTIC
-               if ((m->m_flags & M_PKTHDR) == 0) {
-                       prev = m;
-                       continue;
-               }
+                       if ((m->m_flags & M_PKTHDR) == 0) {
+                               prev = m;
+                               continue;
+                       }
 #endif
-               if (m->m_pkthdr.rcvif != ifp) {
-                       prev = m;
-                       continue;
-               }
+                       if (m->m_pkthdr.rcvif != ifp) {
+                               prev = m;
+                               continue;
+                       }
 
-               if (prev)
-                       prev->m_nextpkt = m->m_nextpkt;
-               else
-                       q->ifq_head = m->m_nextpkt;
-               if (q->ifq_tail == m)
-                       q->ifq_tail = prev;
-               q->ifq_len--;
+                       if (prev)
+                               prev->m_nextpkt = m->m_nextpkt;
+                       else
+                               q->ifq_q[prio - 1].head = m->m_nextpkt;
+                       if (q->ifq_q[prio - 1].tail == m)
+                               q->ifq_q[prio - 1].tail = prev;
+                       q->ifq_len--;
 
-               m->m_nextpkt = NULL;
-               m_freem(m);
-               IF_DROP(q);
+                       m->m_nextpkt = NULL;
+                       m_freem(m);
+                       IF_DROP(q);
+               }
        }
 }
 
Index: sys/net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.126
diff -u -p -r1.126 if.h
--- sys/net/if.h        5 Jul 2011 00:58:27 -0000       1.126
+++ sys/net/if.h        7 Jul 2011 01:24:36 -0000
@@ -44,6 +44,7 @@
  * the size of struct ifnet does not changed based on the option.  The
  * ALTQ queue structure is API-compatible with the legacy ifqueue.
  */
+
 #include <altq/if_altq.h>
 
 /*
@@ -80,6 +81,7 @@ struct socket;
 struct ether_header;
 struct arpcom;
 struct rt_addrinfo;
+struct ifnet;
 
 /*
  * Structure describing a `cloning' interface.
@@ -146,13 +148,19 @@ struct    if_data {
        struct mclpool  ifi_mclpool[MCLPOOLS];
 };
 
+#define IFQ_NQUEUES    ALTQ_IFQ_NQUEUES
+#define IFQ_MAXPRIO    IFQ_NQUEUES - 1
+#define IFQ_DEFPRIO    3
+
 /*
  * Structure defining a queue for a network interface.
  * XXX keep in sync with struct ifaltq.
  */
 struct ifqueue {
-       struct  mbuf *ifq_head;
-       struct  mbuf *ifq_tail;
+       struct {
+               struct  mbuf *head;
+               struct  mbuf *tail;
+       }       ifq_q[IFQ_NQUEUES];
        int     ifq_len;
        int     ifq_maxlen;
        int     ifq_drops;
@@ -367,31 +375,44 @@ struct ifnet {                            /* and the 
entries */
 #define        IF_DROP(ifq)            ((ifq)->ifq_drops++)
 #define        IF_ENQUEUE(ifq, m)                                              
\
 do {                                                                   \
-       (m)->m_nextpkt = 0;                                             \
-       if ((ifq)->ifq_tail == 0)                                       \
-               (ifq)->ifq_head = m;                                    \
+       (m)->m_nextpkt = NULL;                                          \
+       if ((ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail == NULL)           \
+               (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head = m;           \
        else                                                            \
-               (ifq)->ifq_tail->m_nextpkt = m;                         \
-       (ifq)->ifq_tail = m;                                            \
+               (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail->m_nextpkt = m; \
+       (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail = m;                   \
        (ifq)->ifq_len++;                                               \
 } while (/* CONSTCOND */0)
 #define        IF_PREPEND(ifq, m)                                              
\
 do {                                                                   \
-       (m)->m_nextpkt = (ifq)->ifq_head;                               \
-       if ((ifq)->ifq_tail == 0)                                       \
-               (ifq)->ifq_tail = (m);                                  \
-       (ifq)->ifq_head = (m);                                          \
+       (m)->m_nextpkt = (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head;      \
+       if ((ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail == NULL)           \
+               (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail = (m);         \
+       (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head = (m);                 \
        (ifq)->ifq_len++;                                               \
 } while (/* CONSTCOND */0)
+
+#define        IF_POLL(ifq, m)                                                 
\
+do {                                                                   \
+       int     if_dequeue_prio = IFQ_MAXPRIO;                          \
+       do {                                                            \
+               (m) = (ifq)->ifq_q[if_dequeue_prio].head;               \
+       } while (!(m) && --if_dequeue_prio >= 0);                       \
+} while (/* CONSTCOND */0)
+
 #define        IF_DEQUEUE(ifq, m)                                              
\
 do {                                                                   \
-       (m) = (ifq)->ifq_head;                                          \
-       if (m) {                                                        \
-               if (((ifq)->ifq_head = (m)->m_nextpkt) == 0)            \
-                       (ifq)->ifq_tail = 0;                            \
-               (m)->m_nextpkt = 0;                                     \
-               (ifq)->ifq_len--;                                       \
-       }                                                               \
+       int     if_dequeue_prio = IFQ_MAXPRIO;                          \
+       do {                                                            \
+               (m) = (ifq)->ifq_q[if_dequeue_prio].head;               \
+               if (m) {                                                \
+                       if (((ifq)->ifq_q[if_dequeue_prio].head =       \
+                           (m)->m_nextpkt) == NULL)                    \
+                               (ifq)->ifq_q[if_dequeue_prio].tail = NULL; \
+                       (m)->m_nextpkt = NULL;                          \
+                       (ifq)->ifq_len--;                               \
+               }                                                       \
+       } while (!(m) && --if_dequeue_prio >= 0);                       \
 } while (/* CONSTCOND */0)
 
 #define        IF_INPUT_ENQUEUE(ifq, m)                                        
\
@@ -405,7 +426,6 @@ do {                                                        
                \
                IF_ENQUEUE(ifq, m);                                     \
 } while (/* CONSTCOND */0)
 
-#define        IF_POLL(ifq, m)         ((m) = (ifq)->ifq_head)
 #define        IF_PURGE(ifq)                                                   
\
 do {                                                                   \
        struct mbuf *__m0;                                              \
@@ -686,9 +706,10 @@ do { \
 
 #define        IFQ_ENQUEUE(ifq, m, pattr, err)                                 
\
 do {                                                                   \
-       if (ALTQ_IS_ENABLED((ifq)))                                     \
+       if (ALTQ_IS_ENABLED((ifq))) {                                   \
+               m->m_pkthdr.pf.prio = IFQ_MAXPRIO;                      \
                ALTQ_ENQUEUE((ifq), (m), (pattr), (err));               \
-       else {                                                          \
+       } else {                                                        \
                if (IF_QFULL((ifq))) {                                  \
                        m_freem((m));                                   \
                        (err) = ENOBUFS;                                \
Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.761
diff -u -p -r1.761 pf.c
--- sys/net/pf.c        7 Jul 2011 00:47:18 -0000       1.761
+++ sys/net/pf.c        7 Jul 2011 01:24:36 -0000
@@ -1969,6 +1969,8 @@ pf_send_tcp(const struct pf_rule *r, sa_
                m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
        m->m_pkthdr.pf.tag = rtag;
        m->m_pkthdr.rdomain = rdom;
+       if (r && r->prio[0] != PF_PRIO_NOTSET)
+               m->m_pkthdr.pf.prio = r->prio[0];
 
 #ifdef ALTQ
        if (r != NULL && r->qid) {
@@ -2091,6 +2093,8 @@ pf_send_icmp(struct mbuf *m, u_int8_t ty
 
        m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
        m0->m_pkthdr.rdomain = rdomain;
+       if (r && r->prio[0] != PF_PRIO_NOTSET)
+               m0->m_pkthdr.pf.prio = r->prio[0];
 
 #ifdef ALTQ
        if (r->qid) {
@@ -2713,6 +2717,10 @@ pf_rule_to_actions(struct pf_rule *r, st
                a->max_mss = r->max_mss;
        a->flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
            PFSTATE_SETTOS|PFSTATE_SCRUB_TCP));
+       if (r->prio[0] != PF_PRIO_NOTSET)
+               a->prio[0] = r->prio[0];
+       if (r->prio[1] != PF_PRIO_NOTSET)
+               a->prio[1] = r->prio[1];
 }
 
 #define PF_TEST_ATTRIB(t, a)                   \
@@ -2755,6 +2763,7 @@ pf_test_rule(struct pf_rule **rm, struct
        PF_ACPY(&pd->ndaddr, pd->dst, pd->af);
 
        bzero(&act, sizeof(act));
+       act.prio[0] = act.prio[1] = PF_PRIO_NOTSET;
        bzero(sns, sizeof(sns));
        act.rtableid = pd->rdomain;
        SLIST_INIT(&rules);
@@ -3154,6 +3163,8 @@ pf_create_state(struct pf_rule *r, struc
        s->max_mss = act->max_mss;
        s->state_flags |= act->flags;
        s->sync_state = PFSYNC_S_NONE;
+       s->prio[0] = act->prio[0];
+       s->prio[1] = act->prio[1];
        switch (pd->proto) {
        case IPPROTO_TCP:
                s->src.seqlo = ntohl(th->th_seq);
@@ -5934,17 +5945,27 @@ done:
                        pf_scrub(m, s->state_flags, pd.af, s->min_ttl,
                            s->set_tos);
                        pf_tag_packet(m, s->tag, s->rtableid[pd.didx]);
-                       if (pqid || (pd.tos & IPTOS_LOWDELAY))
+                       if (pqid || (pd.tos & IPTOS_LOWDELAY)) {
                                qid = s->pqid;
-                       else
+                               if (s->prio[1] != PF_PRIO_NOTSET)
+                                        m->m_pkthdr.pf.prio = s->prio[1];
+                       } else {
                                qid = s->qid;
+                               if (s->prio[0] != PF_PRIO_NOTSET)
+                                        m->m_pkthdr.pf.prio = s->prio[0];
+                       }
                } else {
                        pf_scrub(m, r->scrub_flags, pd.af, r->min_ttl,
                            r->set_tos);
-                       if (pqid || (pd.tos & IPTOS_LOWDELAY))
+                       if (pqid || (pd.tos & IPTOS_LOWDELAY)) {
                                qid = r->pqid;
-                       else
+                               if (r->prio[1] != PF_PRIO_NOTSET)
+                                        m->m_pkthdr.pf.prio = r->prio[1];
+                       } else {
                                qid = r->qid;
+                               if (r->prio[0] != PF_PRIO_NOTSET)
+                                        m->m_pkthdr.pf.prio = r->prio[0];
+                       }
                }
        }
 
Index: sys/net/pf_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.240
diff -u -p -r1.240 pf_ioctl.c
--- sys/net/pf_ioctl.c  2 Jun 2011 22:03:30 -0000       1.240
+++ sys/net/pf_ioctl.c  7 Jul 2011 01:24:36 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pf_ioctl.c,v 1.240 2011/06/02 22:03:30 sthen Exp $ */
+/*     $OpenBSD: pf_ioctl.c,v 1.239 2011/04/19 21:58:03 chl Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -1067,6 +1067,10 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                        error = EINVAL;
                if (rule->rt && !rule->direction)
                        error = EINVAL;
+               if ((rule->prio[0] != PF_PRIO_NOTSET && rule->prio[0] >
+                   IFQ_MAXPRIO) || (rule->prio[1] != PF_PRIO_NOTSET &&
+                    rule->prio[1] > IFQ_MAXPRIO))
+                       error = EINVAL;
 
                if (error) {
                        pf_rm_rule(NULL, rule);
@@ -2595,6 +2599,8 @@ pf_rule_copyin(struct pf_rule *from, str
        to->divert.port = from->divert.port;
        to->divert_packet.addr = from->divert_packet.addr;
        to->divert_packet.port = from->divert_packet.port;
+       to->prio[0] = from->prio[0];
+       to->prio[1] = from->prio[1];
 
        return (0);
 }
Index: sys/net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.338
diff -u -p -r1.338 pfvar.h
--- sys/net/pfvar.h     7 Jul 2011 00:47:19 -0000       1.338
+++ sys/net/pfvar.h     7 Jul 2011 01:24:36 -0000
@@ -525,11 +525,12 @@ struct pf_rule_actions {
        u_int16_t       qid;
        u_int16_t       pqid;
        u_int16_t       max_mss;
+       u_int16_t       flags;
        u_int8_t        log;
        u_int8_t        set_tos;
        u_int8_t        min_ttl;
-       u_int8_t        pad[1];
-       u_int16_t       flags;
+       u_int8_t        prio[2];
+       u_int8_t        pad[3];
 };
 
 union pf_rule_ptr {
@@ -645,7 +646,9 @@ struct pf_rule {
 #define PF_FLUSH               0x01
 #define PF_FLUSH_GLOBAL                0x02
        u_int8_t                 flush;
-       u_int8_t                 pad2[3];
+#define PF_PRIO_NOTSET         0xff
+       u_int8_t                 prio[2];
+       u_int8_t                 pad;
 
        struct {
                struct pf_addr          addr;
@@ -840,6 +843,8 @@ struct pf_state {
        u_int8_t                 min_ttl;
        u_int8_t                 set_tos;
        u_int16_t                max_mss;
+       u_int8_t                 prio[2];
+       u_int8_t                 pad2[2];
 };
 
 /*
Index: sys/sys/mbuf.h
===================================================================
RCS file: /cvs/src/sys/sys/mbuf.h,v
retrieving revision 1.154
diff -u -p -r1.154 mbuf.h
--- sys/sys/mbuf.h      17 Jun 2011 23:45:19 -0000      1.154
+++ sys/sys/mbuf.h      7 Jul 2011 01:24:36 -0000
@@ -82,6 +82,8 @@ struct pkthdr_pf {
        u_int16_t        tag;           /* tag id */
        u_int8_t         flags;
        u_int8_t         routed;
+       u_int8_t         prio;
+       u_int8_t         pad[3];
 };
 
 /* pkthdr_pf.flags */
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.603
diff -u -p -r1.603 parse.y
--- sbin/pfctl/parse.y  7 Jul 2011 00:47:19 -0000       1.603
+++ sbin/pfctl/parse.y  7 Jul 2011 02:06:04 -0000
@@ -230,6 +230,7 @@ struct filter_opts {
 #define FOM_MAXMSS     0x0040
 #define FOM_SETTOS     0x0100
 #define FOM_SCRUB_TCP  0x0200
+#define FOM_PRIO       0x0400
        struct node_uid         *uid;
        struct node_gid         *gid;
        struct node_if          *rcv;
@@ -254,6 +255,7 @@ struct filter_opts {
        char                    *match_tag;
        u_int8_t                 match_tag_not;
        u_int                    rtableid;
+       u_int8_t                 prio[2];
        struct {
                struct node_host        *addr;
                u_int16_t               port;
@@ -451,7 +453,7 @@ int parseport(char *, struct range *r, i
 %token BITMASK RANDOM SOURCEHASH ROUNDROBIN LEASTSTATES STATICPORT PROBABILITY
 %token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT
 %token QUEUE PRIORITY QLIMIT RTABLE RDOMAIN
-%token LOAD RULESET_OPTIMIZATION
+%token LOAD RULESET_OPTIMIZATION RTABLE RDOMAIN PRIO
 %token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
 %token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
 %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
@@ -466,7 +468,7 @@ int parseport(char *, struct range *r, i
 %type  <v.i>                   dir af optimizer
 %type  <v.i>                   sourcetrack flush unaryop statelock
 %type  <v.b>                   action
-%type  <v.b>                   flags flag blockspec
+%type  <v.b>                   flags flag blockspec prio
 %type  <v.range>               portplain portstar portrange
 %type  <v.hashkey>             hashkey
 %type  <v.proto>               proto proto_list proto_item
@@ -870,6 +872,11 @@ anchorrule : ANCHOR anchorname dir quick
                                        YYERROR;
                                }
                        r.match_tag_not = $9.match_tag_not;
+                       if ($9.marker & FOM_PRIO) {
+                               r.prio[0] = $9.prio[0];
+                               r.prio[1] = $9.prio[1];
+                       } else
+                               r.prio[0] = r.prio[1] = PF_PRIO_NOTSET;
 
                        decide_address_family($8.src.host, &r.af);
                        decide_address_family($8.dst.host, &r.af);
@@ -1665,6 +1672,11 @@ pfrule           : action dir logquick interface 
                        }
                        if ($8.marker & FOM_SCRUB_TCP)
                                r.scrub_flags |= PFSTATE_SCRUB_TCP;
+                       if ($8.marker & FOM_PRIO) {
+                               r.prio[0] = $8.prio[0];
+                               r.prio[1] = $8.prio[1];
+                       } else
+                               r.prio[0] = r.prio[1] = PF_PRIO_NOTSET;
 
                        r.af = $5;
                        if ($8.tag)
@@ -2266,6 +2278,32 @@ filter_opt       : USER uids {
                        }
                        filter_opts.rcv = $2;
                }
+               | prio {
+                       if (filter_opts.marker & FOM_PRIO) {
+                               yyerror("prio cannot be redefined");
+                               YYERROR;
+                       }
+                       filter_opts.marker |= FOM_PRIO;
+                       filter_opts.prio[0] = $1.b1;
+                       filter_opts.prio[1] = $1.b2;
+               }
+               ;
+
+prio           : PRIO NUMBER {
+                       if ($2 > IFQ_MAXPRIO) {
+                               yyerror("prio too big: max %u", IFQ_MAXPRIO);
+                               YYERROR;
+                       }
+                       $$.b1 = $$.b2 = $2;
+               }
+               | PRIO '(' NUMBER comma NUMBER ')' {
+                       if ($3 > IFQ_MAXPRIO || $5 > IFQ_MAXPRIO) {
+                               yyerror("prio too big: max %u", IFQ_MAXPRIO);
+                               YYERROR;
+                       }
+                       $$.b1 = $3;
+                       $$.b2 = $5;
+               }
                ;
 
 probability    : STRING                                {
@@ -5046,6 +5084,7 @@ lookup(char *s)
                { "pass",               PASS},
                { "pflow",              PFLOW},
                { "port",               PORT},
+               { "prio",               PRIO},
                { "priority",           PRIORITY},
                { "priq",               PRIQ},
                { "probability",        PROBABILITY},
Index: sbin/pfctl/pfctl_parser.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.276
diff -u -p -r1.276 pfctl_parser.c
--- sbin/pfctl/pfctl_parser.c   3 Jul 2011 23:37:55 -0000       1.276
+++ sbin/pfctl/pfctl_parser.c   7 Jul 2011 02:06:04 -0000
@@ -1068,6 +1068,12 @@ print_rule(struct pf_rule *r, const char
                printf(" ");
                print_pool(&r->route, 0, 0, r->af, PF_POOL_ROUTE, verbose);
        }
+       if (r->prio[0] != PF_PRIO_NOTSET) {
+               if (r->prio[0] == r->prio[1])
+                       printf(" prio %u", r->prio[0]);
+               else
+                       printf(" prio(%u, %u)", r->prio[0], r->prio[1]);
+       }
 }
 
 void

Reply via email to