summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/mbuf.9 4.html
blob: de9adb9980b55cc4409587c798860db4f8ae3d35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
<table class="head">
  <tr>
    <td class="head-ltitle">MBUF(9)</td>
    <td class="head-vol">Kernel Developer's Manual</td>
    <td class="head-rtitle">MBUF(9)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">mbuf</code> &#x2014; <span class="Nd">memory
    management in the kernel IPC subsystem</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
    &lt;<a class="In">sys/param.h</a>&gt;</code>
  <br/>
  <code class="In">#include &lt;<a class="In">sys/systm.h</a>&gt;</code>
  <br/>
  <code class="In">#include &lt;<a class="In">sys/mbuf.h</a>&gt;</code></p>
<section class="Ss">
<h2 class="Ss" id="Mbuf_allocation_macros"><a class="permalink" href="#Mbuf_allocation_macros">Mbuf
  allocation macros</a></h2>
<p class="Pp"><code class="Fn">MGET</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    how</var>, <var class="Fa" style="white-space: nowrap;">short
  type</var>);</p>
<p class="Pp"><code class="Fn">MGETHDR</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    how</var>, <var class="Fa" style="white-space: nowrap;">short
  type</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">MCLGET</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    how</var>);</p>
<p class="Pp"><code class="Fn">MEXTADD</code>(<var class="Fa">struct mbuf
    *mbuf</var>, <var class="Fa">char *buf</var>, <var class="Fa">u_int
    size</var>, <var class="Fa">void (*free)(struct mbuf *)</var>,
    <var class="Fa">void *opt_arg1</var>, <var class="Fa">void *opt_arg2</var>,
    <var class="Fa">int flags</var>, <var class="Fa">int type</var>);</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Mbuf_utility_macros"><a class="permalink" href="#Mbuf_utility_macros">Mbuf
  utility macros</a></h2>
<p class="Pp"><var class="Ft">type</var>
  <br/>
  <code class="Fn">mtod</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>,
  <var class="Fa" style="white-space: nowrap;">type</var>);</p>
<p class="Pp"><var class="Ft">void *</var>
  <br/>
  <code class="Fn">mtodo</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>,
    <var class="Fa" style="white-space: nowrap;">offset</var>);</p>
<p class="Pp"><code class="Fn">M_ALIGN</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">u_int
    len</var>);</p>
<p class="Pp"><code class="Fn">MH_ALIGN</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">u_int
    len</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">M_LEADINGSPACE</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">M_TRAILINGSPACE</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>);</p>
<p class="Pp"><code class="Fn">M_MOVE_PKTHDR</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *to</var>, <var class="Fa" style="white-space: nowrap;">struct mbuf
    *from</var>);</p>
<p class="Pp"><code class="Fn">M_PREPEND</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>, <var class="Fa" style="white-space: nowrap;">int how</var>);</p>
<p class="Pp"><code class="Fn">MCHTYPE</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">short
    type</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">M_WRITABLE</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>);</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Mbuf_allocation_functions"><a class="permalink" href="#Mbuf_allocation_functions">Mbuf
  allocation functions</a></h2>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_get</code>(<var class="Fa" style="white-space: nowrap;">int
    how</var>, <var class="Fa" style="white-space: nowrap;">short
  type</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_get2</code>(<var class="Fa" style="white-space: nowrap;">int
    size</var>, <var class="Fa" style="white-space: nowrap;">int how</var>,
    <var class="Fa" style="white-space: nowrap;">short type</var>,
    <var class="Fa" style="white-space: nowrap;">int flags</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_get3</code>(<var class="Fa" style="white-space: nowrap;">int
    size</var>, <var class="Fa" style="white-space: nowrap;">int how</var>,
    <var class="Fa" style="white-space: nowrap;">short type</var>,
    <var class="Fa" style="white-space: nowrap;">int flags</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_getm</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *orig</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>, <var class="Fa" style="white-space: nowrap;">int how</var>,
    <var class="Fa" style="white-space: nowrap;">short type</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_getjcl</code>(<var class="Fa" style="white-space: nowrap;">int
    how</var>, <var class="Fa" style="white-space: nowrap;">short type</var>,
    <var class="Fa" style="white-space: nowrap;">int flags</var>,
    <var class="Fa" style="white-space: nowrap;">int size</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_getcl</code>(<var class="Fa" style="white-space: nowrap;">int
    how</var>, <var class="Fa" style="white-space: nowrap;">short type</var>,
    <var class="Fa" style="white-space: nowrap;">int flags</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_gethdr</code>(<var class="Fa" style="white-space: nowrap;">int
    how</var>, <var class="Fa" style="white-space: nowrap;">short
  type</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_free</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_freem</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>);</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Mbuf_utility_functions"><a class="permalink" href="#Mbuf_utility_functions">Mbuf
  utility functions</a></h2>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_adj</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_align</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">m_append</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>, <var class="Fa" style="white-space: nowrap;">c_caddr_t
  cp</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_prepend</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>, <var class="Fa" style="white-space: nowrap;">int how</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_copyup</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>, <var class="Fa" style="white-space: nowrap;">int
  dstoff</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_pullup</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_pulldown</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    offset</var>, <var class="Fa" style="white-space: nowrap;">int len</var>,
    <var class="Fa" style="white-space: nowrap;">int *offsetp</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_copym</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    offset</var>, <var class="Fa" style="white-space: nowrap;">int len</var>,
    <var class="Fa" style="white-space: nowrap;">int how</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_copypacket</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    how</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_dup</code>(<var class="Fa" style="white-space: nowrap;">const
    struct mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    how</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_copydata</code>(<var class="Fa" style="white-space: nowrap;">const
    struct mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    offset</var>, <var class="Fa" style="white-space: nowrap;">int len</var>,
    <var class="Fa" style="white-space: nowrap;">caddr_t buf</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_copyback</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    offset</var>, <var class="Fa" style="white-space: nowrap;">int len</var>,
    <var class="Fa" style="white-space: nowrap;">caddr_t buf</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_devget</code>(<var class="Fa">char *buf</var>,
    <var class="Fa">int len</var>, <var class="Fa">int offset</var>,
    <var class="Fa">struct ifnet *ifp</var>, <var class="Fa">void (*copy)(char
    *from, caddr_t to, u_int len)</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_cat</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *m</var>, <var class="Fa" style="white-space: nowrap;">struct mbuf
    *n</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_catpkt</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *m</var>, <var class="Fa" style="white-space: nowrap;">struct mbuf
    *n</var>);</p>
<p class="Pp"><var class="Ft">u_int</var>
  <br/>
  <code class="Fn">m_fixhdr</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">m_dup_pkthdr</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *to</var>, <var class="Fa" style="white-space: nowrap;">const struct
    mbuf *from</var>, <var class="Fa" style="white-space: nowrap;">int
    how</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">m_move_pkthdr</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *to</var>, <var class="Fa" style="white-space: nowrap;">struct mbuf
    *from</var>);</p>
<p class="Pp"><var class="Ft">u_int</var>
  <br/>
  <code class="Fn">m_length</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">struct mbuf
    **last</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_split</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    len</var>, <var class="Fa" style="white-space: nowrap;">int how</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">m_apply</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    off</var>, <var class="Fa" style="white-space: nowrap;">int len</var>,
    <var class="Fa" style="white-space: nowrap;">int (*f)(void *arg, void *data,
    u_int len)</var>, <var class="Fa" style="white-space: nowrap;">void
    *arg</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_getptr</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *mbuf</var>, <var class="Fa" style="white-space: nowrap;">int
    loc</var>, <var class="Fa" style="white-space: nowrap;">int *off</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_defrag</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *m0</var>, <var class="Fa" style="white-space: nowrap;">int
  how</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_collapse</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *m0</var>, <var class="Fa" style="white-space: nowrap;">int how</var>,
    <var class="Fa" style="white-space: nowrap;">int maxfrags</var>);</p>
<p class="Pp"><var class="Ft">struct mbuf *</var>
  <br/>
  <code class="Fn">m_unshare</code>(<var class="Fa" style="white-space: nowrap;">struct
    mbuf *m0</var>, <var class="Fa" style="white-space: nowrap;">int
  how</var>);</p>
</section>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">An <var class="Vt">mbuf</var> is a basic unit of memory management
    in the kernel IPC subsystem. Network packets and socket buffers are stored
    in <var class="Vt">mbufs</var>. A network packet may span multiple
    <var class="Vt">mbufs</var> arranged into a <var class="Vt">mbuf chain</var>
    (linked list), which allows adding or trimming network headers with little
    overhead.</p>
<p class="Pp">While a developer should not bother with
    <var class="Vt">mbuf</var> internals without serious reason in order to
    avoid incompatibilities with future changes, it is useful to understand the
    general structure of an <var class="Vt">mbuf</var>.</p>
<p class="Pp">An <var class="Vt">mbuf</var> consists of a variable-sized header
    and a small internal buffer for data. The total size of an
    <var class="Vt">mbuf</var>, <code class="Dv">MSIZE</code>, is a constant
    defined in <code class="In">&lt;<a class="In">sys/param.h</a>&gt;</code>.
    The <var class="Vt">mbuf</var> header includes:</p>
<div class="Bd-indent">
<dl class="Bl-tag">
  <dt id="m_next"><var class="Va">m_next</var></dt>
  <dd>(<var class="Vt">struct mbuf *</var>) A pointer to the next
      <var class="Vt">mbuf</var> in the <var class="Vt">mbuf chain</var>.</dd>
  <dt id="m_nextpkt"><var class="Va">m_nextpkt</var></dt>
  <dd>(<var class="Vt">struct mbuf *</var>) A pointer to the next
      <var class="Vt">mbuf chain</var> in the queue.</dd>
  <dt id="m_data"><var class="Va">m_data</var></dt>
  <dd>(<var class="Vt">caddr_t</var>) A pointer to data attached to this
      <var class="Vt">mbuf</var>.</dd>
  <dt id="m_len"><var class="Va">m_len</var></dt>
  <dd>(<var class="Vt">int</var>) The length of the data.</dd>
  <dt id="m_type"><var class="Va">m_type</var></dt>
  <dd>(<var class="Vt">short</var>) The type of the data.</dd>
  <dt id="m_flags"><var class="Va">m_flags</var></dt>
  <dd>(<var class="Vt">int</var>) The <var class="Vt">mbuf</var> flags.</dd>
</dl>
</div>
<p class="Pp">The <var class="Vt">mbuf</var> flag bits are defined as
  follows:</p>
<div class="Bd Pp Li">
<pre>#define	M_EXT		0x00000001 /* has associated external storage */
#define	M_PKTHDR	0x00000002 /* start of record */
#define	M_EOR		0x00000004 /* end of record */
#define	M_RDONLY	0x00000008 /* associated data marked read-only */
#define	M_BCAST		0x00000010 /* send/received as link-level broadcast */
#define	M_MCAST		0x00000020 /* send/received as link-level multicast */
#define	M_PROMISC	0x00000040 /* packet was not for us */
#define	M_VLANTAG	0x00000080 /* ether_vtag is valid */
#define	M_EXTPG		0x00000100 /* has array of unmapped pages and TLS */
#define	M_NOFREE	0x00000200 /* do not free mbuf, embedded in cluster */
#define	M_TSTMP		0x00000400 /* rcv_tstmp field is valid */
#define	M_TSTMP_HPREC	0x00000800 /* rcv_tstmp is high-prec, typically
				      hw-stamped on port (useful for IEEE 1588
				      and 802.1AS) */

#define	M_PROTO1	0x00001000 /* protocol-specific */
#define	M_PROTO2	0x00002000 /* protocol-specific */
#define	M_PROTO3	0x00004000 /* protocol-specific */
#define	M_PROTO4	0x00008000 /* protocol-specific */
#define	M_PROTO5	0x00010000 /* protocol-specific */
#define	M_PROTO6	0x00020000 /* protocol-specific */
#define	M_PROTO7	0x00040000 /* protocol-specific */
#define	M_PROTO8	0x00080000 /* protocol-specific */
#define	M_PROTO9	0x00100000 /* protocol-specific */
#define	M_PROTO10	0x00200000 /* protocol-specific */
#define	M_PROTO11	0x00400000 /* protocol-specific */
#define	M_PROTO12	0x00800000 /* protocol-specific */</pre>
</div>
<p class="Pp">The available <var class="Vt">mbuf</var> types are defined as
    follows:</p>
<div class="Bd Pp Li">
<pre>#define	MT_DATA		1	/* dynamic (data) allocation */
#define	MT_HEADER	MT_DATA	/* packet header */

#define	MT_VENDOR1	4	/* for vendor-internal use */
#define	MT_VENDOR2	5	/* for vendor-internal use */
#define	MT_VENDOR3	6	/* for vendor-internal use */
#define	MT_VENDOR4	7	/* for vendor-internal use */

#define	MT_SONAME	8	/* socket name */

#define	MT_EXP1		9	/* for experimental use */
#define	MT_EXP2		10	/* for experimental use */
#define	MT_EXP3		11	/* for experimental use */
#define	MT_EXP4		12	/* for experimental use */

#define	MT_CONTROL	14	/* extra-data protocol message */
#define	MT_EXTCONTROL	15	/* control message with externalized contents */
#define	MT_OOBDATA	16	/* expedited data  */</pre>
</div>
<p class="Pp">The available external buffer types are defined as follows:</p>
<div class="Bd Pp Li">
<pre>#define	EXT_CLUSTER	1	/* mbuf cluster */
#define	EXT_SFBUF	2	/* sendfile(2)'s sf_bufs */
#define	EXT_JUMBOP	3	/* jumbo cluster 4096 bytes */
#define	EXT_JUMBO9	4	/* jumbo cluster 9216 bytes */
#define	EXT_JUMBO16	5	/* jumbo cluster 16184 bytes */
#define	EXT_PACKET	6	/* mbuf+cluster from packet zone */
#define	EXT_MBUF	7	/* external mbuf reference */
#define	EXT_RXRING	8	/* data in NIC receive ring */
#define	EXT_PGS		9	/* array of unmapped pages */

#define	EXT_VENDOR1	224	/* for vendor-internal use */
#define	EXT_VENDOR2	225	/* for vendor-internal use */
#define	EXT_VENDOR3	226	/* for vendor-internal use */
#define	EXT_VENDOR4	227	/* for vendor-internal use */

#define	EXT_EXP1	244	/* for experimental use */
#define	EXT_EXP2	245	/* for experimental use */
#define	EXT_EXP3	246	/* for experimental use */
#define	EXT_EXP4	247	/* for experimental use */

#define	EXT_NET_DRV	252	/* custom ext_buf provided by net driver(s) */
#define	EXT_MOD_TYPE	253	/* custom module's ext_buf type */
#define	EXT_DISPOSABLE	254	/* can throw this buffer away w/page flipping */
#define	EXT_EXTREF	255	/* has externally maintained ref_cnt ptr */</pre>
</div>
<p class="Pp">If the <code class="Dv">M_PKTHDR</code> flag is set, a
    <var class="Vt">struct pkthdr</var> <var class="Va">m_pkthdr</var> is added
    to the <var class="Vt">mbuf</var> header. It contains a pointer to the
    interface the packet has been received from (<var class="Vt">struct
    ifnet</var> <var class="Va">*rcvif</var>), and the total packet length
    (<var class="Vt">int</var> <var class="Va">len</var>). Optionally, it may
    also contain an attached list of packet tags (<var class="Vt">struct
    m_tag</var>). See <a class="Xr">mbuf_tags(9)</a> for details. Fields used in
    offloading checksum calculation to the hardware are kept in
    <var class="Va">m_pkthdr</var> as well. See
    <a class="Sx" href="#HARDWARE_ASSISTED_CHECKSUM_CALCULATION">HARDWARE-ASSISTED
    CHECKSUM CALCULATION</a> for details.</p>
<p class="Pp">If small enough, data is stored in the internal data buffer of an
    <var class="Vt">mbuf</var>. If the data is sufficiently large, another
    <var class="Vt">mbuf</var> may be added to the <var class="Vt">mbuf
    chain</var>, or external storage may be associated with the
    <var class="Vt">mbuf</var>. <code class="Dv">MHLEN</code> bytes of data can
    fit into an <var class="Vt">mbuf</var> with the
    <code class="Dv">M_PKTHDR</code> flag set, <code class="Dv">MLEN</code>
    bytes can otherwise.</p>
<p class="Pp">If external storage is being associated with an
    <var class="Vt">mbuf</var>, the <var class="Va">m_ext</var> header is added
    at the cost of losing the internal data buffer. It includes a pointer to
    external storage, the size of the storage, a pointer to a function used for
    freeing the storage, a pointer to an optional argument that can be passed to
    the function, and a pointer to a reference counter. An
    <var class="Vt">mbuf</var> using external storage has the
    <code class="Dv">M_EXT</code> flag set.</p>
<p class="Pp">The system supplies a macro for allocating the desired external
    storage buffer, <code class="Dv">MEXTADD</code>.</p>
<p class="Pp">The allocation and management of the reference counter is handled
    by the subsystem.</p>
<p class="Pp">The system also supplies a default type of external storage buffer
    called an <var class="Vt">mbuf cluster</var>. <var class="Vt">Mbuf
    clusters</var> can be allocated and configured with the use of the
    <code class="Dv">MCLGET</code> macro. Each <var class="Vt">mbuf
    cluster</var> is <code class="Dv">MCLBYTES</code> in size, where MCLBYTES is
    a machine-dependent constant. The system defines an advisory macro
    <code class="Dv">MINCLSIZE</code>, which is the smallest amount of data to
    put into an <var class="Vt">mbuf cluster</var>. It is equal to
    <code class="Dv">MHLEN</code> plus one. It is typically preferable to store
    data into the data region of an <var class="Vt">mbuf</var>, if size permits,
    as opposed to allocating a separate <var class="Vt">mbuf cluster</var> to
    hold the same data.</p>
<section class="Ss">
<h2 class="Ss" id="Macros_and_Functions"><a class="permalink" href="#Macros_and_Functions">Macros
  and Functions</a></h2>
<p class="Pp">There are numerous predefined macros and functions that provide
    the developer with common utilities.</p>
<dl class="Bl-ohang Bd-indent">
  <dt id="mtod"><a class="permalink" href="#mtod"><code class="Fn">mtod</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">type</var>)</dt>
  <dd>Convert an <var class="Fa">mbuf</var> pointer to a data pointer. The macro
      expands to the data pointer cast to the specified
      <var class="Fa">type</var>. <b class="Sy">Note</b>: It is advisable to
      ensure that there is enough contiguous data in <var class="Fa">mbuf</var>.
      See
      <a class="permalink" href="#m_pullup"><code class="Fn" id="m_pullup">m_pullup</code></a>()
      for details.</dd>
  <dt id="mtodo"><a class="permalink" href="#mtodo"><code class="Fn">mtodo</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">offset</var>)</dt>
  <dd>Return a data pointer at an offset (in bytes) into the data attached to
      <var class="Fa">mbuf</var>. Returns a <var class="Ft">void *</var> pointer
      . <b class="Sy">Note</b>: The caller must ensure that the offset is in
      bounds of the attached data.</dd>
  <dt><code class="Fn">MGET</code>(<var class="Fa">mbuf</var>,
    <var class="Fa">how</var>, <var class="Fa">type</var>)</dt>
  <dd>Allocate an <var class="Vt">mbuf</var> and initialize it to contain
      internal data. <var class="Fa">mbuf</var> will point to the allocated
      <var class="Vt">mbuf</var> on success, or be set to
      <code class="Dv">NULL</code> on failure. The <var class="Fa">how</var>
      argument is to be set to <code class="Dv">M_WAITOK</code> or
      <code class="Dv">M_NOWAIT</code>. It specifies whether the caller is
      willing to block if necessary. A number of other functions and macros
      related to <var class="Vt">mbufs</var> have the same argument because they
      may at some point need to allocate new <var class="Vt">mbufs</var>.</dd>
  <dt id="MGETHDR"><a class="permalink" href="#MGETHDR"><code class="Fn">MGETHDR</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">how</var>, <var class="Fa">type</var>)</dt>
  <dd>Allocate an <var class="Vt">mbuf</var> and initialize it to contain a
      packet header and internal data. See <code class="Fn">MGET</code>() for
      details.</dd>
  <dt id="MEXTADD"><a class="permalink" href="#MEXTADD"><code class="Fn">MEXTADD</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">buf</var>, <var class="Fa">size</var>,
    <var class="Fa">free</var>, <var class="Fa">opt_arg1</var>,
    <var class="Fa">opt_arg2</var>, <var class="Fa">flags</var>,
    <var class="Fa">type</var>)</dt>
  <dd>Associate externally managed data with <var class="Fa">mbuf</var>. Any
      internal data contained in the mbuf will be discarded, and the
      <code class="Dv">M_EXT</code> flag will be set. The
      <var class="Fa">buf</var> and <var class="Fa">size</var> arguments are the
      address and length, respectively, of the data. The
      <var class="Fa">free</var> argument points to a function which will be
      called to free the data when the mbuf is freed; it is only used if
      <var class="Fa">type</var> is <code class="Dv">EXT_EXTREF</code>. The
      <var class="Fa">opt_arg1</var> and <var class="Fa">opt_arg2</var>
      arguments will be saved in <var class="Va">ext_arg1</var> and
      <var class="Va">ext_arg2</var> fields of the <var class="Va">struct
      m_ext</var> of the mbuf. The <var class="Fa">flags</var> argument
      specifies additional <var class="Vt">mbuf</var> flags; it is not necessary
      to specify <code class="Dv">M_EXT</code>. Finally, the
      <var class="Fa">type</var> argument specifies the type of external data,
      which controls how it will be disposed of when the
      <var class="Vt">mbuf</var> is freed. In most cases, the correct value is
      <code class="Dv">EXT_EXTREF</code>.</dd>
  <dt id="MCLGET"><a class="permalink" href="#MCLGET"><code class="Fn">MCLGET</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">how</var>)</dt>
  <dd>Allocate and attach an <var class="Vt">mbuf cluster</var> to
      <var class="Fa">mbuf</var>. On success, a non-zero value returned;
      otherwise, 0. Historically, consumers would check for success by testing
      the <code class="Dv">M_EXT</code> flag on the mbuf, but this is now
      discouraged to avoid unnecessary awareness of the implementation of
      external storage in protocol stacks and device drivers.</dd>
  <dt id="M_ALIGN"><a class="permalink" href="#M_ALIGN"><code class="Fn">M_ALIGN</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>)</dt>
  <dd>Set the pointer <var class="Fa">mbuf-&gt;m_data</var> to place an object
      of the size <var class="Fa">len</var> at the end of the internal data area
      of <var class="Fa">mbuf</var>, long word aligned. Applicable only if
      <var class="Fa">mbuf</var> is newly allocated with
      <code class="Fn">MGET</code>() or <code class="Fn">m_get</code>().</dd>
  <dt id="MH_ALIGN"><a class="permalink" href="#MH_ALIGN"><code class="Fn">MH_ALIGN</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>)</dt>
  <dd>Serves the same purpose as <code class="Fn">M_ALIGN</code>() does, but
      only for <var class="Fa">mbuf</var> newly allocated with
      <code class="Fn">MGETHDR</code>() or <code class="Fn">m_gethdr</code>(),
      or initialized by
      <a class="permalink" href="#m_dup_pkthdr"><code class="Fn" id="m_dup_pkthdr">m_dup_pkthdr</code></a>()
      or
      <a class="permalink" href="#m_move_pkthdr"><code class="Fn" id="m_move_pkthdr">m_move_pkthdr</code></a>().</dd>
  <dt id="m_align"><a class="permalink" href="#m_align"><code class="Fn">m_align</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>)</dt>
  <dd>Services the same purpose as <code class="Fn">M_ALIGN</code>() but handles
      any type of mbuf.</dd>
  <dt id="M_LEADINGSPACE"><a class="permalink" href="#M_LEADINGSPACE"><code class="Fn">M_LEADINGSPACE</code></a>(<var class="Fa">mbuf</var>)</dt>
  <dd>Returns the number of bytes available before the beginning of data in
      <var class="Fa">mbuf</var>.</dd>
  <dt id="M_TRAILINGSPACE"><a class="permalink" href="#M_TRAILINGSPACE"><code class="Fn">M_TRAILINGSPACE</code></a>(<var class="Fa">mbuf</var>)</dt>
  <dd>Returns the number of bytes available after the end of data in
      <var class="Fa">mbuf</var>.</dd>
  <dt id="M_PREPEND"><a class="permalink" href="#M_PREPEND"><code class="Fn">M_PREPEND</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>, <var class="Fa">how</var>)</dt>
  <dd>This macro operates on an <var class="Vt">mbuf chain</var>. It is an
      optimized wrapper for <code class="Fn">m_prepend</code>() that can make
      use of possible empty space before data (e.g. left after trimming of a
      link-layer header). The new <var class="Vt">mbuf chain</var> pointer or
      <code class="Dv">NULL</code> is in <var class="Fa">mbuf</var> after the
      call.</dd>
  <dt id="M_MOVE_PKTHDR"><a class="permalink" href="#M_MOVE_PKTHDR"><code class="Fn">M_MOVE_PKTHDR</code></a>(<var class="Fa">to</var>,
    <var class="Fa">from</var>)</dt>
  <dd>Using this macro is equivalent to calling
      <code class="Fn">m_move_pkthdr</code>(<var class="Fa">to</var>,
      <var class="Fa">from</var>).</dd>
  <dt id="M_WRITABLE"><a class="permalink" href="#M_WRITABLE"><code class="Fn">M_WRITABLE</code></a>(<var class="Fa">mbuf</var>)</dt>
  <dd>This macro will evaluate true if <var class="Fa">mbuf</var> is not marked
      <code class="Dv">M_RDONLY</code> and if either <var class="Fa">mbuf</var>
      does not contain external storage or, if it does, then if the reference
      count of the storage is not greater than 1. The
      <code class="Dv">M_RDONLY</code> flag can be set in
      <var class="Fa">mbuf-&gt;m_flags</var>. This can be achieved during setup
      of the external storage, by passing the <code class="Dv">M_RDONLY</code>
      bit as a <var class="Fa">flags</var> argument to the
      <code class="Fn">MEXTADD</code>() macro, or can be directly set in
      individual <var class="Vt">mbufs</var>.</dd>
  <dt id="MCHTYPE"><a class="permalink" href="#MCHTYPE"><code class="Fn">MCHTYPE</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">type</var>)</dt>
  <dd>Change the type of <var class="Fa">mbuf</var> to
      <var class="Fa">type</var>. This is a relatively expensive operation and
      should be avoided.</dd>
</dl>
<p class="Pp">The functions are:</p>
<dl class="Bl-ohang Bd-indent">
  <dt id="m_get"><a class="permalink" href="#m_get"><code class="Fn">m_get</code></a>(<var class="Fa">how</var>,
    <var class="Fa">type</var>)</dt>
  <dd>A function version of
      <a class="permalink" href="#MGET"><code class="Fn" id="MGET">MGET</code></a>()
      for non-critical paths.</dd>
  <dt id="m_get2"><a class="permalink" href="#m_get2"><code class="Fn">m_get2</code></a>(<var class="Fa">size</var>,
    <var class="Fa">how</var>, <var class="Fa">type</var>,
    <var class="Fa">flags</var>)</dt>
  <dd>Allocate an <var class="Vt">mbuf</var> with enough space to hold specified
      amount of data. If the size is larger than
      <code class="Dv">MJUMPAGESIZE</code>, <code class="Dv">NULL</code> will be
      returned.</dd>
  <dt id="m_get3"><a class="permalink" href="#m_get3"><code class="Fn">m_get3</code></a>(<var class="Fa">size</var>,
    <var class="Fa">how</var>, <var class="Fa">type</var>,
    <var class="Fa">flags</var>)</dt>
  <dd>Allocate an <var class="Vt">mbuf</var> with enough space to hold specified
      amount of data. If the size is larger than <code class="Dv">MJUM16BYTES,
      NULL</code> will be returned.</dd>
  <dt id="m_getm"><a class="permalink" href="#m_getm"><code class="Fn">m_getm</code></a>(<var class="Fa">orig</var>,
    <var class="Fa">len</var>, <var class="Fa">how</var>,
    <var class="Fa">type</var>)</dt>
  <dd>Allocate <var class="Fa">len</var> bytes worth of
      <var class="Vt">mbufs</var> and <var class="Vt">mbuf clusters</var> if
      necessary and append the resulting allocated <var class="Vt">mbuf
      chain</var> to the <var class="Vt">mbuf chain</var>
      <var class="Fa">orig</var>, if it is
      <span class="No">non-</span><code class="Dv">NULL</code>. If the
      allocation fails at any point, free whatever was allocated and return
      <code class="Dv">NULL</code>. If <var class="Fa">orig</var> is
      <span class="No">non-</span><code class="Dv">NULL</code>, it will not be
      freed. It is possible to use <code class="Fn">m_getm</code>() to either
      append <var class="Fa">len</var> bytes to an existing
      <var class="Vt">mbuf</var> or <var class="Vt">mbuf chain</var> (for
      example, one which may be sitting in a pre-allocated ring) or to simply
      perform an all-or-nothing <var class="Vt">mbuf</var> and
      <var class="Vt">mbuf cluster</var> allocation.</dd>
  <dt id="m_gethdr"><a class="permalink" href="#m_gethdr"><code class="Fn">m_gethdr</code></a>(<var class="Fa">how</var>,
    <var class="Fa">type</var>)</dt>
  <dd>A function version of <code class="Fn">MGETHDR</code>() for non-critical
      paths.</dd>
  <dt id="m_getcl"><a class="permalink" href="#m_getcl"><code class="Fn">m_getcl</code></a>(<var class="Fa">how</var>,
    <var class="Fa">type</var>, <var class="Fa">flags</var>)</dt>
  <dd>Fetch an <var class="Vt">mbuf</var> with a <var class="Vt">mbuf
      cluster</var> attached to it. If one of the allocations fails, the entire
      allocation fails. This routine is the preferred way of fetching both the
      <var class="Vt">mbuf</var> and <var class="Vt">mbuf cluster</var>
      together, as it avoids having to unlock/relock between allocations.
      Returns <code class="Dv">NULL</code> on failure.</dd>
  <dt id="m_getjcl"><a class="permalink" href="#m_getjcl"><code class="Fn">m_getjcl</code></a>(<var class="Fa">how</var>,
    <var class="Fa">type</var>, <var class="Fa">flags</var>,
    <var class="Fa">size</var>)</dt>
  <dd>This is like <code class="Fn">m_getcl</code>() but the specified
      <var class="Fa">size</var> of the cluster to be allocated must be one of
      <code class="Dv">MCLBYTES</code>, <code class="Dv">MJUMPAGESIZE</code>,
      <code class="Dv">MJUM9BYTES</code>, or
      <code class="Dv">MJUM16BYTES</code>.</dd>
  <dt id="m_free"><a class="permalink" href="#m_free"><code class="Fn">m_free</code></a>(<var class="Fa">mbuf</var>)</dt>
  <dd>Frees <var class="Vt">mbuf</var>. Returns <var class="Va">m_next</var> of
      the freed <var class="Vt">mbuf</var>.</dd>
</dl>
<p class="Pp">The functions below operate on <var class="Vt">mbuf
  chains</var>.</p>
<dl class="Bl-ohang Bd-indent">
  <dt id="m_freem"><a class="permalink" href="#m_freem"><code class="Fn">m_freem</code></a>(<var class="Fa">mbuf</var>)</dt>
  <dd>Free an entire <var class="Vt">mbuf chain</var>, including any external
      storage.</dd>
  <dt id="m_adj"><a class="permalink" href="#m_adj"><code class="Fn">m_adj</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>)</dt>
  <dd>Trim <var class="Fa">len</var> bytes from the head of an
      <var class="Vt">mbuf chain</var> if <var class="Fa">len</var> is positive,
      from the tail otherwise.</dd>
  <dt id="m_append"><a class="permalink" href="#m_append"><code class="Fn">m_append</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>, <var class="Fa">cp</var>)</dt>
  <dd>Append <var class="Vt">len</var> bytes of data <var class="Vt">cp</var> to
      the <var class="Vt">mbuf chain</var>. Extend the mbuf chain if the new
      data does not fit in existing space.</dd>
  <dt id="m_prepend"><a class="permalink" href="#m_prepend"><code class="Fn">m_prepend</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>, <var class="Fa">how</var>)</dt>
  <dd>Allocate a new <var class="Vt">mbuf</var> and prepend it to the
      <var class="Vt">mbuf chain</var>, handle <code class="Dv">M_PKTHDR</code>
      properly. <b class="Sy">Note</b>: It does not allocate any
      <var class="Vt">mbuf clusters</var>, so <var class="Fa">len</var> must be
      less than <code class="Dv">MLEN</code> or <code class="Dv">MHLEN</code>,
      depending on the <code class="Dv">M_PKTHDR</code> flag setting.</dd>
  <dt id="m_copyup"><a class="permalink" href="#m_copyup"><code class="Fn">m_copyup</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>, <var class="Fa">dstoff</var>)</dt>
  <dd>Similar to <code class="Fn">m_pullup</code>() but copies
      <var class="Fa">len</var> bytes of data into a new mbuf at
      <var class="Fa">dstoff</var> bytes into the mbuf. The
      <var class="Fa">dstoff</var> argument aligns the data and leaves room for
      a link layer header. Returns the new <var class="Vt">mbuf chain</var> on
      success, and frees the <var class="Vt">mbuf chain</var> and returns
      <code class="Dv">NULL</code> on failure. <b class="Sy">Note</b>: The
      function does not allocate <var class="Vt">mbuf clusters</var>, so
      <var class="Fa">len + dstoff</var> must be less than
      <code class="Dv">MHLEN</code>.</dd>
  <dt><code class="Fn">m_pullup</code>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>)</dt>
  <dd>Arrange that the first <var class="Fa">len</var> bytes of an
      <var class="Vt">mbuf chain</var> are contiguous and lay in the data area
      of <var class="Fa">mbuf</var>, so they are accessible with
      <code class="Fn">mtod</code>(<var class="Fa">mbuf</var>,
      <var class="Fa">type</var>). It is important to remember that this may
      involve reallocating some mbufs and moving data so all pointers
      referencing data within the old mbuf chain must be recalculated or made
      invalid. Return the new <var class="Vt">mbuf chain</var> on success,
      <code class="Dv">NULL</code> on failure (the <var class="Vt">mbuf
      chain</var> is freed in this case). <b class="Sy">Note</b>: It does not
      allocate any <var class="Vt">mbuf clusters</var>, so
      <var class="Fa">len</var> must be less than or equal to
      <code class="Dv">MHLEN</code>.</dd>
  <dt id="m_pulldown"><a class="permalink" href="#m_pulldown"><code class="Fn">m_pulldown</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">offset</var>, <var class="Fa">len</var>,
    <var class="Fa">offsetp</var>)</dt>
  <dd>Arrange that <var class="Fa">len</var> bytes between
      <var class="Fa">offset</var> and <var class="Fa">offset + len</var> in the
      <var class="Vt">mbuf chain</var> are contiguous and lay in the data area
      of <var class="Fa">mbuf</var>, so they are accessible with
      <code class="Fn">mtod</code>() or <code class="Fn">mtodo</code>().
      <var class="Fa">len</var> must be smaller than, or equal to, the size of
      an <var class="Vt">mbuf cluster</var>. Return a pointer to an intermediate
      <var class="Vt">mbuf</var> in the chain containing the requested region;
      the offset in the data region of the <var class="Vt">mbuf chain</var> to
      the data contained in the returned mbuf is stored in
      <var class="Fa">*offsetp</var>. If <var class="Fa">offsetp</var> is NULL,
      the region may be accessed using
      <code class="Fn">mtod</code>(<var class="Fa">mbuf</var>,
      <var class="Fa">type</var>) or
      <code class="Fn">mtodo</code>(<var class="Fa">mbuf</var>,
      <var class="Fa">0</var>). If <var class="Fa">offsetp</var> is non-NULL,
      the region may be accessed using
      <code class="Fn">mtodo</code>(<var class="Fa">mbuf</var>,
      <var class="Fa">*offsetp</var>). The region of the mbuf chain between its
      beginning and <var class="Fa">offset</var> is not modified, therefore it
      is safe to hold pointers to data within this region before calling
      <code class="Fn">m_pulldown</code>().</dd>
  <dt id="m_copym"><a class="permalink" href="#m_copym"><code class="Fn">m_copym</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">offset</var>, <var class="Fa">len</var>,
    <var class="Fa">how</var>)</dt>
  <dd>Make a copy of an <var class="Vt">mbuf chain</var> starting
      <var class="Fa">offset</var> bytes from the beginning, continuing for
      <var class="Fa">len</var> bytes. If <var class="Fa">len</var> is
      <code class="Dv">M_COPYALL</code>, copy to the end of the
      <var class="Vt">mbuf chain</var>. <b class="Sy">Note</b>: The copy is
      read-only, because the <var class="Vt">mbuf clusters</var> are not copied,
      only their reference counts are incremented.</dd>
  <dt id="m_copypacket"><a class="permalink" href="#m_copypacket"><code class="Fn">m_copypacket</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">how</var>)</dt>
  <dd>Copy an entire packet including header, which must be present. This is an
      optimized version of the common case
      <code class="Fn">m_copym</code>(<var class="Fa">mbuf</var>,
      <var class="Fa">0</var>, <var class="Fa">M_COPYALL</var>,
      <var class="Fa">how</var>). <b class="Sy">Note</b>: the copy is read-only,
      because the <var class="Vt">mbuf clusters</var> are not copied, only their
      reference counts are incremented.</dd>
  <dt id="m_dup"><a class="permalink" href="#m_dup"><code class="Fn">m_dup</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">how</var>)</dt>
  <dd>Copy a packet header <var class="Vt">mbuf chain</var> into a completely
      new <var class="Vt">mbuf chain</var>, including copying any
      <var class="Vt">mbuf clusters</var>. Use this instead of
      <code class="Fn">m_copypacket</code>() when you need a writable copy of an
      <var class="Vt">mbuf chain</var>.</dd>
  <dt id="m_copydata"><a class="permalink" href="#m_copydata"><code class="Fn">m_copydata</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">offset</var>, <var class="Fa">len</var>,
    <var class="Fa">buf</var>)</dt>
  <dd>Copy data from an <var class="Vt">mbuf chain</var> starting
      <var class="Fa">off</var> bytes from the beginning, continuing for
      <var class="Fa">len</var> bytes, into the indicated buffer
      <var class="Fa">buf</var>.</dd>
  <dt id="m_copyback"><a class="permalink" href="#m_copyback"><code class="Fn">m_copyback</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">offset</var>, <var class="Fa">len</var>,
    <var class="Fa">buf</var>)</dt>
  <dd>Copy <var class="Fa">len</var> bytes from the buffer
      <var class="Fa">buf</var> back into the indicated <var class="Vt">mbuf
      chain</var>, starting at <var class="Fa">offset</var> bytes from the
      beginning of the <var class="Vt">mbuf chain</var>, extending the
      <var class="Vt">mbuf chain</var> if necessary. <b class="Sy">Note</b>: It
      does not allocate any <var class="Vt">mbuf clusters</var>, just adds
      <var class="Vt">mbufs</var> to the <var class="Vt">mbuf chain</var>. It is
      safe to set <var class="Fa">offset</var> beyond the current
      <var class="Vt">mbuf chain</var> end: zeroed <var class="Vt">mbufs</var>
      will be allocated to fill the space.</dd>
  <dt id="m_length"><a class="permalink" href="#m_length"><code class="Fn">m_length</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">last</var>)</dt>
  <dd>Return the length of the <var class="Vt">mbuf chain</var>, and optionally
      a pointer to the last <var class="Vt">mbuf</var>.</dd>
  <dt><code class="Fn">m_dup_pkthdr</code>(<var class="Fa">to</var>,
    <var class="Fa">from</var>, <var class="Fa">how</var>)</dt>
  <dd>Upon the function's completion, the <var class="Vt">mbuf</var>
      <var class="Fa">to</var> will contain an identical copy of
      <var class="Fa">from-&gt;m_pkthdr</var> and the per-packet attributes
      found in the <var class="Vt">mbuf chain</var> <var class="Fa">from</var>.
      The <var class="Vt">mbuf</var> <var class="Fa">from</var> must have the
      flag <code class="Dv">M_PKTHDR</code> initially set, and
      <var class="Fa">to</var> must be empty on entry.</dd>
  <dt><code class="Fn">m_move_pkthdr</code>(<var class="Fa">to</var>,
    <var class="Fa">from</var>)</dt>
  <dd>Move <var class="Va">m_pkthdr</var> and the per-packet attributes from the
      <var class="Vt">mbuf chain</var> <var class="Fa">from</var> to the
      <var class="Vt">mbuf</var> <var class="Fa">to</var>. The
      <var class="Vt">mbuf</var> <var class="Fa">from</var> must have the flag
      <code class="Dv">M_PKTHDR</code> initially set, and
      <var class="Fa">to</var> must be empty on entry. Upon the function's
      completion, <var class="Fa">from</var> will have the flag
      <code class="Dv">M_PKTHDR</code> and the per-packet attributes
    cleared.</dd>
  <dt id="m_fixhdr"><a class="permalink" href="#m_fixhdr"><code class="Fn">m_fixhdr</code></a>(<var class="Fa">mbuf</var>)</dt>
  <dd>Set the packet-header length to the length of the <var class="Vt">mbuf
      chain</var>.</dd>
  <dt id="m_devget"><a class="permalink" href="#m_devget"><code class="Fn">m_devget</code></a>(<var class="Fa">buf</var>,
    <var class="Fa">len</var>, <var class="Fa">offset</var>,
    <var class="Fa">ifp</var>, <var class="Fa">copy</var>)</dt>
  <dd>Copy data from a device local memory pointed to by
      <var class="Fa">buf</var> to an <var class="Vt">mbuf chain</var>. The copy
      is done using a specified copy routine <var class="Fa">copy</var>, or
      <a class="permalink" href="#bcopy"><code class="Fn" id="bcopy">bcopy</code></a>()
      if <var class="Fa">copy</var> is <code class="Dv">NULL</code>.</dd>
  <dt id="m_cat"><a class="permalink" href="#m_cat"><code class="Fn">m_cat</code></a>(<var class="Fa">m</var>,
    <var class="Fa">n</var>)</dt>
  <dd>Concatenate <var class="Fa">n</var> to <var class="Fa">m</var>. Both
      <var class="Vt">mbuf chains</var> must be of the same type.
      <var class="Fa">n</var> is not guaranteed to be valid after
      <code class="Fn">m_cat</code>() returns. <code class="Fn">m_cat</code>()
      does not update any packet header fields or free mbuf tags.</dd>
  <dt id="m_catpkt"><a class="permalink" href="#m_catpkt"><code class="Fn">m_catpkt</code></a>(<var class="Fa">m</var>,
    <var class="Fa">n</var>)</dt>
  <dd>A variant of <code class="Fn">m_cat</code>() that operates on packets.
      Both <var class="Fa">m</var> and <var class="Fa">n</var> must contain
      packet headers. <var class="Fa">n</var> is not guaranteed to be valid
      after <code class="Fn">m_catpkt</code>() returns.</dd>
  <dt id="m_split"><a class="permalink" href="#m_split"><code class="Fn">m_split</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">len</var>, <var class="Fa">how</var>)</dt>
  <dd>Partition an <var class="Vt">mbuf chain</var> in two pieces, returning the
      tail: all but the first <var class="Fa">len</var> bytes. In case of
      failure, it returns <code class="Dv">NULL</code> and attempts to restore
      the <var class="Vt">mbuf chain</var> to its original state.</dd>
  <dt><code class="Fn">m_apply</code>(<var class="Fa">mbuf</var>,
    <var class="Fa">off</var>, <var class="Fa">len</var>,
    <var class="Fa">f</var>, <var class="Fa">arg</var>)</dt>
  <dd>Apply a function to an <var class="Vt">mbuf chain</var>, at offset
      <var class="Fa">off</var>, for length <var class="Fa">len</var> bytes.
      Typically used to avoid calls to <code class="Fn">m_pullup</code>() which
      would otherwise be unnecessary or undesirable. <var class="Fa">arg</var>
      is a convenience argument which is passed to the callback function
      <var class="Fa">f</var>.
    <p class="Pp" id="f">Each time
        <a class="permalink" href="#f"><code class="Fn">f</code></a>() is
        called, it will be passed <var class="Fa">arg</var>, a pointer to the
        <var class="Fa">data</var> in the current mbuf, and the length
        <var class="Fa">len</var> of the data in this mbuf to which the function
        should be applied.</p>
    <p class="Pp" id="m_apply">The function should return zero to indicate
        success; otherwise, if an error is indicated, then
        <a class="permalink" href="#m_apply"><code class="Fn">m_apply</code></a>()
        will return the error and stop iterating through the
        <var class="Vt">mbuf chain</var>.</p>
  </dd>
  <dt id="m_getptr"><a class="permalink" href="#m_getptr"><code class="Fn">m_getptr</code></a>(<var class="Fa">mbuf</var>,
    <var class="Fa">loc</var>, <var class="Fa">off</var>)</dt>
  <dd>Return a pointer to the mbuf containing the data located at
      <var class="Fa">loc</var> bytes from the beginning of the
      <var class="Vt">mbuf chain</var>. The corresponding offset into the mbuf
      will be stored in <var class="Fa">*off</var>.</dd>
  <dt><code class="Fn">m_defrag</code>(<var class="Fa">m0</var>,
    <var class="Fa">how</var>)</dt>
  <dd>Defragment an mbuf chain, returning the shortest possible chain of mbufs
      and clusters. If allocation fails and this can not be completed,
      <code class="Dv">NULL</code> will be returned and the original chain will
      be unchanged. Upon success, the original chain will be freed and the new
      chain will be returned. <var class="Fa">how</var> should be either
      <code class="Dv">M_WAITOK</code> or <code class="Dv">M_NOWAIT</code>,
      depending on the caller's preference.
    <p class="Pp">This function is especially useful in network drivers, where
        certain long mbuf chains must be shortened before being added to TX
        descriptor lists.</p>
  </dd>
  <dt id="m_collapse"><a class="permalink" href="#m_collapse"><code class="Fn">m_collapse</code></a>(<var class="Fa">m0</var>,
    <var class="Fa">how</var>, <var class="Fa">maxfrags</var>)</dt>
  <dd>Defragment an mbuf chain, returning a chain of at most
      <var class="Fa">maxfrags</var> mbufs and clusters. If allocation fails or
      the chain cannot be collapsed as requested, <code class="Dv">NULL</code>
      will be returned, with the original chain possibly modified. As with
      <a class="permalink" href="#m_defrag"><code class="Fn" id="m_defrag">m_defrag</code></a>(),
      <var class="Fa">how</var> should be one of
      <code class="Dv">M_WAITOK</code> or <code class="Dv">M_NOWAIT</code>.</dd>
  <dt id="m_unshare"><a class="permalink" href="#m_unshare"><code class="Fn">m_unshare</code></a>(<var class="Fa">m0</var>,
    <var class="Fa">how</var>)</dt>
  <dd>Create a version of the specified mbuf chain whose contents can be safely
      modified without affecting other users. If allocation fails and this
      operation can not be completed, <code class="Dv">NULL</code> will be
      returned. The original mbuf chain is always reclaimed and the reference
      count of any shared mbuf clusters is decremented.
      <var class="Fa">how</var> should be either
      <code class="Dv">M_WAITOK</code> or <code class="Dv">M_NOWAIT</code>,
      depending on the caller's preference. As a side-effect of this process the
      returned mbuf chain may be compacted.
    <p class="Pp">This function is especially useful in the transmit path of
        network code, when data must be encrypted or otherwise altered prior to
        transmission.</p>
  </dd>
</dl>
</section>
</section>
<section class="Sh">
<h1 class="Sh" id="HARDWARE-ASSISTED_CHECKSUM_CALCULATION"><a class="permalink" href="#HARDWARE-ASSISTED_CHECKSUM_CALCULATION">HARDWARE-ASSISTED
  CHECKSUM CALCULATION</a></h1>
<p class="Pp">This section currently applies to SCTP, TCP, and UDP over IP only.
    In order to save the host CPU resources, computing checksums is offloaded to
    the network interface hardware if possible. The
    <var class="Va">m_pkthdr</var> member of the leading
    <var class="Vt">mbuf</var> of a packet contains two fields used for that
    purpose, <var class="Vt">int</var> <var class="Va">csum_flags</var> and
    <var class="Vt">int</var> <var class="Va">csum_data</var>. The meaning of
    those fields depends on whether the packet is fragmented. Henceforth,
    <var class="Va">csum_flags</var> or <var class="Va">csum_data</var> of a
    packet will denote the corresponding field of the
    <var class="Va">m_pkthdr</var> member of the leading
    <var class="Vt">mbuf</var> in the <var class="Vt">mbuf chain</var>
    containing the packet.</p>
<p class="Pp">When a packet is sent by SCTP, TCP, or UDP, the computation of the
    checksum is delayed until the outgoing interface has been determined for a
    packet. The interface-specific field
    <var class="Va">ifnet.if_data.ifi_hwassist</var> (see
    <a class="Xr">ifnet(9)</a>) is consulted by IP for the capabilities of the
    network interface selected for output to assist in computing checksums. The
    <var class="Va">csum_flags</var> field of the packet header is set to
    indicate which actions the interface is supposed to perform on it. The
    actions unsupported by the network interface are done in the software prior
    to passing the packet down to the interface driver; such actions will never
    be requested through <var class="Va">csum_flags</var>.</p>
<p class="Pp">The flags demanding a particular action from an interface are as
    follows:</p>
<div class="Bd-indent">
<dl class="Bl-tag">
  <dt id="CSUM_IP"><a class="permalink" href="#CSUM_IP"><code class="Dv">CSUM_IP</code></a></dt>
  <dd>The IP header checksum is to be computed and stored in the corresponding
      field of the packet. The hardware is expected to know the format of an IP
      header to determine the offset of the IP checksum field.</dd>
  <dt id="CSUM_SCTP"><a class="permalink" href="#CSUM_SCTP"><code class="Dv">CSUM_SCTP</code></a></dt>
  <dd>The SCTP checksum is to be computed. (See below.)</dd>
  <dt id="CSUM_TCP"><a class="permalink" href="#CSUM_TCP"><code class="Dv">CSUM_TCP</code></a></dt>
  <dd>The TCP checksum is to be computed. (See below.)</dd>
  <dt id="CSUM_UDP"><a class="permalink" href="#CSUM_UDP"><code class="Dv">CSUM_UDP</code></a></dt>
  <dd>The UDP checksum is to be computed. (See below.)</dd>
</dl>
</div>
<p class="Pp">Should a SCTP, TCP, or UDP checksum be offloaded to the hardware,
    the field <var class="Va">csum_data</var> will contain the byte offset of
    the checksum field relative to the end of the IP header. In the case of TCP
    or UDP, the checksum field will be initially set by the TCP or UDP
    implementation to the checksum of the pseudo header defined by the TCP and
    UDP specifications. In the case of SCTP, the checksum field will be
    initially set by the SCTP implementation to 0.</p>
<p class="Pp">When a packet is received by an interface, it indicates the
    actions it has performed on a packet by setting one or more of the following
    flags in <var class="Va">csum_flags</var> associated with the packet:</p>
<div class="Bd-indent">
<dl class="Bl-tag">
  <dt id="CSUM_IP_CHECKED"><a class="permalink" href="#CSUM_IP_CHECKED"><code class="Dv">CSUM_IP_CHECKED</code></a></dt>
  <dd>The IP header checksum has been computed.</dd>
  <dt id="CSUM_IP_VALID"><a class="permalink" href="#CSUM_IP_VALID"><code class="Dv">CSUM_IP_VALID</code></a></dt>
  <dd>The IP header has a valid checksum. This flag can appear only in
      combination with <code class="Dv">CSUM_IP_CHECKED</code>.</dd>
  <dt id="CSUM_DATA_VALID"><a class="permalink" href="#CSUM_DATA_VALID"><code class="Dv">CSUM_DATA_VALID</code></a></dt>
  <dd>The checksum of the data portion of the IP packet has been computed and
      stored in the field <var class="Va">csum_data</var> in network byte
    order.</dd>
  <dt id="CSUM_PSEUDO_HDR"><a class="permalink" href="#CSUM_PSEUDO_HDR"><code class="Dv">CSUM_PSEUDO_HDR</code></a></dt>
  <dd>Can be set only along with <code class="Dv">CSUM_DATA_VALID</code> to
      indicate that the IP data checksum found in
      <var class="Va">csum_data</var> allows for the pseudo header defined by
      the TCP and UDP specifications. Otherwise the checksum of the pseudo
      header must be calculated by the host CPU and added to
      <var class="Va">csum_data</var> to obtain the final checksum to be used
      for TCP or UDP validation purposes.</dd>
</dl>
</div>
<p class="Pp">If a particular network interface just indicates success or
    failure of SCTP, TCP, or UDP checksum validation without returning the exact
    value of the checksum to the host CPU, its driver can mark
    <code class="Dv">CSUM_DATA_VALID</code> in <var class="Va">csum_flags</var>
    as well as, for TCP and UDP, <code class="Dv">CSUM_PSEUDO_HDR</code> and set
    <var class="Va">csum_data</var> to <code class="Li">0xFFFF</code>
    hexadecimal to indicate a valid checksum. It is a peculiarity of the
    algorithm used that the Internet checksum calculated over any valid packet
    will be <code class="Li">0xFFFF</code> as long as the original checksum
    field is included. Note that for SCTP the value of
    <var class="Va">csum_data</var> is not relevant and
    <code class="Dv">CSUM_PSEUDO_HDR</code> in <var class="Va">csum_flags</var>
    is not set, since SCTP does not use a pseudo header checksum.</p>
<p class="Pp">If IP delivers a packet with the flags
    <code class="Dv">CSUM_IP</code>, <code class="Dv">CSUM_SCTP</code>,
    <code class="Dv">CSUM_TCP</code>, or <code class="Dv">CSUM_UDP</code> set in
    <var class="Va">csum_flags</var> to a local IP, SCTP, TCP, or UDP stack, the
    packet will be processed without computing or validating the checksum, since
    the packet has not been on the wire. This can happen if the packet was
    handled by a virtual interface such as <a class="Xr">tap(4)</a> or
    <a class="Xr">epair(4)</a>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="STRESS_TESTING"><a class="permalink" href="#STRESS_TESTING">STRESS
  TESTING</a></h1>
<p class="Pp">When running a kernel compiled with the option
    <code class="Dv">MBUF_STRESS_TEST</code>, the following
    <a class="Xr">sysctl(8)</a>-controlled options may be used to create various
    failure/extreme cases for testing of network drivers and other parts of the
    kernel that rely on <var class="Vt">mbufs</var>.</p>
<dl class="Bl-tag">
  <dt id="net.inet.ip.mbuf_frag_size"><var class="Va">net.inet.ip.mbuf_frag_size</var></dt>
  <dd>Causes
      <a class="permalink" href="#ip_output"><code class="Fn" id="ip_output">ip_output</code></a>()
      to fragment outgoing <var class="Vt">mbuf chains</var> into fragments of
      the specified size. Setting this variable to 1 is an excellent way to test
      the long <var class="Vt">mbuf chain</var> handling ability of network
      drivers.</dd>
  <dt id="kern.ipc.m_defragrandomfailures"><var class="Va">kern.ipc.m_defragrandomfailures</var></dt>
  <dd>Causes the function
      <a class="permalink" href="#m_defrag~2"><code class="Fn" id="m_defrag~2">m_defrag</code></a>()
      to randomly fail, returning <code class="Dv">NULL</code>. Any piece of
      code which uses <code class="Fn">m_defrag</code>() should be tested with
      this feature.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="RETURN_VALUES"><a class="permalink" href="#RETURN_VALUES">RETURN
  VALUES</a></h1>
<p class="Pp">See above.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr">ifnet(9)</a>, <a class="Xr">mbuf_tags(9)</a></p>
<p class="Pp"><cite class="Rs"><span class="RsA">S. J. Leffler</span>,
    <span class="RsA">W. N. Joy</span>, <span class="RsA">R. S. Fabry</span>,
    and <span class="RsA">M. J. Karels</span>, <span class="RsT">Networking
    Implementation Notes</span>, <i class="RsB">4.4BSD System Manager's Manual
    (SMM)</i>.</cite></p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp"><var class="Vt">Mbufs</var> appeared in an early version of
    <span class="Ux">BSD</span>. Besides being used for network packets, they
    were used to store various dynamic structures, such as routing table
    entries, interface addresses, protocol control blocks, etc. In more recent
    <span class="Ux">FreeBSD</span> use of <var class="Vt">mbufs</var> is almost
    entirely limited to packet storage, with <a class="Xr">uma(9)</a> zones
    being used directly to store other network-related memory.</p>
<p class="Pp">Historically, the <var class="Vt">mbuf</var> allocator has been a
    special-purpose memory allocator able to run in interrupt contexts and
    allocating from a special kernel address space map. As of
    <span class="Ux">FreeBSD 5.3</span>, the <var class="Vt">mbuf</var>
    allocator is a wrapper around <a class="Xr">uma(9)</a>, allowing caching of
    <var class="Vt">mbufs</var>, clusters, and <var class="Vt">mbuf</var> +
    cluster pairs in per-CPU caches, as well as bringing other benefits of slab
    allocation.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp">The original <code class="Nm">mbuf</code> manual page was written
    by <span class="An">Yar Tikhiy</span>. The <a class="Xr">uma(9)</a>
    <var class="Vt">mbuf</var> allocator was written by
  <br/>
  <span class="An">Bosko Milekic</span>.</p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">January 20, 2026</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>