18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci================ 48c2ecf20Sopenharmony_ciKernel Connector 58c2ecf20Sopenharmony_ci================ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciKernel connector - new netlink based userspace <-> kernel space easy 88c2ecf20Sopenharmony_cito use communication module. 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ciThe Connector driver makes it easy to connect various agents using a 118c2ecf20Sopenharmony_cinetlink based network. One must register a callback and an identifier. 128c2ecf20Sopenharmony_ciWhen the driver receives a special netlink message with the appropriate 138c2ecf20Sopenharmony_ciidentifier, the appropriate callback will be called. 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciFrom the userspace point of view it's quite straightforward: 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci - socket(); 188c2ecf20Sopenharmony_ci - bind(); 198c2ecf20Sopenharmony_ci - send(); 208c2ecf20Sopenharmony_ci - recv(); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciBut if kernelspace wants to use the full power of such connections, the 238c2ecf20Sopenharmony_cidriver writer must create special sockets, must know about struct sk_buff 248c2ecf20Sopenharmony_cihandling, etc... The Connector driver allows any kernelspace agents to use 258c2ecf20Sopenharmony_cinetlink based networking for inter-process communication in a significantly 268c2ecf20Sopenharmony_cieasier way:: 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *)); 298c2ecf20Sopenharmony_ci void cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask); 308c2ecf20Sopenharmony_ci void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci struct cb_id 338c2ecf20Sopenharmony_ci { 348c2ecf20Sopenharmony_ci __u32 idx; 358c2ecf20Sopenharmony_ci __u32 val; 368c2ecf20Sopenharmony_ci }; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciidx and val are unique identifiers which must be registered in the 398c2ecf20Sopenharmony_ciconnector.h header for in-kernel usage. `void (*callback) (void *)` is a 408c2ecf20Sopenharmony_cicallback function which will be called when a message with above idx.val 418c2ecf20Sopenharmony_ciis received by the connector core. The argument for that function must 428c2ecf20Sopenharmony_cibe dereferenced to `struct cn_msg *`:: 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci struct cn_msg 458c2ecf20Sopenharmony_ci { 468c2ecf20Sopenharmony_ci struct cb_id id; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci __u32 seq; 498c2ecf20Sopenharmony_ci __u32 ack; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci __u16 len; /* Length of the following data */ 528c2ecf20Sopenharmony_ci __u16 flags; 538c2ecf20Sopenharmony_ci __u8 data[0]; 548c2ecf20Sopenharmony_ci }; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciConnector interfaces 578c2ecf20Sopenharmony_ci==================== 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci .. kernel-doc:: include/linux/connector.h 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci Note: 628c2ecf20Sopenharmony_ci When registering new callback user, connector core assigns 638c2ecf20Sopenharmony_ci netlink group to the user which is equal to its id.idx. 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciProtocol description 668c2ecf20Sopenharmony_ci==================== 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ciThe current framework offers a transport layer with fixed headers. The 698c2ecf20Sopenharmony_cirecommended protocol which uses such a header is as following: 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cimsg->seq and msg->ack are used to determine message genealogy. When 728c2ecf20Sopenharmony_cisomeone sends a message, they use a locally unique sequence and random 738c2ecf20Sopenharmony_ciacknowledge number. The sequence number may be copied into 748c2ecf20Sopenharmony_cinlmsghdr->nlmsg_seq too. 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciThe sequence number is incremented with each message sent. 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ciIf you expect a reply to the message, then the sequence number in the 798c2ecf20Sopenharmony_cireceived message MUST be the same as in the original message, and the 808c2ecf20Sopenharmony_ciacknowledge number MUST be the same + 1. 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ciIf we receive a message and its sequence number is not equal to one we 838c2ecf20Sopenharmony_ciare expecting, then it is a new message. If we receive a message and 848c2ecf20Sopenharmony_ciits sequence number is the same as one we are expecting, but its 858c2ecf20Sopenharmony_ciacknowledge is not equal to the sequence number in the original 868c2ecf20Sopenharmony_cimessage + 1, then it is a new message. 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ciObviously, the protocol header contains the above id. 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ciThe connector allows event notification in the following form: kernel 918c2ecf20Sopenharmony_cidriver or userspace process can ask connector to notify it when 928c2ecf20Sopenharmony_ciselected ids will be turned on or off (registered or unregistered its 938c2ecf20Sopenharmony_cicallback). It is done by sending a special command to the connector 948c2ecf20Sopenharmony_cidriver (it also registers itself with id={-1, -1}). 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ciAs example of this usage can be found in the cn_test.c module which 978c2ecf20Sopenharmony_ciuses the connector to request notification and to send messages. 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ciReliability 1008c2ecf20Sopenharmony_ci=========== 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ciNetlink itself is not a reliable protocol. That means that messages can 1038c2ecf20Sopenharmony_cibe lost due to memory pressure or process' receiving queue overflowed, 1048c2ecf20Sopenharmony_ciso caller is warned that it must be prepared. That is why the struct 1058c2ecf20Sopenharmony_cicn_msg [main connector's message header] contains u32 seq and u32 ack 1068c2ecf20Sopenharmony_cifields. 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ciUserspace usage 1098c2ecf20Sopenharmony_ci=============== 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci2.6.14 has a new netlink socket implementation, which by default does not 1128c2ecf20Sopenharmony_ciallow people to send data to netlink groups other than 1. 1138c2ecf20Sopenharmony_ciSo, if you wish to use a netlink socket (for example using connector) 1148c2ecf20Sopenharmony_ciwith a different group number, the userspace application must subscribe to 1158c2ecf20Sopenharmony_cithat group first. It can be achieved by the following pseudocode:: 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci l_local.nl_family = AF_NETLINK; 1208c2ecf20Sopenharmony_ci l_local.nl_groups = 12345; 1218c2ecf20Sopenharmony_ci l_local.nl_pid = 0; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { 1248c2ecf20Sopenharmony_ci perror("bind"); 1258c2ecf20Sopenharmony_ci close(s); 1268c2ecf20Sopenharmony_ci return -1; 1278c2ecf20Sopenharmony_ci } 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci { 1308c2ecf20Sopenharmony_ci int on = l_local.nl_groups; 1318c2ecf20Sopenharmony_ci setsockopt(s, 270, 1, &on, sizeof(on)); 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ciWhere 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket 1358c2ecf20Sopenharmony_cioption. To drop a multicast subscription, one should call the above socket 1368c2ecf20Sopenharmony_cioption with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0. 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci2.6.14 netlink code only allows to select a group which is less or equal to 1398c2ecf20Sopenharmony_cithe maximum group number, which is used at netlink_kernel_create() time. 1408c2ecf20Sopenharmony_ciIn case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use 1418c2ecf20Sopenharmony_cigroup number 12345, you must increment CN_NETLINK_USERS to that number. 1428c2ecf20Sopenharmony_ciAdditional 0xf numbers are allocated to be used by non-in-kernel users. 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ciDue to this limitation, group 0xffffffff does not work now, so one can 1458c2ecf20Sopenharmony_cinot use add/remove connector's group notifications, but as far as I know, 1468c2ecf20Sopenharmony_cionly cn_test.c test module used it. 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ciSome work in netlink area is still being done, so things can be changed in 1498c2ecf20Sopenharmony_ci2.6.15 timeframe, if it will happen, documentation will be updated for that 1508c2ecf20Sopenharmony_cikernel. 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ciCode samples 1538c2ecf20Sopenharmony_ci============ 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ciSample code for a connector test module and user space can be found 1568c2ecf20Sopenharmony_ciin samples/connector/. To build this code, enable CONFIG_CONNECTOR 1578c2ecf20Sopenharmony_ciand CONFIG_SAMPLES. 158