ssphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}(hhparenthuba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget(/translations/zh_CN/driver-api/connectormodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}(hhhh2ubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/zh_TW/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}(hhhhFubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/it_IT/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}(hhhhZubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/ja_JP/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}(hhhhnubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/ko_KR/driver-api/connectormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}(hhhhubah}(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}(hhhhubah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhB/var/lib/git/docbuild/linux/Documentation/driver-api/connector.rsthKubhsection)}(hhh](htitle)}(hKernel Connectorh]hKernel Connector}(hhhhhhhNhNubah}(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.}(hhhhhhhNhNubah}(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.}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hFrom the userspace point of view it’s quite straightforward:}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh block_quote)}(hhh]h bullet_list)}(hhh](h list_item)}(h socket();h]h)}(hjh]h socket();}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhubj)}(hbind();h]h)}(hjh]hbind();}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhubj)}(hsend();h]h)}(hj1h]hsend();}(hj1hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj/ubah}(h]h ]h"]h$]h&]uh1hhhubj)}(hrecv(); h]h)}(hrecv();h]hrecv();}(hjLhjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjFubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhNhNubh)}(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:}(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:hjlhhhNhNubah}(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; };}(hhhj}ubah}(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. }(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 *)}(hhhjhhhNhNubah}(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 }(h 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 *}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(h: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]; };}(hhhjubah}(h]h ]h"]h$]h&]hhuh1j{hhhK,hhhhubh)}(hhh](h)}(hConnector interfacesh]hConnector interfaces}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK9ubh)}(hhh](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}(hhhjhhhNhNubah}(h]h ]ktah"]h$]h&]uh1jhjhhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK;ubhdesc_sig_space)}(h h]h }(hhhjhhhNhNubah}(h]h ]wah"]h$]h&]uh1jhjhhhjhK;ubh desc_name)}(hcn_add_callbackh]h desc_sig_name)}(hcn_add_callbackh]hcn_add_callback}(hhhj1hhhNhNubah}(h]h ]nah"]h$]h&]uh1j/hj+ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j)hjhhhjhK;ubhdesc_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}(hhhjVhhhNhNubah}(h]h ]kah"]h$]h&]uh1jThjPubj)}(h h]h }(hhhjehhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjPubjU)}(hstructh]hstruct}(hhhjshhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjPubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjPubh)}(hhh]j0)}(hcb_idh]hcb_id}(hhhjhhhNhNubah}(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)}jj3sbc.cn_add_callbackasbuh1hhjPubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjPubhdesc_sig_punctuation)}(h*h]h*}(hhhjhhhNhNubah}(h]h ]pah"]h$]h&]uh1jhjPubj0)}(hidh]hid}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjPubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjJubjO)}(hconst char *nameh](jU)}(hjXh]hconst}(hhhjhhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj)}(hcharh]hchar}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj)}(hjh]h*}(hhhj*hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj0)}(hnameh]hname}(hhhj7hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjJubjO)}(h;void (*callback)(struct cn_msg*, struct netlink_skb_parms*)h](j)}(hvoidh]hvoid}(hhhjPhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(h h]h }(hhhj^hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjLubj)}(h(h]h(}(hhhjlhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(hjh]h*}(hhhjzhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj0)}(hcallbackh]hcallback}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjLubj)}(h)h]h)}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(hjnh]h(}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubjU)}(hjuh]hstruct}(hhhjhhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjLubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjLubh)}(hhh]j0)}(hcn_msgh]hcn_msg}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_add_callbackasbuh1hhjLubj)}(hjh]h*}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(h,h]h,}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjLubjU)}(hjuh]hstruct}(hhhjhhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjLubj)}(h h]h }(hhhj"hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjLubh)}(hhh]j0)}(hnetlink_skb_parmsh]hnetlink_skb_parms}(hhhj3hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj0ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj5modnameN classnameNjj)}j]jc.cn_add_callbackasbuh1hhjLubj)}(hjh]h*}(hhhjQhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(hjh]h)}(hhhj^hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjJubeh}(h]h ]h"]h$]h&]hhuh1jHhjhhhjhK;ubeh}(h]h ]h"]h$]h&]hh add_permalinkuh1jsphinx_line_type declaratorhjhhhjhK;ubah}(h]jah ](sig sig-objecteh"]h$]h&] is_multilineuh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKChjhhubh desc_content)}(hhh]h)}(h+Registers new callback with connector core.h]h+Registers new callback with connector core.}(hjhjhhhNhNubah}(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&]uh1jhjhhhjhK;ubeh}(h]h ](jfunctioneh"]h$]h&]domainjobjtypejdesctypejnoindexuh1jhhhjubh 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}(hhhjhhhNhNubah}(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}(hhhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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}(hhhjhhhNhNubah}(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.}(hj8hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj2hK?hj3ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj2hK?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)}(hjVh]h=void (*callback)(struct cn_msg *, struct netlink_skb_parms *)}(hhhjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK@hjPubj)}(hhh]h)}(hLconnector's callback. parameters are ``cn_msg`` and the sender's credentialsh](h'connector’s callback. parameters are }(h%connector's callback. parameters are hjohhhNhNubj)}(h ``cn_msg``h]hcn_msg}(hhhjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjoubh and the sender’s credentials}(h and the sender's credentialshjohhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjkhK@hjlubah}(h]h ]h"]h$]h&]uh1jhjPubeh}(h]h ]h"]h$]h&]uh1jhjkhK@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}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKGubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjhhhjhKGubj*)}(hcn_del_callbackh]j0)}(hcn_del_callbackh]hcn_del_callback}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubah}(h]h ](jCjDeh"]h$]h&]hhuh1j)hjhhhjhKGubjI)}(h(const struct cb_id *id)h]jO)}(hconst struct cb_id *idh](jU)}(hjXh]hconst}(hhhjhhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjubj)}(h h]h }(hhhj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubjU)}(hjuh]hstruct}(hhhjhhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjubj)}(h h]h }(hhhj(hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubh)}(hhh]j0)}(hcb_idh]hcb_id}(hhhj9hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj6ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj;modnameN classnameNjj)}j]j)}jjsbc.cn_del_callbackasbuh1hhjubj)}(h h]h }(hhhjYhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj)}(hjh]h*}(hhhjghhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj0)}(hidh]hid}(hhhjthhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjubah}(h]h ]h"]h$]h&]hhuh1jHhjhhhjhKGubeh}(h]h ]h"]h$]h&]hhj~uh1jjjhjhhhjhKGubah}(h]jah ](jjeh"]h$]h&]juh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKJhjhhubj)}(hhh]h)}(h-Unregisters new callback with connector core.h]h-Unregisters new callback with connector core.}(hjhjhhhNhNubah}(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&]uh1jhjhhhjhKGubeh}(h]h ](jfunctioneh"]h$]h&]jjjjjjjuh1jhhhjubj)}(hP**Parameters** ``const struct cb_id *id`` unique connector's user identifier.h](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hhhjhhhNhNubah}(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}(hhhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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}(hhhj:hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj6hhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKOubj)}(h h]h }(hhhjIhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj6hhhjHhKOubj*)}(hcn_netlink_send_multh]j0)}(hcn_netlink_send_multh]hcn_netlink_send_mult}(hhhj[hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjWubah}(h]h ](jCjDeh"]h$]h&]hhuh1j)hj6hhhjHhKOubjI)}(hq(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask, netlink_filter_fn filter, void *filter_data)h](jO)}(hstruct cn_msg *msgh](jU)}(hjuh]hstruct}(hhhjwhhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThjsubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjsubh)}(hhh]j0)}(hcn_msgh]hcn_msg}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]j)}jj]sbc.cn_netlink_send_multasbuh1hhjsubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjsubj)}(hjh]h*}(hhhjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjsubj0)}(hmsgh]hmsg}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjsubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubjO)}(hu16 lenh](h)}(hhh]j0)}(hu16h]hu16}(hhhjhhhNhNubah}(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 }(hhhj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj0)}(hlenh]hlen}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubjO)}(h u32 portidh](h)}(hhh]j0)}(hu32h]hu32}(hhhj4hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj1ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj6modnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhj-ubj)}(h h]h }(hhhjRhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj-ubj0)}(hportidh]hportid}(hhhj`hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj-ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubjO)}(h u32 grouph](h)}(hhh]j0)}(hu32h]hu32}(hhhj|hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjyubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj~modnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjuubj)}(h h]h }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjuubj0)}(hgrouph]hgroup}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjuubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubjO)}(hgfp_t gfp_maskh](h)}(hhh]j0)}(hgfp_th]hgfp_t}(hhhjhhhNhNubah}(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 }(hhhjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj0)}(hgfp_maskh]hgfp_mask}(hhhjhhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubjO)}(hnetlink_filter_fn filterh](h)}(hhh]j0)}(hnetlink_filter_fnh]hnetlink_filter_fn}(hhhj 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 }(hhhj* hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj ubj0)}(hfilterh]hfilter}(hhhj8 hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubjO)}(hvoid *filter_datah](j)}(hvoidh]hvoid}(hhhjQ hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjM ubj)}(h h]h }(hhhj_ hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjM ubj)}(hjh]h*}(hhhjm hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjM ubj0)}(h filter_datah]h filter_data}(hhhjz hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hjM ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjoubeh}(h]h ]h"]h$]h&]hhuh1jHhj6hhhjHhKOubeh}(h]h ]h"]h$]h&]hhj~uh1jjjhj2hhhjHhKOubah}(h]j-ah ](jjeh"]h$]h&]juh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKehj/hhubj)}(hhh]h)}(h&Sends message to the specified groups.h]h&Sends message to the specified groups.}(hj 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/hhhjHhKOubeh}(h]h ](jfunctioneh"]h$]h&]jjjj jj juh1jhhhjubj)}(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}(hhhj 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}(hhhj 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 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}(hhhj! 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 }(h Number of hj8 hhhNhNubj)}(h**msg**h]hmsg}(hhhjA hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj8 ubh to be sent.}(h to be sent.hj8 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhj4 hKQhj5 ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj4 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)}(hjl h]h u32 portid}(hhhjn hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjj ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKThjf 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 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&]uh1jhjf 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}(hhhj 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 }(hdestination group. If hj hhhNhNubj)}(h **portid**h]hportid}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh and }(h and hj hhhNhNubj)}(h **group**h]hgroup}(hhhj 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 }(h 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}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. If }(h. If hj hhhNhNubj)}(h **group**h]hgroup}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhD is not zero, then message will be delivered to the specified group.}(hD 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}(hhhj/ 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.}(hjH hjF hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjB hK\hjC ubah}(h]h ]h"]h$]h&]uh1jhj' ubeh}(h]h ]h"]h$]h&]uh1jhjB 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)}(hjf h]hnetlink_filter_fn filter}(hhhjh hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjd 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,Filter function to be used at netlink layer.h]h,Filter function to be used at netlink layer.}(hj 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 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}(hhhj 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 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}(hhhj 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 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 }(h*If there are no listeners for given group hj hhhNhNubj)}(h ``-ESRCH``h]h-ESRCH}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh can be returned.}(h 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}(hhhjB hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj> hhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKlubj)}(h h]h }(hhhjQ hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj> hhhjP hKlubj*)}(hcn_netlink_sendh]j0)}(hcn_netlink_sendh]hcn_netlink_send}(hhhjc hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj_ ubah}(h]h ](jCjDeh"]h$]h&]hhuh1j)hj> hhhjP hKlubjI)}(h;(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask)h](jO)}(hstruct cn_msg *msgh](jU)}(hjuh]hstruct}(hhhj hhhNhNubah}(h]h ]jaah"]h$]h&]uh1jThj{ ubj)}(h h]h }(hhhj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj{ ubh)}(hhh]j0)}(hcn_msgh]hcn_msg}(hhhj hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j)}jje sbc.cn_netlink_sendasbuh1hhj{ ubj)}(h h]h }(hhhj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj{ ubj)}(hjh]h*}(hhhj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj{ ubj0)}(hmsgh]hmsg}(hhhj hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj{ ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjw ubjO)}(h u32 portidh](h)}(hhh]j0)}(hu32h]hu32}(hhhj 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 }(hhhj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj ubj0)}(hportidh]hportid}(hhhj hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjw ubjO)}(h u32 grouph](h)}(hhh]j0)}(hu32h]hu32}(hhhj< hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj9 ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj> modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhj5 ubj)}(h h]h }(hhhjZ hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj5 ubj0)}(hgrouph]hgroup}(hhhjh hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj5 ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjw ubjO)}(hgfp_t gfp_maskh](h)}(hhh]j0)}(hgfp_th]hgfp_t}(hhhj 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 }(hhhj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj} ubj0)}(hgfp_maskh]hgfp_mask}(hhhj hhhNhNubah}(h]h ]j<ah"]h$]h&]uh1j/hj} ubeh}(h]h ]h"]h$]h&]noemphhhuh1jNhjw ubeh}(h]h ]h"]h$]h&]hhuh1jHhj> hhhjP hKlubeh}(h]h ]h"]h$]h&]hhj~uh1jjjhj: hhhjP hKlubah}(h]j5 ah ](jjeh"]h$]h&]juh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKhj7 hhubj)}(hhh]h)}(h&Sends message to the specified groups.h]h&Sends message to the specified groups.}(hj 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&]uh1jhj7 hhhjP hKlubeh}(h]h ](jfunctioneh"]h$]h&]jjjj jj juh1jhhhjubj)}(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}(hhhj 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}(hhhjhhhNhNubah}(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.hhKmhjubj)}(hhh]h)}(h#message header(with attached data).h]h#message header(with attached data).}(hj7hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj1hKmhj2ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj1hKmhjubj)}(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)}(hjUh]h u32 portid}(hhhjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjSubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKphjOubj)}(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.}(hjphjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKnhjkubah}(h]h ]h"]h$]h&]uh1jhjOubeh}(h]h ]h"]h$]h&]uh1jhjjhKphjubj)}(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}(hhhjhhhNhNubah}(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.hhKwhjubj)}(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 }(hdestination group. If hjhhhNhNubj)}(h **portid**h]hportid}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(h and hjhhhNhNubj)}(h **group**h]hgroup}(hhhjhhhNhNubah}(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 }(h 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}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. If }(h. If hjhhhNhNubj)}(h **group**h]hgroup}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhD is not zero, then message will be delivered to the specified group.}(hD 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&]uh1jhjubeh}(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}(hhhjhhhNhNubah}(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.}(hj1hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj+hKxhj,ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj+hKxhjubeh}(h]h ]h"]h$]h&]uh1jhj ubh)}(h**Description**h]j)}(hjQh]h Description}(hhhjShhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubah}(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.}(hjihjghhhNhNubah}(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 }(h*If there are no listeners for given group hjvhhhNhNubj)}(h ``-ESRCH``h]h-ESRCH}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjvubh can be returned.}(h can be returned.hjvhhhNhNubeh}(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:}(hjhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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&]uh1hhjhhhNhNubeh}(h]connector-interfacesah ]h"]connector interfacesah$]h&]uh1hhhhhhhhK9ubh)}(hhh](h)}(hProtocol descriptionh]hProtocol description}(hjhjhhhNhNubah}(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:}(hjhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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#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.}(hj1hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKRhjhhubh)}(h5Obviously, the protocol header contains the above id.h]h5Obviously, the protocol header contains the above id.}(hj?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}).}(hjMhjKhhhNhNubah}(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.}(hj[hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjhhubeh}(h]protocol-descriptionah ]h"]protocol descriptionah$]h&]uh1hhhhhhhhKBubh)}(hhh](h)}(h Reliabilityh]h Reliability}(hjthjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjohhhhhKdubh)}(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.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjohhubeh}(h] reliabilityah ]h"] reliabilityah$]h&]uh1hhhhhhhhKdubh)}(hhh](h)}(hUserspace usageh]hUserspace usage}(hjhjhhhNhNubah}(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:}(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)); }}(hhhjubah}(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.}(hjhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(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.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]userspace-usageah ]h"]userspace usageah$]h&]uh1hhhhhhhhKmubh)}(hhh](h)}(h Code samplesh]h Code samples}(hj 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.}(hjhjhhhNhNubah}(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_handlerjVerror_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.confapep_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_spacefile_insertion_enabled raw_enabledKline_length_limitM'syntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_link embed_imagesenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j0j-jjjljijjjjj(j%u nametypes}(j0NjNjlNjNjNj(Nuh}(j-hjjjjjjj-j2j5 j: jijjjojjj%ju 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.