@@ -33,19 +33,20 @@ static void netlink_receive_link(struct netlink_data *netlink,
}
-static void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx)
+static void _netlink_process_one_event(struct netlink_data *netlink,
+ int wait_single)
{
- struct netlink_data *netlink = eloop_ctx;
char buf[8192];
int left;
struct sockaddr_nl from;
socklen_t fromlen;
struct nlmsghdr *h;
- int max_events = 10;
+ int max_events = wait_single ? 1 : 10;
try_again:
fromlen = sizeof(from);
- left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
+ left = recvfrom(netlink->sock, buf, sizeof(buf),
+ wait_single ? 0 : MSG_DONTWAIT,
(struct sockaddr *) &from, &fromlen);
if (left < 0) {
if (errno != EINTR && errno != EAGAIN)
@@ -88,6 +89,40 @@ try_again:
}
+void netlink_process_one_event(struct netlink_data *netlink,
+ unsigned int timeout_ms)
+{
+ if (timeout_ms) {
+ struct timeval timeout = {
+ .tv_sec = timeout_ms / 1000,
+ .tv_usec = 1000 * (timeout_ms % 1000),
+ };
+ fd_set read_set;
+ int ret;
+
+ FD_ZERO(&read_set);
+ FD_SET(netlink->sock, &read_set);
+
+ ret = select(netlink->sock + 1, &read_set, NULL, NULL,
+ &timeout);
+ if (ret < 0) {
+ perror("select on netlink socket");
+ return;
+ }
+ if (ret == 0)
+ return;
+ }
+
+ _netlink_process_one_event(netlink, 1);
+}
+
+
+static void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx)
+{
+ _netlink_process_one_event(eloop_ctx, 0);
+}
+
+
struct netlink_data * netlink_init(struct netlink_config *cfg)
{
struct netlink_data *netlink;
@@ -21,6 +21,8 @@ struct netlink_config {
};
struct netlink_data * netlink_init(struct netlink_config *cfg);
+void netlink_process_one_event(struct netlink_data *netlink,
+ unsigned int timeout_ms);
void netlink_deinit(struct netlink_data *netlink);
int netlink_send_oper_ifla(struct netlink_data *netlink, int ifindex,
int linkmode, int operstate);