[nft PATCH 1/4] mnl: Maximize socket receive buffer by default

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

 



With --echo option, regular commands may receive large replies just like
'nft monitor' does. Avoid buffer overruns and message loss by maximizing
the global nf_sock's receive buffer size upon creating, not just when
calling mnl_nft_event_listener.

Error reporting is tricky in nft_mnl_socket_open(), also being warned
about failures during receive buffer increase adds little value to the
user. So just fail silently instead.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 src/mnl.c | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/src/mnl.c b/src/mnl.c
index 9bb712adfa3b5..2c5a26a5e3465 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -33,6 +33,26 @@
 #include <utils.h>
 #include <nftables.h>
 
+#define NFTABLES_NLEVENT_BUFSIZ	(1 << 24)
+
+static void maximize_recv_buffer(struct mnl_socket *nf_sock)
+{
+	unsigned int bufsiz = NFTABLES_NLEVENT_BUFSIZ;
+	int fd = mnl_socket_get_fd(nf_sock);
+
+	/* Set netlink socket buffer size to 16 Mbytes to reduce chances of
+	 * message loss due to ENOBUFS.
+	 */
+	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE,
+		       &bufsiz, sizeof(socklen_t)) < 0) {
+		/* If this doesn't work, try to reach the system wide maximum
+		 * (or whatever the user requested).
+		 */
+		setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+			   &bufsiz, sizeof(socklen_t));
+	}
+}
+
 struct mnl_socket *nft_mnl_socket_open(void)
 {
 	struct mnl_socket *nf_sock;
@@ -44,6 +64,7 @@ struct mnl_socket *nft_mnl_socket_open(void)
 	if (fcntl(mnl_socket_get_fd(nf_sock), F_SETFL, O_NONBLOCK))
 		netlink_init_error();
 
+	maximize_recv_buffer(nf_sock);
 	return nf_sock;
 }
 
@@ -1379,37 +1400,17 @@ int mnl_nft_flowtable_del(struct netlink_ctx *ctx, const struct cmd *cmd)
 /*
  * events
  */
-#define NFTABLES_NLEVENT_BUFSIZ	(1 << 24)
 
 int mnl_nft_event_listener(struct mnl_socket *nf_sock, unsigned int debug_mask,
 			   struct output_ctx *octx,
 			   int (*cb)(const struct nlmsghdr *nlh, void *data),
 			   void *cb_data)
 {
-	/* Set netlink socket buffer size to 16 Mbytes to reduce chances of
- 	 * 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(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(fd, SOL_SOCKET, SO_RCVBUF, &bufsiz,
-				 sizeof(socklen_t));
-		if (ret < 0)
-			nft_print(octx, "# Cannot increase netlink socket buffer size, expect message loss\n");
-		else
-			nft_print(octx, "# Cannot set up netlink socket buffer size to %u bytes, falling back to %u bytes\n",
-				  NFTABLES_NLEVENT_BUFSIZ, bufsiz);
-	}
-
 	while (1) {
 		FD_ZERO(&readfds);
 		FD_SET(fd, &readfds);
-- 
2.21.0




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

  Powered by Linux