diff mbox series

[libnetfilter_queue,v2,03/15] src: Convert nfq_close() to use libmnl

Message ID 20240524053742.27294-4-duncan_roe@optusnet.com.au
State New
Headers show
Series Convert libnetfilter_queue to not need libnfnetlink | expand

Commit Message

Duncan Roe May 24, 2024, 5:37 a.m. UTC
Use mnl_close() and clean up the NFNL_SUBSYS_QUEUE subsystem as
nfnl_close() would have done

Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au>
---
 Changes in v2:
 - Propogate return from mnl_socket_close()
 - Don't free callbacks in the qh_list since nfq_close() didn't
   (reported as a bug)
 - Do a complete emulation of nfnl_close()
 - Add explanatory comments

 src/libnetfilter_queue.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/libnetfilter_queue.c b/src/libnetfilter_queue.c
index bfb6482..0483780 100644
--- a/src/libnetfilter_queue.c
+++ b/src/libnetfilter_queue.c
@@ -577,8 +577,30 @@  EXPORT_SYMBOL
 int nfq_close(struct nfq_handle *h)
 {
 	int ret;
+	int i;
+
+	ret = mnl_socket_close(h->nl);
+	h->nl = NULL;              /* mnl_socket_close() always frees it */
+
+	/* Replacement code for nfnl_close().
+	 * It seems unlikely that we need to go through all 16 subsystems
+	 * instead of only subsys[NFNL_SUBSYS_QUEUE] which h->nfnlssh
+	 * conveniently points to, but better safe than sorry.
+	 */
+	for (i = 0; i < NFNL_MAX_SUBSYS; i++) {
+		h->nfnlh->subsys[i].subscriptions = 0;
+		h->nfnlh->subsys[i].cb_count = 0;
+		if (h->nfnlh->subsys[i].cb) {
+			free(h->nfnlh->subsys[i].cb);
+			h->nfnlh->subsys[i].cb = NULL;
+		}
+	}
+	if (ret == 0)
+		free(h->nfnlh);
 
-	ret = nfnl_close(h->nfnlh);
+	/* nfnl_close() didn't free nfnlh if close() returned an error.
+	 * Presumably that's why nfq_close() doesn't free h in that case.
+	 */
 	if (ret == 0)
 		free(h);
 	return ret;