]>
git.saurik.com Git - apple/xnu.git/blob - bsd/net/altq/altq_hfsc.c
2 * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $OpenBSD: altq_hfsc.c,v 1.25 2007/09/13 20:40:02 chl Exp $ */
30 /* $KAME: altq_hfsc.c,v 1.17 2002/11/29 07:48:33 kjc Exp $ */
33 * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved.
35 * Permission to use, copy, modify, and distribute this software and
36 * its documentation is hereby granted (including for commercial or
37 * for-profit use), provided that both the copyright notice and this
38 * permission notice appear in all copies of the software, derivative
39 * works, or modified versions, and any portions thereof.
41 * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF
42 * WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS
43 * SOFTWARE IN ITS ``AS IS'' CONDITION, AND ANY EXPRESS OR IMPLIED
44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46 * DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
49 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
50 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
51 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
53 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
56 * Carnegie Mellon encourages (but does not require) users of this
57 * software to return any improvements or extensions that they make,
58 * and to grant Carnegie Mellon the rights to redistribute these
59 * changes without encumbrance.
62 #include <sys/cdefs.h>
64 #if PF_ALTQ && PKTSCHED_HFSC
66 #include <sys/cdefs.h>
67 #include <sys/param.h>
68 #include <sys/malloc.h>
70 #include <sys/systm.h>
71 #include <sys/errno.h>
72 #include <sys/kernel.h>
75 #include <net/pfvar.h>
76 #include <net/net_osdep.h>
77 #include <net/altq/altq.h>
78 #include <net/altq/altq_hfsc.h>
79 #include <netinet/in.h>
84 static int altq_hfsc_request(struct ifaltq
*, enum altrq
, void *);
85 static int altq_hfsc_enqueue(struct ifaltq
*, struct mbuf
*);
86 static struct mbuf
*altq_hfsc_dequeue(struct ifaltq
*, enum altdq_op
);
89 altq_hfsc_pfattach(struct pf_altq
*a
)
94 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
96 if ((ifp
= ifunit(a
->ifname
)) == NULL
|| a
->altq_disc
== NULL
)
99 IFCQ_LOCK(&ifp
->if_snd
);
100 error
= altq_attach(IFCQ_ALTQ(&ifp
->if_snd
), ALTQT_HFSC
, a
->altq_disc
,
101 altq_hfsc_enqueue
, altq_hfsc_dequeue
, NULL
, altq_hfsc_request
);
102 IFCQ_UNLOCK(&ifp
->if_snd
);
108 altq_hfsc_add(struct pf_altq
*a
)
113 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
115 if ((ifp
= ifunit(a
->ifname
)) == NULL
)
117 if (!ALTQ_IS_READY(IFCQ_ALTQ(&ifp
->if_snd
)))
120 hif
= hfsc_alloc(ifp
, M_WAITOK
, TRUE
);
124 /* keep the state in pf_altq */
131 altq_hfsc_remove(struct pf_altq
*a
)
135 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
137 if ((hif
= a
->altq_disc
) == NULL
)
141 return (hfsc_destroy(hif
));
145 altq_hfsc_add_queue(struct pf_altq
*a
)
148 struct hfsc_opts
*opts
= &a
->pq_u
.hfsc_opts
;
149 struct service_curve rtsc
, lssc
, ulsc
;
152 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
154 if ((hif
= a
->altq_disc
) == NULL
)
157 bzero(&rtsc
, sizeof (rtsc
));
158 bzero(&lssc
, sizeof (lssc
));
159 bzero(&ulsc
, sizeof (ulsc
));
161 rtsc
.m1
= opts
->rtsc_m1
;
162 rtsc
.d
= opts
->rtsc_d
;
163 rtsc
.m2
= opts
->rtsc_m2
;
164 rtsc
.fl
= opts
->rtsc_fl
;
165 lssc
.m1
= opts
->lssc_m1
;
166 lssc
.d
= opts
->lssc_d
;
167 lssc
.m2
= opts
->lssc_m2
;
168 lssc
.fl
= opts
->lssc_fl
;
169 ulsc
.m1
= opts
->ulsc_m1
;
170 ulsc
.d
= opts
->ulsc_d
;
171 ulsc
.m2
= opts
->ulsc_m2
;
172 ulsc
.fl
= opts
->ulsc_fl
;
174 IFCQ_LOCK(hif
->hif_ifq
);
175 err
= hfsc_add_queue(hif
, &rtsc
, &lssc
, &ulsc
, a
->qlimit
,
176 opts
->flags
, a
->parent_qid
, a
->qid
, NULL
);
177 IFCQ_UNLOCK(hif
->hif_ifq
);
183 altq_hfsc_remove_queue(struct pf_altq
*a
)
188 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
190 if ((hif
= a
->altq_disc
) == NULL
)
193 IFCQ_LOCK(hif
->hif_ifq
);
194 err
= hfsc_remove_queue(hif
, a
->qid
);
195 IFCQ_UNLOCK(hif
->hif_ifq
);
201 altq_hfsc_getqstats(struct pf_altq
*a
, void *ubuf
, int *nbytes
)
203 struct ifclassq
*ifq
= NULL
;
205 struct hfsc_classstats stats
;
208 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
210 if ((unsigned)*nbytes
< sizeof (stats
))
213 if ((hif
= altq_lookup(a
->ifname
, ALTQT_HFSC
)) == NULL
)
217 IFCQ_LOCK_ASSERT_HELD(ifq
); /* lock held by altq_lookup */
218 error
= hfsc_get_class_stats(hif
, a
->qid
, &stats
);
223 if ((error
= copyout((caddr_t
)&stats
, (user_addr_t
)(uintptr_t)ubuf
,
224 sizeof (stats
))) != 0)
227 *nbytes
= sizeof (stats
);
233 altq_hfsc_request(struct ifaltq
*altq
, enum altrq req
, void *arg
)
235 struct hfsc_if
*hif
= (struct hfsc_if
*)altq
->altq_disc
;
243 /* not supported for ALTQ instance */
247 hfsc_event(hif
, (cqev_t
)arg
);
254 * altq_hfsc_enqueue is an enqueue function to be registered to
255 * (*altq_enqueue) in struct ifaltq.
258 altq_hfsc_enqueue(struct ifaltq
*altq
, struct mbuf
*m
)
260 /* grab class set by classifier */
261 if (!(m
->m_flags
& M_PKTHDR
)) {
262 /* should not happen */
263 printf("%s: packet for %s does not have pkthdr\n", __func__
,
264 if_name(altq
->altq_ifcq
->ifcq_ifp
));
269 return (hfsc_enqueue(altq
->altq_disc
, NULL
, m
, m_pftag(m
)));
273 * altq_hfsc_dequeue is a dequeue function to be registered to
274 * (*altq_dequeue) in struct ifaltq.
276 * note: ALTDQ_POLL returns the next packet without removing the packet
277 * from the queue. ALTDQ_REMOVE is a normal dequeue operation.
278 * ALTDQ_REMOVE must return the same packet if called immediately
282 altq_hfsc_dequeue(struct ifaltq
*altq
, enum altdq_op op
)
284 return (hfsc_dequeue(altq
->altq_disc
, (cqdq_op_t
)op
));
286 #endif /* PF_ALTQ && PKTSCHED_HFSC */