[sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget5/translations/zh_CN/userspace-api/netlink/intro-specsmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget5/translations/zh_TW/userspace-api/netlink/intro-specsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget5/translations/it_IT/userspace-api/netlink/intro-specsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget5/translations/ja_JP/userspace-api/netlink/intro-specsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget5/translations/ko_KR/userspace-api/netlink/intro-specsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget5/translations/sp_SP/userspace-api/netlink/intro-specsmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h%SPDX-License-Identifier: BSD-3-Clauseh]h%SPDX-License-Identifier: BSD-3-Clause}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhO/var/lib/git/docbuild/linux/Documentation/userspace-api/netlink/intro-specs.rsthKubhsection)}(hhh](htitle)}(h%Using Netlink protocol specificationsh]h%Using Netlink protocol specifications}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hThis document is a quick starting guide for using Netlink protocol specifications. For more detailed description of the specs see :doc:`specs`.h](hThis document is a quick starting guide for using Netlink protocol specifications. For more detailed description of the specs see }(hhhhhNhNubh)}(h :doc:`specs`h]hinline)}(hhh]hspecs}(hhhhhNhNubah}(h]h ](xrefstdstd-doceh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoc!userspace-api/netlink/intro-specs refdomainhreftypedoc refexplicitrefwarn reftargetspecsuh1hhhhKhhubh.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h Simple CLIh]h Simple CLI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK ubh)}(hKernel 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. Only Generic Netlink is supported.h]hKernel 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. Only Generic Netlink is supported.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjhhubh)}(huThe tool is located at ``tools/net/ynl/pyynl/cli.py``. It accepts a handul of arguments, the most important ones are:h](hThe tool is located at }(hj!hhhNhNubhliteral)}(h``tools/net/ynl/pyynl/cli.py``h]htools/net/ynl/pyynl/cli.py}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1j)hj!ubh@. It accepts a handul of arguments, the most important ones are:}(hj!hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh 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 fileh]h)}(hjRh](j*)}(h ``--spec``h]h--spec}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjTubh - point to the spec file}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjPubah}(h]h ]h"]h$]h&]uh1jNhjKubjO)}(h;``--do $name`` / ``--dump $name`` - issue request ``$name``h]h)}(hjwh](j*)}(h``--do $name``h]h --do $name}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjyubh / }(hjyhhhNhNubj*)}(h``--dump $name``h]h --dump $name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjyubh - issue request }(hjyhhhNhNubj*)}(h ``$name``h]h$name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjyubeh}(h]h ]h"]h$]h&]uh1hhhhKhjuubah}(h]h ]h"]h$]h&]uh1jNhjKubjO)}(h6``--json $attrs`` - provide attributes for the requesth]h)}(hjh](j*)}(h``--json $attrs``h]h --json $attrs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh% - provide attributes for the request}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jNhjKubjO)}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh - receive notifications from }(hjhhhNhNubj*)}(h ``$group``h]h$group}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jNhjKubeh}(h]h ]h"]h$]h&]bullet-uh1jIhhhKhjEubah}(h]h ]h"]h$]h&]uh1jChhhKhjhhubh)}(h?YAML specs can be found under ``Documentation/netlink/specs/``.h](hYAML specs can be found under }(hj!hhhNhNubj*)}(h ``Documentation/netlink/specs/``h]hDocumentation/netlink/specs/}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j)hj!ubh.}(hj!hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h Example use::h]h Example use:}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh 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}}hjQsbah}(h]h ]h"]h$]h&]hhuh1jOhhhKhjhhubh)}(hThe 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]hThe 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.}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjhhubh)}(hThe 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](hThe spec and Netlink internals are factored out as a standalone library - it should be easy to write Python tools / tests reusing code from }(hjmhhhNhNubj*)}(h ``cli.py``h]hcli.py}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjmubh.}(hjmhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK1hjhhubeh}(h] simple-cliah ]h"] simple cliah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(hGenerating kernel codeh]hGenerating kernel code}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK6ubh)}(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]htools/net/ynl/ynl-regen.sh}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh 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.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK8hjhhubh)}(hhBy default code is re-generated only if spec is newer than the source, to force regeneration use ``-f``.h](haBy default code is re-generated only if spec is newer than the source, to force regeneration use }(hjhhhNhNubj*)}(h``-f``h]h-f}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKerr.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);}hj9sbah}(h]h ]h"]h$]h&]hhforcelanguagechighlight_args}uh1jOhhhKkhjhhubeh}(h] ynl-requestsah ]h"] ynl requestsah$]h&]uh1hhjhhhhhKeubh)}(hhh](h)}(h YNL dumpsh]h YNL dumps}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThhhhhKubh)}(hPerforming 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](hPerforming dumps follows similar pattern as requests. Dumps return a list of objects terminated by a special marker, or NULL on error. Use }(hjehhhNhNubj*)}(h``ynl_dump_foreach()``h]hynl_dump_foreach()}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjeubh to iterate over the result.}(hjehhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjThhubeh}(h] ynl-dumpsah ]h"] ynl dumpsah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hYNL notificationsh]hYNL notifications}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hYNL 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]hYNL 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hTo 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 }(hjhhhNhNubj*)}(h``ynl_subscribe()``h]hynl_subscribe()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh9. The notifications have to be read out from the socket, }(hjhhhNhNubj*)}(h``ynl_socket_get_fd()``h]hynl_socket_get_fd()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubha returns the underlying socket fd which can be plugged into appropriate asynchronous IO API like }(hjhhhNhNubj*)}(h``poll``h]hpoll}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh, or }(hjhhhNhNubj*)}(h ``select``h]hselect}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(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 }(hjhhhNhNubj*)}(h``ynl_ntf_dequeue()``h]hynl_ntf_dequeue()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh and have to be freed using }(hjhhhNhNubj*)}(h``ynl_ntf_free()``h]hynl_ntf_free()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubhX. Since we don’t know the notification type upfront the notifications are returned as }(hjhhhNhNubj*)}(h``struct ynl_ntf_base_type *``h]hstruct ynl_ntf_base_type *}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubhM and user is expected to cast them to the appropriate full type based on the }(hjhhhNhNubj*)}(h``cmd``h]hcmd}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1j)hjubh member.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]ynl-notificationsah ]h"]ynl notificationsah$]h&]uh1hhjhhhhhKubeh}(h]ynl-libah ]h"]ynl libah$]h&]uh1hhhhhhhhKSubeh}(h]%using-netlink-protocol-specificationsah ]h"]%using netlink protocol specificationsah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jmjjjjjjjejbjjjQjNjjj]jZu nametypes}(jmjjjejjQjj]uh}(jjhjjjjjbjjjjNjjjTjZju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.