summaryrefslogtreecommitdiffstats
path: root/src/origin.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-05-23 12:54:51 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-05-23 12:54:51 +0200
commitef047d03613bf9fa105db009773136817e2ec4c6 (patch)
tree7bdeaa64da5ebe1aeb79bdfaa8c24fa8de2cfad7 /src/origin.c
parent0374398fd14bf587d80d9d31e361e266e69387c8 (diff)
conntrackd: detect where the events comes from
Since Linux kernel 2.6.29, ctnetlink reports the changes that have been done using ctnetlink. With this patch, conntrackd can recognize who is the origin of the event messages. For example, this is interesting to avoid a messy implicit bulk send during the commit of entries. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/origin.c')
-rw-r--r--src/origin.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/origin.c b/src/origin.c
new file mode 100644
index 0000000..3c65f3d
--- /dev/null
+++ b/src/origin.c
@@ -0,0 +1,70 @@
+/*
+ * (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "conntrackd.h"
+#include "origin.h"
+
+static LIST_HEAD(origin_list);
+
+struct origin {
+ struct list_head head;
+ unsigned int nl_portid;
+ int type;
+};
+
+/* register a Netlink socket as origin of possible events */
+int origin_register(struct nfct_handle *h, int origin_type)
+{
+ struct origin *nlp;
+
+ nlp = calloc(sizeof(struct origin), 1);
+ if (nlp == NULL)
+ return -1;
+
+ nlp->nl_portid = nfnl_portid(nfct_nfnlh(h));
+ nlp->type = origin_type;
+
+ list_add(&nlp->head, &origin_list);
+ return 0;
+}
+
+/* look up for the origin of this Netlink event */
+int origin_find(const struct nlmsghdr *nlh)
+{
+ struct origin *this;
+
+ list_for_each_entry(this, &origin_list, head) {
+ if (this->nl_portid == nlh->nlmsg_pid) {
+ return this->type;
+ }
+ }
+ return CTD_ORIGIN_NOT_ME;
+}
+
+int origin_unregister(struct nfct_handle *h)
+{
+ struct origin *this, *tmp;
+
+ list_for_each_entry_safe(this, tmp, &origin_list, head) {
+ if (this->nl_portid == nfnl_portid(nfct_nfnlh(h))) {
+ list_del(&this->head);
+ free(this);
+ return 1;
+ }
+ }
+ return 0;
+}