]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
mnl: remove nft_mnl_socket_reopen()
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 2 Mar 2021 11:35:20 +0000 (12:35 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 5 Mar 2021 19:42:14 +0000 (20:42 +0100)
nft_mnl_socket_reopen() was introduced to deal with the EINTR case.
By reopening the netlink socket, pending netlink messages that are part of
a stale netlink dump are implicitly drop. This patch replaces the
nft_mnl_socket_reopen() strategy by pulling out all of the remaining
netlink message to restart in a clean state.

This is implicitly fixing up a bug in the table ownership support, which
assumes that the netlink socket remains open until nft_ctx_free() is
invoked.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/mnl.h
src/mnl.c
src/rule.c

index 74b1b56fd6864249364e36fc2b8f7699275220e0..979929c31c17bfcc5b9c34e384830c0eb461b615 100644 (file)
@@ -7,7 +7,6 @@
 #include <libmnl/libmnl.h>
 
 struct mnl_socket *nft_mnl_socket_open(void);
-struct mnl_socket *nft_mnl_socket_reopen(struct mnl_socket *nf_sock);
 
 uint32_t mnl_seqnum_alloc(uint32_t *seqnum);
 uint32_t mnl_genid_get(struct netlink_ctx *ctx);
index 84cfb2380f555a63f37b27f15b2c188cccf8725f..9c965446521c0359689553a65de0049be20e4eca 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -52,13 +52,6 @@ struct mnl_socket *nft_mnl_socket_open(void)
        return nf_sock;
 }
 
-struct mnl_socket *nft_mnl_socket_reopen(struct mnl_socket *nf_sock)
-{
-       mnl_socket_close(nf_sock);
-
-       return nft_mnl_socket_open();
-}
-
 uint32_t mnl_seqnum_alloc(unsigned int *seqnum)
 {
        return (*seqnum)++;
@@ -77,20 +70,31 @@ nft_mnl_recv(struct netlink_ctx *ctx, uint32_t portid,
             int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
 {
        char buf[NFT_NLMSG_MAXSIZE];
+       bool eintr = false;
        int ret;
 
        ret = mnl_socket_recvfrom(ctx->nft->nf_sock, buf, sizeof(buf));
        while (ret > 0) {
                ret = mnl_cb_run(buf, ret, ctx->seqnum, portid, cb, cb_data);
-               if (ret <= 0)
-                       goto out;
+               if (ret == 0)
+                       break;
+               if (ret < 0) {
+                       if (errno == EAGAIN) {
+                               ret = 0;
+                               break;
+                       }
+                       if (errno != EINTR)
+                               break;
 
+                       /* process all pending messages before reporting EINTR */
+                       eintr = true;
+               }
                ret = mnl_socket_recvfrom(ctx->nft->nf_sock, buf, sizeof(buf));
        }
-out:
-       if (ret < 0 && errno == EAGAIN)
-               return 0;
-
+       if (eintr) {
+               ret = -1;
+               errno = EINTR;
+       }
        return ret;
 }
 
index acb10f65a517145ee1f41df667f5037ae98e1ca4..367c5c8be9521975290320f5141ff298527f4420 100644 (file)
@@ -292,10 +292,9 @@ replay:
        ret = cache_init(&ctx, flags);
        if (ret < 0) {
                cache_release(cache);
-               if (errno == EINTR) {
-                       nft->nf_sock = nft_mnl_socket_reopen(nft->nf_sock);
+               if (errno == EINTR)
                        goto replay;
-               }
+
                return -1;
        }