[PATCH alternative v2] ifplugd: fix netlink recv
Tito
farmatito at tiscali.it
Tue Jul 9 20:32:12 UTC 2013
On Tuesday 09 July 2013 18:07:17 you wrote:
> On Tue, Jul 09, 2013 at 04:30:40PM +0200, Tito wrote:
> > On Tuesday 09 July 2013 15:08:50 Johannes Stezenbach wrote:
> > > Without doing research on it, my assumption is that
> > > in older kernels the message was smaller, and now it is
> > > larger, and in future kernels the size might increase even more.
> > > and it varies with the type of the interface.
> > > And the point of using the netlink protocol is that messages
> > > can be extended with additional attributes without breaking
> > > backwards compatibility.
> > > Or is there some max size guaranteed for NETLINK_ROUTE messages
> > > in group RTMGRP_LINK? If not, then the code needs to
> > > be able to handle the max size of a netlink message.
> > >
> >
> > Looking at the __kernel__ of part netlink.h it seems to me
> > that the max size for a netlink message is 8k
> >
> > * skb should fit one page. This choice is good for headerless malloc.
> > * But we should limit to 8K so that userspace does not have to
> > * use enormous buffer sizes on recvmsg() calls just to avoid
> > * MSG_TRUNC when PAGE_SIZE is very large.
> > */
> > #if PAGE_SIZE < 8192UL
> > #define NLMSG_GOODSIZE SKB_WITH_OVERHEAD(PAGE_SIZE)
> > #else
> > #define NLMSG_GOODSIZE SKB_WITH_OVERHEAD(8192UL)
> > #endif
> >
> > #define NLMSG_DEFAULT_SIZE (NLMSG_GOODSIZE - NLMSG_HDRLEN)
>
> That matches networking/libiproute/libnetlink.c which uses
> char *buf = xmalloc(8*1024); /* avoid big stack buffer */
>
> (not sure what is the advantage of using xmalloc() vs. stack)
>
> > also looking at the ifplugd man page
> >
> > "ifplugd [options]
> > Description
> > ifplugd is a daemon which will automatically configure your ethernet device when
> > a cable is plugged in and automatically unconfigure it if the cable is pulled.
> > This is useful on laptops with on-board network adapters, since it will only
> > configure the interface when a cable is really connected. "
> >
> > it seems to me that ifplugd is to be used only with ethernet devices
> > so maybe a 1024 buffer is enough for them but not for br* devices?
>
> Maybe br0 is an artificial test case, but IMHO ifplugd should
> work on all interfaces, e.g. monitor when wlan0 devices appear
> when USB dongle is plugged in, or reconfigured between AP
> and client mode etc. Also you missed the point that it doesn't
> matter what the currect kernel does, we want something that
> is guaranteed to work with future kernels that might increase
> the message size.
>
>
> > Also while reading about this netlink stuff I noticed the existence of
> > multipart messages, is this our case?
> >
> > Did you check the size of the offending netlink message just for reference?
> >
> > Also checking the kernel source for the module of br devices could be an option.
> >
> > I'm wondering If it would be possible to malloc the buffer on demand like:
> >
> > while (1) {
> > read_just_the_nl_msg_hdr_first
> > s = nlmsg_len - size_of_header
> > buf = malloc(s)
> > read_rest_of_msg
> > (concatenate messges if needed?)
> > do something
> > ....
> > free it
> > }
>
> I like the simple code much better. Let Denys decide.
>
>
> Thanks,
> Johannes
>
Hi,
here v2 of the patch that mallocs a buffer the size of pagesize and not more then 8192.
I tested it and it seems to work as before on my system. Can you test if it solves your problem.
Ciao,
Tito
--- networking/ifplugd.c.orig 2013-07-08 22:51:22.748468426 +0200
+++ networking/ifplugd.c 2013-07-09 22:14:50.105451385 +0200
@@ -451,17 +451,19 @@ static smallint detect_link(void)
static NOINLINE int check_existence_through_netlink(void)
{
int iface_len;
- char replybuf[1024];
+ /* netlink.h: limit to 8K to avoid MSG_TRUNC when PAGE_SIZE is very large.*/
+ int size = MIN(sysconf(_SC_PAGESIZE), 8192);
+ char *replybuf = xmalloc(size);
iface_len = strlen(G.iface);
while (1) {
struct nlmsghdr *mhdr;
ssize_t bytes;
- bytes = recv(netlink_fd, &replybuf, sizeof(replybuf), MSG_DONTWAIT);
+ bytes = recv(netlink_fd, replybuf, size, MSG_DONTWAIT);
if (bytes < 0) {
if (errno == EAGAIN)
- return G.iface_exists;
+ break;
if (errno == EINTR)
continue;
@@ -506,7 +508,8 @@ static NOINLINE int check_existence_thro
mhdr = NLMSG_NEXT(mhdr, bytes);
}
}
-
+ /* on error program exits so no need to free */
+ free(replybuf);
return G.iface_exists;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ifplugd_v2.patch
Type: text/x-patch
Size: 1141 bytes
Desc: not available
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20130709/70d56456/attachment-0001.bin>
More information about the busybox
mailing list