]>
git.saurik.com Git - apple/xnu.git/blob - bsd/net/altq/altq_fairq.c
2 * Copyright (c) 2011-2013 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@
30 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
32 * This code is derived from software contributed to The DragonFly Project
33 * by Matthew Dillon <dillon@backplane.com>
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in
43 * the documentation and/or other materials provided with the
45 * 3. Neither the name of The DragonFly Project nor the names of its
46 * contributors may be used to endorse or promote products derived
47 * from this software without specific, prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
52 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
53 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
54 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
55 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
57 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
58 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
59 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * $DragonFly: src/sys/net/altq/altq_fairq.c,v 1.2 2008/05/14 11:59:23 sephe Exp $
65 * Matt: I gutted altq_priq.c and used it as a skeleton on which to build
66 * fairq. The fairq algorithm is completely different then priq, of course,
67 * but because I used priq's skeleton I believe I should include priq's
70 * Copyright (C) 2000-2003
71 * Sony Computer Science Laboratories Inc. All rights reserved.
73 * Redistribution and use in source and binary forms, with or without
74 * modification, are permitted provided that the following conditions
76 * 1. Redistributions of source code must retain the above copyright
77 * notice, this list of conditions and the following disclaimer.
78 * 2. Redistributions in binary form must reproduce the above copyright
79 * notice, this list of conditions and the following disclaimer in the
80 * documentation and/or other materials provided with the distribution.
82 * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
83 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85 * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
86 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
88 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
90 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
95 #if PF_ALTQ && PKTSCHED_FAIRQ
97 #include <sys/cdefs.h>
98 #include <sys/param.h>
99 #include <sys/malloc.h>
100 #include <sys/mbuf.h>
101 #include <sys/systm.h>
102 #include <sys/errno.h>
103 #include <sys/kernel.h>
106 #include <net/pfvar.h>
107 #include <net/net_osdep.h>
108 #include <net/altq/altq.h>
109 #include <net/altq/altq_fairq.h>
110 #include <netinet/in.h>
113 * function prototypes
115 static int altq_fairq_enqueue(struct ifaltq
*, struct mbuf
*);
116 static struct mbuf
*altq_fairq_dequeue(struct ifaltq
*, enum altdq_op
);
117 static int altq_fairq_request(struct ifaltq
*, enum altrq
, void *);
120 altq_fairq_pfattach(struct pf_altq
*a
)
125 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
127 if ((ifp
= ifunit(a
->ifname
)) == NULL
|| a
->altq_disc
== NULL
)
130 IFCQ_LOCK(&ifp
->if_snd
);
131 error
= altq_attach(IFCQ_ALTQ(&ifp
->if_snd
), ALTQT_FAIRQ
, a
->altq_disc
,
132 altq_fairq_enqueue
, altq_fairq_dequeue
, NULL
, altq_fairq_request
);
133 IFCQ_UNLOCK(&ifp
->if_snd
);
139 altq_fairq_add(struct pf_altq
*a
)
141 struct fairq_if
*fif
;
144 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
146 if ((ifp
= ifunit(a
->ifname
)) == NULL
)
148 if (!ALTQ_IS_READY(IFCQ_ALTQ(&ifp
->if_snd
)))
151 fif
= fairq_alloc(ifp
, M_WAITOK
, TRUE
);
155 /* keep the state in pf_altq */
162 altq_fairq_remove(struct pf_altq
*a
)
164 struct fairq_if
*fif
;
166 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
168 if ((fif
= a
->altq_disc
) == NULL
)
172 return (fairq_destroy(fif
));
176 altq_fairq_add_queue(struct pf_altq
*a
)
178 struct fairq_if
*fif
;
179 struct fairq_opts
*opts
= &a
->pq_u
.fairq_opts
;
182 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
184 if ((fif
= a
->altq_disc
) == NULL
)
187 IFCQ_LOCK(fif
->fif_ifq
);
188 err
= fairq_add_queue(fif
, a
->priority
, a
->qlimit
, a
->bandwidth
,
189 opts
->nbuckets
, opts
->flags
, opts
->hogs_m1
, opts
->lssc_m1
,
190 opts
->lssc_d
, opts
->lssc_m2
, a
->qid
, NULL
);
191 IFCQ_UNLOCK(fif
->fif_ifq
);
197 altq_fairq_remove_queue(struct pf_altq
*a
)
199 struct fairq_if
*fif
;
202 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
204 if ((fif
= a
->altq_disc
) == NULL
)
207 IFCQ_LOCK(fif
->fif_ifq
);
208 err
= fairq_remove_queue(fif
, a
->qid
);
209 IFCQ_UNLOCK(fif
->fif_ifq
);
215 altq_fairq_getqstats(struct pf_altq
*a
, void *ubuf
, int *nbytes
)
217 struct ifclassq
*ifq
= NULL
;
218 struct fairq_if
*fif
;
219 struct fairq_classstats stats
;
222 lck_mtx_assert(pf_lock
, LCK_MTX_ASSERT_OWNED
);
224 if ((unsigned)*nbytes
< sizeof (stats
))
227 if ((fif
= altq_lookup(a
->ifname
, ALTQT_FAIRQ
)) == NULL
)
231 IFCQ_LOCK_ASSERT_HELD(ifq
); /* lock held by altq_lookup */
232 error
= fairq_get_class_stats(fif
, a
->qid
, &stats
);
237 if ((error
= copyout((caddr_t
)&stats
, (user_addr_t
)(uintptr_t)ubuf
,
238 sizeof (stats
))) != 0)
241 *nbytes
= sizeof (stats
);
247 altq_fairq_request(struct ifaltq
*altq
, enum altrq req
, void *arg
)
249 struct fairq_if
*fif
= (struct fairq_if
*)altq
->altq_disc
;
257 /* not supported for ALTQ instance */
261 fairq_event(fif
, (cqev_t
)arg
);
272 * altq_fairq_enqueue is an enqueue function to be registered to
273 * (*altq_enqueue) in struct ifaltq.
276 altq_fairq_enqueue(struct ifaltq
*altq
, struct mbuf
*m
)
278 /* grab class set by classifier */
279 if (!(m
->m_flags
& M_PKTHDR
)) {
280 /* should not happen */
281 printf("%s: packet for %s does not have pkthdr\n", __func__
,
282 if_name(altq
->altq_ifcq
->ifcq_ifp
));
287 return (fairq_enqueue(altq
->altq_disc
, NULL
, m
, m_pftag(m
)));
291 * altq_fairq_dequeue is a dequeue function to be registered to
292 * (*altq_dequeue) in struct ifaltq.
294 * note: ALTDQ_POLL returns the next packet without removing the packet
295 * from the queue. ALTDQ_REMOVE is a normal dequeue operation.
296 * ALTDQ_REMOVE must return the same packet if called immediately
300 altq_fairq_dequeue(struct ifaltq
*altq
, enum altdq_op op
)
302 return (fairq_dequeue(altq
->altq_disc
, (cqdq_op_t
)op
));
304 #endif /* PF_ALTQ && PKTSCHED_FAIRQ */