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@xxxxxxxxxxxxxxx> --- src/conntrack.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) 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(); } -- 2.25.1