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