* [PATCH v4 0/5] conntrack: save output format
@ 2021-04-06 10:09 Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 1/5] conntrack: introduce ct_cmd_list Mikhail Sennikovsky
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Mikhail Sennikovsky @ 2021-04-06 10:09 UTC (permalink / raw)
To: netfilter-devel, pablo, mikhail.sennikovskii
Hi Pablo & all,
Here is the updated version of the "save output format"
patches adjusted in accordance with our latest discussion with Pablo.
Thanks & regards,
Mikhail
Mikhail Sennikovsky (5):
conntrack: introduce ct_cmd_list
conntrack: accept commands from file
conntrack.8: man update for --load-file support
tests: saving and loading ct entries, save format
tests: conntrack -L/-D ip family filtering
conntrack.8 | 8 +
src/conntrack.c | 250 +++++++++++++++++++++++++++-
tests/conntrack/test-conntrack.c | 84 ++++++++--
tests/conntrack/testsuite/08stdin | 80 +++++++++
tests/conntrack/testsuite/09dumpopt | 147 ++++++++++++++++
5 files changed, 552 insertions(+), 17 deletions(-)
create mode 100644 tests/conntrack/testsuite/08stdin
create mode 100644 tests/conntrack/testsuite/09dumpopt
--
2.25.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 1/5] conntrack: introduce ct_cmd_list
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
@ 2021-04-06 10:09 ` Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 2/5] conntrack: accept commands from file Mikhail Sennikovsky
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Mikhail Sennikovsky @ 2021-04-06 10:09 UTC (permalink / raw)
To: netfilter-devel, pablo, mikhail.sennikovskii
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 --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;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 2/5] conntrack: accept commands from file
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 1/5] conntrack: introduce ct_cmd_list Mikhail Sennikovsky
@ 2021-04-06 10:09 ` Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 3/5] conntrack.8: man update for --load-file support Mikhail Sennikovsky
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Mikhail Sennikovsky @ 2021-04-06 10:09 UTC (permalink / raw)
To: netfilter-devel, pablo, mikhail.sennikovskii
This commit implements the --load-file option which
allows processing conntrack commands stored in file.
Most often this would be used as a counter-part for the
-o save option, which outputs conntrack entries
in the format of the conntrack tool options.
This could be useful when one needs to add/update/delete a large
set of ct entries with a single conntrack tool invocation.
Expected syntax is "conntrack --load-file file".
If "-" is given as a file name, stdin is used.
No other commands or options are allowed to be specified
in conjunction with the --load-file command.
It is however possible to specify multiple --load-file file pairs.
Example:
Copy all entries from ct zone 11 to ct zone 12:
conntrack -L -w 11 -o save | sed "s/-w 11/-w 12/g" | \
conntrack --load-file -
Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@ionos.com>
---
src/conntrack.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 178 insertions(+), 2 deletions(-)
diff --git a/src/conntrack.c b/src/conntrack.c
index 6040828..905d3a7 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -615,6 +615,17 @@ 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 \
+ )
+
+static unsigned int cmd_allowed = ~0;
+
+static bool print_stats_allowed = true;
+
static LIST_HEAD(proto_list);
static struct nfct_labelmap *labelmap;
@@ -1267,6 +1278,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;
}
@@ -2798,7 +2812,7 @@ nfct_set_nat_details(const int opt, struct nf_conntrack *ct,
static int print_stats(const struct ct_cmd *cmd)
{
- if (cmd->command && exit_msg[cmd->cmd][0]) {
+ if (print_stats_allowed && cmd->command && exit_msg[cmd->cmd][0]) {
fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
fprintf(stderr, exit_msg[cmd->cmd], counter);
if (counter == 0 && !(cmd->command & (CT_LIST | EXP_LIST)))
@@ -3606,6 +3620,168 @@ static void ct_cmd_list_parse_argv(struct ct_cmd_list *list,
ct_cmd_list_add(list, ct_cmd_create(argc, argv));
}
+#define MAX_ARGC 255
+struct argv_store {
+ int argc;
+ char *argv[MAX_ARGC];
+ int argvattr[MAX_ARGC];
+};
+
+/* function adding one argument to store, updating argc
+ * returns if argument added, does not return otherwise */
+static void add_argv(struct argv_store *store, const char *what, int quoted)
+{
+ if (store->argc + 1 >= MAX_ARGC)
+ exit_error(PARAMETER_PROBLEM,
+ "Parser cannot handle more arguments\n");
+ if (!what)
+ exit_error(PARAMETER_PROBLEM,
+ "Trying to store NULL argument\n");
+
+ store->argv[store->argc] = strdup(what);
+ store->argvattr[store->argc] = quoted;
+ store->argv[++store->argc] = NULL;
+}
+
+static void free_argv(struct argv_store *store)
+{
+ while (store->argc) {
+ store->argc--;
+ free(store->argv[store->argc]);
+ store->argvattr[store->argc] = 0;
+ }
+}
+
+struct ct_param_buf {
+ char buffer[1024];
+ int len;
+};
+
+static void add_param(struct ct_param_buf *param, const char *curchar)
+{
+ param->buffer[param->len++] = *curchar;
+ if (param->len >= (int)sizeof(param->buffer))
+ exit_error(PARAMETER_PROBLEM, "Parameter too long!");
+}
+
+static void add_param_to_argv(struct argv_store *store, char *parsestart)
+{
+ int quote_open = 0, escaped = 0, quoted = 0;
+ struct ct_param_buf param = {};
+ char *curchar;
+
+ /* After fighting with strtok enough, here's now
+ * a 'real' parser. According to Rusty I'm now no
+ * longer a real hacker, but I can live with that */
+
+ for (curchar = parsestart; *curchar; curchar++) {
+ if (quote_open) {
+ if (escaped) {
+ add_param(¶m, curchar);
+ escaped = 0;
+ continue;
+ } else if (*curchar == '\\') {
+ escaped = 1;
+ continue;
+ } else if (*curchar == '"') {
+ quote_open = 0;
+ } else {
+ add_param(¶m, curchar);
+ continue;
+ }
+ } else {
+ if (*curchar == '"') {
+ quote_open = 1;
+ quoted = 1;
+ continue;
+ }
+ }
+
+ switch (*curchar) {
+ case '"':
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ if (!param.len) {
+ /* two spaces? */
+ continue;
+ }
+ break;
+ default:
+ /* regular character, copy to buffer */
+ add_param(¶m, curchar);
+ continue;
+ }
+
+ param.buffer[param.len] = '\0';
+ add_argv(store, param.buffer, quoted);
+ param.len = 0;
+ quoted = 0;
+ }
+ if (param.len) {
+ param.buffer[param.len] = '\0';
+ add_argv(store, param.buffer, 0);
+ }
+}
+
+static void ct_cmd_list_parse_line(struct ct_cmd_list *list,
+ const char *progname, char *buffer)
+{
+ struct argv_store store = {};
+
+ /* skip prepended tabs and spaces */
+ for (; *buffer == ' ' || *buffer == '\t'; buffer++);
+
+ if (buffer[0] == '\n'
+ || buffer[0] == '#')
+ return;
+
+ add_argv(&store, progname, false);
+
+ add_param_to_argv(&store, buffer);
+
+ ct_cmd_list_parse_argv(list, store.argc, store.argv);
+
+ free_argv(&store);
+}
+
+static void ct_cmd_list_parse_file(struct ct_cmd_list *list,
+ const char *progname,
+ const char *file_name)
+{
+ char buffer[10240] = {};
+ FILE *file;
+
+ if (!strcmp(file_name, "-"))
+ file_name = "/dev/stdin";
+
+ file = fopen(file_name, "r");
+ if (!file)
+ exit_error(PARAMETER_PROBLEM, NULL,
+ "Failed to open file %s for reading", file_name);
+
+ while (fgets(buffer, sizeof(buffer), file))
+ ct_cmd_list_parse_line(list, progname, buffer);
+}
+
+static void ct_cmd_list_parse(struct ct_cmd_list *list, int argc, char *argv[])
+{
+ if (argc > 2
+ && (!strcmp(argv[1], "-R")
+ || !strcmp(argv[1], "--load-file"))) {
+ int i;
+
+ cmd_allowed = CT_COMMANDS_LOAD_FILE_ALLOWED;
+ print_stats_allowed = false;
+
+ for (i = 2; i < argc; ++i)
+ ct_cmd_list_parse_file(list, argv[0], argv[i]);
+ return;
+ }
+ ct_cmd_list_parse_argv(list, argc, argv);
+}
+
int main(int argc, char *argv[])
{
struct ct_cmd_list list;
@@ -3622,7 +3798,7 @@ int main(int argc, char *argv[])
ct_cmd_list_init(&list);
- ct_cmd_list_parse_argv(&list, argc, argv);
+ ct_cmd_list_parse(&list, argc, argv);
if (ct_cmd_list_apply(&list, argv[0]) < 0)
return EXIT_FAILURE;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 3/5] conntrack.8: man update for --load-file support
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 1/5] conntrack: introduce ct_cmd_list Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 2/5] conntrack: accept commands from file Mikhail Sennikovsky
@ 2021-04-06 10:09 ` Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 4/5] tests: saving and loading ct entries, save format Mikhail Sennikovsky
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Mikhail Sennikovsky @ 2021-04-06 10:09 UTC (permalink / raw)
To: netfilter-devel, pablo, mikhail.sennikovskii; +Cc: Mikhail Sennikovsky
From: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
---
conntrack.8 | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/conntrack.8 b/conntrack.8
index 898daae..a14cca6 100644
--- a/conntrack.8
+++ b/conntrack.8
@@ -23,6 +23,8 @@ conntrack \- command line interface for netfilter connection tracking
.BR "conntrack -C [table]"
.br
.BR "conntrack -S "
+.br
+.BR "conntrack -R file"
.SH DESCRIPTION
The \fBconntrack\fP utilty provides a full featured userspace interface to the
Netfilter connection tracking system that is intended to replace the old
@@ -102,6 +104,9 @@ Show the table counter.
.TP
.BI "-S, --stats "
Show the in-kernel connection tracking system statistics.
+.TP
+.BI "-R, --load-file "
+Load entries from a given file. To read from stdin, "\-" should be specified.
.SS PARAMETERS
.TP
@@ -394,6 +399,9 @@ Delete all flow whose source address is 1.2.3.4
.TP
.B conntrack \-U \-s 1.2.3.4 \-m 1
Set connmark to 1 of all the flows whose source address is 1.2.3.4
+.TP
+.B conntrack -L -w 11 -o save | sed "s/-w 11/-w 12/g" | conntrack --load-file -
+Copy all entries from ct zone 11 to ct zone 12
.SH BUGS
Please, report them to netfilter-devel@vger.kernel.org or file a bug in
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 4/5] tests: saving and loading ct entries, save format
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
` (2 preceding siblings ...)
2021-04-06 10:09 ` [PATCH v4 3/5] conntrack.8: man update for --load-file support Mikhail Sennikovsky
@ 2021-04-06 10:09 ` Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 5/5] tests: conntrack -L/-D ip family filtering Mikhail Sennikovsky
2021-05-03 20:42 ` [PATCH v4 0/5] conntrack: save output format Pablo Neira Ayuso
5 siblings, 0 replies; 7+ messages in thread
From: Mikhail Sennikovsky @ 2021-04-06 10:09 UTC (permalink / raw)
To: netfilter-devel, pablo, mikhail.sennikovskii; +Cc: Mikhail Sennikovsky
From: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
---
tests/conntrack/test-conntrack.c | 84 ++++++++++++++++++++++++-----
tests/conntrack/testsuite/08stdin | 80 +++++++++++++++++++++++++++
tests/conntrack/testsuite/09dumpopt | 77 ++++++++++++++++++++++++++
3 files changed, 229 insertions(+), 12 deletions(-)
create mode 100644 tests/conntrack/testsuite/08stdin
create mode 100644 tests/conntrack/testsuite/09dumpopt
diff --git a/tests/conntrack/test-conntrack.c b/tests/conntrack/test-conntrack.c
index 76ab051..372e025 100644
--- a/tests/conntrack/test-conntrack.c
+++ b/tests/conntrack/test-conntrack.c
@@ -28,6 +28,23 @@ int main()
struct dirent *dent;
char file[1024];
int i,n;
+ char cmd_buf[1024 * 8];
+ int i_cmd_buf = 0;
+ char cmd, cur_cmd = 0;
+ char *cmd_opt;
+
+#define cmd_strappend(_s) do { \
+ char * pos = stpncpy(cmd_buf + i_cmd_buf, _s, sizeof(cmd_buf) - i_cmd_buf); \
+ i_cmd_buf = pos - cmd_buf; \
+ if (i_cmd_buf == sizeof(cmd_buf)) { \
+ printf("buffer full!\n"); \
+ exit(EXIT_FAILURE); \
+ } \
+} while (0)
+
+#define cmd_reset() do { \
+ i_cmd_buf = 0; \
+} while (0)
n = scandir("testsuite", &dents, NULL, alphasort);
@@ -48,9 +65,7 @@ int main()
}
while (fgets(buf, sizeof(buf), fp)) {
- char tmp[1024] = CT_PROG, *res;
- tmp[strlen(CT_PROG)] = ' ';
-
+ char *res;
line++;
if (buf[0] == '#' || buf[0] == ' ')
@@ -63,27 +78,72 @@ int main()
exit(EXIT_FAILURE);
}
*res = '\0';
- res+=2;
+ res++;
+ for (; *res == ' ' || *res == '\t'; res++);
+ cmd = res[0];
+ cmd_opt = &res[1];
+ for (; *cmd_opt == ' ' || *cmd_opt == '\t'; cmd_opt++);
+ res = strchr(cmd_opt, '\n');
+ if (res)
+ *res = '\0';
+
+ if (cur_cmd && cmd != cur_cmd) {
+ /* complete current multi-line command */
+ switch (cur_cmd) {
+ case '\n':
+ cmd_strappend("\" | ");
+ break;
+ default:
+ printf("Internal Error: unexpected multiline command %c",
+ cur_cmd);
+ exit(EXIT_FAILURE);
+ break;
+ }
+
+ cur_cmd = 0;
+ }
+
+ switch (cmd) {
+ case '\n':
+ if (!cur_cmd) {
+ cmd_strappend("echo \"");
+ cur_cmd = cmd;
+ } else
+ cmd_strappend("\n");
+ cmd_strappend(buf);
+ continue;
+ default:
+ cmd_strappend(CT_PROG);
+ cmd_strappend(" ");
+ cmd_strappend(buf);
+ if (cmd == '|') {
+ cmd_strappend(" | ");
+ if (cmd_opt[0]) {
+ cmd_strappend("sed \"");
+ cmd_strappend(cmd_opt);
+ cmd_strappend("\" | ");
+ }
+ continue;
+ }
+ cmd_reset();
+ break;
+ }
- strcpy(tmp + strlen(CT_PROG) + 1, buf);
- printf("(%d) Executing: %s\n", line, tmp);
+ printf("(%d) Executing: %s\n", line, cmd_buf);
fflush(stdout);
- ret = system(tmp);
+ ret = system(cmd_buf);
if (WIFEXITED(ret) &&
WEXITSTATUS(ret) == EXIT_SUCCESS) {
- if (res[0] == 'O' &&
- res[1] == 'K')
+ if (cmd == 'O')
ok++;
else {
bad++;
printf("^----- BAD\n");
}
} else {
- if (res[0] == 'B' &&
- res[1] == 'A' &&
- res[2] == 'D')
+ if (cmd == 'B')
ok++;
else {
bad++;
diff --git a/tests/conntrack/testsuite/08stdin b/tests/conntrack/testsuite/08stdin
new file mode 100644
index 0000000..1d31176
--- /dev/null
+++ b/tests/conntrack/testsuite/08stdin
@@ -0,0 +1,80 @@
+# create
+# create a conntrack
+-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+# create from reply
+-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ;
+# create a v6 conntrack
+-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+# creae icmp ping request entry
+-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ;
+-R - ; OK
+# create again
+-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+# make sure create again with stdio mode fails as well
+-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+-R - ; BAD
+-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ;
+-R - ; BAD
+# empty lines are ignored
+;
+-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+-R - ; BAD
+# spaces or tabs are ignored as well
+ ;
+ ;
+-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ;
+-R - ; BAD
+# delete
+-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ;
+# empty lines should be just ignored
+;
+;
+# delete reverse
+-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ;
+# empty lines with spaces or tabs should be ignored as well
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+# delete v6 conntrack
+-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ;
+# delete icmp ping request entry
+-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ;
+;
+;
+-R - ; OK
+# create again - should succeed now
+-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK
+-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK
+-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK
+-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# delete again (for cleanup)
+-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ;
+-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ;
+-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ;
+-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ;
+;
+-R - ; OK
+# delete no entries - should return err
+-D -w 123 ; BAD
+# delete no entries via stdin - should succeed since we do not count entries in stdin mode atm
+-D -w 123 ;
+-R - ; OK
+# delete no entries in parallel with adding entries via stdin - should succeed
+# -D and -I should work in parallel
+-D -w 123 ;
+-I -w 123 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+-R - ; OK
+# now deleting entries should return success
+-D -w 123 ;
+-R - ; OK
+# delete no entries via stdin - should succeed since we do not count entries in stdin mode atm
+-D -w 123 ;
+-R - ; OK
+# validate it via standard command line way
+-D -w 123 ; BAD
\ No newline at end of file
diff --git a/tests/conntrack/testsuite/09dumpopt b/tests/conntrack/testsuite/09dumpopt
new file mode 100644
index 0000000..0d5d9d4
--- /dev/null
+++ b/tests/conntrack/testsuite/09dumpopt
@@ -0,0 +1,77 @@
+# test opts output for -L
+# create
+# create a conntrack
+-I -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+# create from reply
+-I -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ;
+# create a v6 conntrack
+-I -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+# creae icmp ping request entry
+-I -w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ;
+-R - ; OK
+# copy ipv4 bits to zone 11
+-L -w 10 -o save -f ipv4 ; |s/-w 10/-w 11/g
+-R - ; OK
+# copy ipv6 bits to zone 11
+-L -w 10 -o save -f ipv6 ; |s/-w 10/-w 11/g
+-R - ; OK
+# create again in zone 11
+-I -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -w 11 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+# delete new entries
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# delete reverse
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK
+# delete v6 conntrack
+-D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# delete icmp ping request entry
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# delete old entries
+-D -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# delete reverse
+-D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK
+# delete v6 conntrack
+-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# delete icmp ping request entry
+-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+#
+# now test opts output for -D
+# create entries again
+# create a conntrack
+-I -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+# create from reply
+-I -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ;
+# create a v6 conntrack
+-I -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ;
+# creae icmp ping request entry
+-I -w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ;
+-R - ; OK
+# move ipv4 bits to zone 11
+-D -w 10 -o save -f ipv4 ; |s/-w 10/-w 11/g; s/-D /-I /g
+-R - ; OK
+# move ipv6 bits to zone 11
+-D -w 10 -o save -f ipv6 ; |s/-w 10/-w 11/g; s/-D /-I /g
+-R - ; OK
+# create again in zone 11
+-I -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD
+-I -w 11 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+# delete new entries
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# delete reverse
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK
+# delete v6 conntrack
+-D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# delete icmp ping request entry
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# delete old entries
+-D -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD
+# delete reverse
+-D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD
+# delete v6 conntrack
+-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD
+# delete icmp ping request entry
+-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
\ No newline at end of file
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 5/5] tests: conntrack -L/-D ip family filtering
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
` (3 preceding siblings ...)
2021-04-06 10:09 ` [PATCH v4 4/5] tests: saving and loading ct entries, save format Mikhail Sennikovsky
@ 2021-04-06 10:09 ` Mikhail Sennikovsky
2021-05-03 20:42 ` [PATCH v4 0/5] conntrack: save output format Pablo Neira Ayuso
5 siblings, 0 replies; 7+ messages in thread
From: Mikhail Sennikovsky @ 2021-04-06 10:09 UTC (permalink / raw)
To: netfilter-devel, pablo, mikhail.sennikovskii; +Cc: Mikhail Sennikovsky
From: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
Tests to cover conntrack -L and conntrack -D with and w/o
family (-f) specfied.
conntrack -L and contnrack -D shold list/delete
both IPv4 and IPv6 entries if no family is specified,
and should ony display the corresponding entries if
the family is given.
Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
---
tests/conntrack/testsuite/09dumpopt | 72 ++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/tests/conntrack/testsuite/09dumpopt b/tests/conntrack/testsuite/09dumpopt
index 0d5d9d4..447590b 100644
--- a/tests/conntrack/testsuite/09dumpopt
+++ b/tests/conntrack/testsuite/09dumpopt
@@ -74,4 +74,74 @@
# delete v6 conntrack
-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD
# delete icmp ping request entry
--D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
\ No newline at end of file
+-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+#
+# Additional tests to check that family attribute is treated properly
+# for -L and -D commands
+# namely:
+# - if family (-f) is given - only entries of the given family are dumped/deleted
+# - if no family is given - entries of both ipv4 and ipv6 families are dumped/deleted
+# First create some ipv4 and ipv6 entries
+-I -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK
+-I -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK
+-I -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK
+-I -w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# dump all entries to zone 11
+-L -w 10 -o save; |s/-w 10/-w 11/g
+-R - ; OK
+# ensure that both ipv4 and ipv6 entries get copied (delete for each of them should succeed)
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY ; OK
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY ; OK
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# dump only ipv4 entries to zone 11
+-L -w 10 -o save -f ipv4; |s/-w 10/-w 11/g
+-R - ; OK
+# ensure that only ipv4 entries get copied (delete only for ipv4 entries should succeed)
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# dump only ipv6 entries to zone 11
+-L -w 10 -o save -f ipv6; |s/-w 10/-w 11/g
+-R - ; OK
+# ensure that only ipv6 entries get copied (delete only for ipv6 entries should succeed)
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+# now test deleting w/ and /o family specified
+# for simplicity do it by re-creating entries in zone 11
+# by copying ezisting entries from zone 10 into it
+# re-create entries in ct zone 11
+-L -w 10 -o save; |s/-w 10/-w 11/g
+-R - ; OK
+# delete all entries in zone 11
+-D -w 11 ; OK
+# both ipv4 and ipv6 should be deleted
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+# re-create entries in ct zone 11
+-L -w 10 -o save; |s/-w 10/-w 11/g
+-R - ; OK
+# delete only ipv4 entries in zone 11
+-D -w 11 -f ipv4 ; OK
+# ipv6 should remain
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
+ # re-create entries in ct zone 11
+-L -w 10 -o save; |s/-w 10/-w 11/g
+-R - ; OK
+# delete only ipv6 entries in zone 11
+-D -w 11 -f ipv6 ; OK
+# ipv4 should remain
+-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; OK
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD
+-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
+# clean up after yourself
+-D -w 10 ; OK
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 0/5] conntrack: save output format
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
` (4 preceding siblings ...)
2021-04-06 10:09 ` [PATCH v4 5/5] tests: conntrack -L/-D ip family filtering Mikhail Sennikovsky
@ 2021-05-03 20:42 ` Pablo Neira Ayuso
5 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2021-05-03 20:42 UTC (permalink / raw)
To: Mikhail Sennikovsky; +Cc: netfilter-devel
Hi Mikhail,
On Tue, Apr 06, 2021 at 12:09:42PM +0200, Mikhail Sennikovsky wrote:
> Hi Pablo & all,
>
> Here is the updated version of the "save output format"
> patches adjusted in accordance with our latest discussion with Pablo.
I have applied this series with changes.
Please, just follow up with incremental fixes in case you find any
bug of mine.
Thanks for your patience.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-05-03 20:42 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-04-06 10:09 [PATCH v4 0/5] conntrack: save output format Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 1/5] conntrack: introduce ct_cmd_list Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 2/5] conntrack: accept commands from file Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 3/5] conntrack.8: man update for --load-file support Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 4/5] tests: saving and loading ct entries, save format Mikhail Sennikovsky
2021-04-06 10:09 ` [PATCH v4 5/5] tests: conntrack -L/-D ip family filtering Mikhail Sennikovsky
2021-05-03 20:42 ` [PATCH v4 0/5] conntrack: save output format Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).