summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhenning <henning@openbsd.org>2013-10-12 12:13:10 +0000
committerhenning <henning@openbsd.org>2013-10-12 12:13:10 +0000
commit6568394152b0023134f4de3cd6ba28f486b45952 (patch)
tree8b0aed2594daac7f687cbc2592c4cfd55d1c2e8d
parenthook in hfsc.c/h (diff)
downloadwireguard-openbsd-6568394152b0023134f4de3cd6ba28f486b45952.tar.xz
wireguard-openbsd-6568394152b0023134f4de3cd6ba28f486b45952.zip
new bandwidth shaping subsystem, kernel side
uses hfsc behind the scenes; altq stays in parallel for a migration phase. if.h even more messy for the transition, but eventuelly it should become readable... looked over & tested by many, ok phessler sthen
-rw-r--r--sys/altq/if_altq.h5
-rw-r--r--sys/net/if.h100
-rw-r--r--sys/net/pf.c9
-rw-r--r--sys/net/pf_ioctl.c252
-rw-r--r--sys/net/pfvar.h58
5 files changed, 369 insertions, 55 deletions
diff --git a/sys/altq/if_altq.h b/sys/altq/if_altq.h
index 2570d841c00..fa6d95d735e 100644
--- a/sys/altq/if_altq.h
+++ b/sys/altq/if_altq.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_altq.h,v 1.15 2011/10/07 17:10:08 henning Exp $ */
+/* $OpenBSD: if_altq.h,v 1.16 2013/10/12 12:13:10 henning Exp $ */
/* $KAME: if_altq.h,v 1.6 2001/01/29 19:59:09 itojun Exp $ */
/*
@@ -29,7 +29,7 @@
#ifndef _ALTQ_IF_ALTQ_H_
#define _ALTQ_IF_ALTQ_H_
-struct altq_pktattr; struct tb_regulator;
+struct altq_pktattr; struct oldtb_regulator; struct hfsc_if;
#define ALTQ_IFQ_NQUEUES 8
@@ -45,6 +45,7 @@ struct ifaltq {
int ifq_len;
int ifq_maxlen;
int ifq_drops;
+ struct hfsc_if *ifq_hfsc;
struct timeout *ifq_congestion;
/* alternate queueing related fields */
diff --git a/sys/net/if.h b/sys/net/if.h
index a6d15726ed7..a95ef74c2b1 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -1,7 +1,8 @@
-/* $OpenBSD: if.h,v 1.146 2013/09/17 13:34:17 mpi Exp $ */
+/* $OpenBSD: if.h,v 1.147 2013/10/12 12:13:10 henning Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
+ * Copyright (c) 2012-2013 Henning Brauer <henning@openbsd.org>
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -61,14 +62,8 @@ __END_DECLS
#include <sys/queue.h>
#include <sys/tree.h>
-
-/*
- * Always include ALTQ glue here -- we use the ALTQ interface queue
- * structure even when ALTQ is not configured into the kernel so that
- * 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>
+#include <net/hfsc.h>
/*
* Structures defining a network interface, providing a packet
@@ -105,6 +100,7 @@ struct ether_header;
struct arpcom;
struct rt_addrinfo;
struct ifnet;
+struct hfsc_if;
struct ifvlan;
/*
@@ -173,7 +169,7 @@ struct if_data {
struct mclpool ifi_mclpool[MCLPOOLS];
};
-#define IFQ_NQUEUES ALTQ_IFQ_NQUEUES
+#define IFQ_NQUEUES 8
#define IFQ_MAXPRIO IFQ_NQUEUES - 1
#define IFQ_DEFPRIO 3
@@ -185,11 +181,12 @@ struct ifqueue {
struct {
struct mbuf *head;
struct mbuf *tail;
- } ifq_q[IFQ_NQUEUES];
- int ifq_len;
- int ifq_maxlen;
- int ifq_drops;
- struct timeout *ifq_congestion;
+ } ifq_q[IFQ_NQUEUES];
+ int ifq_len;
+ int ifq_maxlen;
+ int ifq_drops;
+ struct hfsc_if *ifq_hfsc;
+ struct timeout *ifq_congestion;
};
/*
@@ -709,11 +706,25 @@ struct if_laddrreq {
#include <net/if_arp.h>
#ifdef _KERNEL
+#define IFAFREE(ifa) \
+do { \
+ if ((ifa)->ifa_refcnt <= 0) \
+ ifafree(ifa); \
+ else \
+ (ifa)->ifa_refcnt--; \
+} while (/* CONSTCOND */0)
+
+/* XXX the IFQ_ macros are a giant mess right now. cleanup once altq gone. */
+
#ifdef ALTQ
+/* XXX pattr unused */
+/* if_snd becomes ifqueue when altq is gone and the casts go away */
#define IFQ_ENQUEUE(ifq, m, pattr, err) \
do { \
- if (ALTQ_IS_ENABLED((ifq))) { \
+ if (HFSC_ENABLED((ifq))) \
+ (err) = hfsc_enqueue(((struct ifqueue *)(ifq)), (m)); \
+ else if (ALTQ_IS_ENABLED((ifq))) { \
m->m_pkthdr.pf.prio = IFQ_MAXPRIO; \
ALTQ_ENQUEUE((ifq), (m), (pattr), (err)); \
} else { \
@@ -731,8 +742,10 @@ do { \
#define IFQ_DEQUEUE(ifq, m) \
do { \
- if (OLDTBR_IS_ENABLED((ifq))) \
- (m) = oldtbr_dequeue((ifq), ALTDQ_REMOVE); \
+ if (HFSC_ENABLED((ifq))) \
+ (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 1); \
+ else if (OLDTBR_IS_ENABLED((ifq))) \
+ (m) = oldtbr_dequeue((ifq), ALTDQ_REMOVE); \
else if (ALTQ_IS_ENABLED((ifq))) \
ALTQ_DEQUEUE((ifq), (m)); \
else \
@@ -741,8 +754,10 @@ do { \
#define IFQ_POLL(ifq, m) \
do { \
- if (TBR_IS_ENABLED((ifq))) \
- (m) = oldtbr_dequeue((ifq), ALTDQ_POLL); \
+ if (HFSC_ENABLED((ifq))) \
+ (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 0); \
+ else if (OLDTBR_IS_ENABLED((ifq))) \
+ (m) = oldtbr_dequeue((ifq), ALTDQ_POLL); \
else if (ALTQ_IS_ENABLED((ifq))) \
ALTQ_POLL((ifq), (m)); \
else \
@@ -751,8 +766,10 @@ do { \
#define IFQ_PURGE(ifq) \
do { \
- if (ALTQ_IS_ENABLED((ifq))) \
- ALTQ_PURGE((ifq)); \
+ if (HFSC_ENABLED((ifq))) \
+ hfsc_purge(((struct ifqueue *)(ifq))); \
+ else if (ALTQ_IS_ENABLED((ifq))) \
+ ALTQ_PURGE(ifq); \
else \
IF_PURGE((ifq)); \
} while (/* CONSTCOND */0)
@@ -764,24 +781,47 @@ do { \
#else /* !ALTQ */
+/* XXX pattr unused */
#define IFQ_ENQUEUE(ifq, m, pattr, err) \
do { \
- if (IF_QFULL((ifq))) { \
- m_freem((m)); \
- (err) = ENOBUFS; \
- } else { \
- IF_ENQUEUE((ifq), (m)); \
- (err) = 0; \
+ if (HFSC_ENABLED(ifq)) \
+ (err) = hfsc_enqueue(((struct ifqueue *)(ifq)), m); \
+ else { \
+ if (IF_QFULL((ifq))) { \
+ m_freem((m)); \
+ (err) = ENOBUFS; \
+ } else { \
+ IF_ENQUEUE((ifq), (m)); \
+ (err) = 0; \
+ } \
} \
if ((err)) \
(ifq)->ifq_drops++; \
} while (/* CONSTCOND */0)
-#define IFQ_DEQUEUE(ifq, m) IF_DEQUEUE((ifq), (m))
+#define IFQ_DEQUEUE(ifq, m) \
+do { \
+ if (HFSC_ENABLED((ifq))) \
+ (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 1); \
+ else \
+ IF_DEQUEUE((ifq), (m)); \
+} while (/* CONSTCOND */0)
-#define IFQ_POLL(ifq, m) IF_POLL((ifq), (m))
+#define IFQ_POLL(ifq, m) \
+do { \
+ if (HFSC_ENABLED((ifq))) \
+ (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 0); \
+ else \
+ IF_POLL((ifq), (m)); \
+} while (/* CONSTCOND */0)
-#define IFQ_PURGE(ifq) IF_PURGE((ifq))
+#define IFQ_PURGE(ifq) \
+do { \
+ if (HFSC_ENABLED((ifq))) \
+ hfsc_purge(((struct ifqueue *)(ifq))); \
+ else \
+ IF_PURGE((ifq)); \
+} while (/* CONSTCOND */0)
#define IFQ_SET_READY(ifq) /* nothing */
diff --git a/sys/net/pf.c b/sys/net/pf.c
index eed83413c25..e6cbaa3c8cf 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: pf.c,v 1.842 2013/10/11 10:58:42 gerhard Exp $ */
+/* $OpenBSD: pf.c,v 1.843 2013/10/12 12:13:10 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002 - 2012 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -100,6 +100,9 @@
* Global variables
*/
struct pf_state_tree pf_statetbl;
+struct pf_queuehead pf_queues[2];
+struct pf_queuehead *pf_queues_active;
+struct pf_queuehead *pf_queues_inactive;
struct pf_altqqueue pf_altqs[2];
struct pf_altqqueue *pf_altqs_active;
@@ -138,7 +141,7 @@ union pf_headers {
};
-struct pool pf_src_tree_pl, pf_rule_pl;
+struct pool pf_src_tree_pl, pf_rule_pl, pf_queue_pl;
struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl;
struct pool pf_altq_pl, pf_rule_item_pl, pf_sn_item_pl;
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index e05d88e3bf3..a0536000372 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: pf_ioctl.c,v 1.260 2013/10/12 11:55:45 henning Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.261 2013/10/12 12:13:11 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002,2003 Henning Brauer
+ * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -101,6 +101,10 @@ int pf_disable_altq(struct pf_altq *);
#endif /* ALTQ */
int pf_begin_rules(u_int32_t *, const char *);
int pf_rollback_rules(u_int32_t, char *);
+int pf_free_queues(char *);
+int pf_remove_queues(void);
+int pf_create_queues(void);
+int pf_commit_queues(char *);
int pf_setup_pfsync_matching(struct pf_ruleset *);
void pf_hash_rule(MD5_CTX *, struct pf_rule *);
void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
@@ -116,6 +120,9 @@ int pf_rule_copyin(struct pf_rule *, struct pf_rule *,
u_int32_t pf_oqname2qid(char *);
void pf_oqid2qname(u_int32_t, char *);
void pf_oqid_unref(u_int32_t);
+u_int16_t pf_qname2qid(char *, int);
+void pf_qid2qname(u_int16_t, char *);
+void pf_qid_unref(u_int16_t);
struct pf_rule pf_default_rule, pf_default_rule_new;
struct rwlock pf_consistency_lock = RWLOCK_INITIALIZER("pfcnslk");
@@ -138,7 +145,8 @@ struct {
#define TAGID_MAX 50000
TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
- pf_oqids = TAILQ_HEAD_INITIALIZER(pf_oqids);
+ pf_oqids = TAILQ_HEAD_INITIALIZER(pf_oqids),
+ pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
@@ -172,6 +180,8 @@ pfattach(int num)
"pfruleitempl", NULL);
pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
&pool_allocator_nointr);
+ pool_init(&pf_queue_pl, sizeof(struct pf_queuespec), 0, 0, 0,
+ "pfqueuepl", NULL);
pfr_initialize();
pfi_initialize();
pf_osfp_initialize();
@@ -186,6 +196,10 @@ pfattach(int num)
RB_INIT(&tree_src_tracking);
RB_INIT(&pf_anchors);
pf_init_ruleset(&pf_main_ruleset);
+ TAILQ_INIT(&pf_queues[0]);
+ TAILQ_INIT(&pf_queues[1]);
+ pf_queues_active = &pf_queues[0];
+ pf_queues_inactive = &pf_queues[1];
TAILQ_INIT(&pf_altqs[0]);
TAILQ_INIT(&pf_altqs[1]);
pf_altqs_active = &pf_altqs[0];
@@ -479,6 +493,24 @@ pf_rtlabel_copyout(struct pf_addr_wrap *a)
}
}
+u_int16_t
+pf_qname2qid(char *qname, int create)
+{
+ return (tagname2tag(&pf_qids, qname, create));
+}
+
+void
+pf_qid2qname(u_int16_t qid, char *p)
+{
+ tag2tagname(&pf_qids, qid, p);
+}
+
+void
+pf_qid_unref(u_int16_t qid)
+{
+ tag_unref(&pf_qids, (u_int16_t)qid);
+}
+
#ifdef ALTQ
u_int32_t
pf_oqname2qid(char *qname)
@@ -685,9 +717,87 @@ pf_rollback_rules(u_int32_t ticket, char *anchor)
rs->rules.inactive.rcount--;
}
rs->rules.inactive.open = 0;
+ return (pf_free_queues(anchor));
+}
+
+int
+pf_free_queues(char *anchor)
+{
+ struct pf_queuespec *q;
+
+ /* queue defs only in the main ruleset */
+ if (anchor[0])
+ return (0);
+
+ while ((q = TAILQ_FIRST(pf_queues_inactive)) != NULL) {
+ TAILQ_REMOVE(pf_queues_inactive, q, entries);
+ pfi_kif_unref(q->kif, PFI_KIF_REF_RULE);
+ pool_put(&pf_queue_pl, q);
+ }
return (0);
}
+int
+pf_remove_queues(void)
+{
+ struct pf_queuespec *q;
+ int error = 0;
+
+ /* remove queues */
+ TAILQ_FOREACH_REVERSE(q, pf_queues_active, pf_queuehead, entries)
+ if ((error = hfsc_delqueue(q)) != 0)
+ return (error);
+
+ /* put back interfaces in normal queueing mode */
+ TAILQ_FOREACH(q, pf_queues_active, entries)
+ if (q->parent_qid == 0)
+ if ((error = hfsc_detach(q->kif->pfik_ifp)) != 0)
+ return (error);
+
+ return (0);
+}
+
+int
+pf_create_queues(void)
+{
+ struct pf_queuespec *q;
+ int error = 0;
+
+ /* find root queues and attach hfsc to these interfaces */
+ TAILQ_FOREACH(q, pf_queues_active, entries)
+ if (q->parent_qid == 0)
+ if ((error = hfsc_attach(q->kif->pfik_ifp)) != 0)
+ return (error);
+
+ /* and now everything */
+ TAILQ_FOREACH(q, pf_queues_active, entries)
+ if ((error = hfsc_addqueue(q)) != 0)
+ return (error);
+
+ return (0);
+}
+
+int
+pf_commit_queues(char *anchor)
+{
+ struct pf_queuehead *qswap;
+
+ /* queue defs only in the main ruleset */
+ if (anchor[0])
+ return (0);
+
+ if (pf_remove_queues() != 0)
+ return (-1);
+
+ /* swap */
+ qswap = pf_queues_active;
+ pf_queues_active = pf_queues_inactive;
+ pf_queues_inactive = qswap;
+ pf_free_queues(anchor);
+
+ return (pf_create_queues());
+}
+
#define PF_MD5_UPD(st, elm) \
MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
@@ -819,7 +929,7 @@ pf_commit_rules(u_int32_t ticket, char *anchor)
rs->rules.inactive.open = 0;
pf_remove_if_empty_ruleset(rs);
splx(s);
- return (0);
+ return (pf_commit_queues(anchor));
}
int
@@ -910,9 +1020,12 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCGETLIMIT:
case DIOCGETALTQS:
case DIOCGETALTQ:
- case DIOCGETQSTATS:
+ case DIOCGETALTQSTATS:
case DIOCGETRULESETS:
case DIOCGETRULESET:
+ case DIOCGETQUEUES:
+ case DIOCGETQUEUE:
+ case DIOCGETQSTATS:
case DIOCRGETTABLES:
case DIOCRGETTSTATS:
case DIOCRCLRTSTATS:
@@ -952,9 +1065,12 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCGETLIMIT:
case DIOCGETALTQS:
case DIOCGETALTQ:
- case DIOCGETQSTATS:
+ case DIOCGETALTQSTATS:
case DIOCGETRULESETS:
case DIOCGETRULESET:
+ case DIOCGETQUEUES:
+ case DIOCGETQUEUE:
+ case DIOCGETQSTATS:
case DIOCNATLOOK:
case DIOCRGETTABLES:
case DIOCRGETTSTATS:
@@ -1007,6 +1123,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pf_status.stateid = time_second;
pf_status.stateid = pf_status.stateid << 32;
}
+ pf_create_queues();
DPFPRINTF(LOG_NOTICE, "pf: started");
}
break;
@@ -1017,10 +1134,110 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
else {
pf_status.running = 0;
pf_status.since = time_second;
+ pf_remove_queues();
DPFPRINTF(LOG_NOTICE, "pf: stopped");
}
break;
+ case DIOCGETQUEUES: {
+ struct pfioc_queue *pq = (struct pfioc_queue *)addr;
+ struct pf_queuespec *qs;
+ u_int32_t nr = 0;
+
+ pq->ticket = pf_main_ruleset.rules.active.ticket;
+
+ /* save state to not run over them all each time? */
+ qs = TAILQ_FIRST(pf_queues_active);
+ while (qs != NULL) {
+ qs = TAILQ_NEXT(qs, entries);
+ nr++;
+ }
+ pq->nr = nr;
+ break;
+ }
+
+ case DIOCGETQUEUE: {
+ struct pfioc_queue *pq = (struct pfioc_queue *)addr;
+ struct pf_queuespec *qs;
+ u_int32_t nr = 0;
+
+ if (pq->ticket != pf_main_ruleset.rules.active.ticket) {
+ error = EBUSY;
+ break;
+ }
+
+ /* save state to not run over them all each time? */
+ qs = TAILQ_FIRST(pf_queues_active);
+ while ((qs != NULL) && (nr++ < pq->nr))
+ qs = TAILQ_NEXT(qs, entries);
+ if (qs == NULL) {
+ error = EBUSY;
+ break;
+ }
+ bcopy(qs, &pq->queue, sizeof(pq->queue));
+ break;
+ }
+
+ case DIOCGETQSTATS: {
+ struct pfioc_qstats *pq = (struct pfioc_qstats *)addr;
+ struct pf_queuespec *qs;
+ u_int32_t nr;
+ int nbytes;
+
+ if (pq->ticket != pf_main_ruleset.rules.active.ticket) {
+ error = EBUSY;
+ break;
+ }
+ nbytes = pq->nbytes;
+ nr = 0;
+
+ /* save state to not run over them all each time? */
+ qs = TAILQ_FIRST(pf_queues_active);
+ while ((qs != NULL) && (nr++ < pq->nr))
+ qs = TAILQ_NEXT(qs, entries);
+ if (qs == NULL) {
+ error = EBUSY;
+ break;
+ }
+ bcopy(qs, &pq->queue, sizeof(pq->queue));
+ error = hfsc_qstats(qs, pq->buf, &nbytes);
+ if (error == 0)
+ pq->nbytes = nbytes;
+ break;
+ }
+
+ case DIOCADDQUEUE: {
+ struct pfioc_queue *q = (struct pfioc_queue *)addr;
+ struct pf_queuespec *qs;
+
+ if (q->ticket != pf_main_ruleset.rules.inactive.ticket) {
+ error = EBUSY;
+ break;
+ }
+ qs = pool_get(&pf_queue_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO);
+ if (qs == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(&q->queue, qs, sizeof(*qs));
+ qs->qid = pf_qname2qid(qs->qname, 1);
+ if (qs->parent[0] && (qs->parent_qid =
+ pf_qname2qid(qs->parent, 0)) == 0)
+ return (ESRCH);
+ qs->kif = pfi_kif_get(qs->ifname);
+ if (!qs->kif->pfik_ifp) {
+ error = ESRCH;
+ break;
+ }
+ /* XXX resolve bw percentage specs */
+ pfi_kif_ref(qs->kif, PFI_KIF_REF_RULE);
+ if (qs->qlimit == 0)
+ qs->qlimit = HFSC_DEFAULT_QLIMIT;
+ TAILQ_INSERT_TAIL(pf_queues_inactive, qs, entries);
+
+ break;
+ }
+
case DIOCADDRULE: {
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
@@ -1753,8 +1970,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENODEV;
break;
- case DIOCGETQSTATS: {
- struct pfioc_qstats *pq = (struct pfioc_qstats *)addr;
+ case DIOCGETALTQSTATS: {
+ struct pfioc_altqstats *pq = (struct pfioc_altqstats *)addr;
struct pf_altq *altq;
u_int32_t nr;
int nbytes;
@@ -2246,6 +2463,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
}
+
/*
* Checked already in DIOCSETLIMIT, but check again as the
* situation might have changed.
@@ -2573,18 +2791,22 @@ pf_rule_copyin(struct pf_rule *from, struct pf_rule *to,
to->max_src_conn_rate.limit = from->max_src_conn_rate.limit;
to->max_src_conn_rate.seconds = from->max_src_conn_rate.seconds;
-#ifdef ALTQ
- /* set queue IDs */
+ /* set queue IDs. little ugly due to both altq and new system... */
if (to->qname[0] != 0) {
- if ((to->qid = pf_oqname2qid(to->qname)) == 0)
- return (EBUSY);
- else if (to->pqname[0] != 0) {
- if ((to->pqid = pf_oqname2qid(to->pqname)) == 0)
+ if ((to->qid = pf_qname2qid(to->qname, 0)) == 0)
+#ifdef ALTQ
+ if ((to->qid = pf_oqname2qid(to->qname)) == 0)
+#endif
return (EBUSY);
+ if (to->pqname[0] != 0) {
+ if ((to->pqid = pf_qname2qid(to->pqname, 0)) == 0)
+#ifdef ALTQ
+ if ((to->pqid = pf_oqname2qid(to->pqname)) == 0)
+#endif
+ return (EBUSY);
} else
to->pqid = to->qid;
}
-#endif
to->rt_listid = from->rt_listid;
to->prob = from->prob;
to->return_icmp = from->return_icmp;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 7490421bd9c..37f61e4e5ce 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,8 +1,8 @@
-/* $OpenBSD: pfvar.h,v 1.390 2013/10/12 11:55:46 henning Exp $ */
+/* $OpenBSD: pfvar.h,v 1.391 2013/10/12 12:13:11 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002 - 2010 Henning Brauer
+ * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1419,6 +1419,32 @@ struct pf_status {
#define PF_REASS_ENABLED 0x01
#define PF_REASS_NODF 0x02
+struct pf_queue_bwspec {
+ u_int absolute;
+ u_int percent;
+};
+
+struct pf_queue_scspec {
+ struct pf_queue_bwspec m1;
+ struct pf_queue_bwspec m2;
+ u_int d;
+};
+
+struct pf_queuespec {
+ TAILQ_ENTRY(pf_queuespec) entries;
+ char qname[PF_QNAME_SIZE];
+ char parent[PF_QNAME_SIZE];
+ char ifname[IFNAMSIZ];
+ struct pf_queue_scspec realtime;
+ struct pf_queue_scspec linkshare;
+ struct pf_queue_scspec upperlimit;
+ struct pfi_kif *kif;
+ u_int flags;
+ u_int qlimit;
+ u_int32_t qid;
+ u_int32_t parent_qid;
+};
+
struct cbq_opts {
u_int minburst;
u_int maxburst;
@@ -1589,7 +1615,7 @@ struct pfioc_altq {
struct pf_altq altq;
};
-struct pfioc_qstats {
+struct pfioc_altqstats {
u_int32_t ticket;
u_int32_t nr;
void *buf;
@@ -1613,6 +1639,20 @@ struct pfioc_trans {
} *array;
};
+struct pfioc_queue {
+ u_int32_t ticket;
+ u_int nr;
+ struct pf_queuespec queue;
+};
+
+struct pfioc_qstats {
+ u_int32_t ticket;
+ u_int32_t nr;
+ struct pf_queuespec queue;
+ void *buf;
+ int nbytes;
+};
+
#define PFR_FLAG_DUMMY 0x00000002
#define PFR_FLAG_FEEDBACK 0x00000004
#define PFR_FLAG_CLSTATS 0x00000008
@@ -1686,7 +1726,7 @@ struct pfioc_iface {
#define DIOCGETALTQS _IOWR('D', 47, struct pfioc_altq)
#define DIOCGETALTQ _IOWR('D', 48, struct pfioc_altq)
#define DIOCCHANGEALTQ _IOWR('D', 49, struct pfioc_altq)
-#define DIOCGETQSTATS _IOWR('D', 50, struct pfioc_qstats)
+#define DIOCGETALTQSTATS _IOWR('D', 50, struct pfioc_altqstats)
/* XXX cut 51 - 57 */
#define DIOCGETRULESETS _IOWR('D', 58, struct pfioc_ruleset)
#define DIOCGETRULESET _IOWR('D', 59, struct pfioc_ruleset)
@@ -1720,6 +1760,10 @@ struct pfioc_iface {
#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
#define DIOCSETREASS _IOWR('D', 92, u_int32_t)
+#define DIOCADDQUEUE _IOWR('D', 93, struct pfioc_queue)
+#define DIOCGETQUEUES _IOWR('D', 94, struct pfioc_queue)
+#define DIOCGETQUEUE _IOWR('D', 95, struct pfioc_queue)
+#define DIOCGETQSTATS _IOWR('D', 96, struct pfioc_qstats)
#ifdef _KERNEL
RB_HEAD(pf_src_tree, pf_src_node);
@@ -1732,6 +1776,10 @@ RB_PROTOTYPE(pf_state_tree_id, pf_state,
extern struct pf_state_tree_id tree_id;
extern struct pf_state_queue state_list;
+TAILQ_HEAD(pf_queuehead, pf_queuespec);
+extern struct pf_queuehead pf_queues[2];
+extern struct pf_queuehead *pf_queues_active, *pf_queues_inactive;
+
TAILQ_HEAD(pf_altqqueue, pf_altq);
extern struct pf_altqqueue pf_altqs[2];
@@ -1748,7 +1796,7 @@ extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
extern void pf_calc_skip_steps(struct pf_rulequeue *);
extern struct pool pf_src_tree_pl, pf_sn_item_pl, pf_rule_pl;
extern struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl,
- pf_altq_pl, pf_rule_item_pl;
+ pf_altq_pl, pf_rule_item_pl, pf_queue_pl;
extern struct pool pf_state_scrub_pl;
extern void pf_purge_thread(void *);
extern void pf_purge_expired_src_nodes(int);