diff mbox series

[v3,4/8] conntrack: introduce ct_cmd_list

Message ID 20210129212452.45352-5-mikhail.sennikovskii@cloud.ionos.com
State Under Review
Delegated to: Pablo Neira
Headers show
Series conntrack: save output format | expand

Commit Message

Mikhail Sennikovsky Jan. 29, 2021, 9:24 p.m. UTC
As a multicommand support preparation, add support for the
ct_cmd_list, which represents a list of ct_cmd elements.
Currently only a single entry generated from the command line
arguments is created.

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

Patch

diff --git a/src/conntrack.c b/src/conntrack.c
index 4783825..1719ca9 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -598,6 +598,19 @@  static unsigned int addr_valid_flags[ADDR_VALID_FLAGS_MAX] = {
 	CT_OPT_REPL_SRC | CT_OPT_REPL_DST,
 };
 
+#define CT_COMMANDS_LOAD_FILE_ALLOWED ( 0 \
+						| CT_CREATE       \
+						| CT_UPDATE_BIT   \
+						| CT_DELETE       \
+						| CT_FLUSH        \
+						| EXP_CREATE      \
+						| EXP_DELETE      \
+						| EXP_FLUSH       \
+						)
+
+static unsigned int cmd_allowed = ~0;
+
+
 static LIST_HEAD(proto_list);
 
 static struct nfct_labelmap *labelmap;
@@ -1250,6 +1263,9 @@  add_command(unsigned int *cmd, const int newcmd)
 {
 	if (*cmd)
 		exit_error(PARAMETER_PROBLEM, "Invalid commands combination");
+	if (!(cmd_allowed & newcmd))
+		exit_error(PARAMETER_PROBLEM,
+				"Command can not be used in the current mode");
 	*cmd |= newcmd;
 }
 
@@ -1472,6 +1488,10 @@  struct ct_cmd {
 	struct ct_tmpl	tmpl;
 };
 
+struct ct_cmd_list {
+	struct list_head list;
+};
+
 static int
 filter_label(const struct nf_conntrack *ct, const struct ct_tmpl *tmpl)
 {
@@ -3155,6 +3175,19 @@  static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 	ct_cmd->socketbuffersize = socketbuffersize;
 }
 
+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 do_command_ct(const char *progname, struct ct_cmd *cmd)
 {
 	struct nfct_filter_dump *filter_dump;
@@ -3587,9 +3620,37 @@  try_proc:
 		nfct_labelmap_destroy(labelmap);
 }
 
+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 void ct_cmd_list_apply(struct ct_cmd_list *list, const char *progname)
+{
+	struct ct_cmd *cmd, *tmp;
+
+	list_for_each_entry_safe(cmd, tmp, &list->list, list_entry) {
+		list_del(&cmd->list_entry);
+		do_command_ct(progname, cmd);
+		free(cmd);
+	}
+}
+
+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();
@@ -3601,9 +3662,11 @@  int main(int argc, char *argv[])
 	register_gre();
 	register_unknown();
 
-	do_parse(cmd, argc, argv);
+	ct_cmd_list_init(&list);
+
+	ct_cmd_list_parse_argv(&list, argc, argv);
 
-	do_command_ct(argv[0], cmd);
+	ct_cmd_list_apply(&list, argv[0]);
 
 	return print_cmd_counters();
 }