diff mbox series

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

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

Commit Message

Duncan Roe Oct. 12, 2024, 11:09 p.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 v3: manually merge f05b188f8b4c patch
 
 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 | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/libnetfilter_queue.c b/src/libnetfilter_queue.c
index b3d1835..8698431 100644
--- a/src/libnetfilter_queue.c
+++ b/src/libnetfilter_queue.c
@@ -577,6 +577,7 @@  EXPORT_SYMBOL
 int nfq_close(struct nfq_handle *h)
 {
 	int ret;
+	int i;
 	struct nfq_q_handle *qh;
 
 	while (h->qh_list) {
@@ -584,7 +585,29 @@  int nfq_close(struct nfq_handle *h)
 		h->qh_list = qh->next;
 		free(qh);
 	}
-	ret = nfnl_close(h->nfnlh);
+
+	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);
+
+	/* 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;