ACK only after second message

Yves Langisch yves at langisch.ch
Thu Nov 4 17:14:49 EDT 2010


Answering my own question: Was waiting too early for the ACK since the 
register cmd from the kernel module is being sent out while receiving 
already. Putting the nl_wait_for_ack after nl_recvmsgs_default solved 
the problem.

Yves

On 04.11.2010 00:28, Yves Langisch wrote:
> Hi,
>
> I have a tough time making my generic netlink communication running.
>
> That's what I try to do:
>
> user space kernel module
>
> register op (+attrs) -> ...
> ... <- register op (registred flag set)
> insert op (+attr) -> ...
> ... <- insert (inserted flag set)
>
> I thought that this should be a pretty simple, sequential scenario but I
> have problems with ACK messages. It looks like an ACK msg is only sent
> from the kernel side after the second operation (insert). As far as I
> understand using nl_send_auto_complete sets the NLM_F_ACK flag
> automatically and I should get an ACK msg for both operations.
>
> My client code looks as follows:
>
> /* Allocate a new netlink socket */
> sock = nl_handle_alloc();
> if (sock == NULL) {
> LOGE("couldn't allocate socket");
> goto out;
> }
>
> /* Connect to the generic netlink socket in the kernel */
> int er = genl_connect(sock);
> if (er < 0) {
> LOGE("error while connecting %i", er);
> goto out;
> }
>
> /* obtain the family id for the CONTROL_EXMPL family */
> family = genl_ctrl_resolve(sock, "DROPSTOP");
> if (family < 0) {
> LOGE("error obtaining family");
> goto out;
> }
>
> /* allocate a new message */
> msg = nlmsg_alloc();
>
> /* make the header */
> genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST,
> DROPSTOP_C_REGISTER, DROPSTOP_VERSION);
>
> /* add the data */
> nla_put_u32(msg, DROPSTOP_A_VERSION, DROPSTOP_VERSION);
>
> LOGI("Sending DROPSTOP_C_REGISTER");
>
> /* send the message */
> sent = nl_send_auto_complete(sock, msg);
> if (sent < 0) {
> LOGE("error sending message");
> goto out;
> }
> nlmsg_free(msg);
>
> //apparently no ACK for the first message?!?
> int ack = nl_wait_for_ack(sock);
> LOGI("ACK %i", ack);
>
> nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, receive_REGISTERED,
> (int *) &registered);
>
> LOGI("Start listening for REGISTERED");
> // Wait for the answer and receive it
> if (nl_recvmsgs_default(sock) < 0) {
> LOGE("Error while receiving message");
> }
>
> //next message
> msg = nlmsg_alloc();
>
> genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST,
> DROPSTOP_C_INSERT, DROPSTOP_VERSION);
> nla_put_u8(msg, DROPSTOP_A_SYSCALL, DROPSTOP_SOCKET_CONNECT);
> nla_put_u8(msg, DROPSTOP_A_PROTOCOL, IPPROTO_TCP);
>
> LOGI("Sending DROPSTOP_C_INSERT");
> if (nl_send_auto_complete(sock, msg) < 0) {
> LOGE("error sending message");
> goto out;
> }
> nlmsg_free(msg);
> int ack2 = nl_wait_for_ack(sock);
> LOGI("ACK %i", ack2);
>
> if (nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, receive_INSERTED,
> (int *) &inserted) <0){
> LOGE("ERRRRRRRRRRRRRRR");
> }
> LOGI("Start listening for INSERTED");
> // Wait for the answer and receive it
> if (nl_recvmsgs_default(sock)<0){
> LOGE("Fehler beim Empfang");
> }
>
> return 0;
>
> Running the code as is gives the following output:
>
> -
> Sending DROPSTOP_C_REGISTER
> ACK 0
> Start listening for REGISTERED
> Sending DROPSTOP_C_INSERT
> Entering receive_REGISTERED
> registration failed
> ACK 0
> Start listening for INSERTED
> -
>
> The first nl_wait_for_ack seems to mix up the message order. Commenting
> out the first nl_wait_for_ack gives the expected result:
>
> -
> Sending DROPSTOP_C_REGISTER
> Start listening for REGISTERED
> Entering receive_REGISTERED
> registration successful
> Sending DROPSTOP_C_INSERT
> ACK 0
> Start listening for INSERTED
> entering receive_INSERTED
> -
>
> I don't know if I use the API in a wrong manner. The kernel module logic
> for receiving and replying is more or less the same. At least the reply
> part.
>
> Any help is greatly appreciated!
>
> Yves
>
>
>
> _______________________________________________
> libnl mailing list
> libnl at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libnl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5198 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20101104/534aaaf2/attachment.p7s>


More information about the libnl mailing list