How to bundle requests?
Thomas Graf
tgraf at infradead.org
Wed Oct 26 03:49:32 EDT 2011
On Tue, Oct 25, 2011 at 10:50:52AM +0100, Tilman Baumann wrote:
> Hi,
>
> I need IP address information and link mac addresses in my programme.
>
> I thought I can combine requests with nlmsg_flags = NLM_F_MULTI but
> it seems like this does not really work at all.
> Or I'm doing it wrong.
>
> I'm not constantly listening on the socket. I just send a request
> and do one recv(). I could imagine that this is bad practice. If you
> tell me how it is better done I would appreciate this very much.
>
> Sorry about the line breaks. I did not take care of max line length.
> I will attach the file as well, to make it more readable.
>
>
> Below code works if I just send one RTM_GETADDR or RTM_GETLINK
> packet. But the combined request like below does only return GETADDR
> data.
>
>
> Am I doing the NLM_F_MULTI request right? Should it work and how
> should I use it do make it work.
You do not need NLM_F_MULTI for this.
The behaviour depends on the netlink family. In this specific case,
rtnetlink will parse any message in sequential order and process
them one by one:
while (skb->len >= nlmsg_total_size(0)) {
int msglen;
nlh = nlmsg_hdr(skb);
err = 0;
if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
return 0;
/* Only requests are handled by the kernel */
if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
goto ack;
/* Skip control messages */
if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
goto ack;
err = cb(skb, nlh);
if (err == -EINTR)
goto skip;
ack:
if (nlh->nlmsg_flags & NLM_F_ACK || err)
netlink_ack(skb, nlh, err);
skip:
msglen = NLMSG_ALIGN(nlh->nlmsg_len);
if (msglen > skb->len)
msglen = skb->len;
skb_pull(skb, msglen);
}
With regards to libnl, you will have to call the receiver() procedure
twice to catch both reply sequences.
More information about the libnl
mailing list