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> — <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
<<a class="In">sys/param.h</a>></code>
<br/>
<code class="In">#include <<a class="In">sys/systm.h</a>></code>
<br/>
<code class="In">#include <<a class="In">sys/mbuf.h</a>></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"><<a class="In">sys/param.h</a>></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->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->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->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>
|