diff mbox series

[RFC,conntrack-tools] conntrack-tools: introduce conntrackdctl

Message ID 161243463641.9380.7754148010781645692.stgit@endurance
State RFC
Delegated to: Pablo Neira
Headers show
Series [RFC,conntrack-tools] conntrack-tools: introduce conntrackdctl | expand

Commit Message

Arturo Borrero Gonzalez Feb. 4, 2021, 10:32 a.m. UTC
Separate conntrackd command line client functionalities into a different
binary.

This should help with several things:
 * avoid reading and parsing the config file, which can fail in some enviroments, for example if
   conntrackd is running inside a netns and the referenced interfaces/addresses doesn't exist in
   the namespace conntrackd client command is running from.
 * easily update conntrakdctl with more functionalities without polluting the daemon binary
 * easier code maintenance

Signed-off-by: Arturo Borrero Gonzalez <arturo@netfilter.org>
---
NOTE: this is just an idea, comments welcome. I have plans to extend this new binary with more
options in the future.

 include/local.h     |   10 +-
 src/.gitignore      |    1 
 src/Makefile.am     |    5 +
 src/conntrackdctl.c |  292 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/local.c         |   18 +--
 src/main.c          |  223 +++------------------------------------
 6 files changed, 325 insertions(+), 224 deletions(-)
 create mode 100644 src/conntrackdctl.c

Comments

Pablo Neira Ayuso Feb. 5, 2021, 12:28 p.m. UTC | #1
On Thu, Feb 04, 2021 at 11:32:06AM +0100, Arturo Borrero Gonzalez wrote:
> Separate conntrackd command line client functionalities into a different
> binary.
> 
> This should help with several things:
>  * avoid reading and parsing the config file, which can fail in some enviroments, for example if
>    conntrackd is running inside a netns and the referenced interfaces/addresses doesn't exist in
>    the namespace conntrackd client command is running from.
>  * easily update conntrakdctl with more functionalities without polluting the daemon binary
>  * easier code maintenance
[...]
> @@ -333,15 +151,6 @@ int main(int argc, char *argv[])
>  		exit(EXIT_FAILURE);
>  	}
>  
> -	if (type == REQUEST) {
> -		if (do_local_request(action, &conf.local, local_step) == -1) {
> -			dlog(LOG_ERR, "can't connect: is conntrackd "
> -			     "running? appropriate permissions?");
> -			exit(EXIT_FAILURE);
> -		}
> -		exit(EXIT_SUCCESS);
> -	}

The existing interface needs to be in place to be backward compatible.

I'm fine for you to add this, but we'll have to leave the existing
interface for quite a bit of time, it might take years before we can
deprecate the old way.
Pablo Neira Ayuso Feb. 6, 2021, 1:57 a.m. UTC | #2
On Fri, Feb 05, 2021 at 01:28:24PM +0100, Pablo Neira Ayuso wrote:
> On Thu, Feb 04, 2021 at 11:32:06AM +0100, Arturo Borrero Gonzalez wrote:
> > Separate conntrackd command line client functionalities into a different
> > binary.
> > 
> > This should help with several things:
> >  * avoid reading and parsing the config file, which can fail in some enviroments, for example if
> >    conntrackd is running inside a netns and the referenced interfaces/addresses doesn't exist in
> >    the namespace conntrackd client command is running from.
> >  * easily update conntrakdctl with more functionalities without polluting the daemon binary
> >  * easier code maintenance
> [...]
> > @@ -333,15 +151,6 @@ int main(int argc, char *argv[])
> >  		exit(EXIT_FAILURE);
> >  	}
> >  
> > -	if (type == REQUEST) {
> > -		if (do_local_request(action, &conf.local, local_step) == -1) {
> > -			dlog(LOG_ERR, "can't connect: is conntrackd "
> > -			     "running? appropriate permissions?");
> > -			exit(EXIT_FAILURE);
> > -		}
> > -		exit(EXIT_SUCCESS);
> > -	}
> 
> The existing interface needs to be in place to be backward compatible.
> 
> I'm fine for you to add this, but we'll have to leave the existing
> interface for quite a bit of time, it might take years before we can
> deprecate the old way.

You could probably update conntrackd to invoke conntrackdctl when you
detect options that represent queries to the daemon. That would allow
you to retain backward compatibility. Hence, old scripts still work
while new ones might start using the new conntrackdctl command.

If the problem is that you would like to skip the config parsing
(which is what has triggered the errors when running things from the
netns environment IIRC), then, you could update the code to skip the
parsing:

- the user does not specify a configuration file

AND

- the options refer to a query to the daemon via UNIX socket.

That's another possibility to consider.
diff mbox series

Patch

diff --git a/include/local.h b/include/local.h
index 9379446..505708b 100644
--- a/include/local.h
+++ b/include/local.h
@@ -5,6 +5,8 @@ 
 #define UNIX_PATH_MAX   108
 #endif
 
+#define DEFAULT_SOCKET_PATH "/var/run/conntrackd.ctl"
+
 struct local_conf {
 	int reuseaddr;
 	char path[UNIX_PATH_MAX + 1];
@@ -26,11 +28,7 @@  void local_server_destroy(struct local_server *server);
 int do_local_server_step(struct local_server *server, void *data, 
 			 int (*process)(int fd, void *data));
 
-/* local client */
-int local_client_create(struct local_conf *conf);
-void local_client_destroy(int fd);
-int do_local_client_step(int fd, void (*process)(char *buf));
-int do_local_request(int, struct local_conf *,void (*step)(char *buf));
-void local_step(char *buf);
+/* local client, conntrackdctl */
+int do_local_request(int request, const char *socket_path);
 
 #endif
diff --git a/src/.gitignore b/src/.gitignore
index 55a0d27..fd09ef1 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,6 +1,7 @@ 
 /conntrack
 /conntrackd
 /nfct
+/conntrackdctl
 
 /read_config_lex.c
 /read_config_yy.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 2e66ee9..ca9e43a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,7 @@  AM_YFLAGS = -d
 
 CLEANFILES = read_config_yy.c read_config_lex.c
 
-sbin_PROGRAMS = conntrack conntrackd nfct
+sbin_PROGRAMS = conntrack conntrackd nfct conntrackdctl
 
 conntrack_SOURCES = conntrack.c
 conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp.la ../extensions/libct_proto_udplite.la ../extensions/libct_proto_icmp.la ../extensions/libct_proto_icmpv6.la ../extensions/libct_proto_sctp.la ../extensions/libct_proto_dccp.la ../extensions/libct_proto_gre.la ../extensions/libct_proto_unknown.la ${LIBNETFILTER_CONNTRACK_LIBS} ${LIBMNL_LIBS} ${LIBNFNETLINK_LIBS}
@@ -54,6 +54,9 @@  conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c queue_tx.c rbtree.c \
 		    read_config_yy.y read_config_lex.l \
 		    stack.c resync.c
 
+conntrackdctl_SOURCES = conntrackdctl.c local.c
+conntrackdctl_LDADD   = ${libdl_LIBS}
+
 if HAVE_CTHELPER
 conntrackd_SOURCES += cthelper.c helpers.c utils.c expect.c
 endif
diff --git a/src/conntrackdctl.c b/src/conntrackdctl.c
new file mode 100644
index 0000000..42f9449
--- /dev/null
+++ b/src/conntrackdctl.c
@@ -0,0 +1,292 @@ 
+/*
+ * (C) 2006-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2011 by Vyatta Inc. <http://www.vyatta.com>
+ *
+ * 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 "log.h"
+#include "helper.h"
+#include "systemd.h"
+#include "resync.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/utsname.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+
+static const char usage_client_commands[] =
+	"conntrackdctl options:\n"
+        "  -u <path>, full path to the Unix domain socket used to connect to conntrackd. "
+        "Defaults to '/var/run/conntrackd.ctl'\n"
+	"  -c [ct|expect], commit external cache to conntrack table\n"
+	"  -f [internal|external], flush internal and external cache\n"
+	"  -F [ct|expect], flush kernel conntrack table\n"
+	"  -i [ct|expect], display content of the internal cache\n"
+	"  -e [ct|expect], display the content of the external cache\n"
+	"  -k, kill conntrack daemon\n"
+	"  -s [network|cache|runtime|link|rsqueue|queue|ct|expect] dump statistics. "
+	"Defaults to 'ct'\n"
+	"  -R [ct|expect], resync with kernel conntrack table\n"
+	"  -n, request resync with other node (only FT-FW and NOTRACK modes)\n"
+	"  -B, force a bulk send to other replica firewalls\n"
+	"  -x, dump cache in XML format (requires -i or -e)\n"
+	"  -t, reset the kernel timeout (see PurgeTimeout clause)\n"
+	"  -v, show version information\n"
+	"  -h, show this help message\n";
+
+static void
+show_usage(char *progname)
+{
+	fprintf(stdout, "conntrackdctl utility to interact with conntrackd, v%s\n", VERSION);
+	fprintf(stdout, "Usage: %s [options]\n\n", progname);
+	fprintf(stdout, "%s\n", usage_client_commands);
+}
+
+static void
+show_version(void)
+{
+	fprintf(stdout, "conntrackdctl utilty to interact with conntrackd, v%s. ", VERSION);
+	fprintf(stdout, "Licensed under GPLv2.\n");
+	fprintf(stdout, "(C) 2006-2009 Pablo Neira Ayuso ");
+	fprintf(stdout, "<pablo@netfilter.org>\n");
+}
+
+static int
+set_action_by_table(int i, int argc, char *argv[],
+		    int ct_action, int exp_action, int dfl_action, int *action)
+{
+	if (i+1 < argc && argv[i+1][0] != '-') {
+		if (strncmp(argv[i+1], "ct", strlen(argv[i+1])) == 0) {
+			*action = ct_action;
+			i++;
+		} else if (strncmp(argv[i+1], "expect",
+						strlen(argv[i+1])) == 0) {
+			*action = exp_action;
+			i++;
+		}
+	} else
+		*action = dfl_action;
+
+	return i;
+}
+
+static void set_exec_env(void)
+{
+	umask(0177);
+	close(STDIN_FILENO);
+	if (chdir("/"))
+		fprintf(stderr, "WARNING: could not chdir to '/' (root): %s", strerror(errno));
+}
+
+int main(int argc, char *argv[])
+{
+	char socket_path[PATH_MAX + 1] = {};
+	int i, action = -1;
+	struct utsname u;
+	int version, major, minor;
+
+	/* Check kernel version: it must be >= 2.6.18 */
+	if (uname(&u) == -1) {
+		fprintf(stderr, "ERROR: can't retrieve kernel version via uname()");
+		exit(EXIT_FAILURE);
+	}
+	sscanf(u.release, "%d.%d.%d", &version, &major, &minor);
+	if (version < 2 && major < 6 && minor < 18) {
+		fprintf(stderr, "ERROR: Linux kernel version must be >= 2.6.18");
+		exit(EXIT_FAILURE);
+	}
+
+	for (i=1; i<argc; i++) {
+		switch(argv[i][1]) {
+		case 'c':
+			i = set_action_by_table(i, argc, argv,
+						CT_COMMIT, EXP_COMMIT,
+						ALL_COMMIT, &action);
+			break;
+		case 'i':
+			i = set_action_by_table(i, argc, argv,
+						CT_DUMP_INTERNAL,
+						EXP_DUMP_INTERNAL,
+						CT_DUMP_INTERNAL, &action);
+			break;
+		case 'e':
+			i = set_action_by_table(i, argc, argv,
+						CT_DUMP_EXTERNAL,
+						EXP_DUMP_EXTERNAL,
+						CT_DUMP_EXTERNAL, &action);
+			break;
+		case 'F':
+			i = set_action_by_table(i, argc, argv,
+						CT_FLUSH_MASTER,
+						EXP_FLUSH_MASTER,
+						ALL_FLUSH_MASTER, &action);
+			break;
+		case 'f':
+			if (i+1 < argc && argv[i+1][0] != '-') {
+				if (strncmp(argv[i+1], "internal",
+					    strlen(argv[i+1])) == 0) {
+					action = CT_FLUSH_INT_CACHE;
+					i++;
+				} else if (strncmp(argv[i+1], "external",
+						 strlen(argv[i+1])) == 0) {
+					action = CT_FLUSH_EXT_CACHE;
+					i++;
+				} else {
+					fprintf(stderr, "unknown parameter `%s' "
+					     "for option `-f'", argv[i + 1]);
+					exit(EXIT_FAILURE);
+				}
+			} else {
+				/* default to general flushing */
+				action = ALL_FLUSH_CACHE;
+			}
+			break;
+		case 'R':
+			i = set_action_by_table(i, argc, argv,
+						CT_RESYNC_MASTER,
+						EXP_RESYNC_MASTER,
+						ALL_RESYNC_MASTER, &action);
+			break;
+		case 'B':
+			action = SEND_BULK;
+			break;
+		case 't':
+			action = RESET_TIMERS;
+			break;
+		case 'k':
+			action = KILL;
+			break;
+		case 's':
+			/* we've got a parameter */
+			if (i+1 < argc && argv[i+1][0] != '-') {
+				if (strncmp(argv[i+1], "network",
+					    strlen(argv[i+1])) == 0) {
+					action = STATS_NETWORK;
+					i++;
+				} else if (strncmp(argv[i+1], "cache",
+						 strlen(argv[i+1])) == 0) {
+					action = STATS_CACHE;
+					i++;
+				} else if (strncmp(argv[i+1], "runtime",
+						 strlen(argv[i+1])) == 0) {
+					action = STATS_RUNTIME;
+					i++;
+				} else if (strncmp(argv[i+1], "multicast",
+						 strlen(argv[i+1])) == 0) {
+					fprintf(stderr, "WARNING: use `link' "
+					     "instead of `multicast' as "
+					     "parameter.");
+					action = STATS_LINK;
+					i++;
+				} else if (strncmp(argv[i+1], "link",
+						 strlen(argv[i+1])) == 0) {
+					action = STATS_LINK;
+					i++;
+				} else if (strncmp(argv[i+1], "rsqueue",
+						strlen(argv[i+1])) == 0) {
+					action = STATS_RSQUEUE;
+					i++;
+				} else if (strncmp(argv[i+1], "process",
+						 strlen(argv[i+1])) == 0) {
+					action = STATS_PROCESS;
+					i++;
+				} else if (strncmp(argv[i+1], "queue",
+						strlen(argv[i+1])) == 0) {
+					action = STATS_QUEUE;
+					i++;
+				} else if (strncmp(argv[i+1], "ct",
+						strlen(argv[i+1])) == 0) {
+					action = STATS;
+					i++;
+				} else if (strncmp(argv[i+1], "expect",
+						strlen(argv[i+1])) == 0) {
+					action = EXP_STATS;
+					i++;
+				} else {
+					fprintf(stderr, "ERROR: unknown parameter `%s' "
+					     "for option `-s'", argv[i + 1]);
+					exit(EXIT_FAILURE);
+				}
+			} else {
+				/* default to general statistics */
+				action = STATS;
+			}
+			break;
+		case 'n':
+			action = REQUEST_DUMP;
+			break;
+		case 'x':
+			if (action == CT_DUMP_INTERNAL)
+				action = CT_DUMP_INT_XML;
+			else if (action == CT_DUMP_EXTERNAL)
+				action = CT_DUMP_EXT_XML;
+			else if (action == EXP_DUMP_INTERNAL)
+				action = EXP_DUMP_INT_XML;
+			else if (action == EXP_DUMP_EXTERNAL)
+				action = EXP_DUMP_EXT_XML;
+			else {
+				show_usage(argv[0]);
+				fprintf(stderr,  "ERROR: invalid parameters");
+				exit(EXIT_FAILURE);
+
+			}
+			break;
+                case 'u':
+			if (++i < argc) {
+				if (strlen(argv[i]) > PATH_MAX) {
+					fprintf(stderr, "WARNING: path to Unix socket too long. "
+						"Cutting it down to %d characters\n", PATH_MAX);
+				}
+				snprintf(socket_path, PATH_MAX, "%s", argv[i]);
+				break;
+			}
+			show_usage(argv[0]);
+			fprintf(stderr, "ERROR: missing Unix socket path\n");
+			exit(EXIT_FAILURE);
+			break;
+
+		case 'v':
+			show_version();
+			exit(EXIT_SUCCESS);
+		case 'h':
+			show_usage(argv[0]);
+			exit(EXIT_SUCCESS);
+		default:
+			show_usage(argv[0]);
+			fprintf(stderr, "ERROR: unknown option: %s\n", argv[i]);
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	if (!socket_path[0])
+		strcpy(socket_path, DEFAULT_SOCKET_PATH);
+
+	set_exec_env();
+
+	if (do_local_request(action, socket_path) == -1) {
+		fprintf(stderr, "ERROR: unable to contact conntrackd. Check if it is running, "
+			"permissions, and the Unix socket path is right (tried '%s')\n",
+			socket_path);
+		exit(EXIT_FAILURE);
+	}
+	exit(EXIT_SUCCESS);
+}
diff --git a/src/local.c b/src/local.c
index 2b67885..dfb0d4c 100644
--- a/src/local.c
+++ b/src/local.c
@@ -91,7 +91,7 @@  int do_local_server_step(struct local_server *server, void *data,
 	return 0;
 }
 
-int local_client_create(struct local_conf *conf)
+static int local_client_create(const char *socket_path)
 {
 	socklen_t len;
 	struct sockaddr_un local;
@@ -101,7 +101,7 @@  int local_client_create(struct local_conf *conf)
 		return -1;
 
 	local.sun_family = AF_UNIX;
-	strcpy(local.sun_path, conf->path);
+	strcpy(local.sun_path, socket_path);
 	len = strlen(local.sun_path) + sizeof(local.sun_family);
 
 	if (connect(fd, (struct sockaddr *) &local, len) == -1) {
@@ -112,12 +112,12 @@  int local_client_create(struct local_conf *conf)
 	return fd;
 }
 
-void local_client_destroy(int fd)
+static void local_client_destroy(int fd)
 {
 	close(fd);
 }
 
-int do_local_client_step(int fd, void (*process)(char *buf))
+static int do_local_client_step(int fd, void (*process)(char *buf))
 {
 	char buf[1024];
 
@@ -132,18 +132,16 @@  int do_local_client_step(int fd, void (*process)(char *buf))
 	return 0;
 }
 
-void local_step(char *buf)
+static void local_step(char *buf)
 {
 	printf("%s", buf);
 }
 
-int do_local_request(int request,
-		     struct local_conf *conf,
-		     void (*step)(char *buf))
+int do_local_request(int request, const char *socket_path)
 {
 	int fd, ret;
 
-	fd = local_client_create(conf);
+	fd = local_client_create(socket_path);
 	if (fd == -1)
 		return -1;
 
@@ -151,7 +149,7 @@  int do_local_request(int request,
 	if (ret == -1)
 		goto err1;
 
-	do_local_client_step(fd, step);
+	do_local_client_step(fd, local_step);
 
 	local_client_destroy(fd);
 
diff --git a/src/main.c b/src/main.c
index 31e0eed..a4e7dd4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -43,29 +43,12 @@  static const char usage_general_commands[] =
 	"  -v, display conntrackd version\n"
 	"  -h, display this help information\n";
 
-static const char usage_client_commands[] =
-	"Client mode commands:\n"
-	"  -c [ct|expect], commit external cache to conntrack table\n"
-	"  -f [internal|external], flush internal and external cache\n"
-	"  -F [ct|expect], flush kernel conntrack table\n"
-	"  -i [ct|expect], display content of the internal cache\n"
-	"  -e [ct|expect], display the content of the external cache\n"
-	"  -k, kill conntrack daemon\n"
-	"  -s  [network|cache|runtime|link|rsqueue|queue|ct|expect], "
-		"dump statistics\n"
-	"  -R [ct|expect], resync with kernel conntrack table\n"
-	"  -n, request resync with other node (only FT-FW and NOTRACK modes)\n"
-	"  -B, force a bulk send to other replica firewalls\n"
-	"  -x, dump cache in XML format (requires -i or -e)\n"
-	"  -t, reset the kernel timeout (see PurgeTimeout clause)\n";
-
 static void
 show_usage(char *progname)
 {
 	fprintf(stdout, "Connection tracking userspace daemon v%s\n", VERSION);
 	fprintf(stdout, "Usage: %s [commands] [options]\n\n", progname);
 	fprintf(stdout, "%s\n", usage_general_commands);
-	fprintf(stdout, "%s\n", usage_client_commands);
 }
 
 static void
@@ -77,39 +60,6 @@  show_version(void)
 	fprintf(stdout, "<pablo@netfilter.org>\n");
 }
 
-static void
-set_operation_mode(int *current, int want, char *argv[])
-{
-	if (*current == NOT_SET) {
-		*current = want;
-		return;
-	}
-	if (*current != want) {
-		show_usage(argv[0]);
-		dlog(LOG_ERR, "Invalid parameters");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static int
-set_action_by_table(int i, int argc, char *argv[],
-		    int ct_action, int exp_action, int dfl_action, int *action)
-{
-	if (i+1 < argc && argv[i+1][0] != '-') {
-		if (strncmp(argv[i+1], "ct", strlen(argv[i+1])) == 0) {
-			*action = ct_action;
-			i++;
-		} else if (strncmp(argv[i+1], "expect",
-						strlen(argv[i+1])) == 0) {
-			*action = exp_action;
-			i++;
-		}
-	} else
-		*action = dfl_action;
-
-	return i;
-}
-
 static void
 do_chdir(const char *d)
 {
@@ -121,8 +71,7 @@  do_chdir(const char *d)
 int main(int argc, char *argv[])
 {
 	char config_file[PATH_MAX + 1] = {};
-	int ret, i, action = -1;
-	int type = 0;
+	int ret, i;
 	struct utsname u;
 	int version, major, minor;
 
@@ -140,29 +89,8 @@  int main(int argc, char *argv[])
 	for (i=1; i<argc; i++) {
 		switch(argv[i][1]) {
 		case 'd':
-			set_operation_mode(&type, DAEMON, argv);
 			CONFIG(running_mode) = DAEMON;
 			break;
-		case 'c':
-			set_operation_mode(&type, REQUEST, argv);
-			i = set_action_by_table(i, argc, argv,
-						CT_COMMIT, EXP_COMMIT,
-						ALL_COMMIT, &action);
-			break;
-		case 'i':
-			set_operation_mode(&type, REQUEST, argv);
-			i = set_action_by_table(i, argc, argv,
-						CT_DUMP_INTERNAL,
-						EXP_DUMP_INTERNAL,
-						CT_DUMP_INTERNAL, &action);
-			break;
-		case 'e':
-			set_operation_mode(&type, REQUEST, argv);
-			i = set_action_by_table(i, argc, argv,
-						CT_DUMP_EXTERNAL,
-						EXP_DUMP_EXTERNAL,
-						CT_DUMP_EXTERNAL, &action);
-			break;
 		case 'C':
 			if (++i < argc) {
 				if (strlen(argv[i]) > PATH_MAX) {
@@ -176,136 +104,26 @@  int main(int argc, char *argv[])
 			show_usage(argv[0]);
 			dlog(LOG_ERR, "Missing config filename");
 			break;
-		case 'F':
-			set_operation_mode(&type, REQUEST, argv);
-			i = set_action_by_table(i, argc, argv,
-						CT_FLUSH_MASTER,
-						EXP_FLUSH_MASTER,
-						ALL_FLUSH_MASTER, &action);
-			break;
-		case 'f':
-			set_operation_mode(&type, REQUEST, argv);
-			if (i+1 < argc && argv[i+1][0] != '-') {
-				if (strncmp(argv[i+1], "internal",
-					    strlen(argv[i+1])) == 0) {
-					action = CT_FLUSH_INT_CACHE;
-					i++;
-				} else if (strncmp(argv[i+1], "external",
-						 strlen(argv[i+1])) == 0) {
-					action = CT_FLUSH_EXT_CACHE;
-					i++;
-				} else {
-					dlog(LOG_ERR, "unknown parameter `%s' "
-					     "for option `-f'", argv[i + 1]);
-					exit(EXIT_FAILURE);
-				}
-			} else {
-				/* default to general flushing */
-				action = ALL_FLUSH_CACHE;
-			}
-			break;
-		case 'R':
-			set_operation_mode(&type, REQUEST, argv);
-			i = set_action_by_table(i, argc, argv,
-						CT_RESYNC_MASTER,
-						EXP_RESYNC_MASTER,
-						ALL_RESYNC_MASTER, &action);
-			break;
-		case 'B':
-			set_operation_mode(&type, REQUEST, argv);
-			action = SEND_BULK;
-			break;
-		case 't':
-			set_operation_mode(&type, REQUEST, argv);
-			action = RESET_TIMERS;
-			break;
-		case 'k':
-			set_operation_mode(&type, REQUEST, argv);
-			action = KILL;
-			break;
-		case 's':
-			set_operation_mode(&type, REQUEST, argv);
-			/* we've got a parameter */
-			if (i+1 < argc && argv[i+1][0] != '-') {
-				if (strncmp(argv[i+1], "network",
-					    strlen(argv[i+1])) == 0) {
-					action = STATS_NETWORK;
-					i++;
-				} else if (strncmp(argv[i+1], "cache",
-						 strlen(argv[i+1])) == 0) {
-					action = STATS_CACHE;
-					i++;
-				} else if (strncmp(argv[i+1], "runtime",
-						 strlen(argv[i+1])) == 0) {
-					action = STATS_RUNTIME;
-					i++;
-				} else if (strncmp(argv[i+1], "multicast",
-						 strlen(argv[i+1])) == 0) {
-					dlog(LOG_WARNING, "use `link' "
-					     "instead of `multicast' as "
-					     "parameter.");
-					action = STATS_LINK;
-					i++;
-				} else if (strncmp(argv[i+1], "link",
-						 strlen(argv[i+1])) == 0) {
-					action = STATS_LINK;
-					i++;
-				} else if (strncmp(argv[i+1], "rsqueue",
-						strlen(argv[i+1])) == 0) {
-					action = STATS_RSQUEUE;
-					i++;
-				} else if (strncmp(argv[i+1], "process",
-						 strlen(argv[i+1])) == 0) {
-					action = STATS_PROCESS;
-					i++;
-				} else if (strncmp(argv[i+1], "queue",
-						strlen(argv[i+1])) == 0) {
-					action = STATS_QUEUE;
-					i++;
-				} else if (strncmp(argv[i+1], "ct",
-						strlen(argv[i+1])) == 0) {
-					action = STATS;
-					i++;
-				} else if (strncmp(argv[i+1], "expect",
-						strlen(argv[i+1])) == 0) {
-					action = EXP_STATS;
-					i++;
-				} else {
-					dlog(LOG_ERR, "unknown parameter `%s' "
-					     "for option `-s'", argv[i + 1]);
-					exit(EXIT_FAILURE);
-				}
-			} else {
-				/* default to general statistics */
-				action = STATS;
-			}
-			break;
-		case 'n':
-			set_operation_mode(&type, REQUEST, argv);
-			action = REQUEST_DUMP;
-			break;
-		case 'x':
-			if (action == CT_DUMP_INTERNAL)
-				action = CT_DUMP_INT_XML;
-			else if (action == CT_DUMP_EXTERNAL)
-				action = CT_DUMP_EXT_XML;
-			else if (action == EXP_DUMP_INTERNAL)
-				action = EXP_DUMP_INT_XML;
-			else if (action == EXP_DUMP_EXTERNAL)
-				action = EXP_DUMP_EXT_XML;
-			else {
-				show_usage(argv[0]);
-				dlog(LOG_ERR,  "Invalid parameters");
-				exit(EXIT_FAILURE);
-
-			}
-			break;
 		case 'v':
 			show_version();
 			exit(EXIT_SUCCESS);
 		case 'h':
 			show_usage(argv[0]);
 			exit(EXIT_SUCCESS);
+		case 'c':
+		case 'f':
+		case 'F':
+		case 'i':
+		case 'e':
+		case 'k':
+		case 's':
+		case 'R':
+		case 'n':
+		case 'B':
+		case 'x':
+		case 't':
+			dlog(LOG_WARNING, "ignored option, use conntrackdctl instead");
+			break;
 		default:
 			show_usage(argv[0]);
 			dlog(LOG_ERR, "Unknown option: %s", argv[i]);
@@ -333,15 +151,6 @@  int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	if (type == REQUEST) {
-		if (do_local_request(action, &conf.local, local_step) == -1) {
-			dlog(LOG_ERR, "can't connect: is conntrackd "
-			     "running? appropriate permissions?");
-			exit(EXIT_FAILURE);
-		}
-		exit(EXIT_SUCCESS);
-	}
-
 	/*
 	 * Setting up logging
 	 */
@@ -377,7 +186,7 @@  int main(int argc, char *argv[])
 	sd_ct_watchdog_init();
 
 	/* Daemonize conntrackd */
-	if (type == DAEMON) {
+	if (CONFIG(running_mode) == DAEMON) {
 		pid_t pid;
 
 		if ((pid = fork()) == -1) {