€•2BŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ%/translations/zh_CN/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/zh_TW/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/it_IT/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/ja_JP/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/ko_KR/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/pt_BR/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/sp_SP/networking/skbuff”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³Œ?/var/lib/git/docbuild/linux/Documentation/networking/skbuff.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒstruct sk_buff”h]”hŒstruct sk_buff”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒI:c:type:`sk_buff` is the main networking structure representing a packet.”h]”(h)�”}”(hŒ:c:type:`sk_buff`”h]”hŒliteral”“”)�”}”(hhåh]”hŒsk_buff”…”�”}”(hhéh²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œc”Œc-type”eh"]”h$]”h&]”uh1hçhhãubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œnetworking/skbuff”Œ refdomain”hôŒreftype”Œtype”Œ refexplicit”‰Œrefwarn”‰Œ reftarget”Œsk_buff”uh1hh³hÇh´KhhßubhŒ8 is the main networking structure representing a packet.”…”�”}”(hhßh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒBasic sk_buff geometry”h]”hŒBasic sk_buff geometry”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´K ubhÞ)�”}”(hŒ|struct sk_buff itself is a metadata structure and does not hold any packet data. All the data is held in associated buffers.”h]”hŒ|struct sk_buff itself is a metadata structure and does not hold any packet data. All the data is held in associated buffers.”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Màhjh²hubhÞ)�”}”(hŒm:c:type:`sk_buff.head ` points to the main "head" buffer. The head buffer is divided into two parts:”h]”(h)�”}”(hŒ :c:type:`sk_buff.head `”h]”hè)�”}”(hj8h]”hŒ sk_buff.head”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”(hóhôŒc-type”eh"]”h$]”h&]”uh1hçhj6ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jŒ refdomain”hôŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jŒsk_buff”uh1hh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Mãhj2ubhŒQ points to the main “headâ€� buffer. The head buffer is divided into two parts:”…”�”}”(hj2h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jUh´Mãhjh²hubhŒ block_quote”“”)�”}”(hX- data buffer, containing headers and sometimes payload; this is the part of the skb operated on by the common helpers such as skb_put() or skb_pull(); - shared info (struct skb_shared_info) which holds an array of pointers to read-only data in the (page, offset, length) format. ”h]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ•data buffer, containing headers and sometimes payload; this is the part of the skb operated on by the common helpers such as skb_put() or skb_pull();”h]”hÞ)�”}”(hŒ•data buffer, containing headers and sometimes payload; this is the part of the skb operated on by the common helpers such as skb_put() or skb_pull();”h]”hŒ•data buffer, containing headers and sometimes payload; this is the part of the skb operated on by the common helpers such as skb_put() or skb_pull();”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Mæhjmubah}”(h]”h ]”h"]”h$]”h&]”uh1jkhjhubjl)�”}”(hŒ~shared info (struct skb_shared_info) which holds an array of pointers to read-only data in the (page, offset, length) format. ”h]”hÞ)�”}”(hŒ}shared info (struct skb_shared_info) which holds an array of pointers to read-only data in the (page, offset, length) format.”h]”hŒ}shared info (struct skb_shared_info) which holds an array of pointers to read-only data in the (page, offset, length) format.”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Méhj†ubah}”(h]”h ]”h"]”h$]”h&]”uh1jkhjhubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jfh³jh´Mæhjbubah}”(h]”h ]”h"]”h$]”h&]”uh1j`h³jh´Mæhjh²hubhÞ)�”}”(hŒZOptionally :c:type:`skb_shared_info.frag_list ` may point to another skb.”h]”(hŒ Optionally ”…”�”}”(hj­h²hh³Nh´Nubh)�”}”(hŒ5:c:type:`skb_shared_info.frag_list `”h]”hè)�”}”(hj·h]”hŒskb_shared_info.frag_list”…”�”}”(hj¹h²hh³Nh´Nubah}”(h]”h ]”(hóhôŒc-type”eh"]”h$]”h&]”uh1hçhjµubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jŒ refdomain”hôŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jŒskb_shared_info”uh1hh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Mìhj­ubhŒ may point to another skb.”…”�”}”(hj­h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jÔh´Mìhjh²hubhÞ)�”}”(hŒ"Basic diagram may look like this::”h]”hŒ!Basic diagram may look like this:”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Mîhjh²hubhŒ literal_block”“”)�”}”(hXB --------------- | sk_buff | --------------- ,--------------------------- + head / ,----------------- + data / / ,----------- + tail | | | , + end | | | | v v v v ----------------------------------------------- | headroom | data | tailroom | skb_shared_info | ----------------------------------------------- + [page frag] + [page frag] + [page frag] + [page frag] --------- + frag_list --> | sk_buff | ---------”h]”hXB --------------- | sk_buff | --------------- ,--------------------------- + head / ,----------------- + data / / ,----------- + tail | | | , + end | | | | v v v v ----------------------------------------------- | headroom | data | tailroom | skb_shared_info | ----------------------------------------------- + [page frag] + [page frag] + [page frag] + [page frag] --------- + frag_list --> | sk_buff | ---------”…”�”}”hjðsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jîh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:12: ./include/linux/skbuff.h”h´Mðhjh²hubeh}”(h]”Œbasic-sk-buff-geometry”ah ]”h"]”Œbasic sk_buff geometry”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒShared skbs and skb clones”h]”hŒShared skbs and skb clones”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´KubhÞ)�”}”(hŒ¿:c:member:`sk_buff.users` is a simple refcount allowing multiple entities to keep a struct sk_buff alive. skbs with a ``sk_buff.users != 1`` are referred to as shared skbs (see skb_shared()).”h]”(h)�”}”(hŒ:c:member:`sk_buff.users`”h]”hè)�”}”(hjh]”hŒ sk_buff.users”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”(hóhôŒc-member”eh"]”h$]”h&]”uh1hçhjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jŒ refdomain”hôŒreftype”Œmember”Œ refexplicit”‰Œrefwarn”‰jŒ sk_buff.users”uh1hh³hÇh´KhjubhŒ] is a simple refcount allowing multiple entities to keep a struct sk_buff alive. skbs with a ”…”�”}”(hjh²hh³Nh´Nubhè)�”}”(hŒ``sk_buff.users != 1``”h]”hŒsk_buff.users != 1”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hçhjubhŒ3 are referred to as shared skbs (see skb_shared()).”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒôskb_clone() allows for fast duplication of skbs. None of the data buffers get copied, but caller gets a new metadata struct (struct sk_buff). &skb_shared_info.refcount indicates the number of skbs pointing at the same packet data (i.e. clones).”h]”hŒôskb_clone() allows for fast duplication of skbs. None of the data buffers get copied, but caller gets a new metadata struct (struct sk_buff). &skb_shared_info.refcount indicates the number of skbs pointing at the same packet data (i.e. clones).”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubeh}”(h]”Œshared-skbs-and-skb-clones”ah ]”h"]”Œshared skbs and skb clones”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒdataref and headerless skbs”h]”hŒdataref and headerless skbs”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjmh²hh³hÇh´KubhÞ)�”}”(hX¥Transport layers send out clones of payload skbs they hold for retransmissions. To allow lower layers of the stack to prepend their headers we split :c:type:`skb_shared_info.dataref ` into two halves. The lower 16 bits count the overall number of references. The higher 16 bits indicate how many of the references are payload-only. skb_header_cloned() checks if skb is allowed to add / write the headers.”h]”(hŒ•Transport layers send out clones of payload skbs they hold for retransmissions. To allow lower layers of the stack to prepend their headers we split ”…”�”}”(hj~h²hh³Nh´Nubh)�”}”(hŒ3:c:type:`skb_shared_info.dataref `”h]”hè)�”}”(hjˆh]”hŒskb_shared_info.dataref”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”(hóhôŒc-type”eh"]”h$]”h&]”uh1hçhj†ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jŒ refdomain”hôŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jŒskb_shared_info”uh1hh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:30: ./include/linux/skbuff.h”h´Mxhj~ubhŒÝ into two halves. The lower 16 bits count the overall number of references. The higher 16 bits indicate how many of the references are payload-only. skb_header_cloned() checks if skb is allowed to add / write the headers.”…”�”}”(hj~h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j¥h´Mxhjmh²hubhÞ)�”}”(hXoThe creator of the skb (e.g. TCP) marks its skb as :c:type:`sk_buff.nohdr ` (via __skb_header_release()). Any clone created from marked skb will get :c:type:`sk_buff.hdr_len ` populated with the available headroom. If there's the only clone in existence it's able to modify the headroom at will. The sequence of calls inside the transport layer is::”h]”(hŒ3The creator of the skb (e.g. TCP) marks its skb as ”…”�”}”(hj°h²hh³Nh´Nubh)�”}”(hŒ!:c:type:`sk_buff.nohdr `”h]”hè)�”}”(hjºh]”hŒ sk_buff.nohdr”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”(hóhôŒc-type”eh"]”h$]”h&]”uh1hçhj¸ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jŒ refdomain”hôŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jŒsk_buff”uh1hh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:30: ./include/linux/skbuff.h”h´Mhj°ubhŒJ (via __skb_header_release()). Any clone created from marked skb will get ”…”�”}”(hj°h²hh³Nh´Nubh)�”}”(hŒ#:c:type:`sk_buff.hdr_len `”h]”hè)�”}”(hjÞh]”hŒsk_buff.hdr_len”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”(hóhôŒc-type”eh"]”h$]”h&]”uh1hçhjÜubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jŒ refdomain”hôŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jŒsk_buff”uh1hh³j×h´Mhj°ubhŒ± populated with the available headroom. If there’s the only clone in existence it’s able to modify the headroom at will. The sequence of calls inside the transport layer is:”…”�”}”(hj°h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j×h´Mhjmh²hubjï)�”}”(hŒ] skb_reserve() __skb_header_release() skb_clone() // send the clone down the stack”h]”hŒ] skb_reserve() __skb_header_release() skb_clone() // send the clone down the stack”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jîh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:30: ./include/linux/skbuff.h”h´M…hjmh²hubhÞ)�”}”(hX$This is not a very generic construct and it depends on the transport layers doing the right thing. In practice there's usually only one payload-only skb. Having multiple payload-only skbs with different lengths of hdr_len is not possible. The payload-only skbs should never leave their owner.”h]”hX&This is not a very generic construct and it depends on the transport layers doing the right thing. In practice there’s usually only one payload-only skb. Having multiple payload-only skbs with different lengths of hdr_len is not possible. The payload-only skbs should never leave their owner.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒX/var/lib/git/docbuild/linux/Documentation/networking/skbuff:30: ./include/linux/skbuff.h”h´M‹hjmh²hubeh}”(h]”Œdataref-and-headerless-skbs”ah ]”h"]”Œdataref and headerless skbs”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´Kubeh}”(h]”Œstruct-sk-buff”ah ]”h"]”Œstruct sk_buff”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jVŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j0j-jjjjjgj(j%uŒ nametypes”}”(j0‰j‰jj‰j(‰uh}”(j-hÊjjjgjj%jmuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.