xref: /freebsd/share/man/man9/altq.9 (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
1.\"	$NetBSD: altq.9,v 1.8 2002/05/28 11:41:45 wiz Exp $
2.\"	$OpenBSD: altq.9,v 1.4 2001/07/12 12:41:42 itojun Exp $
3.\"
4.\" Copyright (C) 2004 Max Laier. All rights reserved.
5.\" Copyright (C) 2001
6.\" Sony Computer Science Laboratories Inc.  All rights reserved.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\"    notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\"    notice, this list of conditions and the following disclaimer in the
15.\"    documentation and/or other materials provided with the distribution.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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
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
27.\" SUCH DAMAGE.
28.\"
29.\" $FreeBSD$
30.\"
31.Dd March 20, 2018
32.Dt ALTQ 9
33.Os
34.\"
35.Sh NAME
36.Nm ALTQ
37.Nd kernel interfaces for manipulating output queues on network interfaces
38.Sh SYNOPSIS
39.In sys/types.h
40.In sys/socket.h
41.In net/if.h
42.In net/if_var.h
43.\"
44.Ss Enqueue macros
45.Fn IFQ_ENQUEUE "struct ifaltq *ifq" "struct mbuf *m" "int error"
46.Fn IFQ_HANDOFF "struct ifnet *ifp" "struct mbuf *m" "int error"
47.Fo IFQ_HANDOFF_ADJ
48.Fa "struct ifnet *ifp" "struct mbuf *m" "int adjust" "int error"
49.Fc
50.\"
51.Ss Dequeue macros
52.Fn IFQ_DEQUEUE "struct ifaltq *ifq" "struct mbuf *m"
53.Fn IFQ_POLL_NOLOCK "struct ifaltq *ifq" "struct mbuf *m"
54.Fn IFQ_PURGE "struct ifaltq *ifq"
55.Fn IFQ_IS_EMPTY "struct ifaltq *ifq"
56.\"
57.Ss Driver managed dequeue macros
58.Fn IFQ_DRV_DEQUEUE "struct ifaltq *ifq" "struct mbuf *m"
59.Fn IFQ_DRV_PREPEND "struct ifaltq *ifq" "struct mbuf *m"
60.Fn IFQ_DRV_PURGE "struct ifaltq *ifq"
61.Fn IFQ_DRV_IS_EMPTY "struct ifaltq *ifq"
62.\"
63.Ss General setup macros
64.Fn IFQ_SET_MAXLEN "struct ifaltq *ifq" "int len"
65.Fn IFQ_INC_LEN "struct ifaltq *ifq"
66.Fn IFQ_DEC_LEN "struct ifaltq *ifq"
67.Fn IFQ_INC_DROPS "struct ifaltq *ifq"
68.Fn IFQ_SET_READY "struct ifaltq *ifq"
69.Sh DESCRIPTION
70The
71.Nm
72system is a framework to manage queuing disciplines on network
73interfaces.
74.Nm
75introduces new macros to manipulate output queues.
76The output queue macros are used to abstract queue operations and not to
77touch the internal fields of the output queue structure.
78The macros are independent from the
79.Nm
80implementation, and compatible with the traditional
81.Vt ifqueue
82macros for ease of transition.
83.Pp
84.Fn IFQ_ENQUEUE ,
85.Fn IFQ_HANDOFF
86and
87.Fn IFQ_HANDOFF_ADJ
88enqueue a packet
89.Fa m
90to the queue
91.Fa ifq .
92The underlying queuing discipline may discard the packet.
93The
94.Fa error
95argument is set to 0 on success, or
96.Er ENOBUFS
97if the packet is discarded.
98The packet pointed to by
99.Fa m
100will be freed by the device driver on success, or by the queuing discipline on
101failure, so the caller should not touch
102.Fa m
103after enqueuing.
104.Fn IFQ_HANDOFF
105and
106.Fn IFQ_HANDOFF_ADJ
107combine the enqueue operation with statistic generation and call
108.Fn if_start
109upon successful enqueue to initiate the actual send.
110.Pp
111.Fn IFQ_DEQUEUE
112dequeues a packet from the queue.
113The dequeued packet is returned in
114.Fa m ,
115or
116.Fa m
117is set to
118.Dv NULL
119if no packet is dequeued.
120The caller must always check
121.Fa m
122since a non-empty queue could return
123.Dv NULL
124under rate-limiting.
125.Pp
126.Fn IFQ_POLL_NOLOCK
127returns the next packet without removing it from the queue.
128The caller must hold the queue mutex when calling
129.Fn IFQ_POLL_NOLOCK
130in order to guarantee that a subsequent call to
131.Fn IFQ_DEQUEUE_NOLOCK
132dequeues the same packet.
133.Pp
134.Fn IFQ_*_NOLOCK
135variants (if available) always assume that the caller holds the queue mutex.
136They can be grabbed with
137.Fn IFQ_LOCK
138and released with
139.Fn IFQ_UNLOCK .
140.Pp
141.Fn IFQ_PURGE
142discards all the packets in the queue.
143The purge operation is needed since a non-work conserving queue cannot be
144emptied by a dequeue loop.
145.Pp
146.Fn IFQ_IS_EMPTY
147can be used to check if the queue is empty.
148Note that
149.Fn IFQ_DEQUEUE
150could still return
151.Dv NULL
152if the queuing discipline is non-work conserving.
153.Pp
154.Fn IFQ_DRV_DEQUEUE
155moves up to
156.Fa ifq->ifq_drv_maxlen
157packets from the queue to the
158.Dq "driver managed"
159queue and returns the first one via
160.Fa m .
161As for
162.Fn IFQ_DEQUEUE ,
163.Fa m
164can be
165.Dv NULL
166even for a non-empty queue.
167Subsequent calls to
168.Fn IFQ_DRV_DEQUEUE
169pass the packets from the
170.Dq "driver managed"
171queue without obtaining the queue mutex.
172It is the responsibility of the caller to protect against concurrent access.
173Enabling
174.Nm
175for a given queue sets
176.Va ifq_drv_maxlen
177to 0 as the
178.Dq "bulk dequeue"
179performed by
180.Fn IFQ_DRV_DEQUEUE
181for higher values of
182.Va ifq_drv_maxlen
183is adverse to
184.Nm ALTQ Ns 's
185internal timing.
186Note that a driver must not mix
187.Fn IFQ_DRV_*
188macros with the default dequeue macros as the default macros do not look at the
189.Dq "driver managed"
190queue which might lead to an mbuf leak.
191.Pp
192.Fn IFQ_DRV_PREPEND
193prepends
194.Fa m
195to the
196.Dq "driver managed"
197queue from where it will be obtained with the next call to
198.Fn IFQ_DRV_DEQUEUE .
199.Pp
200.Fn IFQ_DRV_PURGE
201flushes all packets in the
202.Dq "driver managed"
203queue and calls to
204.Fn IFQ_PURGE
205afterwards.
206.Pp
207.Fn IFQ_DRV_IS_EMPTY
208checks for packets in the
209.Dq "driver managed"
210part of the queue.
211If it is empty, it forwards to
212.Fn IFQ_IS_EMPTY .
213.Pp
214.Fn IFQ_SET_MAXLEN
215sets the queue length limit to the default FIFO queue.
216The
217.Va ifq_drv_maxlen
218member of the
219.Vt ifaltq
220structure controls the length limit of the
221.Dq "driver managed"
222queue.
223.Pp
224.Fn IFQ_INC_LEN
225and
226.Fn IFQ_DEC_LEN
227increment or decrement the current queue length in packets.
228This is mostly for internal purposes.
229.Pp
230.Fn IFQ_INC_DROPS
231increments the drop counter and is identical to
232.Fn IF_DROP .
233It is defined for naming consistency only.
234.Pp
235.Fn IFQ_SET_READY
236sets a flag to indicate that a driver was converted to use the new macros.
237.Nm
238can be enabled only on interfaces with this flag.
239.Sh COMPATIBILITY
240.Ss Vt ifaltq structure
241In order to keep compatibility with the existing code, the new
242output queue structure
243.Vt ifaltq
244has the same fields.
245The traditional
246.Fn IF_*
247macros and the code directly referencing the fields within
248.Va if_snd
249still work with
250.Vt ifaltq .
251.Bd -literal
252            ##old-style##                           ##new-style##
253                                       |
254 struct ifqueue {                      | struct ifaltq {
255    struct mbuf *ifq_head;             |    struct mbuf *ifq_head;
256    struct mbuf *ifq_tail;             |    struct mbuf *ifq_tail;
257    int          ifq_len;              |    int          ifq_len;
258    int          ifq_maxlen;           |    int          ifq_maxlen;
259 };                                    |    /* driver queue fields */
260                                       |    ......
261                                       |    /* altq related fields */
262                                       |    ......
263                                       | };
264                                       |
265.Ed
266The new structure replaces
267.Vt "struct ifqueue"
268in
269.Vt "struct ifnet" .
270.Bd -literal
271            ##old-style##                           ##new-style##
272                                       |
273 struct ifnet {                        | struct ifnet {
274     ....                              |     ....
275                                       |
276     struct ifqueue if_snd;            |     struct ifaltq if_snd;
277                                       |
278     ....                              |     ....
279 };                                    | };
280                                       |
281.Ed
282The (simplified) new
283.Fn IFQ_*
284macros look like:
285.Bd -literal
286	#define IFQ_DEQUEUE(ifq, m)			\e
287		if (ALTQ_IS_ENABLED((ifq))		\e
288			ALTQ_DEQUEUE((ifq), (m));	\e
289		else					\e
290			IF_DEQUEUE((ifq), (m));
291.Ed
292.Ss Enqueue operation
293The semantics of the enqueue operation is changed.
294In the new style,
295enqueue and packet drop are combined since they cannot be easily
296separated in many queuing disciplines.
297The new enqueue operation corresponds to the following macro that is
298written with the old macros.
299.Bd -literal
300#define	IFQ_ENQUEUE(ifq, m, error)                      \e
301do {                                                    \e
302        if (IF_QFULL((ifq))) {                          \e
303                m_freem((m));                           \e
304                (error) = ENOBUFS;                      \e
305                IF_DROP(ifq);                           \e
306        } else {                                        \e
307                IF_ENQUEUE((ifq), (m));                 \e
308                (error) = 0;                            \e
309        }                                               \e
310} while (0)
311.Ed
312.Pp
313.Fn IFQ_ENQUEUE
314does the following:
315.Pp
316.Bl -hyphen -compact
317.It
318queue a packet,
319.It
320drop (and free) a packet if the enqueue operation fails.
321.El
322.Pp
323If the enqueue operation fails,
324.Fa error
325is set to
326.Er ENOBUFS .
327The
328.Fa m
329mbuf is freed by the queuing discipline.
330The caller should not touch mbuf after calling
331.Fn IFQ_ENQUEUE
332so that the caller may need to copy
333.Va m_pkthdr.len
334or
335.Va m_flags
336field beforehand for statistics.
337.Fn IFQ_HANDOFF
338and
339.Fn IFQ_HANDOFF_ADJ
340can be used if only default interface statistics and an immediate call to
341.Fn if_start
342are desired.
343The caller should not use
344.Fn senderr
345since mbuf was already freed.
346.Pp
347The new style
348.Fn if_output
349looks as follows:
350.Bd -literal
351            ##old-style##                           ##new-style##
352                                       |
353 int                                   | int
354 ether_output(ifp, m0, dst, rt0)       | ether_output(ifp, m0, dst, rt0)
355 {                                     | {
356     ......                            |     ......
357                                       |
358                                       |     mflags = m->m_flags;
359                                       |     len = m->m_pkthdr.len;
360     s = splimp();                     |     s = splimp();
361     if (IF_QFULL(&ifp->if_snd)) {     |     IFQ_ENQUEUE(&ifp->if_snd, m,
362                                       |                 error);
363         IF_DROP(&ifp->if_snd);        |     if (error != 0) {
364         splx(s);                      |         splx(s);
365         senderr(ENOBUFS);             |         return (error);
366     }                                 |     }
367     IF_ENQUEUE(&ifp->if_snd, m);      |
368     ifp->if_obytes +=                 |     ifp->if_obytes += len;
369                    m->m_pkthdr.len;   |
370     if (m->m_flags & M_MCAST)         |     if (mflags & M_MCAST)
371         ifp->if_omcasts++;            |         ifp->if_omcasts++;
372                                       |
373     if ((ifp->if_flags & IFF_OACTIVE) |     if ((ifp->if_flags & IFF_OACTIVE)
374         == 0)                         |         == 0)
375         (*ifp->if_start)(ifp);        |         (*ifp->if_start)(ifp);
376     splx(s);                          |     splx(s);
377     return (error);                   |     return (error);
378                                       |
379 bad:                                  | bad:
380     if (m)                            |     if (m)
381         m_freem(m);                   |         m_freem(m);
382     return (error);                   |     return (error);
383 }                                     | }
384                                       |
385.Ed
386.Sh HOW TO CONVERT THE EXISTING DRIVERS
387First, make sure the corresponding
388.Fn if_output
389is already converted to the new style.
390.Pp
391Look for
392.Va if_snd
393in the driver.
394Probably, you need to make changes to the lines that include
395.Va if_snd .
396.Ss Empty check operation
397If the code checks
398.Va ifq_head
399to see whether the queue is empty or not, use
400.Fn IFQ_IS_EMPTY .
401.Bd -literal
402            ##old-style##                           ##new-style##
403                                       |
404 if (ifp->if_snd.ifq_head != NULL)     | if (!IFQ_IS_EMPTY(&ifp->if_snd))
405                                       |
406.Ed
407.Fn IFQ_IS_EMPTY
408only checks if there is any packet stored in the queue.
409Note that even when
410.Fn IFQ_IS_EMPTY
411is
412.Dv FALSE ,
413.Fn IFQ_DEQUEUE
414could still return
415.Dv NULL
416if the queue is under rate-limiting.
417.Ss Dequeue operation
418Replace
419.Fn IF_DEQUEUE
420by
421.Fn IFQ_DEQUEUE .
422Always check whether the dequeued mbuf is
423.Dv NULL
424or not.
425Note that even when
426.Fn IFQ_IS_EMPTY
427is
428.Dv FALSE ,
429.Fn IFQ_DEQUEUE
430could return
431.Dv NULL
432due to rate-limiting.
433.Bd -literal
434            ##old-style##                           ##new-style##
435                                       |
436 IF_DEQUEUE(&ifp->if_snd, m);          | IFQ_DEQUEUE(&ifp->if_snd, m);
437                                       | if (m == NULL)
438                                       |     return;
439                                       |
440.Ed
441A driver is supposed to call
442.Fn if_start
443from transmission complete interrupts in order to trigger the next dequeue.
444.Ss Poll-and-dequeue operation
445If the code polls the packet at the head of the queue and actually uses
446the packet before dequeuing it, use
447.Fn IFQ_POLL_NOLOCK
448and
449.Fn IFQ_DEQUEUE_NOLOCK .
450.Bd -literal
451            ##old-style##                           ##new-style##
452                                       |
453                                       | IFQ_LOCK(&ifp->if_snd);
454 m = ifp->if_snd.ifq_head;             | IFQ_POLL_NOLOCK(&ifp->if_snd, m);
455 if (m != NULL) {                      | if (m != NULL) {
456                                       |
457     /* use m to get resources */      |     /* use m to get resources */
458     if (something goes wrong)         |     if (something goes wrong)
459                                       |         IFQ_UNLOCK(&ifp->if_snd);
460         return;                       |         return;
461                                       |
462     IF_DEQUEUE(&ifp->if_snd, m);      |     IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
463                                       |     IFQ_UNLOCK(&ifp->if_snd);
464                                       |
465     /* kick the hardware */           |     /* kick the hardware */
466 }                                     | }
467                                       |
468.Ed
469It is guaranteed that
470.Fn IFQ_DEQUEUE_NOLOCK
471under the same lock as a previous
472.Fn IFQ_POLL_NOLOCK
473returns the same packet.
474Note that they need to be guarded by
475.Fn IFQ_LOCK .
476.Ss Eliminating Fn IF_PREPEND
477If the code uses
478.Fn IF_PREPEND ,
479you have to eliminate it unless you can use a
480.Dq "driver managed"
481queue which allows the use of
482.Fn IFQ_DRV_PREPEND
483as a substitute.
484A common usage of
485.Fn IF_PREPEND
486is to cancel the previous dequeue operation.
487You have to convert the logic into poll-and-dequeue.
488.Bd -literal
489            ##old-style##                           ##new-style##
490                                       |
491                                       | IFQ_LOCK(&ifp->if_snd);
492 IF_DEQUEUE(&ifp->if_snd, m);          | IFQ_POLL_NOLOCK(&ifp->if_snd, m);
493 if (m != NULL) {                      | if (m != NULL) {
494                                       |
495     if (something_goes_wrong) {       |     if (something_goes_wrong) {
496         IF_PREPEND(&ifp->if_snd, m);  |         IFQ_UNLOCK(&ifp->if_snd);
497         return;                       |         return;
498     }                                 |     }
499                                       |
500                                       |     /* at this point, the driver
501                                       |      * is committed to send this
502                                       |      * packet.
503                                       |      */
504                                       |     IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
505                                       |     IFQ_UNLOCK(&ifp->if_snd);
506                                       |
507     /* kick the hardware */           |     /* kick the hardware */
508 }                                     | }
509                                       |
510.Ed
511.Ss Purge operation
512Use
513.Fn IFQ_PURGE
514to empty the queue.
515Note that a non-work conserving queue cannot be emptied by a dequeue loop.
516.Bd -literal
517            ##old-style##                           ##new-style##
518                                       |
519 while (ifp->if_snd.ifq_head != NULL) {|  IFQ_PURGE(&ifp->if_snd);
520     IF_DEQUEUE(&ifp->if_snd, m);      |
521     m_freem(m);                       |
522 }                                     |
523                                       |
524.Ed
525.Ss Conversion using a driver managed queue
526Convert
527.Fn IF_*
528macros to their equivalent
529.Fn IFQ_DRV_*
530and employ
531.Fn IFQ_DRV_IS_EMPTY
532where appropriate.
533.Bd -literal
534            ##old-style##                           ##new-style##
535                                       |
536 if (ifp->if_snd.ifq_head != NULL)     | if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
537                                       |
538.Ed
539Make sure that calls to
540.Fn IFQ_DRV_DEQUEUE ,
541.Fn IFQ_DRV_PREPEND
542and
543.Fn IFQ_DRV_PURGE
544are protected with a mutex of some kind.
545.Ss Attach routine
546Use
547.Fn IFQ_SET_MAXLEN
548to set
549.Va ifq_maxlen
550to
551.Fa len .
552Initialize
553.Va ifq_drv_maxlen
554with a sensible value if you plan to use the
555.Fn IFQ_DRV_*
556macros.
557Add
558.Fn IFQ_SET_READY
559to show this driver is converted to the new style.
560(This is used to distinguish new-style drivers.)
561.Bd -literal
562            ##old-style##                           ##new-style##
563                                       |
564 ifp->if_snd.ifq_maxlen = qsize;       | IFQ_SET_MAXLEN(&ifp->if_snd, qsize);
565                                       | ifp->if_snd.ifq_drv_maxlen = qsize;
566                                       | IFQ_SET_READY(&ifp->if_snd);
567 if_attach(ifp);                       | if_attach(ifp);
568                                       |
569.Ed
570.Ss Other issues
571The new macros for statistics:
572.Bd -literal
573            ##old-style##                           ##new-style##
574                                       |
575 IF_DROP(&ifp->if_snd);                | IFQ_INC_DROPS(&ifp->if_snd);
576                                       |
577 ifp->if_snd.ifq_len++;                | IFQ_INC_LEN(&ifp->if_snd);
578                                       |
579 ifp->if_snd.ifq_len--;                | IFQ_DEC_LEN(&ifp->if_snd);
580                                       |
581.Ed
582.Sh QUEUING DISCIPLINES
583Queuing disciplines need to maintain
584.Fa ifq_len
585(used by
586.Fn IFQ_IS_EMPTY ) .
587Queuing disciplines also need to guarantee that the same mbuf is returned if
588.Fn IFQ_DEQUEUE
589is called immediately after
590.Fn IFQ_POLL .
591.Sh SEE ALSO
592.Xr pf 4 ,
593.Xr pf.conf 5 ,
594.Xr pfctl 8
595.Sh HISTORY
596The
597.Nm
598system first appeared in March 1997 and found home in the KAME project
599(https://www.kame.net).
600It was imported to
601.Fx
602in 5.3 .
603