ACK only after second message
Yves Langisch
yves at langisch.ch
Wed Nov 3 19:28:49 EDT 2010
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 *) ®istered);
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
-------------- 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/85327b51/attachment.p7s>
More information about the libnl
mailing list