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