@@ -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;
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(-)