Add debug per 100 messages.
{
socklen_t socklen;
int rcvbuflen;
+ char buf[2048];
+ ssize_t rlen;
+ size_t rcnt;
struct if_head *ifaces;
struct ifaddrs *ifaddrs;
struct interface *ifp, *ifn, *ifp1;
logerrx("route socket overflowed (rcvbuflen %d)"
" - learning interface state", rcvbuflen);
-#ifndef HAVE_PLEDGE
- /* Close the existing socket and open a new one.
- * This is easier than draining the kernel buffer of an
- * in-determinate size. */
- eloop_event_delete(ctx->eloop, ctx->link_fd);
- close(ctx->link_fd);
- if_closesockets_os(ctx);
- if (if_opensockets_os(ctx) == -1) {
- logerr("%s: if_opensockets", __func__);
- eloop_exit(ctx->eloop, EXIT_FAILURE);
- return;
- }
-#endif
-
-#ifndef SMALL
- dhcpcd_setlinkrcvbuf(ctx);
-#endif
- eloop_event_add(ctx->eloop, ctx->link_fd, dhcpcd_handlelink, ctx);
+ /* Drain the socket.
+ * We cannot open a new one due to privsep. */
+ rcnt = 0;
+ do {
+ rlen = read(ctx->link_fd, buf, sizeof(buf));
+ if (++rcnt == 100) {
+ logwarnx("drained %zu messages", rcnt);
+ rcnt = 0;
+ }
+ } while (rlen != -1 || errno == ENOBUFS || errno == ENOMEM);
+ if (rcnt != 100)
+ logwarnx("drained %zu messages", rcnt);
/* Work out the current interfaces. */
ifaces = if_discover(ctx, &ifaddrs, ctx->ifc, ctx->ifv);
}
int
-if_linksocket(struct sockaddr_nl *nl, int protocol)
+if_linksocket(struct sockaddr_nl *nl, int protocol, int flags)
{
int fd;
- if ((fd = xsocket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol)) == -1)
+ fd = xsocket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC | flags, protocol);
+ if (fd == -1)
return -1;
nl->nl_family = AF_NETLINK;
if (bind(fd, (struct sockaddr *)nl, sizeof(*nl)) == -1) {
snl.nl_groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH;
#endif
- ctx->link_fd = if_linksocket(&snl, NETLINK_ROUTE);
+ ctx->link_fd = if_linksocket(&snl, NETLINK_ROUTE, SOCK_NONBLOCK);
if (ctx->link_fd == -1)
return -1;
#ifdef NETLINK_BROADCAST_ERROR
ctx->priv = priv;
memset(&snl, 0, sizeof(snl));
- priv->route_fd = if_linksocket(&snl, NETLINK_ROUTE);
+ priv->route_fd = if_linksocket(&snl, NETLINK_ROUTE, 0);
if (priv->route_fd == -1)
return -1;
len = sizeof(snl);
s = priv->route_fd;
} else {
- if ((s = if_linksocket(&snl, protocol)) == -1)
+ if ((s = if_linksocket(&snl, protocol, 0)) == -1)
return -1;
#ifdef NETLINK_GET_STRICT_CHK
if (hdr->nlmsg_type == RTM_GETADDR) {
int xsocket(int, int, int);
#ifdef __linux__
-int if_linksocket(struct sockaddr_nl *, int);
+int if_linksocket(struct sockaddr_nl *, int, int);
int if_getnetlink(struct dhcpcd_ctx *, struct iovec *, int, int,
int (*)(struct dhcpcd_ctx *, void *, struct nlmsghdr *), void *);
#endif
};
ssize_t retval;
- if ((s = if_linksocket(&snl, protocol)) == -1)
+ if ((s = if_linksocket(&snl, protocol, 0)) == -1)
return -1;
if (sendmsg(s, msg, 0) == -1) {