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