All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nftables,v2] iface: handle EINTR case when creating the cache
@ 2022-01-27 23:06 Pablo Neira Ayuso
  2022-01-28  8:39 ` Eugene Crosser
  0 siblings, 1 reply; 2+ messages in thread
From: Pablo Neira Ayuso @ 2022-01-27 23:06 UTC (permalink / raw)
  To: netfilter-devel; +Cc: crosser

If interface netlink dump is interrupted, then retry.

Before this patch, the netlink socket is reopened to drop stale dump
messages, instead empty the netlink queue and retry.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: immediately return on non-eintr error (instead of breaking the loop),
    per Eugene Crosser.

 src/iface.c | 50 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/src/iface.c b/src/iface.c
index d0e1834ca82f..c0642e0cc397 100644
--- a/src/iface.c
+++ b/src/iface.c
@@ -59,13 +59,13 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
 	return MNL_CB_OK;
 }
 
-void iface_cache_update(void)
+static int iface_mnl_talk(struct mnl_socket *nl, uint32_t portid)
 {
 	char buf[MNL_SOCKET_BUFFER_SIZE];
-	struct mnl_socket *nl;
 	struct nlmsghdr *nlh;
 	struct rtgenmsg *rt;
-	uint32_t seq, portid;
+	bool eintr = false;
+	uint32_t seq;
 	int ret;
 
 	nlh = mnl_nlmsg_put_header(buf);
@@ -75,6 +75,38 @@ void iface_cache_update(void)
 	rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
 	rt->rtgen_family = AF_PACKET;
 
+	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
+		return -1;
+
+	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+	while (ret > 0) {
+		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
+		if (ret == 0)
+			break;
+		if (ret < 0) {
+			if (errno != EINTR)
+				return ret;
+
+			/* process all pending messages before reporting EINTR */
+			eintr = true;
+		}
+		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+	}
+
+	if (eintr) {
+		ret = -1;
+		errno = EINTR;
+	}
+
+	return ret;
+}
+
+void iface_cache_update(void)
+{
+	struct mnl_socket *nl;
+	uint32_t portid;
+	int ret;
+
 	nl = mnl_socket_open(NETLINK_ROUTE);
 	if (nl == NULL)
 		netlink_init_error();
@@ -84,16 +116,10 @@ void iface_cache_update(void)
 
 	portid = mnl_socket_get_portid(nl);
 
-	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
-		netlink_init_error();
+	do {
+		ret = iface_mnl_talk(nl, portid);
+	} while (ret < 0 && errno == EINTR);
 
-	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
-	while (ret > 0) {
-		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
-		if (ret <= MNL_CB_STOP)
-			break;
-		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
-	}
 	if (ret == -1)
 		netlink_init_error();
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH nftables,v2] iface: handle EINTR case when creating the cache
  2022-01-27 23:06 [PATCH nftables,v2] iface: handle EINTR case when creating the cache Pablo Neira Ayuso
@ 2022-01-28  8:39 ` Eugene Crosser
  0 siblings, 0 replies; 2+ messages in thread
From: Eugene Crosser @ 2022-01-28  8:39 UTC (permalink / raw)
  To: Pablo Neira Ayuso, netfilter-devel


[-- Attachment #1.1: Type: text/plain, Size: 2725 bytes --]

Reviewed-by: Eugene Crosser <crosser@average.org>

On 28/01/2022 00:06, Pablo Neira Ayuso wrote:
> If interface netlink dump is interrupted, then retry.
> 
> Before this patch, the netlink socket is reopened to drop stale dump
> messages, instead empty the netlink queue and retry.
> 
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> v2: immediately return on non-eintr error (instead of breaking the loop),
>     per Eugene Crosser.
> 
>  src/iface.c | 50 ++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 38 insertions(+), 12 deletions(-)
> 
> diff --git a/src/iface.c b/src/iface.c
> index d0e1834ca82f..c0642e0cc397 100644
> --- a/src/iface.c
> +++ b/src/iface.c
> @@ -59,13 +59,13 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
>  	return MNL_CB_OK;
>  }
>  
> -void iface_cache_update(void)
> +static int iface_mnl_talk(struct mnl_socket *nl, uint32_t portid)
>  {
>  	char buf[MNL_SOCKET_BUFFER_SIZE];
> -	struct mnl_socket *nl;
>  	struct nlmsghdr *nlh;
>  	struct rtgenmsg *rt;
> -	uint32_t seq, portid;
> +	bool eintr = false;
> +	uint32_t seq;
>  	int ret;
>  
>  	nlh = mnl_nlmsg_put_header(buf);
> @@ -75,6 +75,38 @@ void iface_cache_update(void)
>  	rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
>  	rt->rtgen_family = AF_PACKET;
>  
> +	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
> +		return -1;
> +
> +	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
> +	while (ret > 0) {
> +		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
> +		if (ret == 0)
> +			break;
> +		if (ret < 0) {
> +			if (errno != EINTR)
> +				return ret;
> +
> +			/* process all pending messages before reporting EINTR */
> +			eintr = true;
> +		}
> +		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
> +	}
> +
> +	if (eintr) {
> +		ret = -1;
> +		errno = EINTR;
> +	}
> +
> +	return ret;
> +}
> +
> +void iface_cache_update(void)
> +{
> +	struct mnl_socket *nl;
> +	uint32_t portid;
> +	int ret;
> +
>  	nl = mnl_socket_open(NETLINK_ROUTE);
>  	if (nl == NULL)
>  		netlink_init_error();
> @@ -84,16 +116,10 @@ void iface_cache_update(void)
>  
>  	portid = mnl_socket_get_portid(nl);
>  
> -	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
> -		netlink_init_error();
> +	do {
> +		ret = iface_mnl_talk(nl, portid);
> +	} while (ret < 0 && errno == EINTR);
>  
> -	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
> -	while (ret > 0) {
> -		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
> -		if (ret <= MNL_CB_STOP)
> -			break;
> -		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
> -	}
>  	if (ret == -1)
>  		netlink_init_error();
>  


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-01-28  8:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-27 23:06 [PATCH nftables,v2] iface: handle EINTR case when creating the cache Pablo Neira Ayuso
2022-01-28  8:39 ` Eugene Crosser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.