bool cache_needed;
};
-extern int netlink_monitor(struct netlink_mon_handler *monhandler);
+extern int netlink_monitor(struct netlink_mon_handler *monhandler,
+ struct mnl_socket *nf_sock);
bool netlink_batch_supported(struct mnl_socket *nf_sock);
#endif /* NFTABLES_NETLINK_H */
* message loss due to ENOBUFS.
*/
unsigned int bufsiz = NFTABLES_NLEVENT_BUFSIZ;
+ int fd = mnl_socket_get_fd(nf_sock);
char buf[NFT_NLMSG_MAXSIZE];
+ fd_set readfds;
int ret;
- ret = setsockopt(mnl_socket_get_fd(nf_sock), SOL_SOCKET, SO_RCVBUFFORCE,
- &bufsiz, sizeof(socklen_t));
- if (ret < 0) {
+ ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &bufsiz,
+ sizeof(socklen_t));
+ if (ret < 0) {
/* If this doesn't work, try to reach the system wide maximum
* (or whatever the user requested).
*/
- ret = setsockopt(mnl_socket_get_fd(nf_sock), SOL_SOCKET,
- SO_RCVBUF, &bufsiz, sizeof(socklen_t));
+ ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsiz,
+ sizeof(socklen_t));
printf("# Cannot set up netlink socket buffer size to %u bytes, falling back to %u bytes\n",
NFTABLES_NLEVENT_BUFSIZ, bufsiz);
}
while (1) {
- ret = mnl_socket_recvfrom(nf_sock, buf, sizeof(buf));
- if (ret < 0) {
- if (errno == ENOBUFS) {
- printf("# ERROR: We lost some netlink events!\n");
- continue;
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ ret = select(fd + 1, &readfds, NULL, NULL, NULL);
+ if (ret < 0)
+ return -1;
+
+ if (FD_ISSET(fd, &readfds)) {
+ ret = mnl_socket_recvfrom(nf_sock, buf, sizeof(buf));
+ if (ret < 0) {
+ if (errno == ENOBUFS) {
+ printf("# ERROR: We lost some netlink events!\n");
+ continue;
+ }
+ fprintf(stdout, "# ERROR: %s\n", strerror(errno));
+ break;
}
- fprintf(stdout, "# ERROR: %s\n", strerror(errno));
- break;
}
#ifdef DEBUG
#include <erec.h>
#include <iface.h>
-static struct mnl_socket *nf_mon_sock;
-
const struct input_descriptor indesc_netlink = {
.name = "netlink",
.type = INDESC_NETLINK,
{
if (nf_sock)
mnl_socket_close(nf_sock);
- if (nf_mon_sock)
- mnl_socket_close(nf_mon_sock);
}
void netlink_restart(struct mnl_socket *nf_sock)
mnl_genid_get(nf_sock);
}
-static void netlink_open_mon_sock(void)
-{
- nf_mon_sock = nfsock_open();
-}
-
void __noreturn __netlink_abi_error(const char *file, int line,
const char *reason)
{
return ret;
}
-int netlink_monitor(struct netlink_mon_handler *monhandler)
+int netlink_monitor(struct netlink_mon_handler *monhandler,
+ struct mnl_socket *nf_sock)
{
- netlink_open_mon_sock();
+ int group;
+
+ group = NFNLGRP_NFTABLES;
+ if (mnl_socket_setsockopt(nf_sock, NETLINK_ADD_MEMBERSHIP, &group,
+ sizeof(int)) < 0)
+ return netlink_io_error(monhandler->ctx, monhandler->loc,
+ "Could not bind to netlink socket %s",
+ strerror(errno));
- if (mnl_socket_bind(nf_mon_sock, (1 << (NFNLGRP_NFTABLES-1)) |
- (1 << (NFNLGRP_NFTRACE-1)),
- MNL_SOCKET_AUTOPID) < 0)
+ group = NFNLGRP_NFTRACE;
+ if (mnl_socket_setsockopt(nf_sock, NETLINK_ADD_MEMBERSHIP, &group,
+ sizeof(int)) < 0)
return netlink_io_error(monhandler->ctx, monhandler->loc,
"Could not bind to netlink socket %s",
strerror(errno));
- return mnl_nft_event_listener(nf_mon_sock, netlink_events_cb,
+ return mnl_nft_event_listener(nf_sock, netlink_events_cb,
monhandler);
}
monhandler.ctx = ctx;
monhandler.loc = &cmd->location;
- return netlink_monitor(&monhandler);
+ return netlink_monitor(&monhandler, ctx->nf_sock);
}
static int do_command_describe(struct netlink_ctx *ctx, struct cmd *cmd)