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