Protect the ALTQ state that's exposed to the ifqueue if the ifq->ifq_lock. This requires exposing some implementation details to ALTQ, which is guarded by an __IFQ_PRIVATE define.diff -r1.22.6.1 -r1.22.6.1.2.1 src/sys/altq/altq_cdnr.c
(thorpej)
--- src/sys/altq/altq_cdnr.c 2023/11/11 13:16:30 1.22.6.1
+++ src/sys/altq/altq_cdnr.c 2023/11/15 02:19:00 1.22.6.1.2.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: altq_cdnr.c,v 1.22.6.1 2023/11/11 13:16:30 thorpej Exp $ */ | 1 | /* $NetBSD: altq_cdnr.c,v 1.22.6.1.2.1 2023/11/15 02:19:00 thorpej Exp $ */ | |
2 | /* $KAME: altq_cdnr.c,v 1.15 2005/04/13 03:44:24 suz Exp $ */ | 2 | /* $KAME: altq_cdnr.c,v 1.15 2005/04/13 03:44:24 suz Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (C) 1999-2002 | 5 | * Copyright (C) 1999-2002 | |
6 | * Sony Computer Science Laboratories Inc. All rights reserved. | 6 | * Sony Computer Science Laboratories Inc. All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -18,27 +18,27 @@ | @@ -18,27 +18,27 @@ | |||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.22.6.1 2023/11/11 13:16:30 thorpej Exp $"); | 31 | __KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.22.6.1.2.1 2023/11/15 02:19:00 thorpej Exp $"); | |
32 | 32 | |||
33 | #ifdef _KERNEL_OPT | 33 | #ifdef _KERNEL_OPT | |
34 | #include "opt_altq.h" | 34 | #include "opt_altq.h" | |
35 | #include "opt_inet.h" | 35 | #include "opt_inet.h" | |
36 | #endif | 36 | #endif | |
37 | 37 | |||
38 | #include <sys/param.h> | 38 | #include <sys/param.h> | |
39 | #include <sys/malloc.h> | 39 | #include <sys/malloc.h> | |
40 | #include <sys/mbuf.h> | 40 | #include <sys/mbuf.h> | |
41 | #include <sys/socket.h> | 41 | #include <sys/socket.h> | |
42 | #include <sys/sockio.h> | 42 | #include <sys/sockio.h> | |
43 | #include <sys/systm.h> | 43 | #include <sys/systm.h> | |
44 | #include <sys/proc.h> | 44 | #include <sys/proc.h> | |
@@ -128,31 +128,36 @@ altqdev_decl(cdnr); | @@ -128,31 +128,36 @@ altqdev_decl(cdnr); | |||
128 | /* | 128 | /* | |
129 | * top level input function called from ip_input. | 129 | * top level input function called from ip_input. | |
130 | * should be called before converting header fields to host-byte-order. | 130 | * should be called before converting header fields to host-byte-order. | |
131 | */ | 131 | */ | |
132 | int | 132 | int | |
133 | altq_cdnr_input(struct mbuf *m, int af) | 133 | altq_cdnr_input(struct mbuf *m, int af) | |
134 | { | 134 | { | |
135 | struct ifnet *ifp; | 135 | struct ifnet *ifp; | |
136 | struct ip *ip; | 136 | struct ip *ip; | |
137 | struct top_cdnr *top; | 137 | struct top_cdnr *top; | |
138 | struct tc_action *tca; | 138 | struct tc_action *tca; | |
139 | struct cdnr_block *cb; | 139 | struct cdnr_block *cb; | |
140 | struct cdnr_pktinfo pktinfo; | 140 | struct cdnr_pktinfo pktinfo; | |
141 | bool is_cnding = false; | |||
141 | 142 | |||
142 | ifp = m_get_rcvif_NOMPSAFE(m); | 143 | ifp = m_get_rcvif_NOMPSAFE(m); | |
143 | if (!ALTQ_IS_CNDTNING(&ifp->if_snd)) | 144 | mutex_enter(ifp->if_snd.ifq_lock); | |
145 | is_cnding = ALTQ_IS_CNDTNING(&ifp->if_snd); | |||
146 | mutex_exit(ifp->if_snd.ifq_lock); | |||
147 | if (!is_cnding) { | |||
144 | /* traffic conditioner is not enabled on this interface */ | 148 | /* traffic conditioner is not enabled on this interface */ | |
145 | return (1); | 149 | return (1); | |
150 | } | |||
146 | 151 | |||
147 | top = ifp->if_snd.ifq_altq->altq_cdnr; | 152 | top = ifp->if_snd.ifq_altq->altq_cdnr; | |
148 | 153 | |||
149 | ip = mtod(m, struct ip *); | 154 | ip = mtod(m, struct ip *); | |
150 | #ifdef INET6 | 155 | #ifdef INET6 | |
151 | if (af == AF_INET6) { | 156 | if (af == AF_INET6) { | |
152 | u_int32_t flowlabel; | 157 | u_int32_t flowlabel; | |
153 | 158 | |||
154 | flowlabel = ((struct ip6_hdr *)ip)->ip6_flow; | 159 | flowlabel = ((struct ip6_hdr *)ip)->ip6_flow; | |
155 | pktinfo.pkt_dscp = (ntohl(flowlabel) >> 20) & DSCP_MASK; | 160 | pktinfo.pkt_dscp = (ntohl(flowlabel) >> 20) & DSCP_MASK; | |
156 | } else | 161 | } else | |
157 | #endif | 162 | #endif | |
158 | pktinfo.pkt_dscp = ip->ip_tos & DSCP_MASK; | 163 | pktinfo.pkt_dscp = ip->ip_tos & DSCP_MASK; | |
@@ -418,50 +423,59 @@ top_create(struct ifaltq *ifq) | @@ -418,50 +423,59 @@ top_create(struct ifaltq *ifq) | |||
418 | 423 | |||
419 | LIST_INSERT_HEAD(&tcb_list, top, tc_next); | 424 | LIST_INSERT_HEAD(&tcb_list, top, tc_next); | |
420 | 425 | |||
421 | ifq->altq_cdnr = top; | 426 | ifq->altq_cdnr = top; | |
422 | 427 | |||
423 | return (top); | 428 | return (top); | |
424 | } | 429 | } | |
425 | 430 | |||
426 | static int | 431 | static int | |
427 | top_destroy(struct top_cdnr *top) | 432 | top_destroy(struct top_cdnr *top) | |
428 | { | 433 | { | |
429 | struct cdnr_block *cb; | 434 | struct cdnr_block *cb; | |
430 | 435 | |||
436 | mutex_enter(top->tc_ifq->altq_ifq->ifq_lock); | |||
431 | if (ALTQ_IS_CNDTNING(top->tc_ifq)) | 437 | if (ALTQ_IS_CNDTNING(top->tc_ifq)) | |
432 | ALTQ_CLEAR_CNDTNING(top->tc_ifq); | 438 | ALTQ_CLEAR_CNDTNING(top->tc_ifq); | |
433 | top->tc_ifq->altq_cdnr = NULL; | 439 | top->tc_ifq->altq_cdnr = NULL; | |
440 | mutex_exit(top->tc_ifq->altq_ifq->ifq_lock); | |||
434 | 441 | |||
435 | /* | 442 | /* | |
436 | * destroy all the conditioner elements belonging to this interface | 443 | * destroy all the conditioner elements belonging to this interface | |
437 | */ | 444 | */ | |
438 | while ((cb = LIST_FIRST(&top->tc_elements)) != NULL) { | 445 | while ((cb = LIST_FIRST(&top->tc_elements)) != NULL) { | |
439 | while (cb != NULL && cb->cb_ref > 0) | 446 | while (cb != NULL && cb->cb_ref > 0) | |
440 | cb = LIST_NEXT(cb, cb_next); | 447 | cb = LIST_NEXT(cb, cb_next); | |
441 | if (cb != NULL) | 448 | if (cb != NULL) | |
442 | generic_element_destroy(cb); | 449 | generic_element_destroy(cb); | |
443 | } | 450 | } | |
444 | 451 | |||
445 | LIST_REMOVE(top, tc_next); | 452 | LIST_REMOVE(top, tc_next); | |
446 | 453 | |||
447 | cdnr_cbdestroy(top); | 454 | cdnr_cbdestroy(top); | |
448 | 455 | |||
449 | /* if there is no active conditioner, remove the input hook */ | 456 | /* if there is no active conditioner, remove the input hook */ | |
450 | if (altq_input != NULL) { | 457 | if (altq_input != NULL) { | |
451 | LIST_FOREACH(top, &tcb_list, tc_next) | 458 | bool is_cnding = false; | |
459 | ||||
460 | LIST_FOREACH(top, &tcb_list, tc_next) { | |||
461 | mutex_enter(top->tc_ifq->altq_ifq->ifq_lock); | |||
452 | if (ALTQ_IS_CNDTNING(top->tc_ifq)) | 462 | if (ALTQ_IS_CNDTNING(top->tc_ifq)) | |
463 | is_cnding = true; | |||
464 | mutex_exit(top->tc_ifq->altq_ifq->ifq_lock); | |||
465 | if (is_cnding) | |||
453 | break; | 466 | break; | |
454 | if (top == NULL) | 467 | } | |
468 | if (!is_cnding) | |||
455 | altq_input = NULL; | 469 | altq_input = NULL; | |
456 | } | 470 | } | |
457 | 471 | |||
458 | return (0); | 472 | return (0); | |
459 | } | 473 | } | |
460 | 474 | |||
461 | /* | 475 | /* | |
462 | * simple tc elements without input function (e.g., dropper and makers). | 476 | * simple tc elements without input function (e.g., dropper and makers). | |
463 | */ | 477 | */ | |
464 | static struct cdnr_block * | 478 | static struct cdnr_block * | |
465 | element_create(struct top_cdnr *top, struct tc_action *action) | 479 | element_create(struct top_cdnr *top, struct tc_action *action) | |
466 | { | 480 | { | |
467 | struct cdnr_block *cb; | 481 | struct cdnr_block *cb; | |
@@ -1210,39 +1224,50 @@ cdnrioctl(dev_t dev, ioctlcmd_t cmd, voi | @@ -1210,39 +1224,50 @@ cdnrioctl(dev_t dev, ioctlcmd_t cmd, voi | |||
1210 | break; | 1224 | break; | |
1211 | 1225 | |||
1212 | case CDNR_ENABLE: | 1226 | case CDNR_ENABLE: | |
1213 | case CDNR_DISABLE: | 1227 | case CDNR_DISABLE: | |
1214 | ifacep = (struct cdnr_interface *)addr; | 1228 | ifacep = (struct cdnr_interface *)addr; | |
1215 | if ((top = tcb_lookup(ifacep->cdnr_ifname)) == NULL) { | 1229 | if ((top = tcb_lookup(ifacep->cdnr_ifname)) == NULL) { | |
1216 | error = EBADF; | 1230 | error = EBADF; | |
1217 | break; | 1231 | break; | |
1218 | } | 1232 | } | |
1219 | 1233 | |||
1220 | switch (cmd) { | 1234 | switch (cmd) { | |
1221 | 1235 | |||
1222 | case CDNR_ENABLE: | 1236 | case CDNR_ENABLE: | |
1237 | mutex_enter(top->tc_ifq->altq_ifq->ifq_lock); | |||
1223 | ALTQ_SET_CNDTNING(top->tc_ifq); | 1238 | ALTQ_SET_CNDTNING(top->tc_ifq); | |
1239 | mutex_exit(top->tc_ifq->altq_ifq->ifq_lock); | |||
1224 | if (altq_input == NULL) | 1240 | if (altq_input == NULL) | |
1225 | altq_input = altq_cdnr_input; | 1241 | altq_input = altq_cdnr_input; | |
1226 | break; | 1242 | break; | |
1227 | 1243 | |||
1228 | case CDNR_DISABLE: | 1244 | case CDNR_DISABLE: { | |
1245 | bool is_cnding = false; | |||
1246 | mutex_enter(top->tc_ifq->altq_ifq->ifq_lock); | |||
1229 | ALTQ_CLEAR_CNDTNING(top->tc_ifq); | 1247 | ALTQ_CLEAR_CNDTNING(top->tc_ifq); | |
1230 | LIST_FOREACH(top, &tcb_list, tc_next) | 1248 | mutex_exit(top->tc_ifq->altq_ifq->ifq_lock); | |
1249 | LIST_FOREACH(top, &tcb_list, tc_next) { | |||
1250 | mutex_enter(top->tc_ifq->altq_ifq->ifq_lock); | |||
1231 | if (ALTQ_IS_CNDTNING(top->tc_ifq)) | 1251 | if (ALTQ_IS_CNDTNING(top->tc_ifq)) | |
1252 | is_cnding = true; | |||
1253 | mutex_exit(top->tc_ifq->altq_ifq->ifq_lock); | |||
1254 | if (is_cnding) | |||
1232 | break; | 1255 | break; | |
1233 | if (top == NULL) | 1256 | } | |
1257 | if (!is_cnding) | |||
1234 | altq_input = NULL; | 1258 | altq_input = NULL; | |
1235 | break; | 1259 | break; | |
1260 | } | |||
1236 | } | 1261 | } | |
1237 | break; | 1262 | break; | |
1238 | 1263 | |||
1239 | case CDNR_ADD_ELEM: | 1264 | case CDNR_ADD_ELEM: | |
1240 | error = cdnrcmd_add_element((struct cdnr_add_element *)addr); | 1265 | error = cdnrcmd_add_element((struct cdnr_add_element *)addr); | |
1241 | break; | 1266 | break; | |
1242 | 1267 | |||
1243 | case CDNR_DEL_ELEM: | 1268 | case CDNR_DEL_ELEM: | |
1244 | error = cdnrcmd_delete_element((struct cdnr_delete_element *)addr); | 1269 | error = cdnrcmd_delete_element((struct cdnr_delete_element *)addr); | |
1245 | break; | 1270 | break; | |
1246 | 1271 | |||
1247 | case CDNR_ADD_TBM: | 1272 | case CDNR_ADD_TBM: | |
1248 | error = cdnrcmd_add_tbm((struct cdnr_add_tbmeter *)addr); | 1273 | error = cdnrcmd_add_tbm((struct cdnr_add_tbmeter *)addr); |
--- src/sys/altq/altq_subr.c 2023/11/11 13:16:30 1.33.46.1
+++ src/sys/altq/altq_subr.c 2023/11/15 02:19:00 1.33.46.1.2.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: altq_subr.c,v 1.33.46.1 2023/11/11 13:16:30 thorpej Exp $ */ | 1 | /* $NetBSD: altq_subr.c,v 1.33.46.1.2.1 2023/11/15 02:19:00 thorpej Exp $ */ | |
2 | /* $KAME: altq_subr.c,v 1.24 2005/04/13 03:44:25 suz Exp $ */ | 2 | /* $KAME: altq_subr.c,v 1.24 2005/04/13 03:44:25 suz Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (C) 1997-2003 | 5 | * Copyright (C) 1997-2003 | |
6 | * Sony Computer Science Laboratories Inc. All rights reserved. | 6 | * Sony Computer Science Laboratories Inc. All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -18,34 +18,36 @@ | @@ -18,34 +18,36 @@ | |||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __KERNEL_RCSID(0, "$NetBSD: altq_subr.c,v 1.33.46.1 2023/11/11 13:16:30 thorpej Exp $"); | 31 | __KERNEL_RCSID(0, "$NetBSD: altq_subr.c,v 1.33.46.1.2.1 2023/11/15 02:19:00 thorpej Exp $"); | |
32 | 32 | |||
33 | #ifdef _KERNEL_OPT | 33 | #ifdef _KERNEL_OPT | |
34 | #include "opt_altq.h" | 34 | #include "opt_altq.h" | |
35 | #include "opt_inet.h" | 35 | #include "opt_inet.h" | |
36 | #include "pf.h" | 36 | #include "pf.h" | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #define __IFQ_PRIVATE | |||
40 | ||||
39 | #include <sys/param.h> | 41 | #include <sys/param.h> | |
40 | #include <sys/malloc.h> | 42 | #include <sys/malloc.h> | |
41 | #include <sys/mbuf.h> | 43 | #include <sys/mbuf.h> | |
42 | #include <sys/systm.h> | 44 | #include <sys/systm.h> | |
43 | #include <sys/proc.h> | 45 | #include <sys/proc.h> | |
44 | #include <sys/socket.h> | 46 | #include <sys/socket.h> | |
45 | #include <sys/socketvar.h> | 47 | #include <sys/socketvar.h> | |
46 | #include <sys/kernel.h> | 48 | #include <sys/kernel.h> | |
47 | #include <sys/kmem.h> | 49 | #include <sys/kmem.h> | |
48 | #include <sys/errno.h> | 50 | #include <sys/errno.h> | |
49 | #include <sys/syslog.h> | 51 | #include <sys/syslog.h> | |
50 | #include <sys/sysctl.h> | 52 | #include <sys/sysctl.h> | |
51 | #include <sys/queue.h> | 53 | #include <sys/queue.h> | |
@@ -130,156 +132,205 @@ altq_alloc(struct ifqueue *ifq, struct i | @@ -130,156 +132,205 @@ altq_alloc(struct ifqueue *ifq, struct i | |||
130 | } | 132 | } | |
131 | if (ifp != NULL) { | 133 | if (ifp != NULL) { | |
132 | ifq->ifq_altq->altq_ifp = ifp; | 134 | ifq->ifq_altq->altq_ifp = ifp; | |
133 | } | 135 | } | |
134 | } | 136 | } | |
135 | 137 | |||
136 | /* | 138 | /* | |
137 | * Free the ifaltq structure associated with an ifqueue. | 139 | * Free the ifaltq structure associated with an ifqueue. | |
138 | */ | 140 | */ | |
139 | void | 141 | void | |
140 | altq_free(struct ifqueue *ifq) | 142 | altq_free(struct ifqueue *ifq) | |
141 | { | 143 | { | |
142 | if (ifq->ifq_altq != NULL) { | 144 | if (ifq->ifq_altq != NULL) { | |
145 | /* | |||
146 | * No need to pre-flight these calls; both can handle | |||
147 | * the not-enabled / not-attached scenarios. | |||
148 | */ | |||
149 | altq_disable(ifq->ifq_altq); | |||
150 | altq_detach(ifq->ifq_altq); | |||
151 | ||||
143 | ifq->ifq_altq->altq_ifp = NULL; | 152 | ifq->ifq_altq->altq_ifp = NULL; | |
144 | kmem_free(ifq->ifq_altq, sizeof(*ifq->ifq_altq)); | 153 | kmem_free(ifq->ifq_altq, sizeof(*ifq->ifq_altq)); | |
145 | ifq->ifq_altq = NULL; | 154 | ifq->ifq_altq = NULL; | |
146 | } | 155 | } | |
147 | } | 156 | } | |
148 | 157 | |||
149 | /* | 158 | /* | |
150 | * Mark's a device's send queue as being ready for (as in | 159 | * Mark's a device's send queue as being ready for (as in | |
151 | * "knowledgeable about") ALTQ processing. | 160 | * "knowledgeable about") ALTQ processing. | |
152 | */ | 161 | */ | |
153 | void | 162 | void | |
154 | altq_set_ready(struct ifqueue *ifq) | 163 | altq_set_ready(struct ifqueue *ifq) | |
155 | { | 164 | { | |
156 | altq_alloc(ifq, NULL); | 165 | altq_alloc(ifq, NULL); | |
157 | ifq->ifq_altq->altq_flags = ALTQF_READY; | 166 | ifq->ifq_altq->altq_flags |= ALTQF_READY; | |
158 | } | 167 | } | |
159 | 168 | |||
160 | /* look up the queue state by the interface name and the queueing type. */ | 169 | /* look up the queue state by the interface name and the queueing type. */ | |
161 | void * | 170 | void * | |
162 | altq_lookup(char *name, int type) | 171 | altq_lookup(char *name, int type) | |
163 | { | 172 | { | |
164 | struct ifnet *ifp; | 173 | struct ifnet *ifp; | |
165 | 174 | |||
166 | if ((ifp = ifunit(name)) != NULL) { | 175 | if ((ifp = ifunit(name)) != NULL) { | |
167 | struct ifaltq *altq = ifp->if_snd.ifq_altq; | 176 | struct ifaltq *altq = ifp->if_snd.ifq_altq; | |
168 | if (type != ALTQT_NONE && altq->altq_type == type) | 177 | if (type != ALTQT_NONE && altq->altq_type == type) | |
169 | return (altq->altq_disc); | 178 | return (altq->altq_disc); | |
170 | } | 179 | } | |
171 | 180 | |||
172 | return NULL; | 181 | return NULL; | |
173 | } | 182 | } | |
174 | 183 | |||
175 | int | 184 | int | |
176 | altq_attach(struct ifaltq *ifq, int type, void *discipline, | 185 | altq_attach(struct ifaltq *altq, int type, void *discipline, | |
177 | int (*enqueue)(struct ifaltq *, struct mbuf *), | 186 | int (*enqueue)(struct ifaltq *, struct mbuf *), | |
178 | struct mbuf *(*dequeue)(struct ifaltq *, int), | 187 | struct mbuf *(*dequeue)(struct ifaltq *, int), | |
179 | int (*request)(struct ifaltq *, int, void *), | 188 | int (*request)(struct ifaltq *, int, void *), | |
180 | void *clfier, void *(*classify)(void *, struct mbuf *, int)) | 189 | void *clfier, void *(*classify)(void *, struct mbuf *, int)) | |
181 | { | 190 | { | |
182 | if (!ALTQ_IS_READY(ifq)) | 191 | struct ifqueue *ifq = altq->altq_ifq; | |
183 | return ENXIO; | 192 | int error = 0; | |
193 | ||||
194 | mutex_enter(ifq->ifq_lock); | |||
195 | ||||
196 | if (!ALTQ_IS_READY(ifq)) { | |||
197 | error = ENXIO; | |||
198 | goto out; | |||
199 | } | |||
184 | 200 | |||
185 | #ifdef ALTQ3_COMPAT | 201 | #ifdef ALTQ3_COMPAT | |
186 | /* | 202 | /* | |
187 | * pfaltq can override the existing discipline, but altq3 cannot. | 203 | * pfaltq can override the existing discipline, but altq3 cannot. | |
188 | * check these if clfier is not NULL (which implies altq3). | 204 | * check these if clfier is not NULL (which implies altq3). | |
189 | */ | 205 | */ | |
190 | if (clfier != NULL) { | 206 | if (clfier != NULL) { | |
191 | if (ALTQ_IS_ENABLED(ifq)) | 207 | if (ALTQ_IS_ENABLED(ifq)) { | |
192 | return EBUSY; | 208 | error = EBUSY; | |
193 | if (ALTQ_IS_ATTACHED(ifq)) | 209 | goto out; | |
194 | return EEXIST; | 210 | } | |
211 | if (ALTQ_IS_ATTACHED(ifq)) { | |||
212 | error = EEXIST; | |||
213 | goto out; | |||
214 | } | |||
195 | } | 215 | } | |
196 | #endif | 216 | #endif | |
197 | ifq->altq_type = type; | 217 | altq->altq_type = type; | |
198 | ifq->altq_disc = discipline; | 218 | altq->altq_disc = discipline; | |
199 | ifq->altq_enqueue = enqueue; | 219 | altq->altq_enqueue = enqueue; | |
200 | ifq->altq_dequeue = dequeue; | 220 | altq->altq_dequeue = dequeue; | |
201 | ifq->altq_request = request; | 221 | altq->altq_request = request; | |
202 | ifq->altq_clfier = clfier; | 222 | altq->altq_clfier = clfier; | |
203 | ifq->altq_classify = classify; | 223 | altq->altq_classify = classify; | |
204 | ifq->altq_flags &= (ALTQF_CANTCHANGE|ALTQF_ENABLED); | 224 | altq->altq_flags &= (ALTQF_CANTCHANGE|ALTQF_ENABLED); | |
205 | #ifdef ALTQ3_COMPAT | 225 | #ifdef ALTQ3_COMPAT | |
206 | #ifdef ALTQ_KLD | 226 | #ifdef ALTQ_KLD | |
207 | altq_module_incref(type); | 227 | altq_module_incref(type); | |
208 | #endif | 228 | #endif | |
209 | #endif | 229 | #endif | |
210 | return 0; | 230 | out: | |
231 | mutex_exit(ifq->ifq_lock); | |||
232 | return error; | |||
211 | } | 233 | } | |
212 | 234 | |||
213 | int | 235 | int | |
214 | altq_detach(struct ifaltq *ifq) | 236 | altq_detach(struct ifaltq *altq) | |
215 | { | 237 | { | |
216 | if (!ALTQ_IS_READY(ifq)) | 238 | struct ifqueue *ifq = altq->altq_ifq; | |
217 | return ENXIO; | 239 | int error = 0; | |
218 | if (ALTQ_IS_ENABLED(ifq)) | 240 | ||
219 | return EBUSY; | 241 | mutex_enter(ifq->ifq_lock); | |
220 | if (!ALTQ_IS_ATTACHED(ifq)) | 242 | ||
221 | return (0); | 243 | if (!ALTQ_IS_READY(ifq)) { | |
244 | error = ENXIO; | |||
245 | goto out; | |||
246 | } | |||
247 | if (ALTQ_IS_ENABLED(ifq)) { | |||
248 | error = EBUSY; | |||
249 | goto out; | |||
250 | } | |||
251 | if (!ALTQ_IS_ATTACHED(ifq)) { | |||
252 | goto out; | |||
253 | } | |||
254 | ||||
222 | #ifdef ALTQ3_COMPAT | 255 | #ifdef ALTQ3_COMPAT | |
223 | #ifdef ALTQ_KLD | 256 | #ifdef ALTQ_KLD | |
224 | altq_module_declref(ifq->altq_type); | 257 | altq_module_declref(ifq->altq_type); | |
225 | #endif | 258 | #endif | |
226 | #endif | 259 | #endif | |
227 | 260 | |||
228 | ifq->altq_type = ALTQT_NONE; | 261 | altq->altq_type = ALTQT_NONE; | |
229 | ifq->altq_disc = NULL; | 262 | altq->altq_disc = NULL; | |
230 | ifq->altq_enqueue = NULL; | 263 | altq->altq_enqueue = NULL; | |
231 | ifq->altq_dequeue = NULL; | 264 | altq->altq_dequeue = NULL; | |
232 | ifq->altq_request = NULL; | 265 | altq->altq_request = NULL; | |
233 | ifq->altq_clfier = NULL; | 266 | altq->altq_clfier = NULL; | |
234 | ifq->altq_classify = NULL; | 267 | altq->altq_classify = NULL; | |
235 | ifq->altq_flags &= ALTQF_CANTCHANGE; | 268 | altq->altq_flags &= ALTQF_CANTCHANGE; | |
236 | return 0; | 269 | out: | |
270 | mutex_exit(ifq->ifq_lock); | |||
271 | return error; | |||
237 | } | 272 | } | |
238 | 273 | |||
239 | int | 274 | int | |
240 | altq_enable(struct ifaltq *ifq) | 275 | altq_enable(struct ifaltq *altq) | |
241 | { | 276 | { | |
242 | int s; | 277 | struct ifqueue *ifq = altq->altq_ifq; | |
278 | struct mbuf *m = NULL; | |||
279 | int error = 0; | |||
243 | 280 | |||
244 | if (!ALTQ_IS_READY(ifq)) | 281 | mutex_enter(ifq->ifq_lock); | |
245 | return ENXIO; | |||
246 | if (ALTQ_IS_ENABLED(ifq)) | |||
247 | return 0; | |||
248 | 282 | |||
249 | s = splnet(); | 283 | if (!ALTQ_IS_READY(ifq)) { | |
250 | IFQ_PURGE(ifq->altq_ifq); | 284 | error = ENXIO; | |
251 | ASSERT(ALTQ_GET_LEN(ifq) == 0); | 285 | goto out; | |
252 | ifq->altq_flags |= ALTQF_ENABLED; | 286 | } | |
253 | if (ifq->altq_clfier != NULL) | 287 | if (ALTQ_IS_ENABLED(ifq)) { | |
254 | ifq->altq_flags |= ALTQF_CLASSIFY; | 288 | goto out; | |
255 | splx(s); | 289 | } | |
256 | 290 | |||
257 | return 0; | 291 | m = ifq_purge_locked(ifq); | |
292 | ASSERT(ALTQ_GET_LEN(altq) == 0); | |||
293 | altq->altq_flags |= ALTQF_ENABLED; | |||
294 | if (altq->altq_clfier != NULL) | |||
295 | altq->altq_flags |= ALTQF_CLASSIFY; | |||
296 | out: | |||
297 | mutex_exit(ifq->ifq_lock); | |||
298 | if (m != NULL) { | |||
299 | ifq_purge_free(m); | |||
300 | } | |||
301 | return error; | |||
258 | } | 302 | } | |
259 | 303 | |||
260 | int | 304 | int | |
261 | altq_disable(struct ifaltq *ifq) | 305 | altq_disable(struct ifaltq *altq) | |
262 | { | 306 | { | |
263 | int s; | 307 | struct ifqueue *ifq = altq->altq_ifq; | |
308 | struct mbuf *m = NULL; | |||
264 | 309 | |||
265 | if (!ALTQ_IS_ENABLED(ifq)) | 310 | mutex_enter(ifq->ifq_lock); | |
266 | return 0; | |||
267 | 311 | |||
268 | s = splnet(); | 312 | if (!ALTQ_IS_ENABLED(ifq)) { | |
269 | IFQ_PURGE(ifq->altq_ifq); | 313 | goto out; | |
270 | ASSERT(ALTQ_GET_LEN(ifq) == 0); | 314 | } | |
271 | ifq->altq_flags &= ~(ALTQF_ENABLED|ALTQF_CLASSIFY); | 315 | ||
272 | splx(s); | 316 | m = ifq_purge_locked(ifq); | |
317 | ASSERT(ALTQ_GET_LEN(altq) == 0); | |||
318 | altq->altq_flags &= ~(ALTQF_ENABLED|ALTQF_CLASSIFY); | |||
319 | out: | |||
320 | mutex_exit(ifq->ifq_lock); | |||
321 | if (m != NULL) { | |||
322 | ifq_purge_free(m); | |||
323 | } | |||
273 | return 0; | 324 | return 0; | |
274 | } | 325 | } | |
275 | 326 | |||
276 | #ifdef ALTQ_DEBUG | 327 | #ifdef ALTQ_DEBUG | |
277 | void | 328 | void | |
278 | altq_assert(const char *file, int line, const char *failedexpr) | 329 | altq_assert(const char *file, int line, const char *failedexpr) | |
279 | { | 330 | { | |
280 | (void)printf("altq assertion \"%s\" failed: file \"%s\", line %d\n", | 331 | (void)printf("altq assertion \"%s\" failed: file \"%s\", line %d\n", | |
281 | failedexpr, file, line); | 332 | failedexpr, file, line); | |
282 | panic("altq assertion"); | 333 | panic("altq assertion"); | |
283 | /* NOTREACHED */ | 334 | /* NOTREACHED */ | |
284 | } | 335 | } | |
285 | #endif | 336 | #endif |
--- src/sys/net/if.c 2023/11/15 02:08:33 1.529.2.1.2.2
+++ src/sys/net/if.c 2023/11/15 02:19:00 1.529.2.1.2.3
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if.c,v 1.529.2.1.2.2 2023/11/15 02:08:33 thorpej Exp $ */ | 1 | /* $NetBSD: if.c,v 1.529.2.1.2.3 2023/11/15 02:19:00 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1999, 2000, 2001, 2008, 2023 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999, 2000, 2001, 2008, 2023 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by William Studenmund and Jason R. Thorpe. | 8 | * by William Studenmund and Jason R. Thorpe. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -80,37 +80,39 @@ | @@ -80,37 +80,39 @@ | |||
80 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 80 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
81 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 81 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
82 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 82 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
83 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 83 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
84 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 84 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
85 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 85 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
86 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 86 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
87 | * SUCH DAMAGE. | 87 | * SUCH DAMAGE. | |
88 | * | 88 | * | |
89 | * @(#)if.c 8.5 (Berkeley) 1/9/95 | 89 | * @(#)if.c 8.5 (Berkeley) 1/9/95 | |
90 | */ | 90 | */ | |
91 | 91 | |||
92 | #include <sys/cdefs.h> | 92 | #include <sys/cdefs.h> | |
93 | __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.529.2.1.2.2 2023/11/15 02:08:33 thorpej Exp $"); | 93 | __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.529.2.1.2.3 2023/11/15 02:19:00 thorpej Exp $"); | |
94 | 94 | |||
95 | #if defined(_KERNEL_OPT) | 95 | #if defined(_KERNEL_OPT) | |
96 | #include "opt_inet.h" | 96 | #include "opt_inet.h" | |
97 | #include "opt_ipsec.h" | 97 | #include "opt_ipsec.h" | |
98 | #include "opt_atalk.h" | 98 | #include "opt_atalk.h" | |
99 | #include "opt_wlan.h" | 99 | #include "opt_wlan.h" | |
100 | #include "opt_net_mpsafe.h" | 100 | #include "opt_net_mpsafe.h" | |
101 | #include "opt_mrouting.h" | 101 | #include "opt_mrouting.h" | |
102 | #endif | 102 | #endif | |
103 | 103 | |||
104 | #define __IFQ_PRIVATE | |||
105 | ||||
104 | #include <sys/param.h> | 106 | #include <sys/param.h> | |
105 | #include <sys/mbuf.h> | 107 | #include <sys/mbuf.h> | |
106 | #include <sys/systm.h> | 108 | #include <sys/systm.h> | |
107 | #include <sys/callout.h> | 109 | #include <sys/callout.h> | |
108 | #include <sys/condvar.h> | 110 | #include <sys/condvar.h> | |
109 | #include <sys/proc.h> | 111 | #include <sys/proc.h> | |
110 | #include <sys/socket.h> | 112 | #include <sys/socket.h> | |
111 | #include <sys/socketvar.h> | 113 | #include <sys/socketvar.h> | |
112 | #include <sys/domain.h> | 114 | #include <sys/domain.h> | |
113 | #include <sys/protosw.h> | 115 | #include <sys/protosw.h> | |
114 | #include <sys/kernel.h> | 116 | #include <sys/kernel.h> | |
115 | #include <sys/ioctl.h> | 117 | #include <sys/ioctl.h> | |
116 | #include <sys/sysctl.h> | 118 | #include <sys/sysctl.h> | |
@@ -1377,30 +1379,26 @@ if_detach(struct ifnet *ifp) | @@ -1377,30 +1379,26 @@ if_detach(struct ifnet *ifp) | |||
1377 | kmem_free(isd, sizeof(*isd)); | 1379 | kmem_free(isd, sizeof(*isd)); | |
1378 | 1380 | |||
1379 | ifp->if_slowtimo_data = NULL; /* paraonia */ | 1381 | ifp->if_slowtimo_data = NULL; /* paraonia */ | |
1380 | ifp->if_slowtimo = NULL; /* paranoia */ | 1382 | ifp->if_slowtimo = NULL; /* paranoia */ | |
1381 | } | 1383 | } | |
1382 | if_deferred_start_destroy(ifp); | 1384 | if_deferred_start_destroy(ifp); | |
1383 | 1385 | |||
1384 | /* | 1386 | /* | |
1385 | * Do an if_down() to give protocols a chance to do something. | 1387 | * Do an if_down() to give protocols a chance to do something. | |
1386 | */ | 1388 | */ | |
1387 | if_down_deactivated(ifp); | 1389 | if_down_deactivated(ifp); | |
1388 | 1390 | |||
1389 | #ifdef ALTQ | 1391 | #ifdef ALTQ | |
1390 | if (ALTQ_IS_ENABLED(&ifp->if_snd)) | |||
1391 | altq_disable(ifp->if_snd.ifq_altq); | |||
1392 | if (ALTQ_IS_ATTACHED(&ifp->if_snd)) | |||
1393 | altq_detach(ifp->if_snd.ifq_altq); | |||
1394 | altq_free(&ifp->if_snd); | 1392 | altq_free(&ifp->if_snd); | |
1395 | #endif | 1393 | #endif | |
1396 | 1394 | |||
1397 | #if NCARP > 0 | 1395 | #if NCARP > 0 | |
1398 | /* Remove the interface from any carp group it is a part of. */ | 1396 | /* Remove the interface from any carp group it is a part of. */ | |
1399 | if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP) | 1397 | if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP) | |
1400 | carp_ifdetach(ifp); | 1398 | carp_ifdetach(ifp); | |
1401 | #endif | 1399 | #endif | |
1402 | 1400 | |||
1403 | /* | 1401 | /* | |
1404 | * Ensure that all packets on protocol input pktqueues have been | 1402 | * Ensure that all packets on protocol input pktqueues have been | |
1405 | * processed, or, at least, removed from the queues. | 1403 | * processed, or, at least, removed from the queues. | |
1406 | * | 1404 | * | |
@@ -4332,59 +4330,75 @@ ifq_purge_slow(struct ifqueue * const if | @@ -4332,59 +4330,75 @@ ifq_purge_slow(struct ifqueue * const if | |||
4332 | ifq->ifq_len = 0; | 4330 | ifq->ifq_len = 0; | |
4333 | } | 4331 | } | |
4334 | KERNEL_UNLOCK_ONE(NULL); | 4332 | KERNEL_UNLOCK_ONE(NULL); | |
4335 | 4333 | |||
4336 | return m; | 4334 | return m; | |
4337 | } | 4335 | } | |
4338 | #endif /* ALTQ */ | 4336 | #endif /* ALTQ */ | |
4339 | 4337 | |||
4340 | /* | 4338 | /* | |
4341 | * ifq_purge -- | 4339 | * ifq_purge -- | |
4342 | * | 4340 | * | |
4343 | * Purge all of the packets from the specified interface queue. | 4341 | * Purge all of the packets from the specified interface queue. | |
4344 | */ | 4342 | */ | |
4345 | void | 4343 | struct mbuf * | |
4346 | ifq_purge(struct ifqueue * const ifq) | 4344 | ifq_purge_locked(struct ifqueue * const ifq) | |
4347 | { | 4345 | { | |
4348 | struct mbuf *m, *nextm; | 4346 | struct mbuf *m; | |
4349 | ||||
4350 | mutex_enter(ifq->ifq_lock); | |||
4351 | 4347 | |||
4352 | #ifdef ALTQ | 4348 | #ifdef ALTQ | |
4353 | if (__predict_false(ALTQ_IS_ENABLED(ifq))) | 4349 | if (__predict_false(ALTQ_IS_ENABLED(ifq))) | |
4354 | m = ifq_purge_slow(ifq); | 4350 | m = ifq_purge_slow(ifq); | |
4355 | else | 4351 | else | |
4356 | #endif /* ALTQ */ | 4352 | #endif /* ALTQ */ | |
4357 | { | 4353 | { | |
4358 | m = ifq->ifq_head; | 4354 | m = ifq->ifq_head; | |
4359 | ifq->ifq_head = ifq->ifq_tail = NULL; | 4355 | ifq->ifq_head = ifq->ifq_tail = NULL; | |
4360 | ifq->ifq_len = 0; | 4356 | ifq->ifq_len = 0; | |
4361 | } | 4357 | } | |
4362 | 4358 | |||
4363 | if (ifq->ifq_staged != NULL) { | 4359 | if (ifq->ifq_staged != NULL) { | |
4364 | ifq->ifq_staged->m_nextpkt = m; | 4360 | ifq->ifq_staged->m_nextpkt = m; | |
4365 | m = ifq->ifq_staged; | 4361 | m = ifq->ifq_staged; | |
4366 | ifq->ifq_staged = NULL; | 4362 | ifq->ifq_staged = NULL; | |
4367 | } | 4363 | } | |
4368 | 4364 | |||
4369 | mutex_exit(ifq->ifq_lock); | 4365 | return m; | |
4366 | } | |||
4367 | ||||
4368 | void | |||
4369 | ifq_purge_free(struct mbuf *m) | |||
4370 | { | |||
4371 | struct mbuf *nextm; | |||
4370 | 4372 | |||
4371 | for (; m != NULL; m = nextm) { | 4373 | for (; m != NULL; m = nextm) { | |
4372 | nextm = m->m_nextpkt; | 4374 | nextm = m->m_nextpkt; | |
4373 | m->m_nextpkt = NULL; | 4375 | m->m_nextpkt = NULL; | |
4374 | m_freem(m); | 4376 | m_freem(m); | |
4375 | } | 4377 | } | |
4376 | } | 4378 | } | |
4377 | 4379 | |||
4380 | void | |||
4381 | ifq_purge(struct ifqueue * const ifq) | |||
4382 | { | |||
4383 | struct mbuf *m; | |||
4384 | ||||
4385 | mutex_enter(ifq->ifq_lock); | |||
4386 | m = ifq_purge_locked(ifq); | |||
4387 | mutex_exit(ifq->ifq_lock); | |||
4388 | ||||
4389 | ifq_purge_free(m); | |||
4390 | } | |||
4391 | ||||
4378 | /* | 4392 | /* | |
4379 | * ifq_classify_packet -- | 4393 | * ifq_classify_packet -- | |
4380 | * | 4394 | * | |
4381 | * Decorate a packet with classificaiton information per the | 4395 | * Decorate a packet with classificaiton information per the | |
4382 | * queue's queueing discipline. | 4396 | * queue's queueing discipline. | |
4383 | * | 4397 | * | |
4384 | * XXX This should be a private function. It's unfortunate that | 4398 | * XXX This should be a private function. It's unfortunate that | |
4385 | * XXX it's called from where it's called. | 4399 | * XXX it's called from where it's called. | |
4386 | */ | 4400 | */ | |
4387 | void | 4401 | void | |
4388 | ifq_classify_packet(struct ifqueue * const ifq, struct mbuf * const m, | 4402 | ifq_classify_packet(struct ifqueue * const ifq, struct mbuf * const m, | |
4389 | sa_family_t af) | 4403 | sa_family_t af) | |
4390 | { | 4404 | { |
--- src/sys/net/if.h 2023/11/15 02:08:34 1.305.2.1.2.2
+++ src/sys/net/if.h 2023/11/15 02:19:00 1.305.2.1.2.3
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if.h,v 1.305.2.1.2.2 2023/11/15 02:08:34 thorpej Exp $ */ | 1 | /* $NetBSD: if.h,v 1.305.2.1.2.3 2023/11/15 02:19:00 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1999, 2000, 2001, 2023 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999, 2000, 2001, 2023 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by William Studenmund and Jason R. Thorpe. | 8 | * by William Studenmund and Jason R. Thorpe. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -1260,26 +1260,31 @@ void ifq_set_maxlen(struct ifqueue *, u | @@ -1260,26 +1260,31 @@ void ifq_set_maxlen(struct ifqueue *, u | |||
1260 | unsigned int ifq_maxlen(struct ifqueue *); | 1260 | unsigned int ifq_maxlen(struct ifqueue *); | |
1261 | uint64_t ifq_drops(struct ifqueue *); | 1261 | uint64_t ifq_drops(struct ifqueue *); | |
1262 | struct mbuf * ifq_get(struct ifqueue *); | 1262 | struct mbuf * ifq_get(struct ifqueue *); | |
1263 | struct mbuf * ifq_stage(struct ifqueue *); | 1263 | struct mbuf * ifq_stage(struct ifqueue *); | |
1264 | int ifq_put(struct ifqueue *, struct mbuf *); | 1264 | int ifq_put(struct ifqueue *, struct mbuf *); | |
1265 | void ifq_restage(struct ifqueue *, struct mbuf *, struct mbuf *); | 1265 | void ifq_restage(struct ifqueue *, struct mbuf *, struct mbuf *); | |
1266 | void ifq_commit(struct ifqueue *, struct mbuf *); | 1266 | void ifq_commit(struct ifqueue *, struct mbuf *); | |
1267 | void ifq_abort(struct ifqueue *, struct mbuf *); | 1267 | void ifq_abort(struct ifqueue *, struct mbuf *); | |
1268 | bool ifq_continue(struct ifqueue *); | 1268 | bool ifq_continue(struct ifqueue *); | |
1269 | void ifq_purge(struct ifqueue *); | 1269 | void ifq_purge(struct ifqueue *); | |
1270 | void ifq_classify_packet(struct ifqueue *, struct mbuf *, | 1270 | void ifq_classify_packet(struct ifqueue *, struct mbuf *, | |
1271 | sa_family_t); | 1271 | sa_family_t); | |
1272 | 1272 | |||
1273 | #ifdef __IFQ_PRIVATE | |||
1274 | struct mbuf * ifq_purge_locked(struct ifqueue *); | |||
1275 | void ifq_purge_free(struct mbuf *); | |||
1276 | #endif /* __IFQ_PRIVATE */ | |||
1277 | ||||
1273 | int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, int); | 1278 | int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, int); | |
1274 | percpu_t *if_tunnel_alloc_ro_percpu(void); | 1279 | percpu_t *if_tunnel_alloc_ro_percpu(void); | |
1275 | void if_tunnel_free_ro_percpu(percpu_t *); | 1280 | void if_tunnel_free_ro_percpu(percpu_t *); | |
1276 | void if_tunnel_ro_percpu_rtcache_free(percpu_t *); | 1281 | void if_tunnel_ro_percpu_rtcache_free(percpu_t *); | |
1277 | 1282 | |||
1278 | struct tunnel_ro { | 1283 | struct tunnel_ro { | |
1279 | struct route *tr_ro; | 1284 | struct route *tr_ro; | |
1280 | kmutex_t *tr_lock; | 1285 | kmutex_t *tr_lock; | |
1281 | }; | 1286 | }; | |
1282 | 1287 | |||
1283 | static inline void | 1288 | static inline void | |
1284 | if_tunnel_get_ro(percpu_t *ro_percpu, struct route **ro, kmutex_t **lock) | 1289 | if_tunnel_get_ro(percpu_t *ro_percpu, struct route **ro, kmutex_t **lock) | |
1285 | { | 1290 | { |