€•jîŒ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/xdp-rx-metadata”Œ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/xdp-rx-metadata”Œ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/xdp-rx-metadata”Œ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/xdp-rx-metadata”Œ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/xdp-rx-metadata”Œ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/xdp-rx-metadata”Œ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/xdp-rx-metadata”Œ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³ŒH/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒXDP RX Metadata”h]”hŒXDP RX Metadata”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒÉThis document describes how an eXpress Data Path (XDP) program can access hardware metadata related to a packet using a set of helper functions, and how it can pass that metadata on to other consumers.”h]”hŒÉThis document describes how an eXpress Data Path (XDP) program can access hardware metadata related to a packet using a set of helper functions, and how it can pass that metadata on to other consumers.”…”�”}”(hhßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒGeneral Design”h]”hŒGeneral Design”…”�”}”(hhðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhíh²hh³hÇh´K ubhÞ)�”}”(hXXDP has access to a set of kfuncs to manipulate the metadata in an XDP frame. Every device driver that wishes to expose additional packet metadata can implement these kfuncs. The set of kfuncs is declared in ``include/net/xdp.h`` via ``XDP_METADATA_KFUNC_xxx``.”h]”(hŒÐXDP has access to a set of kfuncs to manipulate the metadata in an XDP frame. Every device driver that wishes to expose additional packet metadata can implement these kfuncs. The set of kfuncs is declared in ”…”�”}”(hhþh²hh³Nh´NubhŒliteral”“”)�”}”(hŒ``include/net/xdp.h``”h]”hŒinclude/net/xdp.h”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒ via ”…”�”}”(hhþh²hh³Nh´Nubj)�”}”(hŒ``XDP_METADATA_KFUNC_xxx``”h]”hŒXDP_METADATA_KFUNC_xxx”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒ.”…”�”}”(hhþh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhíh²hubhÞ)�”}”(hŒpCurrently, the following kfuncs are supported. In the future, as more metadata is supported, this set will grow:”h]”hŒpCurrently, the following kfuncs are supported. In the future, as more metadata is supported, this set will grow:”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhíh²hubhŒindex”“”)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(Œsingle”Œ*bpf_xdp_metadata_rx_timestamp (C function)”Œc.bpf_xdp_metadata_rx_timestamp”hNt”auh1j@hhíh²hh³Nh´NubhŒdesc”“”)�”}”(hhh]”(hŒdesc_signature”“”)�”}”(hŒX__bpf_kfunc int bpf_xdp_metadata_rx_timestamp (const struct xdp_md *ctx, u64 *timestamp)”h]”hŒdesc_signature_line”“”)�”}”(hŒW__bpf_kfunc int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)”h]”(hŒ __bpf_kfunc”…”�”}”(hj^h²hh³Nh´NubhŒdesc_sig_space”“”)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”Œw”ah"]”h$]”h&]”uh1jfhj^h²hh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M~ubhŒdesc_sig_keyword_type”“”)�”}”(hŒint”h]”hŒint”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”Œkt”ah"]”h$]”h&]”uh1jxhj^h²hh³jwh´M~ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj^h²hh³jwh´M~ubhŒ desc_name”“”)�”}”(hŒbpf_xdp_metadata_rx_timestamp”h]”hŒ desc_sig_name”“”)�”}”(hŒbpf_xdp_metadata_rx_timestamp”h]”hŒbpf_xdp_metadata_rx_timestamp”…”�”}”(hjŸh²hh³Nh´Nubah}”(h]”h ]”Œn”ah"]”h$]”h&]”uh1j�hj™ubah}”(h]”h ]”(Œsig-name”Œdescname”eh"]”h$]”h&]”hÅhÆuh1j—hj^h²hh³jwh´M~ubhŒdesc_parameterlist”“”)�”}”(hŒ*(const struct xdp_md *ctx, u64 *timestamp)”h]”(hŒdesc_parameter”“”)�”}”(hŒconst struct xdp_md *ctx”h]”(hŒdesc_sig_keyword”“”)�”}”(hŒconst”h]”hŒconst”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”Œk”ah"]”h$]”h&]”uh1jÂhj¾ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj¾ubjÃ)�”}”(hŒstruct”h]”hŒstruct”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”jÏah"]”h$]”h&]”uh1jÂhj¾ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjïh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj¾ubh)�”}”(hhh]”jž)�”}”(hŒxdp_md”h]”hŒxdp_md”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjýubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”Œc”Œreftype”Œ identifier”Œ reftarget”jŒmodname”NŒ classname”NŒ c:parent_key”Œsphinx.domains.c”Œ LookupKey”“”)�”}”Œdata”]”jŒ ASTIdentifier”“”)�”}”jj¡sbŒc.bpf_xdp_metadata_rx_timestamp”†”asbuh1hhj¾ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj¾ubhŒdesc_sig_punctuation”“”)�”}”(hŒ*”h]”hŒ*”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”Œp”ah"]”h$]”h&]”uh1j7hj¾ubjž)�”}”(hŒctx”h]”hŒctx”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj¾ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj¸ubj½)�”}”(hŒu64 *timestamp”h]”(h)�”}”(hhh]”jž)�”}”(hŒu64”h]”hŒu64”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjaubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”jfŒmodname”NŒ classname”Njj)�”}”j!]”j%Œc.bpf_xdp_metadata_rx_timestamp”†”asbuh1hhj]ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‚h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj]ubj8)�”}”(hj;h]”hŒ*”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hj]ubjž)�”}”(hŒ timestamp”h]”hŒ timestamp”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj]ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj¸ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¶hj^h²hh³jwh´M~ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒ add_permalink”ˆuh1j\Œsphinx_line_type”Œ declarator”hjXh²hh³jwh´M~ubah}”(h]”jOah ]”(Œsig”Œ sig-object”eh"]”h$]”h&]”Œ is_multiline”ˆŒ _toc_parts”)Œ _toc_name”huh1jVh³jwh´M~hjSh²hubhŒ desc_content”“”)�”}”(hhh]”hÞ)�”}”(hŒRead XDP frame RX timestamp.”h]”hŒRead XDP frame RX timestamp.”…”�”}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M~hjÎh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jÌhjSh²hh³jwh´M~ubeh}”(h]”h ]”(jŒfunction”eh"]”h$]”h&]”Œdomain”jŒobjtype”jéŒdesctype”jéŒnoindex”‰Œ noindexentry”‰Œnocontentsentry”‰uh1jQh²hhhíh³Nh´NubhŒ container”“”)�”}”(hX/**Parameters** ``const struct xdp_md *ctx`` XDP context pointer. ``u64 *timestamp`` Return value pointer. **Return** * Returns 0 on success or ``-errno`` on error. * ``-EOPNOTSUPP`` : means device driver does not implement kfunc * ``-ENODATA`` : means no RX-timestamp available for this frame”h]”(hÞ)�”}”(hŒ**Parameters**”h]”hŒstrong”“”)�”}”(hjûh]”hŒ Parameters”…”�”}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhjùubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M‚hjõubhŒdefinition_list”“”)�”}”(hhh]”(hŒdefinition_list_item”“”)�”}”(hŒ2``const struct xdp_md *ctx`` XDP context pointer. ”h]”(hŒterm”“”)�”}”(hŒ``const struct xdp_md *ctx``”h]”j)�”}”(hj"h]”hŒconst struct xdp_md *ctx”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´MhjubhŒ definition”“”)�”}”(hhh]”hÞ)�”}”(hŒXDP context pointer.”h]”hŒXDP context pointer.”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j7h´Mhj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1j8hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³j7h´Mhjubj)�”}”(hŒ)``u64 *timestamp`` Return value pointer. ”h]”(j)�”}”(hŒ``u64 *timestamp``”h]”j)�”}”(hj]h]”hŒu64 *timestamp”…”�”}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M€hjWubj9)�”}”(hhh]”hÞ)�”}”(hŒReturn value pointer.”h]”hŒReturn value pointer.”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jrh´M€hjsubah}”(h]”h ]”h"]”h$]”h&]”uh1j8hjWubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³jrh´M€hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjõubhÞ)�”}”(hŒ **Return**”h]”jþ)�”}”(hj˜h]”hŒReturn”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhj–ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M‚hjõubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ,Returns 0 on success or ``-errno`` on error.”h]”hÞ)�”}”(hj·h]”(hŒReturns 0 on success or ”…”�”}”(hj¹h²hh³Nh´Nubj)�”}”(hŒ ``-errno``”h]”hŒ-errno”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¹ubhŒ on error.”…”�”}”(hj¹h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M‚hjµubah}”(h]”h ]”h"]”h$]”h&]”uh1j³hj°ubj´)�”}”(hŒ>``-EOPNOTSUPP`` : means device driver does not implement kfunc”h]”hÞ)�”}”(hjáh]”(j)�”}”(hŒ``-EOPNOTSUPP``”h]”hŒ -EOPNOTSUPP”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjãubhŒ/ : means device driver does not implement kfunc”…”�”}”(hjãh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´Mƒhjßubah}”(h]”h ]”h"]”h$]”h&]”uh1j³hj°ubj´)�”}”(hŒ@``-ENODATA`` : means no RX-timestamp available for this frame”h]”hÞ)�”}”(hjh]”(j)�”}”(hŒ ``-ENODATA``”h]”hŒ-ENODATA”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj ubhŒ4 : means no RX-timestamp available for this frame”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:22: ./net/core/xdp.c”h´M„hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j³hj°ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”j;uh1j®h³jØh´M‚hjõubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jóhhíh²hh³Nh´NubjA)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(jMŒ%bpf_xdp_metadata_rx_hash (C function)”Œc.bpf_xdp_metadata_rx_hash”hNt”auh1j@hhíh²hh³Nh´NubjR)�”}”(hhh]”(jW)�”}”(hŒp__bpf_kfunc int bpf_xdp_metadata_rx_hash (const struct xdp_md *ctx, u32 *hash, enum xdp_rss_hash_type *rss_type)”h]”j])�”}”(hŒo__bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash, enum xdp_rss_hash_type *rss_type)”h]”(hŒ __bpf_kfunc”…”�”}”(hjNh²hh³Nh´Nubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhjNh²hh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M�ubjy)�”}”(hŒint”h]”hŒint”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”j…ah"]”h$]”h&]”uh1jxhjNh²hh³jdh´M�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhjNh²hh³jdh´M�ubj˜)�”}”(hŒbpf_xdp_metadata_rx_hash”h]”jž)�”}”(hŒbpf_xdp_metadata_rx_hash”h]”hŒbpf_xdp_metadata_rx_hash”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj�ubah}”(h]”h ]”(j±j²eh"]”h$]”h&]”hÅhÆuh1j—hjNh²hh³jdh´M�ubj·)�”}”(hŒG(const struct xdp_md *ctx, u32 *hash, enum xdp_rss_hash_type *rss_type)”h]”(j½)�”}”(hŒconst struct xdp_md *ctx”h]”(jÃ)�”}”(hjÆh]”hŒconst”…”�”}”(hj¡h²hh³Nh´Nubah}”(h]”h ]”jÏah"]”h$]”h&]”uh1jÂhj�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj®h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj�ubjÃ)�”}”(hjãh]”hŒstruct”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”jÏah"]”h$]”h&]”uh1jÂhj�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj�ubh)�”}”(hhh]”jž)�”}”(hŒxdp_md”h]”hŒxdp_md”…”�”}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj×ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”jÜŒmodname”NŒ classname”Njj)�”}”j!]”j$)�”}”jj‡sbŒc.bpf_xdp_metadata_rx_hash”†”asbuh1hhj�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjúh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj�ubj8)�”}”(hj;h]”hŒ*”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hj�ubjž)�”}”(hŒctx”h]”hŒctx”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj�ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj™ubj½)�”}”(hŒ u32 *hash”h]”(h)�”}”(hhh]”jž)�”}”(hŒu32”h]”hŒu32”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj.ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”j3Œmodname”NŒ classname”Njj)�”}”j!]”jöŒc.bpf_xdp_metadata_rx_hash”†”asbuh1hhj*ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj*ubj8)�”}”(hj;h]”hŒ*”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hj*ubjž)�”}”(hŒhash”h]”hŒhash”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj*ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj™ubj½)�”}”(hŒ enum xdp_rss_hash_type *rss_type”h]”(jÃ)�”}”(hŒenum”h]”hŒenum”…”�”}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”jÏah"]”h$]”h&]”uh1jÂhjubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhjubh)�”}”(hhh]”jž)�”}”(hŒxdp_rss_hash_type”h]”hŒxdp_rss_hash_type”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjŸubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”j¤Œmodname”NŒ classname”Njj)�”}”j!]”jöŒc.bpf_xdp_metadata_rx_hash”†”asbuh1hhjubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhjubj8)�”}”(hj;h]”hŒ*”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hjubjž)�”}”(hŒrss_type”h]”hŒrss_type”…”�”}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj™ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¶hjNh²hh³jdh´M�ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆj¾ˆuh1j\j¿jÀhjJh²hh³jdh´M�ubah}”(h]”jEah ]”(jÄjÅeh"]”h$]”h&]”jɈjÊ)jËhuh1jVh³jdh´M�hjGh²hubjÍ)�”}”(hhh]”hÞ)�”}”(hŒRead XDP frame RX hash.”h]”hŒRead XDP frame RX hash.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M�hjh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jÌhjGh²hh³jdh´M�ubeh}”(h]”h ]”(jŒfunction”eh"]”h$]”h&]”jíjjîjjïjjð‰jñ‰jò‰uh1jQh²hhhíh³Nh´Nubjô)�”}”(hXÐ**Parameters** ``const struct xdp_md *ctx`` XDP context pointer. ``u32 *hash`` Return value pointer. ``enum xdp_rss_hash_type *rss_type`` Return value pointer for RSS type. **Description** The RSS hash type (**rss_type**) specifies what portion of packet headers NIC hardware used when calculating RSS hash value. The RSS type can be decoded via :c:type:`enum xdp_rss_hash_type ` either matching on individual L3/L4 bits ``XDP_RSS_L*`` or by combined traditional *RSS Hashing Types* ``XDP_RSS_TYPE_L*``. **Return** * Returns 0 on success or ``-errno`` on error. * ``-EOPNOTSUPP`` : means device driver doesn't implement kfunc * ``-ENODATA`` : means no RX-hash available for this frame”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jþ)�”}”(hj'h]”hŒ Parameters”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M‘hj!ubj)�”}”(hhh]”(j)�”}”(hŒ2``const struct xdp_md *ctx`` XDP context pointer. ”h]”(j)�”}”(hŒ``const struct xdp_md *ctx``”h]”j)�”}”(hjFh]”hŒconst struct xdp_md *ctx”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjDubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´MŽhj@ubj9)�”}”(hhh]”hÞ)�”}”(hŒXDP context pointer.”h]”hŒXDP context pointer.”…”�”}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j[h´MŽhj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1j8hj@ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³j[h´MŽhj=ubj)�”}”(hŒ$``u32 *hash`` Return value pointer. ”h]”(j)�”}”(hŒ ``u32 *hash``”h]”j)�”}”(hjh]”hŒ u32 *hash”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M�hjyubj9)�”}”(hhh]”hÞ)�”}”(hŒReturn value pointer.”h]”hŒReturn value pointer.”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j”h´M�hj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1j8hjyubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³j”h´M�hj=ubj)�”}”(hŒH``enum xdp_rss_hash_type *rss_type`` Return value pointer for RSS type. ”h]”(j)�”}”(hŒ$``enum xdp_rss_hash_type *rss_type``”h]”j)�”}”(hj¸h]”hŒ enum xdp_rss_hash_type *rss_type”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¶ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M�hj²ubj9)�”}”(hhh]”hÞ)�”}”(hŒ"Return value pointer for RSS type.”h]”hŒ"Return value pointer for RSS type.”…”�”}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jÍh´M�hjÎubah}”(h]”h ]”h"]”h$]”h&]”uh1j8hj²ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³jÍh´M�hj=ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhj!ubhÞ)�”}”(hŒ**Description**”h]”jþ)�”}”(hjóh]”hŒ Description”…”�”}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhjñubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M’hj!ubhÞ)�”}”(hXNThe RSS hash type (**rss_type**) specifies what portion of packet headers NIC hardware used when calculating RSS hash value. The RSS type can be decoded via :c:type:`enum xdp_rss_hash_type ` either matching on individual L3/L4 bits ``XDP_RSS_L*`` or by combined traditional *RSS Hashing Types* ``XDP_RSS_TYPE_L*``.”h]”(hŒThe RSS hash type (”…”�”}”(hj h²hh³Nh´Nubjþ)�”}”(hŒ **rss_type**”h]”hŒrss_type”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhj ubhŒ) specifies what portion of packet headers NIC hardware used when calculating RSS hash value. The RSS type can be decoded via ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ4:c:type:`enum xdp_rss_hash_type `”h]”j)�”}”(hj%h]”hŒenum xdp_rss_hash_type”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”(Œxref”jŒc-type”eh"]”h$]”h&]”uh1jhj#ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œnetworking/xdp-rx-metadata”Œ refdomain”jŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jj)�”}”j!]”sbŒ reftarget”Œxdp_rss_hash_type”uh1hh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M‘hj ubhŒ* either matching on individual L3/L4 bits ”…”�”}”(hj h²hh³Nh´Nubj)�”}”(hŒ``XDP_RSS_L*``”h]”hŒ XDP_RSS_L*”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj ubhŒ or by combined traditional ”…”�”}”(hj h²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ*RSS Hashing Types*”h]”hŒRSS Hashing Types”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hj ubhŒ ”…”�”}”(hj h²hh³Nh´Nubj)�”}”(hŒ``XDP_RSS_TYPE_L*``”h]”hŒXDP_RSS_TYPE_L*”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj ubhŒ.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jHh´M‘hj!ubhÞ)�”}”(hŒ **Return**”h]”jþ)�”}”(hj�h]”hŒReturn”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M—hj!ubj¯)�”}”(hhh]”(j´)�”}”(hŒ,Returns 0 on success or ``-errno`` on error.”h]”hÞ)�”}”(hj¨h]”(hŒReturns 0 on success or ”…”�”}”(hjªh²hh³Nh´Nubj)�”}”(hŒ ``-errno``”h]”hŒ-errno”…”�”}”(hj±h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjªubhŒ on error.”…”�”}”(hjªh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M˜hj¦ubah}”(h]”h ]”h"]”h$]”h&]”uh1j³hj£ubj´)�”}”(hŒ=``-EOPNOTSUPP`` : means device driver doesn't implement kfunc”h]”hÞ)�”}”(hjÒh]”(j)�”}”(hŒ``-EOPNOTSUPP``”h]”hŒ -EOPNOTSUPP”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÔubhŒ0 : means device driver doesn’t implement kfunc”…”�”}”(hjÔh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´M™hjÐubah}”(h]”h ]”h"]”h$]”h&]”uh1j³hj£ubj´)�”}”(hŒ;``-ENODATA`` : means no RX-hash available for this frame”h]”hÞ)�”}”(hjøh]”(j)�”}”(hŒ ``-ENODATA``”h]”hŒ-ENODATA”…”�”}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjúubhŒ/ : means no RX-hash available for this frame”…”�”}”(hjúh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:25: ./net/core/xdp.c”h´Mšhjöubah}”(h]”h ]”h"]”h$]”h&]”uh1j³hj£ubeh}”(h]”h ]”h"]”h$]”h&]”j1j;uh1j®h³jÉh´M˜hj!ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jóhhíh²hh³Nh´NubjA)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(jMŒ)bpf_xdp_metadata_rx_vlan_tag (C function)”Œc.bpf_xdp_metadata_rx_vlan_tag”hNt”auh1j@hhíh²hh³Nh´NubjR)�”}”(hhh]”(jW)�”}”(hŒj__bpf_kfunc int bpf_xdp_metadata_rx_vlan_tag (const struct xdp_md *ctx, __be16 *vlan_proto, u16 *vlan_tci)”h]”j])�”}”(hŒi__bpf_kfunc int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto, u16 *vlan_tci)”h]”(hŒ __bpf_kfunc”…”�”}”(hj>h²hh³Nh´Nubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj>h²hh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:28: ./net/core/xdp.c”h´M¤ubjy)�”}”(hŒint”h]”hŒint”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”j…ah"]”h$]”h&]”uh1jxhj>h²hh³jTh´M¤ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjch²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj>h²hh³jTh´M¤ubj˜)�”}”(hŒbpf_xdp_metadata_rx_vlan_tag”h]”jž)�”}”(hŒbpf_xdp_metadata_rx_vlan_tag”h]”hŒbpf_xdp_metadata_rx_vlan_tag”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjqubah}”(h]”h ]”(j±j²eh"]”h$]”h&]”hÅhÆuh1j—hj>h²hh³jTh´M¤ubj·)�”}”(hŒ=(const struct xdp_md *ctx, __be16 *vlan_proto, u16 *vlan_tci)”h]”(j½)�”}”(hŒconst struct xdp_md *ctx”h]”(jÃ)�”}”(hjÆh]”hŒconst”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”jÏah"]”h$]”h&]”uh1jÂhj�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj�ubjÃ)�”}”(hjãh]”hŒstruct”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”jÏah"]”h$]”h&]”uh1jÂhj�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¹h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj�ubh)�”}”(hhh]”jž)�”}”(hŒxdp_md”h]”hŒxdp_md”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjÇubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”jÌŒmodname”NŒ classname”Njj)�”}”j!]”j$)�”}”jjwsbŒc.bpf_xdp_metadata_rx_vlan_tag”†”asbuh1hhj�ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj�ubj8)�”}”(hj;h]”hŒ*”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hj�ubjž)�”}”(hŒctx”h]”hŒctx”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj�ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj‰ubj½)�”}”(hŒ__be16 *vlan_proto”h]”(h)�”}”(hhh]”jž)�”}”(hŒ__be16”h]”hŒ__be16”…”�”}”(hj! h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”j# Œmodname”NŒ classname”Njj)�”}”j!]”jæŒc.bpf_xdp_metadata_rx_vlan_tag”†”asbuh1hhj ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj? h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhj ubj8)�”}”(hj;h]”hŒ*”…”�”}”(hjM h²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hj ubjž)�”}”(hŒ vlan_proto”h]”hŒ vlan_proto”…”�”}”(hjZ h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hj ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj‰ubj½)�”}”(hŒ u16 *vlan_tci”h]”(h)�”}”(hhh]”jž)�”}”(hŒu16”h]”hŒu16”…”�”}”(hjv h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjs ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jŒreftype”jŒ reftarget”jx Œmodname”NŒ classname”Njj)�”}”j!]”jæŒc.bpf_xdp_metadata_rx_vlan_tag”†”asbuh1hhjo ubjg)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj” h²hh³Nh´Nubah}”(h]”h ]”jsah"]”h$]”h&]”uh1jfhjo ubj8)�”}”(hj;h]”hŒ*”…”�”}”(hj¢ h²hh³Nh´Nubah}”(h]”h ]”jDah"]”h$]”h&]”uh1j7hjo ubjž)�”}”(hŒvlan_tci”h]”hŒvlan_tci”…”�”}”(hj¯ h²hh³Nh´Nubah}”(h]”h ]”jªah"]”h$]”h&]”uh1j�hjo ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j¼hj‰ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j¶hj>h²hh³jTh´M¤ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆj¾ˆuh1j\j¿jÀhj:h²hh³jTh´M¤ubah}”(h]”j5ah ]”(jÄjÅeh"]”h$]”h&]”jɈjÊ)jËhuh1jVh³jTh´M¤hj7h²hubjÍ)�”}”(hhh]”hÞ)�”}”(hŒ!Get XDP packet outermost VLAN tag”h]”hŒ!Get XDP packet outermost VLAN tag”…”�”}”(hjÙ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:28: ./net/core/xdp.c”h´M¤hjÖ h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jÌhj7h²hh³jTh´M¤ubeh}”(h]”h ]”(jŒfunction”eh"]”h$]”h&]”jíjjîjñ jïjñ jð‰jñ‰jò‰uh1jQh²hhhíh³Nh´Nubjô)�”}”(hXØ**Parameters** ``const struct xdp_md *ctx`` XDP context pointer. ``__be16 *vlan_proto`` Destination pointer for VLAN Tag protocol identifier (TPID). ``u16 *vlan_tci`` Destination pointer for VLAN TCI (VID + DEI + PCP) **Description** In case of success, ``vlan_proto`` contains *Tag protocol identifier (TPID)*, usually ``ETH_P_8021Q`` or ``ETH_P_8021AD``, but some networks can use custom TPIDs. ``vlan_proto`` is stored in **network byte order (BE)** and should be used as follows: ``if (vlan_proto == bpf_htons(ETH_P_8021Q)) do_something();`` ``vlan_tci`` contains the remaining 16 bits of a VLAN tag. Driver is expected to provide those in **host byte order (usually LE)**, so the bpf program should not perform byte conversion. According to 802.1Q standard, *VLAN TCI (Tag control information)* is a bit field that contains: *VLAN identifier (VID)* that can be read with ``vlan_tci & 0xfff``, *Drop eligible indicator (DEI)* - 1 bit, *Priority code point (PCP)* - 3 bits. For detailed meaning of DEI and PCP, please refer to other sources. **Return** * Returns 0 on success or ``-errno`` on error. * ``-EOPNOTSUPP`` : device driver doesn't implement kfunc * ``-ENODATA`` : VLAN tag was not stripped or is not available”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jþ)�”}”(hjû h]”hŒ Parameters”…”�”}”(hjý h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jýhjù ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:28: ./net/core/xdp.c”h´M¨hjõ ubj)�”}”(hhh]”(j)�”}”(hŒ2``const struct xdp_md *ctx`` XDP context pointer. ”h]”(j)�”}”(hŒ``const struct xdp_md *ctx``”h]”j)�”}”(hj h]”hŒconst struct xdp_md *ctx”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:28: ./net/core/xdp.c”h´M¥hj ubj9)�”}”(hhh]”hÞ)�”}”(hŒXDP context pointer.”h]”hŒXDP context pointer.”…”�”}”(hj3 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j/ h´M¥hj0 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j8hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³j/ h´M¥hj ubj)�”}”(hŒT``__be16 *vlan_proto`` Destination pointer for VLAN Tag protocol identifier (TPID). ”h]”(j)�”}”(hŒ``__be16 *vlan_proto``”h]”j)�”}”(hjS h]”hŒ__be16 *vlan_proto”…”�”}”(hjU h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjQ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³ŒY/var/lib/git/docbuild/linux/Documentation/networking/xdp-rx-metadata:28: ./net/core/xdp.c”h´M¦hjM ubj9)�”}”(hhh]”hÞ)�”}”(hŒdata_meta xdp_buff->data”h]”hŒÕ+----------+-----------------+------+ | headroom | custom metadata | data | +----------+-----------------+------+ ^ ^ | | xdp_buff->data_meta xdp_buff->data”…”�”}”hjï sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jí h³hÇh´K-hhíh²hubhÞ)�”}”(hŒøAn XDP program can store individual metadata items into this ``data_meta`` area in whichever format it chooses. Later consumers of the metadata will have to agree on the format by some out of band contract (like for the AF_XDP use case, see below).”h]”(hŒ=An XDP program can store individual metadata items into this ”…”�”}”(hjý h²hh³Nh´Nubj)�”}”(hŒ ``data_meta``”h]”hŒ data_meta”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjý ubhŒ® area in whichever format it chooses. Later consumers of the metadata will have to agree on the format by some out of band contract (like for the AF_XDP use case, see below).”…”�”}”(hjý h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K4hhíh²hubeh}”(h]”Œgeneral-design”ah ]”h"]”Œgeneral design”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒAF_XDP”h]”hŒAF_XDP”…”�”}”(hj( h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj% h²hh³hÇh´K:ubhÞ)�”}”(hXo:doc:`af_xdp` use-case implies that there is a contract between the BPF program that redirects XDP frames into the ``AF_XDP`` socket (``XSK``) and the final consumer. Thus the BPF program manually allocates a fixed number of bytes out of metadata via ``bpf_xdp_adjust_meta`` and calls a subset of kfuncs to populate it. The userspace ``XSK`` consumer computes ``xsk_umem__get_data() - METADATA_SIZE`` to locate that metadata. Note, ``xsk_umem__get_data`` is defined in ``libxdp`` and ``METADATA_SIZE`` is an application-specific constant (``AF_XDP`` receive descriptor does _not_ explicitly carry the size of the metadata).”h]”(h)�”}”(hŒ :doc:`af_xdp`”h]”hŒinline”“”)�”}”(hj< h]”hŒaf_xdp”…”�”}”(hj@ h²hh³Nh´Nubah}”(h]”h ]”(j1Œstd”Œstd-doc”eh"]”h$]”h&]”uh1j> hj: ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”j=Œ refdomain”jJ Œreftype”Œdoc”Œ refexplicit”‰Œrefwarn”ˆjFŒaf_xdp”uh1hh³hÇh´Kaddress”h]”hŒÖ+----------+-----------------+------+ | headroom | custom metadata | data | +----------+-----------------+------+ ^ | rx_desc->address”…”�”}”hj:sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jí h³hÇh´KHhj% h²hubeh}”(h]”Œaf-xdp”ah ]”h"]”Œaf_xdp”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K:ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒXDP_PASS”h]”hŒXDP_PASS”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjPh²hh³hÇh´KPubhÞ)�”}”(hXÒThis is the path where the packets processed by the XDP program are passed into the kernel. The kernel creates the ``skb`` out of the ``xdp_buff`` contents. Currently, every driver has custom kernel code to parse the descriptors and populate ``skb`` metadata when doing this ``xdp_buff->skb`` conversion, and the XDP metadata is not used by the kernel when building ``skbs``. However, TC-BPF programs can access the XDP metadata area using the ``data_meta`` pointer.”h]”(hŒsThis is the path where the packets processed by the XDP program are passed into the kernel. The kernel creates the ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ``skb``”h]”hŒskb”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒ out of the ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ ``xdp_buff``”h]”hŒxdp_buff”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒ` contents. Currently, every driver has custom kernel code to parse the descriptors and populate ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ``skb``”h]”hŒskb”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒ metadata when doing this ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ``xdp_buff->skb``”h]”hŒ xdp_buff->skb”…”�”}”(hjŸh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒJ conversion, and the XDP metadata is not used by the kernel when building ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ``skbs``”h]”hŒskbs”…”�”}”(hj±h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒF. However, TC-BPF programs can access the XDP metadata area using the ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ ``data_meta``”h]”hŒ data_meta”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒ pointer.”…”�”}”(hjah²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KRhjPh²hubhÞ)�”}”(hŒ}In the future, we'd like to support a case where an XDP program can override some of the metadata used for building ``skbs``.”h]”(hŒvIn the future, we’d like to support a case where an XDP program can override some of the metadata used for building ”…”�”}”(hjÛh²hh³Nh´Nubj)�”}”(hŒ``skbs``”h]”hŒskbs”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÛubhŒ.”…”�”}”(hjÛh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KZhjPh²hubeh}”(h]”Œxdp-pass”ah ]”h"]”Œxdp_pass”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KPubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒbpf_redirect_map”h]”hŒbpf_redirect_map”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´K^ubhÞ)�”}”(hXn``bpf_redirect_map`` can redirect the frame to a different device. Some devices (like virtual ethernet links) support running a second XDP program after the redirect. However, the final consumer doesn't have access to the original hardware descriptor and can't access any of the original metadata. The same applies to XDP programs installed into devmaps and cpumaps.”h]”(j)�”}”(hŒ``bpf_redirect_map``”h]”hŒbpf_redirect_map”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhX^ can redirect the frame to a different device. Some devices (like virtual ethernet links) support running a second XDP program after the redirect. However, the final consumer doesn’t have access to the original hardware descriptor and can’t access any of the original metadata. The same applies to XDP programs installed into devmaps and cpumaps.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K`hjh²hubhÞ)�”}”(hX˜This means that for redirected packets only custom metadata is currently supported, which has to be prepared by the initial XDP program before redirect. If the frame is eventually passed to the kernel, the ``skb`` created from such a frame won't have any hardware metadata populated in its ``skb``. If such a packet is later redirected into an ``XSK``, that will also only have access to the custom metadata.”h]”(hŒÎThis means that for redirected packets only custom metadata is currently supported, which has to be prepared by the initial XDP program before redirect. If the frame is eventually passed to the kernel, the ”…”�”}”(hj0h²hh³Nh´Nubj)�”}”(hŒ``skb``”h]”hŒskb”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj0ubhŒO created from such a frame won’t have any hardware metadata populated in its ”…”�”}”(hj0h²hh³Nh´Nubj)�”}”(hŒ``skb``”h]”hŒskb”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj0ubhŒ/. If such a packet is later redirected into an ”…”�”}”(hj0h²hh³Nh´Nubj)�”}”(hŒ``XSK``”h]”hŒXSK”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj0ubhŒ9, that will also only have access to the custom metadata.”…”�”}”(hj0h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kghjh²hubeh}”(h]”Œbpf-redirect-map”ah ]”h"]”Œbpf_redirect_map”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K^ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ bpf_tail_call”h]”hŒ bpf_tail_call”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj|h²hh³hÇh´KoubhÞ)�”}”(hŒjAdding programs that access metadata kfuncs to the ``BPF_MAP_TYPE_PROG_ARRAY`` is currently not supported.”h]”(hŒ3Adding programs that access metadata kfuncs to the ”…”�”}”(hj�h²hh³Nh´Nubj)�”}”(hŒ``BPF_MAP_TYPE_PROG_ARRAY``”h]”hŒBPF_MAP_TYPE_PROG_ARRAY”…”�”}”(hj•h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�ubhŒ is currently not supported.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kqhj|h²hubeh}”(h]”Œ bpf-tail-call”ah ]”h"]”Œ bpf_tail_call”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KoubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒSupported Devices”h]”hŒSupported Devices”…”�”}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjµh²hh³hÇh´KuubhÞ)�”}”(hŒ°It is possible to query which kfunc the particular netdev implements via netlink. See ``xdp-rx-metadata-features`` attribute set in ``Documentation/netlink/specs/netdev.yaml``.”h]”(hŒVIt is possible to query which kfunc the particular netdev implements via netlink. See ”…”�”}”(hjÆh²hh³Nh´Nubj)�”}”(hŒ``xdp-rx-metadata-features``”h]”hŒxdp-rx-metadata-features”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÆubhŒ attribute set in ”…”�”}”(hjÆh²hh³Nh´Nubj)�”}”(hŒ+``Documentation/netlink/specs/netdev.yaml``”h]”hŒ'Documentation/netlink/specs/netdev.yaml”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÆubhŒ.”…”�”}”(hjÆh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kwhjµh²hubeh}”(h]”Œsupported-devices”ah ]”h"]”Œsupported devices”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KuubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒDriver Implementation”h]”hŒDriver Implementation”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´K|ubhÞ)�”}”(hX=Certain devices may prepend metadata to received packets. However, as of now, ``AF_XDP`` lacks the ability to communicate the size of the ``data_meta`` area to the consumer. Therefore, it is the responsibility of the driver to copy any device-reserved metadata out from the metadata area and ensure that ``xdp_buff->data_meta`` is pointing to ``xdp_buff->data`` before presenting the frame to the XDP program. This is necessary so that, after the XDP program adjusts the metadata area, the consumer can reliably retrieve the metadata address using ``METADATA_SIZE`` offset.”h]”(hŒNCertain devices may prepend metadata to received packets. However, as of now, ”…”�”}”(hjh²hh³Nh´Nubj)�”}”(hŒ ``AF_XDP``”h]”hŒAF_XDP”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ2 lacks the ability to communicate the size of the ”…”�”}”(hjh²hh³Nh´Nubj)�”}”(hŒ ``data_meta``”h]”hŒ data_meta”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ™ area to the consumer. Therefore, it is the responsibility of the driver to copy any device-reserved metadata out from the metadata area and ensure that ”…”�”}”(hjh²hh³Nh´Nubj)�”}”(hŒ``xdp_buff->data_meta``”h]”hŒxdp_buff->data_meta”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ is pointing to ”…”�”}”(hjh²hh³Nh´Nubj)�”}”(hŒ``xdp_buff->data``”h]”hŒxdp_buff->data”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ» before presenting the frame to the XDP program. This is necessary so that, after the XDP program adjusts the metadata area, the consumer can reliably retrieve the metadata address using ”…”�”}”(hjh²hh³Nh´Nubj)�”}”(hŒ``METADATA_SIZE``”h]”hŒ METADATA_SIZE”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ offset.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K~hjh²hubhÞ)�”}”(hŒ�The following diagram shows how custom metadata is positioned relative to the packet data and how pointers are adjusted for metadata access::”h]”hŒŒThe following diagram shows how custom metadata is positioned relative to the packet data and how pointers are adjusted for metadata access:”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‡hjh²hubjî )�”}”(hX  |<-- bpf_xdp_adjust_meta(xdp_buff, -METADATA_SIZE) --| new xdp_buff->data_meta old xdp_buff->data_meta | | | xdp_buff->data | | +----------+----------------------------------------------------+------+ | headroom | custom metadata | data | +----------+----------------------------------------------------+------+ | | | xdp_desc->addr |<------ xsk_umem__get_data() - METADATA_SIZE -------|”h]”hX  |<-- bpf_xdp_adjust_meta(xdp_buff, -METADATA_SIZE) --| new xdp_buff->data_meta old xdp_buff->data_meta | | | xdp_buff->data | | +----------+----------------------------------------------------+------+ | headroom | custom metadata | data | +----------+----------------------------------------------------+------+ | | | xdp_desc->addr |<------ xsk_umem__get_data() - METADATA_SIZE -------|”…”�”}”hj‡sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jí h³hÇh´KŠhjh²hubhÞ)�”}”(hX=``bpf_xdp_adjust_meta`` ensures that ``METADATA_SIZE`` is aligned to 4 bytes, does not exceed 252 bytes, and leaves sufficient space for building the xdp_frame. If these conditions are not met, it returns a negative error. In this case, the BPF program should not proceed to populate data into the ``data_meta`` area.”h]”(j)�”}”(hŒ``bpf_xdp_adjust_meta``”h]”hŒbpf_xdp_adjust_meta”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj•ubhŒ ensures that ”…”�”}”(hj•h²hh³Nh´Nubj)�”}”(hŒ``METADATA_SIZE``”h]”hŒ METADATA_SIZE”…”�”}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj•ubhŒô is aligned to 4 bytes, does not exceed 252 bytes, and leaves sufficient space for building the xdp_frame. If these conditions are not met, it returns a negative error. In this case, the BPF program should not proceed to populate data into the ”…”�”}”(hj•h²hh³Nh´Nubj)�”}”(hŒ ``data_meta``”h]”hŒ data_meta”…”�”}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj•ubhŒ area.”…”�”}”(hj•h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K–hjh²hubeh}”(h]”Œdriver-implementation”ah ]”h"]”Œdriver implementation”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K|ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒExample”h]”hŒExample”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÝh²hh³hÇh´K�ubhÞ)�”}”(hŒ¯See ``tools/testing/selftests/bpf/progs/xdp_metadata.c`` and ``tools/testing/selftests/bpf/prog_tests/xdp_metadata.c`` for an example of BPF program that handles XDP metadata.”h]”(hŒSee ”…”�”}”(hjîh²hh³Nh´Nubj)�”}”(hŒ4``tools/testing/selftests/bpf/progs/xdp_metadata.c``”h]”hŒ0tools/testing/selftests/bpf/progs/xdp_metadata.c”…”�”}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjîubhŒ and ”…”�”}”(hjîh²hh³Nh´Nubj)�”}”(hŒ9``tools/testing/selftests/bpf/prog_tests/xdp_metadata.c``”h]”hŒ5tools/testing/selftests/bpf/prog_tests/xdp_metadata.c”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjîubhŒ9 for an example of BPF program that handles XDP metadata.”…”�”}”(hjîh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KŸhjÝh²hubeh}”(h]”Œexample”ah ]”h"]”Œexample”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K�ubeh}”(h]”Œxdp-rx-metadata”ah ]”h"]”Œxdp rx metadata”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”jSŒ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”}”(j-j*j" j jMjJjjýjyjvj²j¯jýjújÚj×j%j"uŒ nametypes”}”(j-‰j" ‰jM‰j‰jy‰j²‰jý‰jÚ‰j%‰uh}”(j*hÊj híjOjXjEjJj5j:jJj% jýjPjvjj¯j|jújµj×jj"jÝuŒ 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.