[libnfnetlink] nfnl: allow disabling and enabling sequence tracking

Pablo Neira netfilter-cvslog-bounces at lists.netfilter.org
Tue Feb 17 20:55:19 CET 2009


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnfnetlink.git;a=commit;h=de8dafc90e335cbb06252a087d25a7589b607ad2
commit de8dafc90e335cbb06252a087d25a7589b607ad2
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Tue Feb 17 20:40:36 2009 +0100
Commit:     Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Tue Feb 17 20:40:36 2009 +0100

    nfnl: allow disabling and enabling sequence tracking
    
    This patch adds a couple of functions to enable and disable netlink
    sequence tracking. Since nfqueue goes over a unicast socket, the
    same channel to receive control messages and packets is used. This
    leads to race conditions that may trigger sporious out-of-sequence
    errors while creating queues and receiving high load of packets at
    the same time.
    
    Reported-by: Anton Vazir <anton.vazir at gmail.com>
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
       via  de8dafc90e335cbb06252a087d25a7589b607ad2 (commit)
      from  b5194b353d27aa0c480691be44e2d4778759c9c0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit de8dafc90e335cbb06252a087d25a7589b607ad2
Author: Pablo Neira Ayuso <pablo at netfilter.org>
Date:   Tue Feb 17 20:40:36 2009 +0100

    nfnl: allow disabling and enabling sequence tracking
    
    This patch adds a couple of functions to enable and disable netlink
    sequence tracking. Since nfqueue goes over a unicast socket, the
    same channel to receive control messages and packets is used. This
    leads to race conditions that may trigger sporious out-of-sequence
    errors while creating queues and receiving high load of packets at
    the same time.
    
    Reported-by: Anton Vazir <anton.vazir at gmail.com>
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

-----------------------------------------------------------------------

 configure.in                        |    2 +-
 include/libnfnetlink/libnfnetlink.h |    4 +++
 src/libnfnetlink.c                  |   37 +++++++++++++++++++++++++++++++---
 3 files changed, 38 insertions(+), 5 deletions(-)
This patch adds a couple of functions to enable and disable netlink
sequence tracking. Since nfqueue goes over a unicast socket, the
same channel to receive control messages and packets is used. This
leads to race conditions that may trigger sporious out-of-sequence
errors while creating queues and receiving high load of packets at
the same time.

Reported-by: Anton Vazir <anton.vazir at gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>

diff --git a/configure.in b/configure.in
index 27b00c2..f760cd0 100644
--- a/configure.in
+++ b/configure.in
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to create configure.
 
-AC_INIT(libnfnetlink, 0.0.40)
+AC_INIT(libnfnetlink, 0.0.41)
 
 AC_CANONICAL_SYSTEM
 
diff --git a/include/libnfnetlink/libnfnetlink.h b/include/libnfnetlink/libnfnetlink.h
index b2f3652..10b6478 100644
--- a/include/libnfnetlink/libnfnetlink.h
+++ b/include/libnfnetlink/libnfnetlink.h
@@ -60,6 +60,10 @@ extern struct nfnl_subsys_handle *nfnl_subsys_open(struct nfnl_handle *,
 						   unsigned int);
 extern void nfnl_subsys_close(struct nfnl_subsys_handle *);
 
+/* set and unset sequence tracking */
+void nfnl_set_sequence_tracking(struct nfnl_handle *h);
+void nfnl_unset_sequence_tracking(struct nfnl_handle *h);
+
 /* set receive buffer size (for nfnl_catch) */
 extern void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size);
 
diff --git a/src/libnfnetlink.c b/src/libnfnetlink.c
index d4212f9..a836de1 100644
--- a/src/libnfnetlink.c
+++ b/src/libnfnetlink.c
@@ -78,6 +78,9 @@ struct nfnl_subsys_handle {
 };
 
 #define		NFNL_MAX_SUBSYS			16 /* enough for now */
+
+#define NFNL_F_SEQTRACK_ENABLED		(1 << 0)
+
 struct nfnl_handle {
 	int			fd;
 	struct sockaddr_nl	local;
@@ -86,6 +89,7 @@ struct nfnl_handle {
 	u_int32_t		seq;
 	u_int32_t		dump;
 	u_int32_t		rcv_buffer_size;	/* for nfnl_catch */
+	u_int32_t		flags;
 	struct nlmsghdr 	*last_nlhdr;
 	struct nfnl_subsys_handle subsys[NFNL_MAX_SUBSYS+1];
 };
@@ -202,6 +206,8 @@ struct nfnl_handle *nfnl_open(void)
 		errno = EINVAL;
 		goto err_close;
 	}
+	/* sequence tracking enabled by default */
+	nfnlh->flags |= NFNL_F_SEQTRACK_ENABLED;
 
 	return nfnlh;
 
@@ -213,6 +219,24 @@ err_free:
 }
 
 /**
+ * nfnl_set_sequence_tracking - set netlink sequence tracking
+ * @h: nfnetlink handler
+ */
+void nfnl_set_sequence_tracking(struct nfnl_handle *h)
+{
+	h->flags |= NFNL_F_SEQTRACK_ENABLED;
+}
+
+/**
+ * nfnl_unset_sequence_tracking - set netlink sequence tracking
+ * @h: nfnetlink handler
+ */
+void nfnl_unset_sequence_tracking(struct nfnl_handle *h)
+{
+	h->flags &= ~NFNL_F_SEQTRACK_ENABLED;
+}
+
+/**
  * nfnl_set_rcv_buffer_size - set the size of the receive buffer
  * @h: libnfnetlink handler
  * @size: buffer size
@@ -418,11 +442,16 @@ void nfnl_fill_hdr(struct nfnl_subsys_handle *ssh,
 	nlh->nlmsg_type = (ssh->subsys_id<<8)|msg_type;
 	nlh->nlmsg_flags = msg_flags;
 	nlh->nlmsg_pid = 0;
-	nlh->nlmsg_seq = ++ssh->nfnlh->seq;
 
-	/* check for wraparounds: assume that seqnum 0 is only used by events */
-	if (!ssh->nfnlh->seq)
-		nlh->nlmsg_seq = ssh->nfnlh->seq = time(NULL);
+	if (ssh->nfnlh->flags & NFNL_F_SEQTRACK_ENABLED) {
+		nlh->nlmsg_seq = ++ssh->nfnlh->seq;
+		/* kernel uses sequence number zero for events */
+		if (!ssh->nfnlh->seq)
+			nlh->nlmsg_seq = ssh->nfnlh->seq = time(NULL);
+	} else {
+		/* unset sequence number, ignore it */
+		nlh->nlmsg_seq = 0;
+	}
 
 	nfg->nfgen_family = family;
 	nfg->version = NFNETLINK_V0;



More information about the netfilter-cvslog mailing list