Fri Jan 22 18:19:54 2016 UTC ()
Prevent interface deletion from running into an infinite loop when altq closes.
$ cat /etc/altq.conf
interface ppp0 bandwidth 10M priq
class priq ppp0 high_class_ppp NULL priority 1
class priq ppp0 low_class_ppp NULL priority 0 default
filter ppp0 high_class_ppp 0 0 0 0 1
$ ifconfig ppp0 create
$ /etc/rc.d/altqd onestart
$ ifconfig ppp0 destroy
$ pkill altqd
XXX: pullup-7


(christos)
diff -r1.24 -r1.25 src/sys/altq/altq_hfsc.c
diff -r1.7 -r1.8 src/sys/altq/altq_jobs.c
diff -r1.21 -r1.22 src/sys/altq/altq_priq.c

cvs diff -r1.24 -r1.25 src/sys/altq/altq_hfsc.c (expand / switch to unified diff)

--- src/sys/altq/altq_hfsc.c 2008/06/18 09:06:27 1.24
+++ src/sys/altq/altq_hfsc.c 2016/01/22 18:19:54 1.25
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: altq_hfsc.c,v 1.24 2008/06/18 09:06:27 yamt Exp $ */ 1/* $NetBSD: altq_hfsc.c,v 1.25 2016/01/22 18:19:54 christos Exp $ */
2/* $KAME: altq_hfsc.c,v 1.26 2005/04/13 03:44:24 suz Exp $ */ 2/* $KAME: altq_hfsc.c,v 1.26 2005/04/13 03:44:24 suz Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved. 5 * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved.
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software and 7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation is hereby granted (including for commercial or 8 * its documentation is hereby granted (including for commercial or
9 * for-profit use), provided that both the copyright notice and this 9 * for-profit use), provided that both the copyright notice and this
10 * permission notice appear in all copies of the software, derivative 10 * permission notice appear in all copies of the software, derivative
11 * works, or modified versions, and any portions thereof. 11 * works, or modified versions, and any portions thereof.
12 * 12 *
13 * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF 13 * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF
14 * WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS 14 * WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS
@@ -33,27 +33,27 @@ @@ -33,27 +33,27 @@
33/* 33/*
34 * H-FSC is described in Proceedings of SIGCOMM'97, 34 * H-FSC is described in Proceedings of SIGCOMM'97,
35 * "A Hierarchical Fair Service Curve Algorithm for Link-Sharing, 35 * "A Hierarchical Fair Service Curve Algorithm for Link-Sharing,
36 * Real-Time and Priority Service" 36 * Real-Time and Priority Service"
37 * by Ion Stoica, Hui Zhang, and T. S. Eugene Ng. 37 * by Ion Stoica, Hui Zhang, and T. S. Eugene Ng.
38 * 38 *
39 * Oleg Cherevko <olwi@aq.ml.com.ua> added the upperlimit for link-sharing. 39 * Oleg Cherevko <olwi@aq.ml.com.ua> added the upperlimit for link-sharing.
40 * when a class has an upperlimit, the fit-time is computed from the 40 * when a class has an upperlimit, the fit-time is computed from the
41 * upperlimit service curve. the link-sharing scheduler does not schedule 41 * upperlimit service curve. the link-sharing scheduler does not schedule
42 * a class whose fit-time exceeds the current time. 42 * a class whose fit-time exceeds the current time.
43 */ 43 */
44 44
45#include <sys/cdefs.h> 45#include <sys/cdefs.h>
46__KERNEL_RCSID(0, "$NetBSD: altq_hfsc.c,v 1.24 2008/06/18 09:06:27 yamt Exp $"); 46__KERNEL_RCSID(0, "$NetBSD: altq_hfsc.c,v 1.25 2016/01/22 18:19:54 christos Exp $");
47 47
48#ifdef _KERNEL_OPT 48#ifdef _KERNEL_OPT
49#include "opt_altq.h" 49#include "opt_altq.h"
50#include "opt_inet.h" 50#include "opt_inet.h"
51#include "pf.h" 51#include "pf.h"
52#endif 52#endif
53 53
54#ifdef ALTQ_HFSC /* hfsc is enabled by ALTQ_HFSC option in opt_altq.h */ 54#ifdef ALTQ_HFSC /* hfsc is enabled by ALTQ_HFSC option in opt_altq.h */
55 55
56#include <sys/param.h> 56#include <sys/param.h>
57#include <sys/malloc.h> 57#include <sys/malloc.h>
58#include <sys/mbuf.h> 58#include <sys/mbuf.h>
59#include <sys/socket.h> 59#include <sys/socket.h>
@@ -136,27 +136,27 @@ static void rtsc_init(struct runtime_sc @@ -136,27 +136,27 @@ static void rtsc_init(struct runtime_sc
136 u_int64_t, u_int64_t); 136 u_int64_t, u_int64_t);
137static u_int64_t rtsc_y2x(struct runtime_sc *, u_int64_t); 137static u_int64_t rtsc_y2x(struct runtime_sc *, u_int64_t);
138static u_int64_t rtsc_x2y(struct runtime_sc *, u_int64_t); 138static u_int64_t rtsc_x2y(struct runtime_sc *, u_int64_t);
139static void rtsc_min(struct runtime_sc *, struct internal_sc *, 139static void rtsc_min(struct runtime_sc *, struct internal_sc *,
140 u_int64_t, u_int64_t); 140 u_int64_t, u_int64_t);
141 141
142static void get_class_stats(struct hfsc_classstats *, 142static void get_class_stats(struct hfsc_classstats *,
143 struct hfsc_class *); 143 struct hfsc_class *);
144static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_int32_t); 144static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_int32_t);
145 145
146 146
147#ifdef ALTQ3_COMPAT 147#ifdef ALTQ3_COMPAT
148static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int); 148static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int);
149static int hfsc_detach(struct hfsc_if *); 149static void hfsc_detach(struct hfsc_if *);
150static int hfsc_class_modify(struct hfsc_class *, struct service_curve *, 150static int hfsc_class_modify(struct hfsc_class *, struct service_curve *,
151 struct service_curve *, struct service_curve *); 151 struct service_curve *, struct service_curve *);
152 152
153static int hfsccmd_if_attach(struct hfsc_attach *); 153static int hfsccmd_if_attach(struct hfsc_attach *);
154static int hfsccmd_if_detach(struct hfsc_interface *); 154static int hfsccmd_if_detach(struct hfsc_interface *);
155static int hfsccmd_add_class(struct hfsc_add_class *); 155static int hfsccmd_add_class(struct hfsc_add_class *);
156static int hfsccmd_delete_class(struct hfsc_delete_class *); 156static int hfsccmd_delete_class(struct hfsc_delete_class *);
157static int hfsccmd_modify_class(struct hfsc_modify_class *); 157static int hfsccmd_modify_class(struct hfsc_modify_class *);
158static int hfsccmd_add_filter(struct hfsc_add_filter *); 158static int hfsccmd_add_filter(struct hfsc_add_filter *);
159static int hfsccmd_delete_filter(struct hfsc_delete_filter *); 159static int hfsccmd_delete_filter(struct hfsc_delete_filter *);
160static int hfsccmd_class_stats(struct hfsc_class_stats *); 160static int hfsccmd_class_stats(struct hfsc_class_stats *);
161 161
162altqdev_decl(hfsc); 162altqdev_decl(hfsc);
@@ -1717,51 +1717,49 @@ hfsc_attach(struct ifaltq *ifq, u_int ba @@ -1717,51 +1717,49 @@ hfsc_attach(struct ifaltq *ifq, u_int ba
1717 free(hif, M_DEVBUF); 1717 free(hif, M_DEVBUF);
1718 return NULL; 1718 return NULL;
1719 } 1719 }
1720 1720
1721 hif->hif_ifq = ifq; 1721 hif->hif_ifq = ifq;
1722 1722
1723 /* add this state to the hfsc list */ 1723 /* add this state to the hfsc list */
1724 hif->hif_next = hif_list; 1724 hif->hif_next = hif_list;
1725 hif_list = hif; 1725 hif_list = hif;
1726 1726
1727 return (hif); 1727 return (hif);
1728} 1728}
1729 1729
1730static int 1730static void
1731hfsc_detach(struct hfsc_if *hif) 1731hfsc_detach(struct hfsc_if *hif)
1732{ 1732{
1733 (void)hfsc_clear_interface(hif); 1733 (void)hfsc_clear_interface(hif);
1734 (void)hfsc_class_destroy(hif->hif_rootclass); 1734 (void)hfsc_class_destroy(hif->hif_rootclass);
1735 1735
1736 /* remove this interface from the hif list */ 1736 /* remove this interface from the hif list */
1737 if (hif_list == hif) 1737 if (hif_list == hif)
1738 hif_list = hif->hif_next; 1738 hif_list = hif->hif_next;
1739 else { 1739 else {
1740 struct hfsc_if *h; 1740 struct hfsc_if *h;
1741 1741
1742 for (h = hif_list; h != NULL; h = h->hif_next) 1742 for (h = hif_list; h != NULL; h = h->hif_next)
1743 if (h->hif_next == hif) { 1743 if (h->hif_next == hif) {
1744 h->hif_next = hif->hif_next; 1744 h->hif_next = hif->hif_next;
1745 break; 1745 break;
1746 } 1746 }
1747 ASSERT(h != NULL); 1747 ASSERT(h != NULL);
1748 } 1748 }
1749 1749
1750 ellist_destroy(hif->hif_eligible); 1750 ellist_destroy(hif->hif_eligible);
1751 1751
1752 free(hif, M_DEVBUF); 1752 free(hif, M_DEVBUF);
1753 
1754 return (0); 
1755} 1753}
1756 1754
1757static int 1755static int
1758hfsc_class_modify(struct hfsc_class *cl, struct service_curve *rsc, 1756hfsc_class_modify(struct hfsc_class *cl, struct service_curve *rsc,
1759 struct service_curve *fsc, struct service_curve *usc) 1757 struct service_curve *fsc, struct service_curve *usc)
1760{ 1758{
1761 struct internal_sc *rsc_tmp, *fsc_tmp, *usc_tmp; 1759 struct internal_sc *rsc_tmp, *fsc_tmp, *usc_tmp;
1762 u_int64_t cur_time; 1760 u_int64_t cur_time;
1763 int s; 1761 int s;
1764 1762
1765 rsc_tmp = fsc_tmp = usc_tmp = NULL; 1763 rsc_tmp = fsc_tmp = usc_tmp = NULL;
1766 if (rsc != NULL && (rsc->m1 != 0 || rsc->m2 != 0) && 1764 if (rsc != NULL && (rsc->m1 != 0 || rsc->m2 != 0) &&
1767 cl->cl_rsc == NULL) { 1765 cl->cl_rsc == NULL) {
@@ -1870,41 +1868,44 @@ hfscopen(dev_t dev, int flag, int fmt, @@ -1870,41 +1868,44 @@ hfscopen(dev_t dev, int flag, int fmt,
1870 printf("hfsc: no CPU clock available!\n"); 1868 printf("hfsc: no CPU clock available!\n");
1871 return (ENXIO); 1869 return (ENXIO);
1872 } 1870 }
1873 1871
1874 /* everything will be done when the queueing scheme is attached. */ 1872 /* everything will be done when the queueing scheme is attached. */
1875 return 0; 1873 return 0;
1876} 1874}
1877 1875
1878int 1876int
1879hfscclose(dev_t dev, int flag, int fmt, 1877hfscclose(dev_t dev, int flag, int fmt,
1880 struct lwp *l) 1878 struct lwp *l)
1881{ 1879{
1882 struct hfsc_if *hif; 1880 struct hfsc_if *hif;
1883 int err, error = 0; 
1884 1881
1885 while ((hif = hif_list) != NULL) { 1882 while ((hif = hif_list) != NULL) {
1886 /* destroy all */ 1883 /* destroy all */
1887 if (ALTQ_IS_ENABLED(hif->hif_ifq)) 1884 if (ALTQ_IS_ENABLED(hif->hif_ifq))
1888 altq_disable(hif->hif_ifq); 1885 altq_disable(hif->hif_ifq);
1889 1886
1890 err = altq_detach(hif->hif_ifq); 1887 int error = altq_detach(hif->hif_ifq);
1891 if (err == 0) 1888 switch (error) {
1892 err = hfsc_detach(hif); 1889 case 0:
1893 if (err != 0 && error == 0) 1890 case ENXIO: /* already disabled */
1894 error = err; 1891 break;
 1892 default:
 1893 return error;
 1894 }
 1895 hfsc_detach(hif);
1895 } 1896 }
1896 1897
1897 return error; 1898 return 0;
1898} 1899}
1899 1900
1900int 1901int
1901hfscioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, 1902hfscioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag,
1902 struct lwp *l) 1903 struct lwp *l)
1903{ 1904{
1904 struct hfsc_if *hif; 1905 struct hfsc_if *hif;
1905 struct hfsc_interface *ifacep; 1906 struct hfsc_interface *ifacep;
1906 int error = 0; 1907 int error = 0;
1907 1908
1908 /* check super-user privilege */ 1909 /* check super-user privilege */
1909 switch (cmd) { 1910 switch (cmd) {
1910 case HFSC_GETSTATS: 1911 case HFSC_GETSTATS:
@@ -2005,47 +2006,48 @@ hfsccmd_if_attach(struct hfsc_attach *ap @@ -2005,47 +2006,48 @@ hfsccmd_if_attach(struct hfsc_attach *ap
2005 2006
2006 if ((ifp = ifunit(ap->iface.hfsc_ifname)) == NULL) 2007 if ((ifp = ifunit(ap->iface.hfsc_ifname)) == NULL)
2007 return (ENXIO); 2008 return (ENXIO);
2008 2009
2009 if ((hif = hfsc_attach(&ifp->if_snd, ap->bandwidth)) == NULL) 2010 if ((hif = hfsc_attach(&ifp->if_snd, ap->bandwidth)) == NULL)
2010 return (ENOMEM); 2011 return (ENOMEM);
2011 2012
2012 /* 2013 /*
2013 * set HFSC to this ifnet structure. 2014 * set HFSC to this ifnet structure.
2014 */ 2015 */
2015 if ((error = altq_attach(&ifp->if_snd, ALTQT_HFSC, hif, 2016 if ((error = altq_attach(&ifp->if_snd, ALTQT_HFSC, hif,
2016 hfsc_enqueue, hfsc_dequeue, hfsc_request, 2017 hfsc_enqueue, hfsc_dequeue, hfsc_request,
2017 &hif->hif_classifier, acc_classify)) != 0) 2018 &hif->hif_classifier, acc_classify)) != 0)
2018 (void)hfsc_detach(hif); 2019 hfsc_detach(hif);
2019 2020
2020 return (error); 2021 return (error);
2021} 2022}
2022 2023
2023static int 2024static int
2024hfsccmd_if_detach(struct hfsc_interface *ap) 2025hfsccmd_if_detach(struct hfsc_interface *ap)
2025{ 2026{
2026 struct hfsc_if *hif; 2027 struct hfsc_if *hif;
2027 int error; 2028 int error;
2028 2029
2029 if ((hif = altq_lookup(ap->hfsc_ifname, ALTQT_HFSC)) == NULL) 2030 if ((hif = altq_lookup(ap->hfsc_ifname, ALTQT_HFSC)) == NULL)
2030 return (EBADF); 2031 return (EBADF);
2031 2032
2032 if (ALTQ_IS_ENABLED(hif->hif_ifq)) 2033 if (ALTQ_IS_ENABLED(hif->hif_ifq))
2033 altq_disable(hif->hif_ifq); 2034 altq_disable(hif->hif_ifq);
2034 2035
2035 if ((error = altq_detach(hif->hif_ifq))) 2036 if ((error = altq_detach(hif->hif_ifq)))
2036 return (error); 2037 return (error);
2037 2038
2038 return hfsc_detach(hif); 2039 hfsc_detach(hif);
 2040 return 0;
2039} 2041}
2040 2042
2041static int 2043static int
2042hfsccmd_add_class(struct hfsc_add_class *ap) 2044hfsccmd_add_class(struct hfsc_add_class *ap)
2043{ 2045{
2044 struct hfsc_if *hif; 2046 struct hfsc_if *hif;
2045 struct hfsc_class *cl, *parent; 2047 struct hfsc_class *cl, *parent;
2046 int i; 2048 int i;
2047 2049
2048 if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL) 2050 if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
2049 return (EBADF); 2051 return (EBADF);
2050 2052
2051 if (ap->parent_handle == HFSC_NULLCLASS_HANDLE && 2053 if (ap->parent_handle == HFSC_NULLCLASS_HANDLE &&

cvs diff -r1.7 -r1.8 src/sys/altq/altq_jobs.c (expand / switch to unified diff)

--- src/sys/altq/altq_jobs.c 2014/08/18 03:14:12 1.7
+++ src/sys/altq/altq_jobs.c 2016/01/22 18:19:54 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: altq_jobs.c,v 1.7 2014/08/18 03:14:12 riastradh Exp $ */ 1/* $NetBSD: altq_jobs.c,v 1.8 2016/01/22 18:19:54 christos Exp $ */
2/* $KAME: altq_jobs.c,v 1.11 2005/04/13 03:44:25 suz Exp $ */ 2/* $KAME: altq_jobs.c,v 1.11 2005/04/13 03:44:25 suz Exp $ */
3/* 3/*
4 * Copyright (c) 2001, the Rector and Board of Visitors of the 4 * Copyright (c) 2001, the Rector and Board of Visitors of the
5 * University of Virginia. 5 * University of Virginia.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, 8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted provided 9 * with or without modification, are permitted provided
10 * that the following conditions are met: 10 * that the following conditions are met:
11 * 11 *
12 * Redistributions of source code must retain the above 12 * Redistributions of source code must retain the above
13 * copyright notice, this list of conditions and the following 13 * copyright notice, this list of conditions and the following
14 * disclaimer. 14 * disclaimer.
@@ -49,27 +49,27 @@ @@ -49,27 +49,27 @@
49 * Contributed by the Multimedia Networks Group at the University 49 * Contributed by the Multimedia Networks Group at the University
50 * of Virginia.  50 * of Virginia.
51 * 51 *
52 * Papers and additional info can be found at  52 * Papers and additional info can be found at
53 * http://qosbox.cs.virginia.edu 53 * http://qosbox.cs.virginia.edu
54 *  54 *
55 */  55 */
56 56
57/* 57/*
58 * JoBS queue 58 * JoBS queue
59 */ 59 */
60 60
61#include <sys/cdefs.h> 61#include <sys/cdefs.h>
62__KERNEL_RCSID(0, "$NetBSD: altq_jobs.c,v 1.7 2014/08/18 03:14:12 riastradh Exp $"); 62__KERNEL_RCSID(0, "$NetBSD: altq_jobs.c,v 1.8 2016/01/22 18:19:54 christos Exp $");
63 63
64#ifdef _KERNEL_OPT 64#ifdef _KERNEL_OPT
65#include "opt_altq.h" 65#include "opt_altq.h"
66#include "opt_inet.h" 66#include "opt_inet.h"
67#endif 67#endif
68 68
69#ifdef ALTQ_JOBS /* jobs is enabled by ALTQ_JOBS option in opt_altq.h */ 69#ifdef ALTQ_JOBS /* jobs is enabled by ALTQ_JOBS option in opt_altq.h */
70 70
71#include <sys/param.h> 71#include <sys/param.h>
72#include <sys/malloc.h> 72#include <sys/malloc.h>
73#include <sys/mbuf.h> 73#include <sys/mbuf.h>
74#include <sys/socket.h> 74#include <sys/socket.h>
75#include <sys/sockio.h> 75#include <sys/sockio.h>
@@ -86,27 +86,27 @@ __KERNEL_RCSID(0, "$NetBSD: altq_jobs.c, @@ -86,27 +86,27 @@ __KERNEL_RCSID(0, "$NetBSD: altq_jobs.c,
86 86
87#include <net/if.h> 87#include <net/if.h>
88#include <net/if_types.h> 88#include <net/if_types.h>
89 89
90#include <altq/altq.h> 90#include <altq/altq.h>
91#include <altq/altq_conf.h> 91#include <altq/altq_conf.h>
92#include <altq/altq_jobs.h> 92#include <altq/altq_jobs.h>
93 93
94#ifdef ALTQ3_COMPAT 94#ifdef ALTQ3_COMPAT
95/* 95/*
96 * function prototypes 96 * function prototypes
97 */ 97 */
98static struct jobs_if *jobs_attach(struct ifaltq *, u_int, u_int, u_int); 98static struct jobs_if *jobs_attach(struct ifaltq *, u_int, u_int, u_int);
99static int jobs_detach(struct jobs_if *); 99static void jobs_detach(struct jobs_if *);
100static int jobs_clear_interface(struct jobs_if *); 100static int jobs_clear_interface(struct jobs_if *);
101static int jobs_request(struct ifaltq *, int, void *); 101static int jobs_request(struct ifaltq *, int, void *);
102static void jobs_purge(struct jobs_if *); 102static void jobs_purge(struct jobs_if *);
103static struct jobs_class *jobs_class_create(struct jobs_if *, 103static struct jobs_class *jobs_class_create(struct jobs_if *,
104 int, int64_t, int64_t, int64_t, int64_t, int64_t, int); 104 int, int64_t, int64_t, int64_t, int64_t, int64_t, int);
105static int jobs_class_destroy(struct jobs_class *); 105static int jobs_class_destroy(struct jobs_class *);
106static int jobs_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); 106static int jobs_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *);
107static struct mbuf *jobs_dequeue(struct ifaltq *, int); 107static struct mbuf *jobs_dequeue(struct ifaltq *, int);
108 108
109static int jobs_addq(struct jobs_class *, struct mbuf *, struct jobs_if*); 109static int jobs_addq(struct jobs_class *, struct mbuf *, struct jobs_if*);
110static struct mbuf *jobs_getq(struct jobs_class *); 110static struct mbuf *jobs_getq(struct jobs_class *);
111static struct mbuf *jobs_pollq(struct jobs_class *); 111static struct mbuf *jobs_pollq(struct jobs_class *);
112static void jobs_purgeq(struct jobs_class *); 112static void jobs_purgeq(struct jobs_class *);
@@ -174,46 +174,45 @@ jobs_attach(struct ifaltq *ifq, u_int ba @@ -174,46 +174,45 @@ jobs_attach(struct ifaltq *ifq, u_int ba
174 jif->avg_cycles_dequeue = 0; 174 jif->avg_cycles_dequeue = 0;
175 jif->avg_cycles2_dequeue = 0; 175 jif->avg_cycles2_dequeue = 0;
176 jif->bc_cycles_dequeue = ALTQ_INFINITY; 176 jif->bc_cycles_dequeue = ALTQ_INFINITY;
177 jif->total_enqueued = 0; 177 jif->total_enqueued = 0;
178 jif->total_dequeued = 0; 178 jif->total_dequeued = 0;
179 179
180 /* add this state to the jobs list */ 180 /* add this state to the jobs list */
181 jif->jif_next = jif_list; 181 jif->jif_next = jif_list;
182 jif_list = jif; 182 jif_list = jif;
183 183
184 return (jif); 184 return (jif);
185} 185}
186 186
187static int 187static void
188jobs_detach(struct jobs_if *jif) 188jobs_detach(struct jobs_if *jif)
189{ 189{
190 (void)jobs_clear_interface(jif); 190 (void)jobs_clear_interface(jif);
191 191
192 /* remove this interface from the jif list */ 192 /* remove this interface from the jif list */
193 if (jif_list == jif) 193 if (jif_list == jif)
194 jif_list = jif->jif_next; 194 jif_list = jif->jif_next;
195 else { 195 else {
196 struct jobs_if *p; 196 struct jobs_if *p;
197 197
198 for (p = jif_list; p != NULL; p = p->jif_next) 198 for (p = jif_list; p != NULL; p = p->jif_next)
199 if (p->jif_next == jif) { 199 if (p->jif_next == jif) {
200 p->jif_next = jif->jif_next; 200 p->jif_next = jif->jif_next;
201 break; 201 break;
202 } 202 }
203 ASSERT(p != NULL); 203 ASSERT(p != NULL);
204 } 204 }
205 free(jif, M_DEVBUF); 205 free(jif, M_DEVBUF);
206 return (0); 
207} 206}
208 207
209/* 208/*
210 * bring the interface back to the initial state by discarding 209 * bring the interface back to the initial state by discarding
211 * all the filters and classes. 210 * all the filters and classes.
212 */ 211 */
213static int 212static int
214jobs_clear_interface(struct jobs_if *jif) 213jobs_clear_interface(struct jobs_if *jif)
215{ 214{
216 struct jobs_class *cl; 215 struct jobs_class *cl;
217 int pri; 216 int pri;
218 217
219 /* free the filters for this interface */ 218 /* free the filters for this interface */
@@ -1827,38 +1826,41 @@ jobsopen(dev_t dev, int flag, int fmt, @@ -1827,38 +1826,41 @@ jobsopen(dev_t dev, int flag, int fmt,
1827 if (machclk_freq == 0) { 1826 if (machclk_freq == 0) {
1828 printf("jobs: no CPU clock available!\n"); 1827 printf("jobs: no CPU clock available!\n");
1829 return (ENXIO); 1828 return (ENXIO);
1830 } 1829 }
1831 /* everything will be done when the queueing scheme is attached. */ 1830 /* everything will be done when the queueing scheme is attached. */
1832 return 0; 1831 return 0;
1833} 1832}
1834 1833
1835int 1834int
1836jobsclose(dev_t dev, int flag, int fmt, 1835jobsclose(dev_t dev, int flag, int fmt,
1837 struct lwp *l) 1836 struct lwp *l)
1838{ 1837{
1839 struct jobs_if *jif; 1838 struct jobs_if *jif;
1840 int err, error = 0; 
1841 1839
1842 while ((jif = jif_list) != NULL) { 1840 while ((jif = jif_list) != NULL) {
1843 /* destroy all */ 1841 /* destroy all */
1844 if (ALTQ_IS_ENABLED(jif->jif_ifq)) 1842 if (ALTQ_IS_ENABLED(jif->jif_ifq))
1845 altq_disable(jif->jif_ifq); 1843 altq_disable(jif->jif_ifq);
1846 1844
1847 err = altq_detach(jif->jif_ifq); 1845 int error = altq_detach(pif->pif_ifq);
1848 if (err == 0) 1846 switch (error) {
1849 err = jobs_detach(jif); 1847 case 0:
1850 if (err != 0 && error == 0) 1848 case ENXIO: /* already disabled */
1851 error = err; 1849 break;
 1850 default:
 1851 return error;
 1852 }
 1853 jobs_detach(jif);
1852 } 1854 }
1853 1855
1854 return error; 1856 return error;
1855} 1857}
1856 1858
1857int 1859int
1858jobsioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, 1860jobsioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag,
1859 struct lwp *l) 1861 struct lwp *l)
1860{ 1862{
1861 struct jobs_if *jif; 1863 struct jobs_if *jif;
1862 struct jobs_interface *ifacep; 1864 struct jobs_interface *ifacep;
1863 struct proc *p = l->l_proc; 1865 struct proc *p = l->l_proc;
1864 int error = 0; 1866 int error = 0;
@@ -1961,47 +1963,48 @@ jobscmd_if_attach(struct jobs_attach *ap @@ -1961,47 +1963,48 @@ jobscmd_if_attach(struct jobs_attach *ap
1961 int error; 1963 int error;
1962 1964
1963 if ((ifp = ifunit(ap->iface.jobs_ifname)) == NULL) 1965 if ((ifp = ifunit(ap->iface.jobs_ifname)) == NULL)
1964 return (ENXIO); 1966 return (ENXIO);
1965 if ((jif = jobs_attach(&ifp->if_snd, ap->bandwidth, ap->qlimit, ap->separate)) == NULL) 1967 if ((jif = jobs_attach(&ifp->if_snd, ap->bandwidth, ap->qlimit, ap->separate)) == NULL)
1966 return (ENOMEM); 1968 return (ENOMEM);
1967 1969
1968 /* 1970 /*
1969 * set JOBS to this ifnet structure. 1971 * set JOBS to this ifnet structure.
1970 */ 1972 */
1971 if ((error = altq_attach(&ifp->if_snd, ALTQT_JOBS, jif, 1973 if ((error = altq_attach(&ifp->if_snd, ALTQT_JOBS, jif,
1972 jobs_enqueue, jobs_dequeue, jobs_request, 1974 jobs_enqueue, jobs_dequeue, jobs_request,
1973 &jif->jif_classifier, acc_classify)) != 0) 1975 &jif->jif_classifier, acc_classify)) != 0)
1974 (void)jobs_detach(jif); 1976 jobs_detach(jif);
1975 1977
1976 return (error); 1978 return (error);
1977} 1979}
1978 1980
1979static int 1981static int
1980jobscmd_if_detach(struct jobs_interface *ap) 1982jobscmd_if_detach(struct jobs_interface *ap)
1981{ 1983{
1982 struct jobs_if *jif; 1984 struct jobs_if *jif;
1983 int error; 1985 int error;
1984 1986
1985 if ((jif = altq_lookup(ap->jobs_ifname, ALTQT_JOBS)) == NULL) 1987 if ((jif = altq_lookup(ap->jobs_ifname, ALTQT_JOBS)) == NULL)
1986 return (EBADF); 1988 return (EBADF);
1987 1989
1988 if (ALTQ_IS_ENABLED(jif->jif_ifq)) 1990 if (ALTQ_IS_ENABLED(jif->jif_ifq))
1989 altq_disable(jif->jif_ifq); 1991 altq_disable(jif->jif_ifq);
1990 1992
1991 if ((error = altq_detach(jif->jif_ifq))) 1993 if ((error = altq_detach(jif->jif_ifq)))
1992 return (error); 1994 return (error);
1993 1995
1994 return jobs_detach(jif); 1996 jobs_detach(jif);
 1997 return 0;
1995} 1998}
1996 1999
1997static int 2000static int
1998jobscmd_add_class(struct jobs_add_class *ap) 2001jobscmd_add_class(struct jobs_add_class *ap)
1999{ 2002{
2000 struct jobs_if *jif; 2003 struct jobs_if *jif;
2001 struct jobs_class *cl; 2004 struct jobs_class *cl;
2002 2005
2003 if ((jif = altq_lookup(ap->iface.jobs_ifname, ALTQT_JOBS)) == NULL) 2006 if ((jif = altq_lookup(ap->iface.jobs_ifname, ALTQT_JOBS)) == NULL)
2004 return (EBADF); 2007 return (EBADF);
2005 2008
2006 if (ap->pri < 0 || ap->pri >= JOBS_MAXPRI) 2009 if (ap->pri < 0 || ap->pri >= JOBS_MAXPRI)
2007 return (EINVAL); 2010 return (EINVAL);

cvs diff -r1.21 -r1.22 src/sys/altq/altq_priq.c (expand / switch to unified diff)

--- src/sys/altq/altq_priq.c 2009/03/14 15:35:58 1.21
+++ src/sys/altq/altq_priq.c 2016/01/22 18:19:54 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: altq_priq.c,v 1.21 2009/03/14 15:35:58 dsl Exp $ */ 1/* $NetBSD: altq_priq.c,v 1.22 2016/01/22 18:19:54 christos Exp $ */
2/* $KAME: altq_priq.c,v 1.13 2005/04/13 03:44:25 suz Exp $ */ 2/* $KAME: altq_priq.c,v 1.13 2005/04/13 03:44:25 suz Exp $ */
3/* 3/*
4 * Copyright (C) 2000-2003 4 * Copyright (C) 2000-2003
5 * Sony Computer Science Laboratories Inc. All rights reserved. 5 * Sony Computer Science Laboratories Inc. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * priority queue 30 * priority queue
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: altq_priq.c,v 1.21 2009/03/14 15:35:58 dsl Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: altq_priq.c,v 1.22 2016/01/22 18:19:54 christos Exp $");
35 35
36#ifdef _KERNEL_OPT 36#ifdef _KERNEL_OPT
37#include "opt_altq.h" 37#include "opt_altq.h"
38#include "opt_inet.h" 38#include "opt_inet.h"
39#include "pf.h" 39#include "pf.h"
40#endif 40#endif
41 41
42#ifdef ALTQ_PRIQ /* priq is enabled by ALTQ_PRIQ option in opt_altq.h */ 42#ifdef ALTQ_PRIQ /* priq is enabled by ALTQ_PRIQ option in opt_altq.h */
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/malloc.h> 45#include <sys/malloc.h>
46#include <sys/mbuf.h> 46#include <sys/mbuf.h>
47#include <sys/socket.h> 47#include <sys/socket.h>
@@ -58,27 +58,27 @@ __KERNEL_RCSID(0, "$NetBSD: altq_priq.c, @@ -58,27 +58,27 @@ __KERNEL_RCSID(0, "$NetBSD: altq_priq.c,
58 58
59#if NPF > 0 59#if NPF > 0
60#include <net/pfvar.h> 60#include <net/pfvar.h>
61#endif 61#endif
62#include <altq/altq.h> 62#include <altq/altq.h>
63#include <altq/altq_conf.h> 63#include <altq/altq_conf.h>
64#include <altq/altq_priq.h> 64#include <altq/altq_priq.h>
65 65
66/* 66/*
67 * function prototypes 67 * function prototypes
68 */ 68 */
69#ifdef ALTQ3_COMPAT 69#ifdef ALTQ3_COMPAT
70static struct priq_if *priq_attach(struct ifaltq *, u_int); 70static struct priq_if *priq_attach(struct ifaltq *, u_int);
71static int priq_detach(struct priq_if *); 71static void priq_detach(struct priq_if *);
72#endif 72#endif
73static int priq_clear_interface(struct priq_if *); 73static int priq_clear_interface(struct priq_if *);
74static int priq_request(struct ifaltq *, int, void *); 74static int priq_request(struct ifaltq *, int, void *);
75static void priq_purge(struct priq_if *); 75static void priq_purge(struct priq_if *);
76static struct priq_class *priq_class_create(struct priq_if *, int, int, int, 76static struct priq_class *priq_class_create(struct priq_if *, int, int, int,
77 int); 77 int);
78static int priq_class_destroy(struct priq_class *); 78static int priq_class_destroy(struct priq_class *);
79static int priq_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); 79static int priq_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *);
80static struct mbuf *priq_dequeue(struct ifaltq *, int); 80static struct mbuf *priq_dequeue(struct ifaltq *, int);
81 81
82static int priq_addq(struct priq_class *, struct mbuf *); 82static int priq_addq(struct priq_class *, struct mbuf *);
83static struct mbuf *priq_getq(struct priq_class *); 83static struct mbuf *priq_getq(struct priq_class *);
84static struct mbuf *priq_pollq(struct priq_class *); 84static struct mbuf *priq_pollq(struct priq_class *);
@@ -638,80 +638,82 @@ priq_attach(struct ifaltq *ifq, u_int ba @@ -638,80 +638,82 @@ priq_attach(struct ifaltq *ifq, u_int ba
638 if (pif == NULL) 638 if (pif == NULL)
639 return (NULL); 639 return (NULL);
640 pif->pif_bandwidth = bandwidth; 640 pif->pif_bandwidth = bandwidth;
641 pif->pif_maxpri = -1; 641 pif->pif_maxpri = -1;
642 pif->pif_ifq = ifq; 642 pif->pif_ifq = ifq;
643 643
644 /* add this state to the priq list */ 644 /* add this state to the priq list */
645 pif->pif_next = pif_list; 645 pif->pif_next = pif_list;
646 pif_list = pif; 646 pif_list = pif;
647 647
648 return (pif); 648 return (pif);
649} 649}
650 650
651static int 651static void
652priq_detach(struct priq_if *pif) 652priq_detach(struct priq_if *pif)
653{ 653{
654 (void)priq_clear_interface(pif); 654 (void)priq_clear_interface(pif);
655 655
656 /* remove this interface from the pif list */ 656 /* remove this interface from the pif list */
657 if (pif_list == pif) 657 if (pif_list == pif)
658 pif_list = pif->pif_next; 658 pif_list = pif->pif_next;
659 else { 659 else {
660 struct priq_if *p; 660 struct priq_if *p;
661 661
662 for (p = pif_list; p != NULL; p = p->pif_next) 662 for (p = pif_list; p != NULL; p = p->pif_next)
663 if (p->pif_next == pif) { 663 if (p->pif_next == pif) {
664 p->pif_next = pif->pif_next; 664 p->pif_next = pif->pif_next;
665 break; 665 break;
666 } 666 }
667 ASSERT(p != NULL); 667 ASSERT(p != NULL);
668 } 668 }
669 669
670 free(pif, M_DEVBUF); 670 free(pif, M_DEVBUF);
671 return (0); 
672} 671}
673 672
674/* 673/*
675 * priq device interface 674 * priq device interface
676 */ 675 */
677int 676int
678priqopen(dev_t dev, int flag, int fmt, 677priqopen(dev_t dev, int flag, int fmt,
679 struct lwp *l) 678 struct lwp *l)
680{ 679{
681 /* everything will be done when the queueing scheme is attached. */ 680 /* everything will be done when the queueing scheme is attached. */
682 return 0; 681 return 0;
683} 682}
684 683
685int 684int
686priqclose(dev_t dev, int flag, int fmt, 685priqclose(dev_t dev, int flag, int fmt,
687 struct lwp *l) 686 struct lwp *l)
688{ 687{
689 struct priq_if *pif; 688 struct priq_if *pif;
690 int err, error = 0; 
691 689
692 while ((pif = pif_list) != NULL) { 690 while ((pif = pif_list) != NULL) {
693 /* destroy all */ 691 /* destroy all */
694 if (ALTQ_IS_ENABLED(pif->pif_ifq)) 692 if (ALTQ_IS_ENABLED(pif->pif_ifq))
695 altq_disable(pif->pif_ifq); 693 altq_disable(pif->pif_ifq);
696 694
697 err = altq_detach(pif->pif_ifq); 695 int error = altq_detach(pif->pif_ifq);
698 if (err == 0) 696 switch (error) {
699 err = priq_detach(pif); 697 case 0:
700 if (err != 0 && error == 0) 698 case ENXIO: /* already disabled */
701 error = err; 699 break;
 700 default:
 701 return error;
 702 }
 703 priq_detach(pif);
702 } 704 }
703 705
704 return error; 706 return 0;
705} 707}
706 708
707int 709int
708priqioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, 710priqioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag,
709 struct lwp *l) 711 struct lwp *l)
710{ 712{
711 struct priq_if *pif; 713 struct priq_if *pif;
712 struct priq_interface *ifacep; 714 struct priq_interface *ifacep;
713 int error = 0; 715 int error = 0;
714 716
715 /* check super-user privilege */ 717 /* check super-user privilege */
716 switch (cmd) { 718 switch (cmd) {
717 case PRIQ_GETSTATS: 719 case PRIQ_GETSTATS:
@@ -811,47 +813,48 @@ priqcmd_if_attach(struct priq_interface  @@ -811,47 +813,48 @@ priqcmd_if_attach(struct priq_interface
811 813
812 if ((ifp = ifunit(ap->ifname)) == NULL) 814 if ((ifp = ifunit(ap->ifname)) == NULL)
813 return (ENXIO); 815 return (ENXIO);
814 816
815 if ((pif = priq_attach(&ifp->if_snd, ap->arg)) == NULL) 817 if ((pif = priq_attach(&ifp->if_snd, ap->arg)) == NULL)
816 return (ENOMEM); 818 return (ENOMEM);
817 819
818 /* 820 /*
819 * set PRIQ to this ifnet structure. 821 * set PRIQ to this ifnet structure.
820 */ 822 */
821 if ((error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, pif, 823 if ((error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, pif,
822 priq_enqueue, priq_dequeue, priq_request, 824 priq_enqueue, priq_dequeue, priq_request,
823 &pif->pif_classifier, acc_classify)) != 0) 825 &pif->pif_classifier, acc_classify)) != 0)
824 (void)priq_detach(pif); 826 priq_detach(pif);
825 827
826 return (error); 828 return (error);
827} 829}
828 830
829static int 831static int
830priqcmd_if_detach(struct priq_interface *ap) 832priqcmd_if_detach(struct priq_interface *ap)
831{ 833{
832 struct priq_if *pif; 834 struct priq_if *pif;
833 int error; 835 int error;
834 836
835 if ((pif = altq_lookup(ap->ifname, ALTQT_PRIQ)) == NULL) 837 if ((pif = altq_lookup(ap->ifname, ALTQT_PRIQ)) == NULL)
836 return (EBADF); 838 return (EBADF);
837 839
838 if (ALTQ_IS_ENABLED(pif->pif_ifq)) 840 if (ALTQ_IS_ENABLED(pif->pif_ifq))
839 altq_disable(pif->pif_ifq); 841 altq_disable(pif->pif_ifq);
840 842
841 if ((error = altq_detach(pif->pif_ifq))) 843 if ((error = altq_detach(pif->pif_ifq)))
842 return (error); 844 return (error);
843 845
844 return priq_detach(pif); 846 priq_detach(pif);
 847 return 0;
845} 848}
846 849
847static int 850static int
848priqcmd_add_class(struct priq_add_class *ap) 851priqcmd_add_class(struct priq_add_class *ap)
849{ 852{
850 struct priq_if *pif; 853 struct priq_if *pif;
851 struct priq_class *cl; 854 struct priq_class *cl;
852 int qid; 855 int qid;
853 856
854 if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL) 857 if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
855 return (EBADF); 858 return (EBADF);
856 859
857 if (ap->pri < 0 || ap->pri >= PRIQ_MAXPRI) 860 if (ap->pri < 0 || ap->pri >= PRIQ_MAXPRI)