]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/altq.9
disk(9): Fix a few mandoc related errors
[FreeBSD/FreeBSD.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 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  };                                    |    /* driver queue fields */
260                                        |    ......
261                                        |    /* altq related fields */
262                                        |    ......
263                                        | };
264                                        |
265 .Ed
266 The new structure replaces
267 .Vt "struct ifqueue"
268 in
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
282 The (simplified) new
283 .Fn IFQ_*
284 macros 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
293 The semantics of the enqueue operation is changed.
294 In the new style,
295 enqueue and packet drop are combined since they cannot be easily
296 separated in many queuing disciplines.
297 The new enqueue operation corresponds to the following macro that is
298 written with the old macros.
299 .Bd -literal
300 #define IFQ_ENQUEUE(ifq, m, error)                      \e
301 do {                                                    \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
314 does the following:
315 .Pp
316 .Bl -hyphen -compact
317 .It
318 queue a packet,
319 .It
320 drop (and free) a packet if the enqueue operation fails.
321 .El
322 .Pp
323 If the enqueue operation fails,
324 .Fa error
325 is set to
326 .Er ENOBUFS .
327 The
328 .Fa m
329 mbuf is freed by the queuing discipline.
330 The caller should not touch mbuf after calling
331 .Fn IFQ_ENQUEUE
332 so that the caller may need to copy
333 .Va m_pkthdr.len
334 or
335 .Va m_flags
336 field beforehand for statistics.
337 .Fn IFQ_HANDOFF
338 and
339 .Fn IFQ_HANDOFF_ADJ
340 can be used if only default interface statistics and an immediate call to
341 .Fn if_start
342 are desired.
343 The caller should not use
344 .Fn senderr
345 since mbuf was already freed.
346 .Pp
347 The new style
348 .Fn if_output
349 looks 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
387 First, make sure the corresponding
388 .Fn if_output
389 is already converted to the new style.
390 .Pp
391 Look for
392 .Va if_snd
393 in the driver.
394 Probably, you need to make changes to the lines that include
395 .Va if_snd .
396 .Ss Empty check operation
397 If the code checks
398 .Va ifq_head
399 to 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
408 only checks if there is any packet stored in the queue.
409 Note that even when
410 .Fn IFQ_IS_EMPTY
411 is
412 .Dv FALSE ,
413 .Fn IFQ_DEQUEUE
414 could still return
415 .Dv NULL
416 if the queue is under rate-limiting.
417 .Ss Dequeue operation
418 Replace
419 .Fn IF_DEQUEUE
420 by
421 .Fn IFQ_DEQUEUE .
422 Always check whether the dequeued mbuf is
423 .Dv NULL
424 or not.
425 Note that even when
426 .Fn IFQ_IS_EMPTY
427 is
428 .Dv FALSE ,
429 .Fn IFQ_DEQUEUE
430 could return
431 .Dv NULL
432 due 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
441 A driver is supposed to call
442 .Fn if_start
443 from transmission complete interrupts in order to trigger the next dequeue.
444 .Ss Poll-and-dequeue operation
445 If the code polls the packet at the head of the queue and actually uses
446 the packet before dequeuing it, use
447 .Fn IFQ_POLL_NOLOCK
448 and
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
469 It is guaranteed that
470 .Fn IFQ_DEQUEUE_NOLOCK
471 under the same lock as a previous
472 .Fn IFQ_POLL_NOLOCK
473 returns the same packet.
474 Note that they need to be guarded by
475 .Fn IFQ_LOCK .
476 .Ss Eliminating Fn IF_PREPEND
477 If the code uses
478 .Fn IF_PREPEND ,
479 you have to eliminate it unless you can use a
480 .Dq "driver managed"
481 queue which allows the use of
482 .Fn IFQ_DRV_PREPEND
483 as a substitute.
484 A common usage of
485 .Fn IF_PREPEND
486 is to cancel the previous dequeue operation.
487 You 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
512 Use
513 .Fn IFQ_PURGE
514 to empty the queue.
515 Note 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
526 Convert
527 .Fn IF_*
528 macros to their equivalent
529 .Fn IFQ_DRV_*
530 and employ
531 .Fn IFQ_DRV_IS_EMPTY
532 where 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
539 Make sure that calls to
540 .Fn IFQ_DRV_DEQUEUE ,
541 .Fn IFQ_DRV_PREPEND
542 and
543 .Fn IFQ_DRV_PURGE
544 are protected with a mutex of some kind.
545 .Ss Attach routine
546 Use
547 .Fn IFQ_SET_MAXLEN
548 to set
549 .Va ifq_maxlen
550 to
551 .Fa len .
552 Initialize
553 .Va ifq_drv_maxlen
554 with a sensible value if you plan to use the
555 .Fn IFQ_DRV_*
556 macros.
557 Add
558 .Fn IFQ_SET_READY
559 to 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
571 The 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
583 Queuing disciplines need to maintain
584 .Fa ifq_len
585 (used by
586 .Fn IFQ_IS_EMPTY ) .
587 Queuing disciplines also need to guarantee that the same mbuf is returned if
588 .Fn IFQ_DEQUEUE
589 is 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
596 The
597 .Nm
598 system first appeared in March 1997 and found home in the KAME project
599 (http://www.kame.net).
600 It was imported to
601 .Fx
602 in 5.3 .