€•npŒ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/bpf/prog_cgroup_sockopt”Œ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/bpf/prog_cgroup_sockopt”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ+/translations/it_IT/bpf/prog_cgroup_sockopt”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ+/translations/ja_JP/bpf/prog_cgroup_sockopt”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ+/translations/ko_KR/bpf/prog_cgroup_sockopt”Œ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/bpf/prog_cgroup_sockopt”Œ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/bpf/prog_cgroup_sockopt”Œ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³ŒE/var/lib/git/docbuild/linux/Documentation/bpf/prog_cgroup_sockopt.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒBPF_PROG_TYPE_CGROUP_SOCKOPT”h]”hŒBPF_PROG_TYPE_CGROUP_SOCKOPT”…””}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)”}”(hŒR``BPF_PROG_TYPE_CGROUP_SOCKOPT`` program type can be attached to two cgroup hooks:”h]”(hŒliteral”“”)”}”(hŒ ``BPF_PROG_TYPE_CGROUP_SOCKOPT``”h]”hŒBPF_PROG_TYPE_CGROUP_SOCKOPT”…””}”(hhåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhhßubhŒ2 program type can be attached to two cgroup hooks:”…””}”(hhßh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒZ``BPF_CGROUP_GETSOCKOPT`` - called every time process executes ``getsockopt`` system call.”h]”hÞ)”}”(hŒZ``BPF_CGROUP_GETSOCKOPT`` - called every time process executes ``getsockopt`` system call.”h]”(hä)”}”(hŒ``BPF_CGROUP_GETSOCKOPT``”h]”hŒBPF_CGROUP_GETSOCKOPT”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjubhŒ& - called every time process executes ”…””}”(hjh²hh³Nh´Nubhä)”}”(hŒ``getsockopt``”h]”hŒ getsockopt”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjubhŒ system call.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhÿh²hh³hÇh´Nubj)”}”(hŒ[``BPF_CGROUP_SETSOCKOPT`` - called every time process executes ``setsockopt`` system call. ”h]”hÞ)”}”(hŒZ``BPF_CGROUP_SETSOCKOPT`` - called every time process executes ``setsockopt`` system call.”h]”(hä)”}”(hŒ``BPF_CGROUP_SETSOCKOPT``”h]”hŒBPF_CGROUP_SETSOCKOPT”…””}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj@ubhŒ& - called every time process executes ”…””}”(hj@h²hh³Nh´Nubhä)”}”(hŒ``setsockopt``”h]”hŒ setsockopt”…””}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj@ubhŒ system call.”…””}”(hj@h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hj<ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhÿh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1hýh³hÇh´K hhÊh²hubhÞ)”}”(hŒThe context (``struct bpf_sockopt``) has associated socket (``sk``) and all input arguments: ``level``, ``optname``, ``optval`` and ``optlen``.”h]”(hŒ The context (”…””}”(hj|h²hh³Nh´Nubhä)”}”(hŒ``struct bpf_sockopt``”h]”hŒstruct bpf_sockopt”…””}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj|ubhŒ) has associated socket (”…””}”(hj|h²hh³Nh´Nubhä)”}”(hŒ``sk``”h]”hŒsk”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj|ubhŒ) and all input arguments: ”…””}”(hj|h²hh³Nh´Nubhä)”}”(hŒ ``level``”h]”hŒlevel”…””}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj|ubhŒ, ”…””}”(hj|h²hh³Nh´Nubhä)”}”(hŒ ``optname``”h]”hŒoptname”…””}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj|ubhŒ, ”…””}”hj|sbhä)”}”(hŒ ``optval``”h]”hŒoptval”…””}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj|ubhŒ and ”…””}”(hj|h²hh³Nh´Nubhä)”}”(hŒ ``optlen``”h]”hŒoptlen”…””}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj|ubhŒ.”…””}”(hj|h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒBPF_CGROUP_SETSOCKOPT”h]”hŒBPF_CGROUP_SETSOCKOPT”…””}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjöh²hh³hÇh´KubhÞ)”}”(hŒõ``BPF_CGROUP_SETSOCKOPT`` is triggered *before* the kernel handling of sockopt and it has writable context: it can modify the supplied arguments before passing them down to the kernel. This hook has access to the cgroup and socket local storage.”h]”(hä)”}”(hŒ``BPF_CGROUP_SETSOCKOPT``”h]”hŒBPF_CGROUP_SETSOCKOPT”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjubhŒ is triggered ”…””}”(hjh²hh³Nh´NubhŒemphasis”“”)”}”(hŒ*before*”h]”hŒbefore”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒÆ the kernel handling of sockopt and it has writable context: it can modify the supplied arguments before passing them down to the kernel. This hook has access to the cgroup and socket local storage.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjöh²hubhÞ)”}”(hŒÎIf BPF program sets ``optlen`` to -1, the control will be returned back to the userspace after all other BPF programs in the cgroup chain finish (i.e. kernel ``setsockopt`` handling will *not* be executed).”h]”(hŒIf BPF program sets ”…””}”(hj7h²hh³Nh´Nubhä)”}”(hŒ ``optlen``”h]”hŒoptlen”…””}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj7ubhŒ€ to -1, the control will be returned back to the userspace after all other BPF programs in the cgroup chain finish (i.e. kernel ”…””}”(hj7h²hh³Nh´Nubhä)”}”(hŒ``setsockopt``”h]”hŒ setsockopt”…””}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj7ubhŒ handling will ”…””}”(hj7h²hh³Nh´Nubj)”}”(hŒ*not*”h]”hŒnot”…””}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj7ubhŒ be executed).”…””}”(hj7h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjöh²hubhÞ)”}”(hŒšNote, that ``optlen`` can not be increased beyond the user-supplied value. It can only be decreased or set to -1. Any other value will trigger ``EFAULT``.”h]”(hŒ Note, that ”…””}”(hj{h²hh³Nh´Nubhä)”}”(hŒ ``optlen``”h]”hŒoptlen”…””}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj{ubhŒz can not be increased beyond the user-supplied value. It can only be decreased or set to -1. Any other value will trigger ”…””}”(hj{h²hh³Nh´Nubhä)”}”(hŒ ``EFAULT``”h]”hŒEFAULT”…””}”(hj•h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj{ubhŒ.”…””}”(hj{h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjöh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Return Type”h]”hŒ Return Type”…””}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj­h²hh³hÇh´K#ubhþ)”}”(hhh]”(j)”}”(hŒH``0`` - reject the syscall, ``EPERM`` will be returned to the userspace.”h]”hÞ)”}”(hjÃh]”(hä)”}”(hŒ``0``”h]”hŒ0”…””}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjÅubhŒ - reject the syscall, ”…””}”(hjÅh²hh³Nh´Nubhä)”}”(hŒ ``EPERM``”h]”hŒEPERM”…””}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjÅubhŒ# will be returned to the userspace.”…””}”(hjÅh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K%hjÁubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¾h²hh³hÇh´Nubj)”}”(hŒE``1`` - success, continue with next BPF program in the cgroup chain. ”h]”hÞ)”}”(hŒD``1`` - success, continue with next BPF program in the cgroup chain.”h]”(hä)”}”(hŒ``1``”h]”hŒ1”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjüubhŒ? - success, continue with next BPF program in the cgroup chain.”…””}”(hjüh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K&hjøubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¾h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jzj{uh1hýh³hÇh´K%hj­h²hubeh}”(h]”Œ return-type”ah ]”h"]”h$]”Œ return type”ah&]”uh1hÈhjöh²hh³hÇh´K#Œ referenced”Kubeh}”(h]”Œbpf-cgroup-setsockopt”ah ]”h"]”Œbpf_cgroup_setsockopt”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒBPF_CGROUP_GETSOCKOPT”h]”hŒBPF_CGROUP_GETSOCKOPT”…””}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj5h²hh³hÇh´K)ubhÞ)”}”(hX—``BPF_CGROUP_GETSOCKOPT`` is triggered *after* the kernel handing of sockopt. The BPF hook can observe ``optval``, ``optlen`` and ``retval`` if it's interested in whatever kernel has returned. BPF hook can override the values above, adjust ``optlen`` and reset ``retval`` to 0. If ``optlen`` has been increased above initial ``getsockopt`` value (i.e. userspace buffer is too small), ``EFAULT`` is returned.”h]”(hä)”}”(hŒ``BPF_CGROUP_GETSOCKOPT``”h]”hŒBPF_CGROUP_GETSOCKOPT”…””}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ is triggered ”…””}”(hjFh²hh³Nh´Nubj)”}”(hŒ*after*”h]”hŒafter”…””}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjFubhŒ9 the kernel handing of sockopt. The BPF hook can observe ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``optval``”h]”hŒoptval”…””}”(hjnh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ, ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``optlen``”h]”hŒoptlen”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ and ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``retval``”h]”hŒretval”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒf if it’s interested in whatever kernel has returned. BPF hook can override the values above, adjust ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``optlen``”h]”hŒoptlen”…””}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ and reset ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``retval``”h]”hŒretval”…””}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ to 0. If ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``optlen``”h]”hŒoptlen”…””}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ" has been increased above initial ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ``getsockopt``”h]”hŒ getsockopt”…””}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ- value (i.e. userspace buffer is too small), ”…””}”(hjFh²hh³Nh´Nubhä)”}”(hŒ ``EFAULT``”h]”hŒEFAULT”…””}”(hjìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjFubhŒ is returned.”…””}”(hjFh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K+hj5h²hubhÞ)”}”(hŒlevel == MY_SOL && ctx->optname == MY_OPTNAME) { ctx->retval = 0; optval[0] = ...; ctx->optlen = 1; return 1; } /* Modify kernel's socket option. */ if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { ctx->retval = 0; optval[0] = ...; ctx->optlen = 1; return 1; } /* optval larger than PAGE_SIZE use kernel's buffer. */ if (ctx->optlen > PAGE_SIZE) ctx->optlen = 0; return 1; } SEC("cgroup/setsockopt") int setsockopt(struct bpf_sockopt *ctx) { /* Custom socket option. */ if (ctx->level == MY_SOL && ctx->optname == MY_OPTNAME) { /* do something */ ctx->optlen = -1; return 1; } /* Modify kernel's socket option. */ if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { optval[0] = ...; return 1; } /* optval larger than PAGE_SIZE use kernel's buffer. */ if (ctx->optlen > PAGE_SIZE) ctx->optlen = 0; return 1; }”h]”hX(SEC("cgroup/getsockopt") int getsockopt(struct bpf_sockopt *ctx) { /* Custom socket option. */ if (ctx->level == MY_SOL && ctx->optname == MY_OPTNAME) { ctx->retval = 0; optval[0] = ...; ctx->optlen = 1; return 1; } /* Modify kernel's socket option. */ if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { ctx->retval = 0; optval[0] = ...; ctx->optlen = 1; return 1; } /* optval larger than PAGE_SIZE use kernel's buffer. */ if (ctx->optlen > PAGE_SIZE) ctx->optlen = 0; return 1; } SEC("cgroup/setsockopt") int setsockopt(struct bpf_sockopt *ctx) { /* Custom socket option. */ if (ctx->level == MY_SOL && ctx->optname == MY_OPTNAME) { /* do something */ ctx->optlen = -1; return 1; } /* Modify kernel's socket option. */ if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) { optval[0] = ...; return 1; } /* optval larger than PAGE_SIZE use kernel's buffer. */ if (ctx->optlen > PAGE_SIZE) ctx->optlen = 0; return 1; }”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”Œc”Œhighlight_args”}”uh1jCh³hÇh´Knhjqh²hubhÞ)”}”(hŒqSee ``tools/testing/selftests/bpf/progs/sockopt_sk.c`` for an example of BPF program that handles socket options.”h]”(hŒSee ”…””}”(hj£h²hh³Nh´Nubhä)”}”(hŒ2``tools/testing/selftests/bpf/progs/sockopt_sk.c``”h]”hŒ.tools/testing/selftests/bpf/progs/sockopt_sk.c”…””}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhj£ubhŒ; for an example of BPF program that handles socket options.”…””}”(hj£h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K¡hjqh²hubeh}”(h]”Œexample”ah ]”h"]”Œexample”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´Kjubeh}”(h]”Œbpf-prog-type-cgroup-sockopt”ah ]”h"]”Œbpf_prog_type_cgroup_sockopt”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”jöŒ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Íj2j/Œ return type”NjýjújLjIjnjkjÈjÅuŒ nametypes”}”(jЉj2‰j:‰jý‰jL‰jn‰jȉuh}”(jÍhÊj/jöj&j­júj5jójDjIjjkjOjÅjquŒ 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”“”}”jKs…”R”Œparse_messages”]”hŒsystem_message”“”)”}”(hhh]”hÞ)”}”(hŒ.Duplicate implicit target name: "return type".”h]”hŒ2Duplicate implicit target name: “return typeâ€.”…””}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj[ubah}”(h]”h ]”h"]”h$]”h&]”jóaŒlevel”KŒtype”ŒINFO”Œsource”hÇŒline”K9uh1jYhjDh²hh³hÇh´K9ubaŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.