From: Daniel Wagner <daniel.wag...@bmw-carit.de>

Add helper function for flushing all nfacct rules.
---
 Makefile.am   |   2 +-
 src/connman.h |   5 +++
 src/nfacct.c  | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 src/nfacct.c

diff --git a/Makefile.am b/Makefile.am
index 119c0f0..a63ebe0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -97,7 +97,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) 
$(gweb_sources) \
                        src/session.c src/tethering.c src/wpad.c src/wispr.c \
                        src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
                        src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
-                       src/inotify.c src/iptctx.c src/netfilter.c
+                       src/inotify.c src/iptctx.c src/netfilter.c src/nfacct.c
 
 src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
                                @XTABLES_LIBS@ @GNUTLS_LIBS@ -lresolv -ldl -lrt
diff --git a/src/connman.h b/src/connman.h
index 1ffecf9..9c8fbc6 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -925,3 +925,8 @@ void __connman_netfilter_cancel(unsigned int id);
 
 int __connman_netfilter_init(void);
 void __connman_netfilter_cleanup(void);
+
+
+typedef int (* connman_nfacct_flush_cb_t) (int error, void *user_data);
+
+int __connman_nfacct_flush(connman_nfacct_flush_cb_t cb, void *user_data);
diff --git a/src/nfacct.c b/src/nfacct.c
new file mode 100644
index 0000000..b24cc30
--- /dev/null
+++ b/src/nfacct.c
@@ -0,0 +1,131 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2013  BMW Car IT GmbH. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include "connman.h"
+
+struct nfacct_flush {
+       unsigned int pending;
+       int error;
+};
+
+static void nfacct_flush_del_cb(int error, void *user_data)
+{
+       struct cb_data *cbd = user_data;
+       struct nfacct_flush *nff = cbd->data;
+       connman_nfacct_flush_cb_t cb = cbd->cb;
+
+       DBG("error %d pending %d", error, nff->pending);
+
+       nff->pending--;
+
+       if (error < 0)
+               nff->error = error;
+
+       /*
+        * Wait for all pending commands before calling
+        * the callback.
+        */
+       if (nff->pending > 0)
+               return;
+
+       cb(nff->error, cbd->user_data);
+
+       g_free(nff);
+       g_free(cbd);
+}
+
+static void nfacct_flush_cb(int error, const char *name,
+                               uint64_t packets, uint64_t bytes,
+                               void *user_data)
+{
+       struct cb_data *cbd = user_data;
+       struct nfacct_flush *nff = cbd->data;
+       connman_nfacct_flush_cb_t cb = cbd->cb;
+       unsigned int id;
+
+       DBG("name %s packets %lu bytes %lu", name, packets, bytes);
+
+       if (error < 0) {
+               /*
+                * We will only be called once with an error and
+                * will be the first call.
+                */
+               nff->error = error;
+               goto out;
+       }
+
+       if (name == NULL) {
+               /* last call */
+
+               /*
+                * If we have one command pending, let that one
+                * report back the error.
+                */
+               if (nff->pending > 0)
+                       return;
+
+               /*
+                * Either all __connman_netfilter_acct_del() failed
+                * or the dump was empty. In both cases just
+                * call the cb.
+                */
+               goto out;
+       }
+
+       id = __connman_netfilter_acct_del(name, nfacct_flush_del_cb, cbd);
+       if (id == 0) {
+               nff->error = -ECOMM;
+               return;
+       }
+
+       nff->pending++;
+       return;
+
+out:
+       cb(nff->error, cbd->user_data);
+
+       g_free(nff);
+       g_free(cbd);
+}
+
+int __connman_nfacct_flush(connman_nfacct_flush_cb_t cb, void *user_data)
+{
+       struct cb_data *cbd = cb_data_new(cb, user_data);
+       struct nfacct_flush *nff = g_new0(struct nfacct_flush, 1);
+
+       DBG("");
+
+       cbd->data = nff;
+
+       if (__connman_netfilter_acct_dump(FALSE, nfacct_flush_cb, cbd) != 0)
+               return 0;
+
+       g_free(nff);
+       g_free(cbd);
+
+       return -ECOMM;
+}
-- 
1.8.1.3.566.gaa39828

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to