[PATCH 1/3] conntrack: introduce new -A command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The -A command works exactly the same way as -I except that it
does not fail if the ct entry already exists.
This command is useful for the batched ct loads to not abort if
some entries being applied exist.

The ct entry dump in the "save" format is now switched to use the
-A command as well for the generated output.

Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@xxxxxxxxx>
---
 src/conntrack.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index 500e736..465a4f9 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -115,6 +115,7 @@ struct ct_cmd {
 	unsigned int	cmd;
 	unsigned int	type;
 	unsigned int	event_mask;
+	unsigned int 	cmd_options;
 	int		options;
 	int		family;
 	int		protonum;
@@ -215,6 +216,11 @@ enum ct_command {
 };
 /* If you add a new command, you have to update NUMBER_OF_CMD in conntrack.h */
 
+enum ct_command_options {
+	CT_CMD_OPT_IGNORE_ALREADY_DONE_BIT = 0,
+	CT_CMD_OPT_IGNORE_ALREADY_DONE     = (1 << CT_CMD_OPT_IGNORE_ALREADY_DONE_BIT),
+};
+
 enum ct_options {
 	CT_OPT_ORIG_SRC_BIT	= 0,
 	CT_OPT_ORIG_SRC 	= (1 << CT_OPT_ORIG_SRC_BIT),
@@ -396,7 +402,7 @@ static struct option original_opts[] = {
 	{0, 0, 0, 0}
 };
 
-static const char *getopt_str = ":L::I::U::D::G::E::F::hVs:d:r:q:"
+static const char *getopt_str = ":L::I::U::D::G::E::F::A::hVs:d:r:q:"
 				"p:t:u:e:a:z[:]:{:}:m:i:f:o:n::"
 				"g::c:b:C::Sj::w:l:<:>::(:):";
 
@@ -805,7 +811,7 @@ static int ct_save_snprintf(char *buf, size_t len,
 
 	switch (type) {
 	case NFCT_T_NEW:
-		ret = snprintf(buf + offset, len, "-I ");
+		ret = snprintf(buf + offset, len, "-A ");
 		BUFFER_SIZE(ret, size, len, offset);
 		break;
 	case NFCT_T_UPDATE:
@@ -2918,7 +2924,10 @@ static int print_stats(const struct ct_cmd *cmd)
 	if (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)))
+		if (counter == 0 &&
+		    !((cmd->command & (CT_LIST | EXP_LIST))
+		       || (cmd->command == CT_CREATE
+		           && (cmd->cmd_options & CT_CMD_OPT_IGNORE_ALREADY_DONE))))
 			return -1;
 	}
 
@@ -2931,6 +2940,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 	int protonum = 0, family = AF_UNSPEC;
 	size_t socketbuffersize = 0;
 	unsigned int command = 0;
+	unsigned int cmd_options = 0;
 	unsigned int options = 0;
 	struct ct_tmpl *tmpl;
 	int res = 0, partial;
@@ -2981,17 +2991,23 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 			add_command(&command, cmd2type[c][type]);
 			break;
 		case 'U':
+		case 'A':
 			type = check_type(argc, argv);
 			if (type == CT_TABLE_DYING ||
 			    type == CT_TABLE_UNCONFIRMED) {
 				exit_error(PARAMETER_PROBLEM,
 					   "Can't do that command with "
 					   "tables `dying' and `unconfirmed'");
-			} else if (type == CT_TABLE_CONNTRACK)
-				add_command(&command, CT_UPDATE);
-			else
+			} else if (type == CT_TABLE_CONNTRACK) {
+				if (c == 'A') {
+					add_command(&command, CT_CREATE);
+					cmd_options |= CT_CMD_OPT_IGNORE_ALREADY_DONE;
+				} else
+					add_command(&command, CT_UPDATE);
+			} else
 				exit_error(PARAMETER_PROBLEM,
-					   "Can't update expectations");
+					   "Can't %s expectations",
+					   c == 'U' ? "update" : "add to");
 			break;
 		/* options */
 		case 's':
@@ -3240,6 +3256,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 
 	ct_cmd->command = command;
 	ct_cmd->cmd = cmd;
+	ct_cmd->cmd_options = cmd_options;
 	ct_cmd->options = options;
 	ct_cmd->family = family;
 	ct_cmd->type = type;
@@ -3345,6 +3362,9 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
 				       NULL, cmd->tmpl.ct, NULL);
 		if (res >= 0)
 			counter++;
+		else if (errno == EEXIST
+			 && (cmd->cmd_options & CT_CMD_OPT_IGNORE_ALREADY_DONE))
+			res = 0;
 
 		break;
 
-- 
2.25.1




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux