diff mbox series

[v4,1/5] conntrack: introduce ct_cmd_list

Message ID 20210406100947.57579-2-mikhail.sennikovskii@ionos.com
State Accepted
Delegated to: Pablo Neira
Headers show
Series conntrack: save output format | expand

Commit Message

Mikhail Sennikovsky April 6, 2021, 10:09 a.m. UTC
As a load from file support preparation, introduce a
ct_cmd_list, which represents a list of ct_cmd elements.
Currently only a single entry is generated for the command line
processing.

Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@ionos.com>
---
 src/conntrack.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 68 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/src/conntrack.c b/src/conntrack.c
index 4bc340f..6040828 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -102,6 +102,7 @@  struct ct_tmpl {
 static struct ct_tmpl *cur_tmpl;
 
 struct ct_cmd {
+	struct list_head list_entry;
 	unsigned int	command;
 	unsigned int	cmd;
 	unsigned int	type;
@@ -113,6 +114,10 @@  struct ct_cmd {
 	struct ct_tmpl	tmpl;
 };
 
+struct ct_cmd_list {
+	struct list_head list;
+};
+
 static int alloc_tmpl_objects(struct ct_tmpl *tmpl)
 {
 	tmpl->ct = nfct_new();
@@ -2823,6 +2828,8 @@  static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 
 	/* disable explicit missing arguments error output from getopt_long */
 	opterr = 0;
+	/* reset optind, for the case do_parse is called multiple times */
+	optind = 0;
 
 	while ((c = getopt_long(argc, argv, getopt_str, opts, NULL)) != -1) {
 	switch(c) {
@@ -3543,9 +3550,65 @@  try_proc:
 	return EXIT_SUCCESS;
 }
 
+static int ct_cmd_process(struct ct_cmd *ct_cmd, const char *progname)
+{
+	int res;
+
+	res = do_command_ct(progname, ct_cmd);
+	if (res < 0)
+		return res;
+
+	return print_stats(ct_cmd);
+}
+
+static struct ct_cmd *ct_cmd_create(int argc, char *argv[])
+{
+	struct ct_cmd *ct_cmd;
+
+	ct_cmd = calloc(1, sizeof(*ct_cmd));
+	if (!ct_cmd)
+		exit_error(OTHER_PROBLEM, "cmd alloc failed!!");
+
+	do_parse(ct_cmd, argc, argv);
+
+	return ct_cmd;
+}
+
+static void ct_cmd_list_init(struct ct_cmd_list *list)
+{
+	memset(list, 0, sizeof(*list));
+	INIT_LIST_HEAD(&list->list);
+}
+
+static void ct_cmd_list_add(struct ct_cmd_list *list, struct ct_cmd *cmd)
+{
+	list_add_tail(&cmd->list_entry, &list->list);
+}
+
+static int ct_cmd_list_apply(struct ct_cmd_list *list, const char *progname)
+{
+	int res = 0;
+	struct ct_cmd *cmd, *tmp;
+
+	list_for_each_entry_safe(cmd, tmp, &list->list, list_entry) {
+		list_del(&cmd->list_entry);
+		res |= ct_cmd_process(cmd, progname);
+
+		free(cmd);
+	}
+
+	return res;
+}
+
+static void ct_cmd_list_parse_argv(struct ct_cmd_list *list,
+		int argc, char *argv[])
+{
+	ct_cmd_list_add(list, ct_cmd_create(argc, argv));
+}
+
 int main(int argc, char *argv[])
 {
-	struct ct_cmd _cmd = {}, *cmd = &_cmd;
+	struct ct_cmd_list list;
 
 	register_tcp();
 	register_udp();
@@ -3557,10 +3620,11 @@  int main(int argc, char *argv[])
 	register_gre();
 	register_unknown();
 
-	do_parse(cmd, argc, argv);
-	do_command_ct(argv[0], cmd);
+	ct_cmd_list_init(&list);
+
+	ct_cmd_list_parse_argv(&list, argc, argv);
 
-	if (print_stats(cmd) < 0)
+	if (ct_cmd_list_apply(&list, argv[0]) < 0)
 		return EXIT_FAILURE;
 
 	return EXIT_SUCCESS;