diff --git a/missing.h b/missing.h index 43ac6cf..f7efd92 100644 --- a/missing.h +++ b/missing.h @@ -58,6 +58,10 @@ enum _missing_hwtstamp_tx_types { #define SIOCGHWTSTAMP 0x89b1 #endif +#ifndef SO_SELECT_ERR_QUEUE +#define SO_SELECT_ERR_QUEUE 45 +#endif + #ifndef HAVE_CLOCK_ADJTIME static inline int clock_adjtime(clockid_t id, struct timex *tx) { diff --git a/sk.c b/sk.c index c48cf45..847855a 100644 --- a/sk.c +++ b/sk.c @@ -32,6 +32,7 @@ #include "address.h" #include "ether.h" +#include "missing.h" #include "print.h" #include "sk.h" @@ -208,6 +209,9 @@ int sk_interface_addr(const char *name, int family, struct address *addr) return result; } +static short sk_events = POLLPRI; +static short sk_revents = POLLPRI; + int sk_receive(int fd, void *buf, int buflen, struct address *addr, struct hw_timestamp *hwts, int flags) { @@ -230,7 +234,7 @@ int sk_receive(int fd, void *buf, int buflen, msg.msg_controllen = sizeof(control); if (flags == MSG_ERRQUEUE) { - struct pollfd pfd = { fd, 0, 0 }; + struct pollfd pfd = { fd, sk_events, 0 }; res = poll(&pfd, 1, sk_tx_timeout); if (res < 1) { pr_err(res ? "poll for tx timestamp failed: %m" : @@ -238,7 +242,7 @@ int sk_receive(int fd, void *buf, int buflen, pr_err("increasing tx_timestamp_timeout may correct " "this issue, but it is likely caused by a driver bug"); return res; - } else if (!(pfd.revents & POLLERR)) { + } else if (!(pfd.revents & sk_revents)) { pr_err("poll for tx timestamp woke up on non ERR event"); return -1; } @@ -352,6 +356,14 @@ int sk_timestamping_init(int fd, const char *device, enum timestamp_type type, return -1; } + flags = 1; + if (setsockopt(fd, SOL_SOCKET, SO_SELECT_ERR_QUEUE, + &flags, sizeof(flags)) < 0) { + pr_warning("%s: SO_SELECT_ERR_QUEUE: %m", device); + sk_events = 0; + sk_revents = POLLERR; + } + /* Enable the sk_check_fupsync option, perhaps. */ if (sk_general_init(fd)) { return -1;