| 1 | |
| 2 |
|
| 3 | ================
|
| 4 | Kernel Connector
|
| 5 | ================
|
| 6 |
|
| 7 | Kernel connector - new netlink based userspace <-> kernel space easy
|
| 8 | to use communication module.
|
| 9 |
|
| 10 | The Connector driver makes it easy to connect various agents using a
|
| 11 | netlink based network. One must register a callback and an identifier.
|
| 12 | When the driver receives a special netlink message with the appropriate
|
| 13 | identifier, the appropriate callback will be called.
|
| 14 |
|
| 15 | From the userspace point of view it's quite straightforward:
|
| 16 |
|
| 17 | - socket();
|
| 18 | - bind();
|
| 19 | - send();
|
| 20 | - recv();
|
| 21 |
|
| 22 | But if kernelspace wants to use the full power of such connections, the
|
| 23 | driver writer must create special sockets, must know about struct sk_buff
|
| 24 | handling, etc... The Connector driver allows any kernelspace agents to use
|
| 25 | netlink based networking for inter-process communication in a significantly
|
| 26 | easier way::
|
| 27 |
|
| 28 | int cn_add_callback(const struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
|
| 29 | void cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask);
|
| 30 | void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask);
|
| 31 |
|
| 32 | struct cb_id
|
| 33 | {
|
| 34 | __u32 idx;
|
| 35 | __u32 val;
|
| 36 | };
|
| 37 |
|
| 38 | idx and val are unique identifiers which must be registered in the
|
| 39 | connector.h header for in-kernel usage. `void (*callback) (void *)` is a
|
| 40 | callback function which will be called when a message with above idx.val
|
| 41 | is received by the connector core. The argument for that function must
|
| 42 | be dereferenced to `struct cn_msg *`::
|
| 43 |
|
| 44 | struct cn_msg
|
| 45 | {
|
| 46 | struct cb_id id;
|
| 47 |
|
| 48 | __u32 seq;
|
| 49 | __u32 ack;
|
| 50 |
|
| 51 | __u16 len; /* Length of the following data */
|
| 52 | __u16 flags;
|
| 53 | __u8 data[0];
|
| 54 | };
|
| 55 |
|
| 56 | Connector interfaces
|
| 57 | ====================
|
| 58 |
|
| 59 | .. kernel-doc:: include/linux/connector.h
|
| 60 |
|
| 61 | Note:
|
| 62 | When registering new callback user, connector core assigns
|
| 63 | netlink group to the user which is equal to its id.idx.
|
| 64 |
|
| 65 | Protocol description
|
| 66 | ====================
|
| 67 |
|
| 68 | The current framework offers a transport layer with fixed headers. The
|
| 69 | recommended protocol which uses such a header is as following:
|
| 70 |
|
| 71 | msg->seq and msg->ack are used to determine message genealogy. When
|
| 72 | someone sends a message, they use a locally unique sequence and random
|
| 73 | acknowledge number. The sequence number may be copied into
|
| 74 | nlmsghdr->nlmsg_seq too.
|
| 75 |
|
| 76 | The sequence number is incremented with each message sent.
|
| 77 |
|
| 78 | If you expect a reply to the message, then the sequence number in the
|
| 79 | received message MUST be the same as in the original message, and the
|
| 80 | acknowledge number MUST be the same + 1.
|
| 81 |
|
| 82 | If we receive a message and its sequence number is not equal to one we
|
| 83 | are expecting, then it is a new message. If we receive a message and
|
| 84 | its sequence number is the same as one we are expecting, but its
|
| 85 | acknowledge is not equal to the sequence number in the original
|
| 86 | message + 1, then it is a new message.
|
| 87 |
|
| 88 | Obviously, the protocol header contains the above id.
|
| 89 |
|
| 90 | The connector allows event notification in the following form: kernel
|
| 91 | driver or userspace process can ask connector to notify it when
|
| 92 | selected ids will be turned on or off (registered or unregistered its
|
| 93 | callback). It is done by sending a special command to the connector
|
| 94 | driver (it also registers itself with id={-1, -1}).
|
| 95 |
|
| 96 | As example of this usage can be found in the cn_test.c module which
|
| 97 | uses the connector to request notification and to send messages.
|
| 98 |
|
| 99 | Reliability
|
| 100 | ===========
|
| 101 |
|
| 102 | Netlink itself is not a reliable protocol. That means that messages can
|
| 103 | be lost due to memory pressure or process' receiving queue overflowed,
|
| 104 | so caller is warned that it must be prepared. That is why the struct
|
| 105 | cn_msg [main connector's message header] contains u32 seq and u32 ack
|
| 106 | fields.
|
| 107 |
|
| 108 | Userspace usage
|
| 109 | ===============
|
| 110 |
|
| 111 | 2.6.14 has a new netlink socket implementation, which by default does not
|
| 112 | allow people to send data to netlink groups other than 1.
|
| 113 | So, if you wish to use a netlink socket (for example using connector)
|
| 114 | with a different group number, the userspace application must subscribe to
|
| 115 | that group first. It can be achieved by the following pseudocode::
|
| 116 |
|
| 117 | s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
| 118 |
|
| 119 | l_local.nl_family = AF_NETLINK;
|
| 120 | l_local.nl_groups = 12345;
|
| 121 | l_local.nl_pid = 0;
|
| 122 |
|
| 123 | if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
|
| 124 | perror("bind");
|
| 125 | close(s);
|
| 126 | return -1;
|
| 127 | }
|
| 128 |
|
| 129 | {
|
| 130 | int on = l_local.nl_groups;
|
| 131 | setsockopt(s, 270, 1, &on, sizeof(on));
|
| 132 | }
|
| 133 |
|
| 134 | Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
|
| 135 | option. To drop a multicast subscription, one should call the above socket
|
| 136 | option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
|
| 137 |
|
| 138 | 2.6.14 netlink code only allows to select a group which is less or equal to
|
| 139 | the maximum group number, which is used at netlink_kernel_create() time.
|
| 140 | In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
|
| 141 | group number 12345, you must increment CN_NETLINK_USERS to that number.
|
| 142 | Additional 0xf numbers are allocated to be used by non-in-kernel users.
|
| 143 |
|
| 144 | Due to this limitation, group 0xffffffff does not work now, so one can
|
| 145 | not use add/remove connector's group notifications, but as far as I know,
|
| 146 | only cn_test.c test module used it.
|
| 147 |
|
| 148 | Some work in netlink area is still being done, so things can be changed in
|
| 149 | 2.6.15 timeframe, if it will happen, documentation will be updated for that
|
| 150 | kernel.
|
| 151 |
|
| 152 | Code samples
|
| 153 | ============
|
| 154 |
|
| 155 | Sample code for a connector test module and user space can be found
|
| 156 | in samples/connector/. To build this code, enable CONFIG_CONNECTOR
|
| 157 | and CONFIG_SAMPLES.
|