diff options
| -rw-r--r-- | networking/ifplugd.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 3cdc2c9d2..b578f4c61 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c | |||
| @@ -451,20 +451,24 @@ static smallint detect_link(void) | |||
| 451 | static NOINLINE int check_existence_through_netlink(void) | 451 | static NOINLINE int check_existence_through_netlink(void) |
| 452 | { | 452 | { |
| 453 | int iface_len; | 453 | int iface_len; |
| 454 | char replybuf[1024]; | 454 | /* Buffer was 1K, but on linux-3.9.9 it was reported to be too small. |
| 455 | * netlink.h: "limit to 8K to avoid MSG_TRUNC when PAGE_SIZE is very large". | ||
| 456 | * Note: on error returns (-1) we exit, no need to free replybuf. | ||
| 457 | */ | ||
| 458 | enum { BUF_SIZE = 8 * 1024 }; | ||
| 459 | char *replybuf = xmalloc(BUF_SIZE); | ||
| 455 | 460 | ||
| 456 | iface_len = strlen(G.iface); | 461 | iface_len = strlen(G.iface); |
| 457 | while (1) { | 462 | while (1) { |
| 458 | struct nlmsghdr *mhdr; | 463 | struct nlmsghdr *mhdr; |
| 459 | ssize_t bytes; | 464 | ssize_t bytes; |
| 460 | 465 | ||
| 461 | bytes = recv(netlink_fd, &replybuf, sizeof(replybuf), MSG_DONTWAIT); | 466 | bytes = recv(netlink_fd, replybuf, BUF_SIZE, MSG_DONTWAIT); |
| 462 | if (bytes < 0) { | 467 | if (bytes < 0) { |
| 463 | if (errno == EAGAIN) | 468 | if (errno == EAGAIN) |
| 464 | return G.iface_exists; | 469 | goto ret; |
| 465 | if (errno == EINTR) | 470 | if (errno == EINTR) |
| 466 | continue; | 471 | continue; |
| 467 | |||
| 468 | bb_perror_msg("netlink: recv"); | 472 | bb_perror_msg("netlink: recv"); |
| 469 | return -1; | 473 | return -1; |
| 470 | } | 474 | } |
| @@ -507,6 +511,8 @@ static NOINLINE int check_existence_through_netlink(void) | |||
| 507 | } | 511 | } |
| 508 | } | 512 | } |
| 509 | 513 | ||
| 514 | ret: | ||
| 515 | free(replybuf); | ||
| 510 | return G.iface_exists; | 516 | return G.iface_exists; |
| 511 | } | 517 | } |
| 512 | 518 | ||
