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]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/pt_BR/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&]uh1jhjubj)}(hbind();h]h)}(hj/h]hbind();}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj-ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hsend();h]h)}(hjFh]hsend();}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjDubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hrecv(); h]h)}(hrecv();h]hrecv();}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj[ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhj ubah}(h]h ]h"]h$]h&]uh1j hhhKhhhhubh)}(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:}(hjhhhNhNubah}(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; };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhhhhubh)}(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&]hhuh1jhhhK,hhhhubh)}(hhh](h)}(hConnector interfacesh]hConnector interfaces}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK9ubj )}(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.hhK:ubhdesc_sig_space)}(h h]h }(hj,hhhNhNubah}(h]h ]wah"]h$]h&]uh1j*hjhhhj)hK:ubh desc_name)}(hcn_add_callbackh]h desc_sig_name)}(hcn_add_callbackh]hcn_add_callback}(hjChhhNhNubah}(h]h ]nah"]h$]h&]uh1jAhj=ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j;hjhhhj)hK: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}(hjhhhhNhNubah}(h]h ]kah"]h$]h&]uh1jfhjbubj+)}(h h]h }(hjwhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjbubjg)}(hstructh]hstruct}(hjhhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhjbubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjbubh)}(hhh]jB)}(hcb_idh]hcb_id}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ]h"]h$]h&] refdomaincreftype identifier reftargetjmodnameN classnameN c:parent_keysphinx.domains.c LookupKey)}data]j ASTIdentifier)}jjEsbc.cn_add_callbackasbuh1hhjbubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjbubhdesc_sig_punctuation)}(h*h]h*}(hjhhhNhNubah}(h]h ]pah"]h$]h&]uh1jhjbubjB)}(hidh]hid}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjbubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj\ubja)}(hconst char *nameh](jg)}(hjjh]hconst}(hjhhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhjubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubj)}(hcharh]hchar}(hj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj+)}(h h]h }(hj.hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubj)}(hjh]h*}(hj<hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjB)}(hnameh]hname}(hjIhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj\ubja)}(h;void (*callback)(struct cn_msg*, struct netlink_skb_parms*)h](j)}(hvoidh]hvoid}(hjbhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj^ubj+)}(h h]h }(hjphhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj^ubj)}(h(h]h(}(hj~hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubjB)}(hcallbackh]hcallback}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj^ubj)}(h)h]h)}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubj)}(hjh]h(}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubjg)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhj^ubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj^ubh)}(hhh]jB)}(hcn_msgh]hcn_msg}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_add_callbackasbuh1hhj^ubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubj)}(h,h]h,}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj^ubjg)}(hjh]hstruct}(hj'hhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhj^ubj+)}(h h]h }(hj4hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj^ubh)}(hhh]jB)}(hnetlink_skb_parmsh]hnetlink_skb_parms}(hjEhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjBubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjGmodnameN classnameNjj)}j]jc.cn_add_callbackasbuh1hhj^ubj)}(hjh]h*}(hjchhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubj)}(hjh]h)}(hjphhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj\ubeh}(h]h ]h"]h$]h&]hhuh1jZhjhhhj)hK:ubeh}(h]h ]h"]h$]h&]hhƌ add_permalinkuh1jsphinx_line_type declaratorhjhhhj)hK:ubah}(h]jah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1j hj)hK:hj hhubh 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&]uh1jhj hhhj)hK:ubeh}(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)}(hj2h]hconst char *name}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0ubah}(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#connector's callback symbolic name.h]h%connector’s callback symbolic name.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGhK?hjHubah}(h]h ]h"]h$]h&]uh1j hj,ubeh}(h]h ]h"]h$]h&]uh1jhjGhK?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)}(hjkh]h=void (*callback)(struct cn_msg *, struct netlink_skb_parms *)}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjiubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK@hjeubj )}(hhh]h)}(hLconnector's callback. parameters are ``cn_msg`` and the sender's credentialsh](h'connector’s callback. parameters are }(hjhhhNhNubj)}(h ``cn_msg``h]hcn_msg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and the sender’s credentials}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhK@hjubah}(h]h ]h"]h$]h&]uh1j hjeubeh}(h]h ]h"]h$]h&]uh1jhjhK@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 ]j%ah"]h$]h&]uh1jhjhhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKFubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjhhhjhKFubj<)}(hcn_del_callbackh]jB)}(hcn_del_callbackh]hcn_del_callback}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ](jUjVeh"]h$]h&]hhuh1j;hjhhhjhKFubj[)}(h(const struct cb_id *id)h]ja)}(hconst struct cb_id *idh](jg)}(hjjh]hconst}(hjhhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhjubj+)}(h h]h }(hj hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubjg)}(hjh]hstruct}(hj.hhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhjubj+)}(h h]h }(hj;hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubh)}(hhh]jB)}(hcb_idh]hcb_id}(hjLhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjIubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjNmodnameN classnameNjj)}j]j)}jjsbc.cn_del_callbackasbuh1hhjubj+)}(h h]h }(hjlhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubj)}(hjh]h*}(hjzhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjB)}(hidh]hid}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj ubah}(h]h ]h"]h$]h&]hhuh1jZhjhhhjhKFubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjhhhjhKFubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1j hjhKFhjhhubj)}(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&]uh1jhjhhhjhKFubeh}(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.}(hj hhhNhNubah}(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&]uh1j hjubeh}(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}(hjLhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjHhhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKNubj+)}(h h]h }(hj[hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjHhhhjZhKNubj<)}(hcn_netlink_send_multh]jB)}(hcn_netlink_send_multh]hcn_netlink_send_mult}(hjmhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjiubah}(h]h ](jUjVeh"]h$]h&]hhuh1j;hjHhhhjZhKNubj[)}(hq(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask, netlink_filter_fn filter, void *filter_data)h](ja)}(hstruct cn_msg *msgh](jg)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhjubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubh)}(hhh]jB)}(hcn_msgh]hcn_msg}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]j)}jjosbc.cn_netlink_send_multasbuh1hhjubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjB)}(hmsgh]hmsg}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubja)}(hu16 lenh](h)}(hhh]jB)}(hu16h]hu16}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubjB)}(hlenh]hlen}(hj*hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubja)}(h u32 portidh](h)}(hhh]jB)}(hu32h]hu32}(hjFhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjCubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjHmodnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhj?ubj+)}(h h]h }(hjdhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj?ubjB)}(hportidh]hportid}(hjrhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj?ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubja)}(h u32 grouph](h)}(hhh]jB)}(hu32h]hu32}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubjB)}(hgrouph]hgroup}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubja)}(hgfp_t gfp_maskh](h)}(hhh]jB)}(hgfp_th]hgfp_t}(hjhhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhjubj+)}(h h]h }(hjhhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjubjB)}(hgfp_maskh]hgfp_mask}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubja)}(hnetlink_filter_fn filterh](h)}(hhh]jB)}(hnetlink_filter_fnh]hnetlink_filter_fn}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]jc.cn_netlink_send_multasbuh1hhj ubj+)}(h h]h }(hj< hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj ubjB)}(hfilterh]hfilter}(hjJ hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubja)}(hvoid *filter_datah](j)}(hvoidh]hvoid}(hjc hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj_ ubj+)}(h h]h }(hjq hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj_ ubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj_ ubjB)}(h filter_datah]h filter_data}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj_ ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hjubeh}(h]h ]h"]h$]h&]hhuh1jZhjHhhhjZhKNubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjDhhhjZhKNubah}(h]j?ah ](jjeh"]h$]h&]jj)jhuh1j hjZhKNhjAhhubj)}(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&]uh1jhjAhhhjZhKNubeh}(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&]uh1j hj 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)}(hj0 h]hu16 len}(hj2 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 }(hjI hhhNhNubj)}(h**msg**h]hmsg}(hjQ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjI ubh to be sent.}(hjI hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjE hKQhjF ubah}(h]h ]h"]h$]h&]uh1j hj* ubeh}(h]h ]h"]h$]h&]uh1jhjE 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)}(hj{ h]h u32 portid}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjy ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKThju 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&]uh1j hju 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&]uh1j hj 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)}(hj7 h]hgfp_t gfp_mask}(hj9 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj5 ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK\hj1 ubj )}(hhh]h)}(h GFP mask.h]h GFP mask.}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjL hK\hjM ubah}(h]h ]h"]h$]h&]uh1j hj1 ubeh}(h]h ]h"]h$]h&]uh1jhjL 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)}(hjp h]hnetlink_filter_fn filter}(hjr hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjn ubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhK]hjj ubj )}(hhh]h)}(h,Filter function to be used at netlink layer.h]h,Filter function to be used at netlink layer.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hK]hj ubah}(h]h ]h"]h$]h&]uh1j hjj 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}(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&]uh1j hj 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.hhKbhj 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}(hjJ hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjF hhh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKkubj+)}(h h]h }(hjY hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hjF hhhjX hKkubj<)}(hcn_netlink_sendh]jB)}(hcn_netlink_sendh]hcn_netlink_send}(hjk hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjg ubah}(h]h ](jUjVeh"]h$]h&]hhuh1j;hjF hhhjX hKkubj[)}(h;(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask)h](ja)}(hstruct cn_msg *msgh](jg)}(hjh]hstruct}(hj hhhNhNubah}(h]h ]jsah"]h$]h&]uh1jfhj ubj+)}(h h]h }(hj hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj ubh)}(hhh]jB)}(hcn_msgh]hcn_msg}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j)}jjm sbc.cn_netlink_sendasbuh1hhj ubj+)}(h h]h }(hj hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj ubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjB)}(hmsgh]hmsg}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj ubja)}(h u32 portidh](h)}(hhh]jB)}(hu32h]hu32}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhj ubj+)}(h h]h }(hj hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj ubjB)}(hportidh]hportid}(hj( hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj ubja)}(h u32 grouph](h)}(hhh]jB)}(hu32h]hu32}(hjD hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhjA ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjF modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhj= ubj+)}(h h]h }(hjb hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj= ubjB)}(hgrouph]hgroup}(hjp hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj= ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj ubja)}(hgfp_t gfp_maskh](h)}(hhh]jB)}(hgfp_th]hgfp_t}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j c.cn_netlink_sendasbuh1hhj ubj+)}(h h]h }(hj hhhNhNubah}(h]h ]j7ah"]h$]h&]uh1j*hj ubjB)}(hgfp_maskh]hgfp_mask}(hj hhhNhNubah}(h]h ]jNah"]h$]h&]uh1jAhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j`hj ubeh}(h]h ]h"]h$]h&]hhuh1jZhjF hhhjX hKkubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjB hhhjX hKkubah}(h]j= ah ](jjeh"]h$]h&]jj)jhuh1j hjX hKkhj? 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? hhhjX hKkubeh}(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)}(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.hhKohj 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.hhKmhjubj )}(hhh]h)}(h#message header(with attached data).h]h#message header(with attached data).}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj8hKmhj9ubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1jhj8hKmhjubj)}(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)}(hj\h]h u32 portid}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjZubah}(h]h ]h"]h$]h&]uh1jh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKphjVubj )}(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.}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKnhjrubah}(h]h ]h"]h$]h&]uh1j hjVubeh}(h]h ]h"]h$]h&]uh1jhjqhKphjubj)}(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.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 }(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&]uh1j hjubeh}(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.}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj-hKxhj.ubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1jhj-hKxhjubeh}(h]h ]h"]h$]h&]uh1jhj ubh)}(h**Description**h]j)}(hjSh]h Description}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQubah}(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.}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1hh^/var/lib/git/docbuild/linux/Documentation/driver-api/connector:59: ./include/linux/connector.hhKyhj ubh)}(hEIf there are no listeners for given group ``-ESRCH`` can be returned.h](h*If there are no listeners for given group }(hjxhhhNhNubj)}(h ``-ESRCH``h]h-ESRCH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubh can be returned.}(hjxhhhNhNubeh}(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&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1jhhhK?hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1j hhhK;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.}(hj/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=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}).}(hjKhhhNhNubah}(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.}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjhhubeh}(h]protocol-descriptionah ]h"]protocol descriptionah$]h&]uh1hhhhhhhhKBubh)}(hhh](h)}(h Reliabilityh]h Reliability}(hjrhhhNhNubah}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjohhubeh}(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&]hhuh1jhhhKuhjhhubh)}(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_handlerjUerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _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}(j/j,jjjljijjjjj'j$u nametypes}(j/jjljjj'uh}(j,hjjjjjjj?jDj= jB 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.