[PATCH nft,v2] mnl: remove nft_mnl_socket_reopen()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



nft_mnl_socket_reopen() was introduced to deal with the EINTR case.
By reopening the netlink socket, pending netlink messages that are part
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@xxxxxxxxxxxxx>
---
v2: split < 0 and == 0 cases in nft_mnl_recv().

 include/mnl.h |  1 -
 src/mnl.c     | 27 ++++++++++++++++-----------
 src/rule.c    |  5 ++---
 3 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/include/mnl.h b/include/mnl.h
index 74b1b56fd686..979929c31c17 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -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);
diff --git a/src/mnl.c b/src/mnl.c
index 84cfb2380f55..e3045accd85a 100644
--- 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,32 @@ 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)
+		if (ret == 0)
 			goto out;
+		if (ret < 0) {
+			if (errno == EAGAIN) {
+				ret = 0;
+				goto out;
+			}
+			if (errno != EINTR)
+				goto out;
 
+			/* 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;
 }
 
diff --git a/src/rule.c b/src/rule.c
index acb10f65a517..367c5c8be952 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -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;
 	}
 
-- 
2.20.1




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux