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-7diff -r1.24 -r1.25 src/sys/altq/altq_hfsc.c
(christos)
--- 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); | |
137 | static u_int64_t rtsc_y2x(struct runtime_sc *, u_int64_t); | 137 | static u_int64_t rtsc_y2x(struct runtime_sc *, u_int64_t); | |
138 | static u_int64_t rtsc_x2y(struct runtime_sc *, u_int64_t); | 138 | static u_int64_t rtsc_x2y(struct runtime_sc *, u_int64_t); | |
139 | static void rtsc_min(struct runtime_sc *, struct internal_sc *, | 139 | static 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 | |||
142 | static void get_class_stats(struct hfsc_classstats *, | 142 | static void get_class_stats(struct hfsc_classstats *, | |
143 | struct hfsc_class *); | 143 | struct hfsc_class *); | |
144 | static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_int32_t); | 144 | static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_int32_t); | |
145 | 145 | |||
146 | 146 | |||
147 | #ifdef ALTQ3_COMPAT | 147 | #ifdef ALTQ3_COMPAT | |
148 | static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int); | 148 | static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int); | |
149 | static int hfsc_detach(struct hfsc_if *); | 149 | static void hfsc_detach(struct hfsc_if *); | |
150 | static int hfsc_class_modify(struct hfsc_class *, struct service_curve *, | 150 | static 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 | |||
153 | static int hfsccmd_if_attach(struct hfsc_attach *); | 153 | static int hfsccmd_if_attach(struct hfsc_attach *); | |
154 | static int hfsccmd_if_detach(struct hfsc_interface *); | 154 | static int hfsccmd_if_detach(struct hfsc_interface *); | |
155 | static int hfsccmd_add_class(struct hfsc_add_class *); | 155 | static int hfsccmd_add_class(struct hfsc_add_class *); | |
156 | static int hfsccmd_delete_class(struct hfsc_delete_class *); | 156 | static int hfsccmd_delete_class(struct hfsc_delete_class *); | |
157 | static int hfsccmd_modify_class(struct hfsc_modify_class *); | 157 | static int hfsccmd_modify_class(struct hfsc_modify_class *); | |
158 | static int hfsccmd_add_filter(struct hfsc_add_filter *); | 158 | static int hfsccmd_add_filter(struct hfsc_add_filter *); | |
159 | static int hfsccmd_delete_filter(struct hfsc_delete_filter *); | 159 | static int hfsccmd_delete_filter(struct hfsc_delete_filter *); | |
160 | static int hfsccmd_class_stats(struct hfsc_class_stats *); | 160 | static int hfsccmd_class_stats(struct hfsc_class_stats *); | |
161 | 161 | |||
162 | altqdev_decl(hfsc); | 162 | altqdev_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 | |||
1730 | static int | 1730 | static void | |
1731 | hfsc_detach(struct hfsc_if *hif) | 1731 | hfsc_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 | |||
1757 | static int | 1755 | static int | |
1758 | hfsc_class_modify(struct hfsc_class *cl, struct service_curve *rsc, | 1756 | hfsc_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 | |||
1878 | int | 1876 | int | |
1879 | hfscclose(dev_t dev, int flag, int fmt, | 1877 | hfscclose(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 | |||
1900 | int | 1901 | int | |
1901 | hfscioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, | 1902 | hfscioctl(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 | |||
2023 | static int | 2024 | static int | |
2024 | hfsccmd_if_detach(struct hfsc_interface *ap) | 2025 | hfsccmd_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 | |||
2041 | static int | 2043 | static int | |
2042 | hfsccmd_add_class(struct hfsc_add_class *ap) | 2044 | hfsccmd_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 && |
--- 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 | */ | |
98 | static struct jobs_if *jobs_attach(struct ifaltq *, u_int, u_int, u_int); | 98 | static struct jobs_if *jobs_attach(struct ifaltq *, u_int, u_int, u_int); | |
99 | static int jobs_detach(struct jobs_if *); | 99 | static void jobs_detach(struct jobs_if *); | |
100 | static int jobs_clear_interface(struct jobs_if *); | 100 | static int jobs_clear_interface(struct jobs_if *); | |
101 | static int jobs_request(struct ifaltq *, int, void *); | 101 | static int jobs_request(struct ifaltq *, int, void *); | |
102 | static void jobs_purge(struct jobs_if *); | 102 | static void jobs_purge(struct jobs_if *); | |
103 | static struct jobs_class *jobs_class_create(struct jobs_if *, | 103 | static 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); | |
105 | static int jobs_class_destroy(struct jobs_class *); | 105 | static int jobs_class_destroy(struct jobs_class *); | |
106 | static int jobs_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); | 106 | static int jobs_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); | |
107 | static struct mbuf *jobs_dequeue(struct ifaltq *, int); | 107 | static struct mbuf *jobs_dequeue(struct ifaltq *, int); | |
108 | 108 | |||
109 | static int jobs_addq(struct jobs_class *, struct mbuf *, struct jobs_if*); | 109 | static int jobs_addq(struct jobs_class *, struct mbuf *, struct jobs_if*); | |
110 | static struct mbuf *jobs_getq(struct jobs_class *); | 110 | static struct mbuf *jobs_getq(struct jobs_class *); | |
111 | static struct mbuf *jobs_pollq(struct jobs_class *); | 111 | static struct mbuf *jobs_pollq(struct jobs_class *); | |
112 | static void jobs_purgeq(struct jobs_class *); | 112 | static 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 | |||
187 | static int | 187 | static void | |
188 | jobs_detach(struct jobs_if *jif) | 188 | jobs_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 | */ | |
213 | static int | 212 | static int | |
214 | jobs_clear_interface(struct jobs_if *jif) | 213 | jobs_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 | |||
1835 | int | 1834 | int | |
1836 | jobsclose(dev_t dev, int flag, int fmt, | 1835 | jobsclose(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 | |||
1857 | int | 1859 | int | |
1858 | jobsioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, | 1860 | jobsioctl(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 | |||
1979 | static int | 1981 | static int | |
1980 | jobscmd_if_detach(struct jobs_interface *ap) | 1982 | jobscmd_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 | |||
1997 | static int | 2000 | static int | |
1998 | jobscmd_add_class(struct jobs_add_class *ap) | 2001 | jobscmd_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); |
--- 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 | |
70 | static struct priq_if *priq_attach(struct ifaltq *, u_int); | 70 | static struct priq_if *priq_attach(struct ifaltq *, u_int); | |
71 | static int priq_detach(struct priq_if *); | 71 | static void priq_detach(struct priq_if *); | |
72 | #endif | 72 | #endif | |
73 | static int priq_clear_interface(struct priq_if *); | 73 | static int priq_clear_interface(struct priq_if *); | |
74 | static int priq_request(struct ifaltq *, int, void *); | 74 | static int priq_request(struct ifaltq *, int, void *); | |
75 | static void priq_purge(struct priq_if *); | 75 | static void priq_purge(struct priq_if *); | |
76 | static struct priq_class *priq_class_create(struct priq_if *, int, int, int, | 76 | static struct priq_class *priq_class_create(struct priq_if *, int, int, int, | |
77 | int); | 77 | int); | |
78 | static int priq_class_destroy(struct priq_class *); | 78 | static int priq_class_destroy(struct priq_class *); | |
79 | static int priq_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); | 79 | static int priq_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); | |
80 | static struct mbuf *priq_dequeue(struct ifaltq *, int); | 80 | static struct mbuf *priq_dequeue(struct ifaltq *, int); | |
81 | 81 | |||
82 | static int priq_addq(struct priq_class *, struct mbuf *); | 82 | static int priq_addq(struct priq_class *, struct mbuf *); | |
83 | static struct mbuf *priq_getq(struct priq_class *); | 83 | static struct mbuf *priq_getq(struct priq_class *); | |
84 | static struct mbuf *priq_pollq(struct priq_class *); | 84 | static 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 | |||
651 | static int | 651 | static void | |
652 | priq_detach(struct priq_if *pif) | 652 | priq_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 | */ | |
677 | int | 676 | int | |
678 | priqopen(dev_t dev, int flag, int fmt, | 677 | priqopen(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 | |||
685 | int | 684 | int | |
686 | priqclose(dev_t dev, int flag, int fmt, | 685 | priqclose(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 | |||
707 | int | 709 | int | |
708 | priqioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, | 710 | priqioctl(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 | |||
829 | static int | 831 | static int | |
830 | priqcmd_if_detach(struct priq_interface *ap) | 832 | priqcmd_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 | |||
847 | static int | 850 | static int | |
848 | priqcmd_add_class(struct priq_add_class *ap) | 851 | priqcmd_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) |