€•W\Œ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”Œ5/translations/zh_CN/userspace-api/netlink/intro-specs”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/zh_TW/userspace-api/netlink/intro-specs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/it_IT/userspace-api/netlink/intro-specs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/ja_JP/userspace-api/netlink/intro-specs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/ko_KR/userspace-api/netlink/intro-specs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/pt_BR/userspace-api/netlink/intro-specs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/sp_SP/userspace-api/netlink/intro-specs”Œ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: BSD-3-Clause”h]”hŒ%SPDX-License-Identifier: BSD-3-Clause”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒO/var/lib/git/docbuild/linux/Documentation/userspace-api/netlink/intro-specs.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ%Using Netlink protocol specifications”h]”hŒ%Using Netlink protocol specifications”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒ�This document is a quick starting guide for using Netlink protocol specifications. For more detailed description of the specs see :doc:`specs`.”h]”(hŒ‚This document is a quick starting guide for using Netlink protocol specifications. For more detailed description of the specs see ”…”�”}”(hhßh²hh³Nh´Nubh)�”}”(hŒ :doc:`specs`”h]”hŒinline”“”)�”}”(hhéh]”hŒspecs”…”�”}”(hhíh²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œstd”Œstd-doc”eh"]”h$]”h&]”uh1hëhhçubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œ!userspace-api/netlink/intro-specs”Œ refdomain”høŒreftype”Œdoc”Œ refexplicit”‰Œrefwarn”ˆŒ reftarget”Œspecs”uh1hh³hÇh´KhhßubhŒ.”…”�”}”(hhßh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Simple CLI”h]”hŒ Simple CLI”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´K ubhÞ)�”}”(hŒÌKernel comes with a simple CLI tool which should be useful when developing Netlink related code. The tool is implemented in Python and can use a YAML specification to issue Netlink requests to the kernel.”h]”hŒÌKernel comes with a simple CLI tool which should be useful when developing Netlink related code. The tool is implemented in Python and can use a YAML specification to issue Netlink requests to the kernel.”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hjh²hubhÞ)�”}”(hŒvThe tool is located at ``tools/net/ynl/pyynl/cli.py``. It accepts a handful of arguments, the most important ones are:”h]”(hŒThe tool is located at ”…”�”}”(hj5h²hh³Nh´NubhŒliteral”“”)�”}”(hŒ``tools/net/ynl/pyynl/cli.py``”h]”hŒtools/net/ynl/pyynl/cli.py”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj5ubhŒA. It accepts a handful of arguments, the most important ones are:”…”�”}”(hj5h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhŒ block_quote”“”)�”}”(hŒÞ- ``--spec`` - point to the spec file - ``--do $name`` / ``--dump $name`` - issue request ``$name`` - ``--json $attrs`` - provide attributes for the request - ``--subscribe $group`` - receive notifications from ``$group`` ”h]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ#``--spec`` - point to the spec file”h]”hÞ)�”}”(hjfh]”(j>)�”}”(hŒ ``--spec``”h]”hŒ--spec”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjhubhŒ - point to the spec file”…”�”}”(hjhh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjdubah}”(h]”h ]”h"]”h$]”h&]”uh1jbhj_ubjc)�”}”(hŒ;``--do $name`` / ``--dump $name`` - issue request ``$name``”h]”hÞ)�”}”(hj‹h]”(j>)�”}”(hŒ``--do $name``”h]”hŒ --do $name”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj�ubhŒ / ”…”�”}”(hj�h²hh³Nh´Nubj>)�”}”(hŒ``--dump $name``”h]”hŒ --dump $name”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj�ubhŒ - issue request ”…”�”}”(hj�h²hh³Nh´Nubj>)�”}”(hŒ ``$name``”h]”hŒ$name”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1jbhj_ubjc)�”}”(hŒ6``--json $attrs`` - provide attributes for the request”h]”hÞ)�”}”(hjÐh]”(j>)�”}”(hŒ``--json $attrs``”h]”hŒ --json $attrs”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjÒubhŒ% - provide attributes for the request”…”�”}”(hjÒh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhjÎubah}”(h]”h ]”h"]”h$]”h&]”uh1jbhj_ubjc)�”}”(hŒ?``--subscribe $group`` - receive notifications from ``$group`` ”h]”hÞ)�”}”(hŒ>``--subscribe $group`` - receive notifications from ``$group``”h]”(j>)�”}”(hŒ``--subscribe $group``”h]”hŒ--subscribe $group”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj÷ubhŒ - receive notifications from ”…”�”}”(hj÷h²hh³Nh´Nubj>)�”}”(hŒ ``$group``”h]”hŒ$group”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj÷ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjóubah}”(h]”h ]”h"]”h$]”h&]”uh1jbhj_ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j]h³hÇh´KhjYubah}”(h]”h ]”h"]”h$]”h&]”uh1jWh³hÇh´Khjh²hubhÞ)�”}”(hŒ?YAML specs can be found under ``Documentation/netlink/specs/``.”h]”(hŒYAML specs can be found under ”…”�”}”(hj5h²hh³Nh´Nubj>)�”}”(hŒ ``Documentation/netlink/specs/``”h]”hŒDocumentation/netlink/specs/”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj5ubhŒ.”…”�”}”(hj5h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhÞ)�”}”(hŒ Example use::”h]”hŒ Example use:”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjh²hubhŒ literal_block”“”)�”}”(hXY$ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \ --do rings-get \ --json '{"header":{"dev-index": 18}}' {'header': {'dev-index': 18, 'dev-name': 'eni1np1'}, 'rx': 0, 'rx-jumbo': 0, 'rx-jumbo-max': 4096, 'rx-max': 4096, 'rx-mini': 0, 'rx-mini-max': 4096, 'tx': 0, 'tx-max': 4096, 'tx-push': 0}”h]”hXY$ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \ --do rings-get \ --json '{"header":{"dev-index": 18}}' {'header': {'dev-index': 18, 'dev-name': 'eni1np1'}, 'rx': 0, 'rx-jumbo': 0, 'rx-jumbo-max': 4096, 'rx-max': 4096, 'rx-mini': 0, 'rx-mini-max': 4096, 'tx': 0, 'tx-max': 4096, 'tx-push': 0}”…”�”}”hjesbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jch³hÇh´Khjh²hubhÞ)�”}”(hŒøThe input arguments are parsed as JSON, while the output is only Python-pretty-printed. This is because some Netlink types can't be expressed as JSON directly. If such attributes are needed in the input some hacking of the script will be necessary.”h]”hŒúThe input arguments are parsed as JSON, while the output is only Python-pretty-printed. This is because some Netlink types can’t be expressed as JSON directly. If such attributes are needed in the input some hacking of the script will be necessary.”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K,hjh²hubhÞ)�”}”(hŒ—The spec and Netlink internals are factored out as a standalone library - it should be easy to write Python tools / tests reusing code from ``cli.py``.”h]”(hŒŒThe spec and Netlink internals are factored out as a standalone library - it should be easy to write Python tools / tests reusing code from ”…”�”}”(hj�h²hh³Nh´Nubj>)�”}”(hŒ ``cli.py``”h]”hŒcli.py”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj�ubhŒ.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K1hjh²hubeh}”(h]”Œ simple-cli”ah ]”h"]”Œ simple cli”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒGenerating kernel code”h]”hŒGenerating kernel code”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj©h²hh³hÇh´K6ubhÞ)�”}”(hŒ½``tools/net/ynl/ynl-regen.sh`` scans the kernel tree in search of auto-generated files which need to be updated. Using this tool is the easiest way to generate / update auto-generated code.”h]”(j>)�”}”(hŒ``tools/net/ynl/ynl-regen.sh``”h]”hŒtools/net/ynl/ynl-regen.sh”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjºubhŒŸ scans the kernel tree in search of auto-generated files which need to be updated. Using this tool is the easiest way to generate / update auto-generated code.”…”�”}”(hjºh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K8hj©h²hubhÞ)�”}”(hŒhBy default code is re-generated only if spec is newer than the source, to force regeneration use ``-f``.”h]”(hŒaBy default code is re-generated only if spec is newer than the source, to force regeneration use ”…”�”}”(hjÖh²hh³Nh´Nubj>)�”}”(hŒ``-f``”h]”hŒ-f”…”�”}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjÖubhŒ.”…”�”}”(hjÖh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K)�”}”(hŒ``ynl-regen.sh``”h]”hŒ ynl-regen.sh”…”�”}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjöubhŒ searches for ”…”�”}”(hjöh²hh³Nh´Nubj>)�”}”(hŒ ``YNL-GEN``”h]”hŒYNL-GEN”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjöubhŒ€ in the contents of files (note that it only scans files in the git index, that is only files tracked by git!) For instance the ”…”�”}”(hjöh²hh³Nh´Nubj>)�”}”(hŒ ``fou_nl.c``”h]”hŒfou_nl.c”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjöubhŒ kernel source contains:”…”�”}”(hjöh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K?hj©h²hubjd)�”}”(hŒI/* Documentation/netlink/specs/fou.yaml */ /* YNL-GEN kernel source */”h]”hŒI/* Documentation/netlink/specs/fou.yaml */ /* YNL-GEN kernel source */”…”�”}”hj6sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jch³hÇh´KChj©h²hubhÞ)�”}”(hŒa``ynl-regen.sh`` will find this marker and replace the file with kernel source based on fou.yaml.”h]”(j>)�”}”(hŒ``ynl-regen.sh``”h]”hŒ ynl-regen.sh”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjDubhŒQ will find this marker and replace the file with kernel source based on fou.yaml.”…”�”}”(hjDh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KFhj©h²hubhÞ)�”}”(hŒÖThe simplest way to generate a new file based on a spec is to add the two marker lines like above to a file, add that file to git, and run the regeneration tool. Grep the tree for ``YNL-GEN`` to see other examples.”h]”(hŒ´The simplest way to generate a new file based on a spec is to add the two marker lines like above to a file, add that file to git, and run the regeneration tool. Grep the tree for ”…”�”}”(hj`h²hh³Nh´Nubj>)�”}”(hŒ ``YNL-GEN``”h]”hŒYNL-GEN”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj`ubhŒ to see other examples.”…”�”}”(hj`h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KIhj©h²hubhÞ)�”}”(hŒªThe code generation itself is performed by ``tools/net/ynl/pyynl/ynl_gen_c.py`` but it takes a few arguments so calling it directly for each file quickly becomes tedious.”h]”(hŒ+The code generation itself is performed by ”…”�”}”(hj€h²hh³Nh´Nubj>)�”}”(hŒ$``tools/net/ynl/pyynl/ynl_gen_c.py``”h]”hŒ tools/net/ynl/pyynl/ynl_gen_c.py”…”�”}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj€ubhŒ[ but it takes a few arguments so calling it directly for each file quickly becomes tedious.”…”�”}”(hj€h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KNhj©h²hubeh}”(h]”Œgenerating-kernel-code”ah ]”h"]”Œgenerating kernel code”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K6ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒYNL lib”h]”hŒYNL lib”…”�”}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj¨h²hh³hÇh´KSubhÞ)�”}”(hŒÇ``tools/net/ynl/lib/`` contains an implementation of a C library (based on libmnl) which integrates with code generated by ``tools/net/ynl/pyynl/ynl_gen_c.py`` to create easy to use netlink wrappers.”h]”(j>)�”}”(hŒ``tools/net/ynl/lib/``”h]”hŒtools/net/ynl/lib/”…”�”}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj¹ubhŒe contains an implementation of a C library (based on libmnl) which integrates with code generated by ”…”�”}”(hj¹h²hh³Nh´Nubj>)�”}”(hŒ$``tools/net/ynl/pyynl/ynl_gen_c.py``”h]”hŒ tools/net/ynl/pyynl/ynl_gen_c.py”…”�”}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hj¹ubhŒ( to create easy to use netlink wrappers.”…”�”}”(hj¹h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KUhj¨h²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ YNL basics”h]”hŒ YNL basics”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjçh²hh³hÇh´KZubhÞ)�”}”(hŒ¢The YNL library consists of two parts - the generic code (functions prefix by ``ynl_``) and per-family auto-generated code (prefixed with the name of the family).”h]”(hŒNThe YNL library consists of two parts - the generic code (functions prefix by ”…”�”}”(hjøh²hh³Nh´Nubj>)�”}”(hŒ``ynl_``”h]”hŒynl_”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjøubhŒL) and per-family auto-generated code (prefixed with the name of the family).”…”�”}”(hjøh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K\hjçh²hubhÞ)�”}”(hŒ§To create a YNL socket call ynl_sock_create() passing the family struct (family structs are exported by the auto-generated code). ynl_sock_destroy() closes the socket.”h]”hŒ§To create a YNL socket call ynl_sock_create() passing the family struct (family structs are exported by the auto-generated code). ynl_sock_destroy() closes the socket.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K`hjçh²hubeh}”(h]”Œ ynl-basics”ah ]”h"]”Œ ynl basics”ah$]”h&]”uh1hÈhj¨h²hh³hÇh´KZubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ YNL requests”h]”hŒ YNL requests”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj.h²hh³hÇh´KeubhÞ)�”}”(hŒ´Steps for issuing YNL requests are best explained on an example. All the functions and types in this example come from the auto-generated code (for the netdev family in this case):”h]”hŒ´Steps for issuing YNL requests are best explained on an example. All the functions and types in this example come from the auto-generated code (for the netdev family in this case):”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kghj.h²hubjd)�”}”(hXg// 0. Request and response pointers struct netdev_dev_get_req *req; struct netdev_dev_get_rsp *d; // 1. Allocate a request req = netdev_dev_get_req_alloc(); // 2. Set request parameters (as needed) netdev_dev_get_req_set_ifindex(req, ifindex); // 3. Issues the request d = netdev_dev_get(ys, req); // 4. Free the request arguments netdev_dev_get_req_free(req); // 5. Error check (the return value from step 3) if (!d) { // 6. Print the YNL-generated error fprintf(stderr, "YNL: %s\n", ys->err.msg); return -1; } // ... do stuff with the response @d // 7. Free response netdev_dev_get_rsp_free(d);”h]”hXg// 0. Request and response pointers struct netdev_dev_get_req *req; struct netdev_dev_get_rsp *d; // 1. Allocate a request req = netdev_dev_get_req_alloc(); // 2. Set request parameters (as needed) netdev_dev_get_req_set_ifindex(req, ifindex); // 3. Issues the request d = netdev_dev_get(ys, req); // 4. Free the request arguments netdev_dev_get_req_free(req); // 5. Error check (the return value from step 3) if (!d) { // 6. Print the YNL-generated error fprintf(stderr, "YNL: %s\n", ys->err.msg); return -1; } // ... do stuff with the response @d // 7. Free response netdev_dev_get_rsp_free(d);”…”�”}”hjMsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”Œc”Œhighlight_args”}”uh1jch³hÇh´Kkhj.h²hubeh}”(h]”Œ ynl-requests”ah ]”h"]”Œ ynl requests”ah$]”h&]”uh1hÈhj¨h²hh³hÇh´KeubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ YNL dumps”h]”hŒ YNL dumps”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjhh²hh³hÇh´K‡ubhÞ)�”}”(hŒ½Performing dumps follows similar pattern as requests. Dumps return a list of objects terminated by a special marker, or NULL on error. Use ``ynl_dump_foreach()`` to iterate over the result.”h]”(hŒ‹Performing dumps follows similar pattern as requests. Dumps return a list of objects terminated by a special marker, or NULL on error. Use ”…”�”}”(hjyh²hh³Nh´Nubj>)�”}”(hŒ``ynl_dump_foreach()``”h]”hŒynl_dump_foreach()”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjyubhŒ to iterate over the result.”…”�”}”(hjyh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‰hjhh²hubeh}”(h]”Œ ynl-dumps”ah ]”h"]”Œ ynl dumps”ah$]”h&]”uh1hÈhj¨h²hh³hÇh´K‡ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒYNL notifications”h]”hŒYNL notifications”…”�”}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj¡h²hh³hÇh´K�ubhÞ)�”}”(hŒÃYNL lib supports using the same socket for notifications and requests. In case notifications arrive during processing of a request they are queued internally and can be retrieved at a later time.”h]”hŒÃYNL lib supports using the same socket for notifications and requests. In case notifications arrive during processing of a request they are queued internally and can be retrieved at a later time.”…”�”}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‘hj¡h²hubhÞ)�”}”(hŒÿTo subscribed to notifications use ``ynl_subscribe()``. The notifications have to be read out from the socket, ``ynl_socket_get_fd()`` returns the underlying socket fd which can be plugged into appropriate asynchronous IO API like ``poll``, or ``select``.”h]”(hŒ#To subscribed to notifications use ”…”�”}”(hjÀh²hh³Nh´Nubj>)�”}”(hŒ``ynl_subscribe()``”h]”hŒynl_subscribe()”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjÀubhŒ9. The notifications have to be read out from the socket, ”…”�”}”(hjÀh²hh³Nh´Nubj>)�”}”(hŒ``ynl_socket_get_fd()``”h]”hŒynl_socket_get_fd()”…”�”}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjÀubhŒa returns the underlying socket fd which can be plugged into appropriate asynchronous IO API like ”…”�”}”(hjÀh²hh³Nh´Nubj>)�”}”(hŒ``poll``”h]”hŒpoll”…”�”}”(hjìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjÀubhŒ, or ”…”�”}”(hjÀh²hh³Nh´Nubj>)�”}”(hŒ ``select``”h]”hŒselect”…”�”}”(hjþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjÀubhŒ.”…”�”}”(hjÀh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K•hj¡h²hubhÞ)�”}”(hX8Notifications can be retrieved using ``ynl_ntf_dequeue()`` and have to be freed using ``ynl_ntf_free()``. Since we don't know the notification type upfront the notifications are returned as ``struct ynl_ntf_base_type *`` and user is expected to cast them to the appropriate full type based on the ``cmd`` member.”h]”(hŒ%Notifications can be retrieved using ”…”�”}”(hjh²hh³Nh´Nubj>)�”}”(hŒ``ynl_ntf_dequeue()``”h]”hŒynl_ntf_dequeue()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjubhŒ and have to be freed using ”…”�”}”(hjh²hh³Nh´Nubj>)�”}”(hŒ``ynl_ntf_free()``”h]”hŒynl_ntf_free()”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjubhŒX. Since we don’t know the notification type upfront the notifications are returned as ”…”�”}”(hjh²hh³Nh´Nubj>)�”}”(hŒ``struct ynl_ntf_base_type *``”h]”hŒstruct ynl_ntf_base_type *”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjubhŒM and user is expected to cast them to the appropriate full type based on the ”…”�”}”(hjh²hh³Nh´Nubj>)�”}”(hŒ``cmd``”h]”hŒcmd”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j=hjubhŒ member.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K›hj¡h²hubeh}”(h]”Œynl-notifications”ah ]”h"]”Œynl notifications”ah$]”h&]”uh1hÈhj¨h²hh³hÇh´K�ubeh}”(h]”Œynl-lib”ah ]”h"]”Œynl lib”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KSubeh}”(h]”Œ%using-netlink-protocol-specifications”ah ]”h"]”Œ%using netlink protocol specifications”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~j¦j£j¥j¢jyjvj+j(jejbjžj›jqjnuŒ nametypes”}”(j�‰j¦‰j¥‰jy‰j+‰je‰jž‰jq‰uh}”(j~hÊj£jj¢j©jvj¨j(jçjbj.j›jhjnj¡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.