diff options
author | 2013-10-12 12:13:10 +0000 | |
---|---|---|
committer | 2013-10-12 12:13:10 +0000 | |
commit | 6568394152b0023134f4de3cd6ba28f486b45952 (patch) | |
tree | 8b0aed2594daac7f687cbc2592c4cfd55d1c2e8d | |
parent | hook in hfsc.c/h (diff) | |
download | wireguard-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.h | 5 | ||||
-rw-r--r-- | sys/net/if.h | 100 | ||||
-rw-r--r-- | sys/net/pf.c | 9 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 252 | ||||
-rw-r--r-- | sys/net/pfvar.h | 58 |
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); |