sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget(/translations/zh_CN/driver-api/connectormodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/zh_TW/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/it_IT/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/ja_JP/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/ko_KR/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/sp_SP/driver-api/connectormodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhB/var/lib/git/docbuild/linux/Documentation/driver-api/connector.rsthKubhsection)}(hhh](htitle)}(hKernel Connectorh]hKernel Connector}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(haKernel connector - new netlink based userspace <-> kernel space easy to use communication module.h]haKernel connector - new netlink based userspace <-> kernel space easy to use communication module.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hX The Connector driver makes it easy to connect various agents using a netlink based network. One must register a callback and an identifier. When the driver receives a special netlink message with the appropriate identifier, the appropriate callback will be called.h]hX The Connector driver makes it easy to connect various agents using a netlink based network. One must register a callback and an identifier. When the driver receives a special netlink message with the appropriate identifier, the appropriate callback will be called.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hFrom the userspace point of view it’s quite straightforward:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh block_quote)}(h*- socket(); - bind(); - send(); - recv(); h]h bullet_list)}(hhh](h list_item)}(h socket();h]h)}(hjh]h socket();}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhubj)}(hbind();h]h)}(hjh]hbind();}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhubj)}(hsend();h]h)}(hj2h]hsend();}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj0ubah}(h]h ]h"]h$]h&]uh1jhhubj)}(hrecv(); h]h)}(hrecv();h]hrecv();}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjGubah}(h]h ]h"]h$]h&]uh1jhhubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hX6But if kernelspace wants to use the full power of such connections, the driver writer must create special sockets, must know about struct sk_buff handling, etc... The Connector driver allows any kernelspace agents to use netlink based networking for inter-process communication in a significantly easier way::h]hX5But if kernelspace wants to use the full power of such connections, the driver writer must create special sockets, must know about struct sk_buff handling, etc... The Connector driver allows any kernelspace agents to use netlink based networking for inter-process communication in a significantly easier way:}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh literal_block)}(hXint cn_add_callback(const struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *)); void cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask); void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask); struct cb_id { __u32 idx; __u32 val; };h]hXint cn_add_callback(const struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *)); void cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask); void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask); struct cb_id { __u32 idx; __u32 val; };}hj}sbah}(h]h ]h"]h$]h&]hhuh1j{hhhKhhhhubh)}(hXDidx and val are unique identifiers which must be registered in the connector.h header for in-kernel usage. `void (*callback) (void *)` is a callback function which will be called when a message with above idx.val is received by the connector core. The argument for that function must be dereferenced to `struct cn_msg *`::h](hlidx and val are unique identifiers which must be registered in the connector.h header for in-kernel usage. }(hjhhhNhNubhtitle_reference)}(h`void (*callback) (void *)`h]hvoid (*callback) (void *)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is a callback function which will be called when a message with above idx.val is received by the connector core. The argument for that function must be dereferenced to }(hjhhhNhNubj)}(h`struct cn_msg *`h]hstruct cn_msg *}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK&hhhhubj|)}(hXstruct cn_msg { struct cb_id id; __u32 seq; __u32 ack; __u16 len; /* Length of the following data */ __u16 flags; __u8 data[0]; };h]hXstruct cn_msg { struct cb_id id; __u32 seq; __u32 ack; __u16 len; /* Length of the following data */ __u16 flags; __u8 data[0]; };}hjsbah}(h]h ]h"]h$]h&]hhuh1j{hhhK,hhhhubh)}(hhh](h)}(hConnector interfacesh]hConnector interfaces}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK9ubh)}(h.. kernel-doc:: include/linux/connector.h Note: When registering new callback user, connector core assigns netlink group to the user which is equal to its id.idx. h](hindex)}(hhh]h}(h]h ]h"]h$]h&]entries](singlecn_add_callback (C function)c.cn_add_callbackhNtauh1jhjubhdesc)}(hhh](hdesc_signature)}(h}int cn_add_callback (const struct cb_id *id, const char *name, void (*callback)(struct cn_msg *, struct netlink_skb_parms *))h]hdesc_signature_line)}(hzint cn_add_callback(const struct cb_id *id, const char *name, void (*callback)(struct cn_msg*, struct netlink_skb_parms*))h](hdesc_sig_keyword_type)}(hinth]hint}(hjhhhNhNubah}(h]h ]ktah"]h$]h&]uh1jhjhhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKCubhdesc_sig_space)}(h h]h }(hjhhhNhNubah}(h]h ]wah"]h$]h&]uh1jhjhhhjhKCubh desc_name)}(hcn_add_callbackh]h desc_sig_name)}(hcn_add_callbackh]hcn_add_callback}(hj/hhhNhNubah}(h]h ]nah"]h$]h&]uh1j-hj)ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j'hjhhhjhKCubhdesc_parameterlist)}(hg(const struct cb_id *id, const char *name, void (*callback)(struct cn_msg*, struct netlink_skb_parms*))h](hdesc_parameter)}(hconst struct cb_id *idh](hdesc_sig_keyword)}(hconsth]hconst}(hjThhhNhNubah}(h]h ]kah"]h$]h&]uh1jRhjNubj)}(h h]h }(hjchhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjNubjS)}(hstructh]hstruct}(hjqhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjNubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjNubh)}(hhh]j.)}(hcb_idh]hcb_id}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubah}(h]h ]h"]h$]h&] refdomaincreftype identifier reftargetjmodnameN classnameN c:parent_keysphinx.domains.c LookupKey)}data]j ASTIdentifier)}jj1sbc.cn_add_callbackasbuh1hhjNubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjNubhdesc_sig_punctuation)}(h*h]h*}(hjhhhNhNubah}(h]h ]pah"]h$]h&]uh1jhjNubj.)}(hidh]hid}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjNubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjHubjM)}(hconst char *nameh](jS)}(hjVh]hconst}(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubj)}(hcharh]hchar}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubj)}(hjh]h*}(hj(hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj.)}(hnameh]hname}(hj5hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjHubjM)}(h;void (*callback)(struct cn_msg*, struct netlink_skb_parms*)h](j)}(hvoidh]hvoid}(hjNhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj)}(h h]h }(hj\hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjJubj)}(h(h]h(}(hjjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj)}(hjh]h*}(hjxhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj.)}(hcallbackh]hcallback}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjJubj)}(h)h]h)}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj)}(hjlh]h(}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubjS)}(hjsh]hstruct}(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjJubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjJubh)}(hhh]j.)}(hcn_msgh]hcn_msg}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_add_callbackasbuh1hhjJubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj)}(h,h]h,}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjJubjS)}(hjsh]hstruct}(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjJubj)}(h h]h }(hj hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjJubh)}(hhh]j.)}(hnetlink_skb_parmsh]hnetlink_skb_parms}(hj1hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj.ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj3modnameN classnameNjj)}j]jc.cn_add_callbackasbuh1hhjJubj)}(hjh]h*}(hjOhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubj)}(hjh]h)}(hj\hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjJubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjHubeh}(h]h ]h"]h$]h&]hhuh1jFhjhhhjhKCubeh}(h]h ]h"]h$]h&]hh add_permalinkuh1jsphinx_line_type declaratorhjhhhjhKCubah}(h]jah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1jhjhKChjhhubh desc_content)}(hhh]h)}(h+Registers new callback with connector core.h]h+Registers new callback with connector core.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK:hjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKCubeh}(h]h ](jfunctioneh"]h$]h&]domainjobjtypejdesctypejnoindex noindexentrynocontentsentryuh1jhhhjubh container)}(hXd**Parameters** ``const struct cb_id *id`` unique connector's user identifier. It must be registered in connector.h for legal in-kernel users. ``const char *name`` connector's callback symbolic name. ``void (*callback)(struct cn_msg *, struct netlink_skb_parms *)`` connector's callback. parameters are ``cn_msg`` and the sender's credentialsh](h)}(h**Parameters**h]hstrong)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK>hjubhdefinition_list)}(hhh](hdefinition_list_item)}(h``const struct cb_id *id`` unique connector's user identifier. It must be registered in connector.h for legal in-kernel users. h](hterm)}(h``const struct cb_id *id``h]hliteral)}(hjh]hconst struct cb_id *id}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK>hjubh definition)}(hhh]h)}(hcunique connector's user identifier. It must be registered in connector.h for legal in-kernel users.h]heunique connector’s user identifier. It must be registered in connector.h for legal in-kernel users.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKhjubj)}(h9``const char *name`` connector's callback symbolic name. h](j)}(h``const char *name``h]j)}(hjh]hconst char *name}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK?hjubj)}(hhh]h)}(h#connector's callback symbolic name.h]h%connector’s callback symbolic name.}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj3hK?hj4ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj3hK?hjubj)}(h``void (*callback)(struct cn_msg *, struct netlink_skb_parms *)`` connector's callback. parameters are ``cn_msg`` and the sender's credentialsh](j)}(hA``void (*callback)(struct cn_msg *, struct netlink_skb_parms *)``h]j)}(hjWh]h=void (*callback)(struct cn_msg *, struct netlink_skb_parms *)}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjUubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK@hjQubj)}(hhh]h)}(hLconnector's callback. parameters are ``cn_msg`` and the sender's credentialsh](h'connector’s callback. parameters are }(hjphhhNhNubj)}(h ``cn_msg``h]hcn_msg}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjpubh and the sender’s credentials}(hjphhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjlhK@hjmubah}(h]h ]h"]h$]h&]uh1jhjQubeh}(h]h ]h"]h$]h&]uh1jhjlhK@hjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jcn_del_callback (C function)c.cn_del_callbackhNtauh1jhjubj)}(hhh](j)}(h-void cn_del_callback (const struct cb_id *id)h]j)}(h,void cn_del_callback(const struct cb_id *id)h](j)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKJubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjhhhjhKJubj()}(hcn_del_callbackh]j.)}(hcn_del_callbackh]hcn_del_callback}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubah}(h]h ](jAjBeh"]h$]h&]hhuh1j'hjhhhjhKJubjG)}(h(const struct cb_id *id)h]jM)}(hconst struct cb_id *idh](jS)}(hjVh]hconst}(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubj)}(h h]h }(hj hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubjS)}(hjsh]hstruct}(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubj)}(h h]h }(hj'hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubh)}(hhh]j.)}(hcb_idh]hcb_id}(hj8hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj5ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj:modnameN classnameNjj)}j]j)}jjsbc.cn_del_callbackasbuh1hhjubj)}(h h]h }(hjXhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubj)}(hjh]h*}(hjfhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj.)}(hidh]hid}(hjshhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjubah}(h]h ]h"]h$]h&]hhuh1jFhjhhhjhKJubeh}(h]h ]h"]h$]h&]hhj|uh1jj}j~hjhhhjhKJubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhjhKJhjhhubj)}(hhh]h)}(h-Unregisters new callback with connector core.h]h-Unregisters new callback with connector core.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKFhjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKJubeh}(h]h ](jfunctioneh"]h$]h&]jjjjjjjjjuh1jhhhjubj)}(hP**Parameters** ``const struct cb_id *id`` unique connector's user identifier.h](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKJhjubj)}(hhh]j)}(h>``const struct cb_id *id`` unique connector's user identifier.h](j)}(h``const struct cb_id *id``h]j)}(hjh]hconst struct cb_id *id}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKLhjubj)}(hhh]h)}(h#unique connector's user identifier.h]h%unique connector’s user identifier.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKHhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKLhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j!cn_netlink_send_mult (C function)c.cn_netlink_send_multhNtauh1jhjubj)}(hhh](j)}(hint cn_netlink_send_mult (struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask, netlink_filter_fn filter, void *filter_data)h]j)}(hint cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask, netlink_filter_fn filter, void *filter_data)h](j)}(hinth]hint}(hj8hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj4hhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKeubj)}(h h]h }(hjGhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhj4hhhjFhKeubj()}(hcn_netlink_send_multh]j.)}(hcn_netlink_send_multh]hcn_netlink_send_mult}(hjYhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjUubah}(h]h ](jAjBeh"]h$]h&]hhuh1j'hj4hhhjFhKeubjG)}(hq(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask, netlink_filter_fn filter, void *filter_data)h](jM)}(hstruct cn_msg *msgh](jS)}(hjsh]hstruct}(hjuhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjqubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjqubh)}(hhh]j.)}(hcn_msgh]hcn_msg}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]j)}jj[sbc.cn_netlink_send_multasbuh1hhjqubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjqubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjqubj.)}(hmsgh]hmsg}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjqubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubjM)}(hu16 lenh](h)}(hhh]j.)}(hu16h]hu16}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubj.)}(hlenh]hlen}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubjM)}(h u32 portidh](h)}(hhh]j.)}(hu32h]hu32}(hj2hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj/ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj4modnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhj+ubj)}(h h]h }(hjPhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhj+ubj.)}(hportidh]hportid}(hj^hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj+ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubjM)}(h u32 grouph](h)}(hhh]j.)}(hu32h]hu32}(hjzhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjwubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj|modnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjsubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjsubj.)}(hgrouph]hgroup}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjsubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubjM)}(hgfp_t gfp_maskh](h)}(hhh]j.)}(hgfp_th]hgfp_t}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjubj.)}(hgfp_maskh]hgfp_mask}(hjhhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubjM)}(hnetlink_filter_fn filterh](h)}(hhh]j.)}(hnetlink_filter_fnh]hnetlink_filter_fn}(hj hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhj ubj)}(h h]h }(hj( hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhj ubj.)}(hfilterh]hfilter}(hj6 hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubjM)}(hvoid *filter_datah](j)}(hvoidh]hvoid}(hjO hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjK ubj)}(h h]h }(hj] hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjK ubj)}(hjh]h*}(hjk hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjK ubj.)}(h filter_datah]h filter_data}(hjx hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjK ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjmubeh}(h]h ]h"]h$]h&]hhuh1jFhj4hhhjFhKeubeh}(h]h ]h"]h$]h&]hhj|uh1jj}j~hj0hhhjFhKeubah}(h]j+ah ](jjeh"]h$]h&]jj)jhuh1jhjFhKehj-hhubj)}(hhh]h)}(h&Sends message to the specified groups.h]h&Sends message to the specified groups.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKNhj hhubah}(h]h ]h"]h$]h&]uh1jhj-hhhjFhKeubeh}(h]h ](jfunctioneh"]h$]h&]jjjj jj jjjuh1jhhhjubj)}(hX**Parameters** ``struct cn_msg *msg`` message header(with attached data). ``u16 len`` Number of **msg** to be sent. ``u32 portid`` destination port. If non-zero the message will be sent to the given port, which should be set to the original sender. ``u32 group`` destination group. If **portid** and **group** is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in **msg**. If **group** is not zero, then message will be delivered to the specified group. ``gfp_t gfp_mask`` GFP mask. ``netlink_filter_fn filter`` Filter function to be used at netlink layer. ``void *filter_data`` Filter data to be supplied to the filter function **Description** It can be safely called from softirq context, but may silently fail under strong memory pressure. If there are no listeners for given group ``-ESRCH`` can be returned.h](h)}(h**Parameters**h]j)}(hj h]h Parameters}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKRhj ubj)}(hhh](j)}(h;``struct cn_msg *msg`` message header(with attached data). h](j)}(h``struct cn_msg *msg``h]j)}(hj h]hstruct cn_msg *msg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKPhj ubj)}(hhh]h)}(h#message header(with attached data).h]h#message header(with attached data).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKPhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKPhj ubj)}(h*``u16 len`` Number of **msg** to be sent. h](j)}(h ``u16 len``h]j)}(hj h]hu16 len}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKQhj ubj)}(hhh]h)}(hNumber of **msg** to be sent.h](h Number of }(hj5 hhhNhNubj)}(h**msg**h]hmsg}(hj= hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj5 ubh to be sent.}(hj5 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhj1 hKQhj2 ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj1 hKQhj ubj)}(h``u32 portid`` destination port. If non-zero the message will be sent to the given port, which should be set to the original sender. h](j)}(h``u32 portid``h]j)}(hjg h]h u32 portid}(hji hhhNhNubah}(h]h ]h"]h$]h&]uh1jhje ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKThja ubj)}(hhh]h)}(hudestination port. If non-zero the message will be sent to the given port, which should be set to the original sender.h]hudestination port. If non-zero the message will be sent to the given port, which should be set to the original sender.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKRhj} ubah}(h]h ]h"]h$]h&]uh1jhja ubeh}(h]h ]h"]h$]h&]uh1jhj| hKThj ubj)}(hXM``u32 group`` destination group. If **portid** and **group** is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in **msg**. If **group** is not zero, then message will be delivered to the specified group. h](j)}(h ``u32 group``h]j)}(hj h]h u32 group}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK[hj ubj)}(hhh]h)}(hX>destination group. If **portid** and **group** is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in **msg**. If **group** is not zero, then message will be delivered to the specified group.h](hdestination group. If }(hj hhhNhNubj)}(h **portid**h]hportid}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh and }(hj hhhNhNubj)}(h **group**h]hgroup}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in }(hj hhhNhNubj)}(h**msg**h]hmsg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. If }(hj hhhNhNubj)}(h **group**h]hgroup}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhD is not zero, then message will be delivered to the specified group.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKUhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hK[hj ubj)}(h``gfp_t gfp_mask`` GFP mask. h](j)}(h``gfp_t gfp_mask``h]j)}(hj# h]hgfp_t gfp_mask}(hj% hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj! ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK\hj ubj)}(hhh]h)}(h GFP mask.h]h GFP mask.}(hj< hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj8 hK\hj9 ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj8 hK\hj ubj)}(hJ``netlink_filter_fn filter`` Filter function to be used at netlink layer. h](j)}(h``netlink_filter_fn filter``h]j)}(hj\ h]hnetlink_filter_fn filter}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjZ ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK]hjV ubj)}(hhh]h)}(h,Filter function to be used at netlink layer.h]h,Filter function to be used at netlink layer.}(hju hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjq hK]hjr ubah}(h]h ]h"]h$]h&]uh1jhjV ubeh}(h]h ]h"]h$]h&]uh1jhjq hK]hj ubj)}(hH``void *filter_data`` Filter data to be supplied to the filter function h](j)}(h``void *filter_data``h]j)}(hj h]hvoid *filter_data}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK^hj ubj)}(hhh]h)}(h1Filter data to be supplied to the filter functionh]h1Filter data to be supplied to the filter function}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hK^hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hK^hj ubeh}(h]h ]h"]h$]h&]uh1jhj ubh)}(h**Description**h]j)}(hj h]h Description}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK`hj ubh)}(haIt can be safely called from softirq context, but may silently fail under strong memory pressure.h]haIt can be safely called from softirq context, but may silently fail under strong memory pressure.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK`hj ubh)}(hEIf there are no listeners for given group ``-ESRCH`` can be returned.h](h*If there are no listeners for given group }(hj hhhNhNubj)}(h ``-ESRCH``h]h-ESRCH}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh can be returned.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKchj ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jcn_netlink_send (C function)c.cn_netlink_sendhNtauh1jhjubj)}(hhh](j)}(hOint cn_netlink_send (struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask)h]j)}(hNint cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask)h](j)}(hinth]hint}(hj6 hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj2 hhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKubj)}(h h]h }(hjE hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhj2 hhhjD hKubj()}(hcn_netlink_sendh]j.)}(hcn_netlink_sendh]hcn_netlink_send}(hjW hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjS ubah}(h]h ](jAjBeh"]h$]h&]hhuh1j'hj2 hhhjD hKubjG)}(h;(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask)h](jM)}(hstruct cn_msg *msgh](jS)}(hjsh]hstruct}(hjs hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjo ubj)}(h h]h }(hj hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjo ubh)}(hhh]j.)}(hcn_msgh]hcn_msg}(hj hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j)}jjY sbc.cn_netlink_sendasbuh1hhjo ubj)}(h h]h }(hj hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjo ubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjo ubj.)}(hmsgh]hmsg}(hj hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjo ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjk ubjM)}(h u32 portidh](h)}(hhh]j.)}(hu32h]hu32}(hj hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhj ubj)}(h h]h }(hj hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhj ubj.)}(hportidh]hportid}(hj hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjk ubjM)}(h u32 grouph](h)}(hhh]j.)}(hu32h]hu32}(hj0 hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj- ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj2 modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhj) ubj)}(h h]h }(hjN hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhj) ubj.)}(hgrouph]hgroup}(hj\ hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hj) ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjk ubjM)}(hgfp_t gfp_maskh](h)}(hhh]j.)}(hgfp_th]hgfp_t}(hjx hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hju ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjz modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhjq ubj)}(h h]h }(hj hhhNhNubah}(h]h ]j#ah"]h$]h&]uh1jhjq ubj.)}(hgfp_maskh]hgfp_mask}(hj hhhNhNubah}(h]h ]j:ah"]h$]h&]uh1j-hjq ubeh}(h]h ]h"]h$]h&]noemphhhuh1jLhjk ubeh}(h]h ]h"]h$]h&]hhuh1jFhj2 hhhjD hKubeh}(h]h ]h"]h$]h&]hhj|uh1jj}j~hj. hhhjD hKubah}(h]j) ah ](jjeh"]h$]h&]jj)jhuh1jhjD hKhj+ hhubj)}(hhh]h)}(h&Sends message to the specified groups.h]h&Sends message to the specified groups.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKkhj hhubah}(h]h ]h"]h$]h&]uh1jhj+ hhhjD hKubeh}(h]h ](jfunctioneh"]h$]h&]jjjj jj jjjuh1jhhhjubj)}(hX**Parameters** ``struct cn_msg *msg`` message header(with attached data). ``u32 portid`` destination port. If non-zero the message will be sent to the given port, which should be set to the original sender. ``u32 group`` destination group. If **portid** and **group** is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in **msg**. If **group** is not zero, then message will be delivered to the specified group. ``gfp_t gfp_mask`` GFP mask. **Description** It can be safely called from softirq context, but may silently fail under strong memory pressure. If there are no listeners for given group ``-ESRCH`` can be returned.h](h)}(h**Parameters**h]j)}(hj h]h Parameters}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKohj ubj)}(hhh](j)}(h;``struct cn_msg *msg`` message header(with attached data). h](j)}(h``struct cn_msg *msg``h]j)}(hjh]hstruct cn_msg *msg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKmhj ubj)}(hhh]h)}(h#message header(with attached data).h]h#message header(with attached data).}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$hKmhj%ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj$hKmhjubj)}(h``u32 portid`` destination port. If non-zero the message will be sent to the given port, which should be set to the original sender. h](j)}(h``u32 portid``h]j)}(hjHh]h u32 portid}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjFubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKphjBubj)}(hhh]h)}(hudestination port. If non-zero the message will be sent to the given port, which should be set to the original sender.h]hudestination port. If non-zero the message will be sent to the given port, which should be set to the original sender.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKnhj^ubah}(h]h ]h"]h$]h&]uh1jhjBubeh}(h]h ]h"]h$]h&]uh1jhj]hKphjubj)}(hXM``u32 group`` destination group. If **portid** and **group** is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in **msg**. If **group** is not zero, then message will be delivered to the specified group. h](j)}(h ``u32 group``h]j)}(hjh]h u32 group}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKwhj|ubj)}(hhh]h)}(hX>destination group. If **portid** and **group** is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in **msg**. If **group** is not zero, then message will be delivered to the specified group.h](hdestination group. If }(hjhhhNhNubj)}(h **portid**h]hportid}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(hjhhhNhNubj)}(h **group**h]hgroup}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is zero, then appropriate group will be searched through all registered connector users, and message will be delivered to the group which was created for user with the same ID as in }(hjhhhNhNubj)}(h**msg**h]hmsg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. If }(hjhhhNhNubj)}(h **group**h]hgroup}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhD is not zero, then message will be delivered to the specified group.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKqhjubah}(h]h ]h"]h$]h&]uh1jhj|ubeh}(h]h ]h"]h$]h&]uh1jhjhKwhjubj)}(h``gfp_t gfp_mask`` GFP mask. h](j)}(h``gfp_t gfp_mask``h]j)}(hjh]hgfp_t gfp_mask}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKxhjubj)}(hhh]h)}(h GFP mask.h]h GFP mask.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKxhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKxhjubeh}(h]h ]h"]h$]h&]uh1jhj ubh)}(h**Description**h]j)}(hj?h]h Description}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKzhj ubh)}(haIt can be safely called from softirq context, but may silently fail under strong memory pressure.h]haIt can be safely called from softirq context, but may silently fail under strong memory pressure.}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKzhj ubh)}(hEIf there are no listeners for given group ``-ESRCH`` can be returned.h](h*If there are no listeners for given group }(hjdhhhNhNubj)}(h ``-ESRCH``h]h-ESRCH}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjdubh can be returned.}(hjdhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK}hj ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjubj)}(hhh]j)}(hyNote: When registering new callback user, connector core assigns netlink group to the user which is equal to its id.idx. h](j)}(hNote:h]hNote:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK?hjubj)}(hhh]h)}(hrWhen registering new callback user, connector core assigns netlink group to the user which is equal to its id.idx.h]hrWhen registering new callback user, connector core assigns netlink group to the user which is equal to its id.idx.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK>hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK?hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhK;hjhhubeh}(h]connector-interfacesah ]h"]connector interfacesah$]h&]uh1hhhhhhhhK9ubh)}(hhh](h)}(hProtocol descriptionh]hProtocol description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKBubh)}(hThe current framework offers a transport layer with fixed headers. The recommended protocol which uses such a header is as following:h]hThe current framework offers a transport layer with fixed headers. The recommended protocol which uses such a header is as following:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjhhubh)}(hmsg->seq and msg->ack are used to determine message genealogy. When someone sends a message, they use a locally unique sequence and random acknowledge number. The sequence number may be copied into nlmsghdr->nlmsg_seq too.h]hmsg->seq and msg->ack are used to determine message genealogy. When someone sends a message, they use a locally unique sequence and random acknowledge number. The sequence number may be copied into nlmsghdr->nlmsg_seq too.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjhhubh)}(h:The sequence number is incremented with each message sent.h]h:The sequence number is incremented with each message sent.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjhhubh)}(hIf you expect a reply to the message, then the sequence number in the received message MUST be the same as in the original message, and the acknowledge number MUST be the same + 1.h]hIf you expect a reply to the message, then the sequence number in the received message MUST be the same as in the original message, and the acknowledge number MUST be the same + 1.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKNhjhhubh)}(hX4If we receive a message and its sequence number is not equal to one we are expecting, then it is a new message. If we receive a message and its sequence number is the same as one we are expecting, but its acknowledge is not equal to the sequence number in the original message + 1, then it is a new message.h]hX4If we receive a message and its sequence number is not equal to one we are expecting, then it is a new message. If we receive a message and its sequence number is the same as one we are expecting, but its acknowledge is not equal to the sequence number in the original message + 1, then it is a new message.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKRhjhhubh)}(h5Obviously, the protocol header contains the above id.h]h5Obviously, the protocol header contains the above id.}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKXhjhhubh)}(hXDThe connector allows event notification in the following form: kernel driver or userspace process can ask connector to notify it when selected ids will be turned on or off (registered or unregistered its callback). It is done by sending a special command to the connector driver (it also registers itself with id={-1, -1}).h]hXDThe connector allows event notification in the following form: kernel driver or userspace process can ask connector to notify it when selected ids will be turned on or off (registered or unregistered its callback). It is done by sending a special command to the connector driver (it also registers itself with id={-1, -1}).}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKZhjhhubh)}(hAs example of this usage can be found in the cn_test.c module which uses the connector to request notification and to send messages.h]hAs example of this usage can be found in the cn_test.c module which uses the connector to request notification and to send messages.}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjhhubeh}(h]protocol-descriptionah ]h"]protocol descriptionah$]h&]uh1hhhhhhhhKBubh)}(hhh](h)}(h Reliabilityh]h Reliability}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj[hhhhhKdubh)}(hX#Netlink itself is not a reliable protocol. That means that messages can be lost due to memory pressure or process' receiving queue overflowed, so caller is warned that it must be prepared. That is why the struct cn_msg [main connector's message header] contains u32 seq and u32 ack fields.h]hX'Netlink itself is not a reliable protocol. That means that messages can be lost due to memory pressure or process’ receiving queue overflowed, so caller is warned that it must be prepared. That is why the struct cn_msg [main connector’s message header] contains u32 seq and u32 ack fields.}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhj[hhubeh}(h] reliabilityah ]h"] reliabilityah$]h&]uh1hhhhhhhhKdubh)}(hhh](h)}(hUserspace usageh]hUserspace usage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKmubh)}(hXX2.6.14 has a new netlink socket implementation, which by default does not allow people to send data to netlink groups other than 1. So, if you wish to use a netlink socket (for example using connector) with a different group number, the userspace application must subscribe to that group first. It can be achieved by the following pseudocode::h]hXW2.6.14 has a new netlink socket implementation, which by default does not allow people to send data to netlink groups other than 1. So, if you wish to use a netlink socket (for example using connector) with a different group number, the userspace application must subscribe to that group first. It can be achieved by the following pseudocode:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjhhubj|)}(hXcs = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); l_local.nl_family = AF_NETLINK; l_local.nl_groups = 12345; l_local.nl_pid = 0; if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { perror("bind"); close(s); return -1; } { int on = l_local.nl_groups; setsockopt(s, 270, 1, &on, sizeof(on)); }h]hXcs = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); l_local.nl_family = AF_NETLINK; l_local.nl_groups = 12345; l_local.nl_pid = 0; if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { perror("bind"); close(s); return -1; } { int on = l_local.nl_groups; setsockopt(s, 270, 1, &on, sizeof(on)); }}hjsbah}(h]h ]h"]h$]h&]hhuh1j{hhhKuhjhhubh)}(hWhere 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket option. To drop a multicast subscription, one should call the above socket option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.h]hWhere 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket option. To drop a multicast subscription, one should call the above socket option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXm2.6.14 netlink code only allows to select a group which is less or equal to the maximum group number, which is used at netlink_kernel_create() time. In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use group number 12345, you must increment CN_NETLINK_USERS to that number. Additional 0xf numbers are allocated to be used by non-in-kernel users.h]hXm2.6.14 netlink code only allows to select a group which is less or equal to the maximum group number, which is used at netlink_kernel_create() time. In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use group number 12345, you must increment CN_NETLINK_USERS to that number. Additional 0xf numbers are allocated to be used by non-in-kernel users.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hDue to this limitation, group 0xffffffff does not work now, so one can not use add/remove connector's group notifications, but as far as I know, only cn_test.c test module used it.h]hDue to this limitation, group 0xffffffff does not work now, so one can not use add/remove connector’s group notifications, but as far as I know, only cn_test.c test module used it.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hSome work in netlink area is still being done, so things can be changed in 2.6.15 timeframe, if it will happen, documentation will be updated for that kernel.h]hSome work in netlink area is still being done, so things can be changed in 2.6.15 timeframe, if it will happen, documentation will be updated for that kernel.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]userspace-usageah ]h"]userspace usageah$]h&]uh1hhhhhhhhKmubh)}(hhh](h)}(h Code samplesh]h Code samples}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hSample code for a connector test module and user space can be found in samples/connector/. To build this code, enable CONFIG_CONNECTOR and CONFIG_SAMPLES.h]hSample code for a connector test module and user space can be found in samples/connector/. To build this code, enable CONFIG_CONNECTOR and CONFIG_SAMPLES.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h] code-samplesah ]h"] code samplesah$]h&]uh1hhhhhhhhKubeh}(h]kernel-connectorah ]h"]kernel connectorah$]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_handlerjAerror_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}(jjjjjXjUjj|jjjju nametypes}(jjjXjjjuh}(jhjjjjjjj+j0j) j. jUjj|j[jjjju 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.