netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH conntrack-tools 0/3] preparing support for command batch
@ 2021-01-14 22:31 Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 1/3] conntrack: add struct ct_cmd Pablo Neira Ayuso
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-01-14 22:31 UTC (permalink / raw)
  To: netfilter-devel; +Cc: mikhail.sennikovskii

Hi Mikhail,

This is a patch to prepare for the command batch support.

Please have a look at the xtables restore parser, it would be great
if the code to read the file lines via fgets() and then turn it into
argc and argv (see add_argv() for reference in iptables/xshared.c).
If conntrack can converge to use existing approach in the iptables code, that
will be good for maintainability reasons.

Thanks for your patience.

Pablo Neira Ayuso (3):
  conntrack: add struct ct_cmd
  conntrack: add struct ct_tmpl
  conntrack: add do_command_ct()

 src/conntrack.c | 346 +++++++++++++++++++++++++++---------------------
 1 file changed, 194 insertions(+), 152 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH conntrack-tools 1/3] conntrack: add struct ct_cmd
  2021-01-14 22:31 [PATCH conntrack-tools 0/3] preparing support for command batch Pablo Neira Ayuso
@ 2021-01-14 22:32 ` Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 2/3] conntrack: add struct ct_tmpl Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 3/3] conntrack: add do_command_ct() Pablo Neira Ayuso
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-01-14 22:32 UTC (permalink / raw)
  To: netfilter-devel; +Cc: mikhail.sennikovskii

This new object stores the result of the command parser, this prepares
for batch support.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 125 +++++++++++++++++++++++++++++-------------------
 1 file changed, 76 insertions(+), 49 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index cc58d3f3df7f..12c9608c1003 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -2762,30 +2762,25 @@ nfct_set_nat_details(const int opt, struct nf_conntrack *ct,
 
 }
 
-int main(int argc, char *argv[])
+struct ct_cmd {
+	unsigned int	command;
+	unsigned int	cmd;
+	unsigned int	type;
+	unsigned int	event_mask;
+	int		family;
+	int		protonum;
+	size_t		socketbuffersize;
+};
+
+static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 {
-	int c, cmd;
 	unsigned int type = 0, event_mask = 0, l4flags = 0, status = 0;
-	int res = 0, partial;
+	int protonum = 0, family = AF_UNSPEC;
 	size_t socketbuffersize = 0;
-	int family = AF_UNSPEC;
-	int protonum = 0;
-	union ct_address ad;
 	unsigned int command = 0;
-
-	/* we release these objects in the exit_error() path. */
-	if (!alloc_tmpl_objects())
-		exit_error(OTHER_PROBLEM, "out of memory");
-
-	register_tcp();
-	register_udp();
-	register_udplite();
-	register_sctp();
-	register_dccp();
-	register_icmp();
-	register_icmpv6();
-	register_gre();
-	register_unknown();
+	int res = 0, partial;
+	union ct_address ad;
+	int c, cmd;
 
 	/* disable explicit missing arguments error output from getopt_long */
 	opterr = 0;
@@ -3065,27 +3060,57 @@ int main(int argc, char *argv[])
 	if (!(command & CT_HELP) && h && h->final_check)
 		h->final_check(l4flags, cmd, tmpl.ct);
 
-	switch(command) {
+	ct_cmd->command = command;
+	ct_cmd->cmd = cmd;
+	ct_cmd->family = family;
+	ct_cmd->type = type;
+	ct_cmd->protonum = protonum;
+	ct_cmd->event_mask = event_mask;
+	ct_cmd->socketbuffersize = socketbuffersize;
+}
+
+int main(int argc, char *argv[])
+{
+	struct ct_cmd _cmd = {}, *cmd = &_cmd;
+	int res = 0;
+
+	/* we release these objects in the exit_error() path. */
+	if (!alloc_tmpl_objects())
+		exit_error(OTHER_PROBLEM, "out of memory");
+
+	register_tcp();
+	register_udp();
+	register_udplite();
+	register_sctp();
+	register_dccp();
+	register_icmp();
+	register_icmpv6();
+	register_gre();
+	register_unknown();
+
+	do_parse(cmd, argc, argv);
+
+	switch(cmd->command) {
 	struct nfct_filter_dump *filter_dump;
 
 	case CT_LIST:
-		if (type == CT_TABLE_DYING) {
+		if (cmd->type == CT_TABLE_DYING) {
 			if (nfct_mnl_socket_open(0) < 0)
 				exit_error(OTHER_PROBLEM, "Can't open handler");
 
 			res = nfct_mnl_dump(NFNL_SUBSYS_CTNETLINK,
 					    IPCTNL_MSG_CT_GET_DYING,
-					    mnl_nfct_dump_cb, family);
+					    mnl_nfct_dump_cb, cmd->family);
 
 			nfct_mnl_socket_close();
 			break;
-		} else if (type == CT_TABLE_UNCONFIRMED) {
+		} else if (cmd->type == CT_TABLE_UNCONFIRMED) {
 			if (nfct_mnl_socket_open(0) < 0)
 				exit_error(OTHER_PROBLEM, "Can't open handler");
 
 			res = nfct_mnl_dump(NFNL_SUBSYS_CTNETLINK,
 					    IPCTNL_MSG_CT_GET_UNCONFIRMED,
-					    mnl_nfct_dump_cb, family);
+					    mnl_nfct_dump_cb, cmd->family);
 
 			nfct_mnl_socket_close();
 			break;
@@ -3100,7 +3125,7 @@ int main(int argc, char *argv[])
 			exit_error(PARAMETER_PROBLEM, "Can't use -z with "
 						      "filtering parameters");
 
-		nfct_filter_init(family);
+		nfct_filter_init(cmd->family);
 
 		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, tmpl.ct);
 
@@ -3115,7 +3140,7 @@ int main(int argc, char *argv[])
 		}
 		nfct_filter_dump_set_attr_u8(filter_dump,
 					     NFCT_FILTER_DUMP_L3NUM,
-					     family);
+					     cmd->family);
 
 		if (options & CT_OPT_ZERO)
 			res = nfct_query(cth, NFCT_Q_DUMP_FILTER_RESET,
@@ -3139,7 +3164,7 @@ int main(int argc, char *argv[])
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
 		nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
-		res = nfexp_query(cth, NFCT_Q_DUMP, &family);
+		res = nfexp_query(cth, NFCT_Q_DUMP, &cmd->family);
 		nfct_close(cth);
 
 		if (dump_xml_header_done == 0) {
@@ -3191,22 +3216,22 @@ int main(int argc, char *argv[])
 		if (!cth || !ith)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		nfct_filter_init(family);
+		nfct_filter_init(cmd->family);
 
 		nfct_callback_register(cth, NFCT_T_ALL, update_cb, tmpl.ct);
 
-		res = nfct_query(cth, NFCT_Q_DUMP, &family);
+		res = nfct_query(cth, NFCT_Q_DUMP, &cmd->family);
 		nfct_close(ith);
 		nfct_close(cth);
 		break;
-		
+
 	case CT_DELETE:
 		cth = nfct_open(CONNTRACK, 0);
 		ith = nfct_open(CONNTRACK, 0);
 		if (!cth || !ith)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		nfct_filter_init(family);
+		nfct_filter_init(cmd->family);
 
 		nfct_callback_register(cth, NFCT_T_ALL, delete_cb, tmpl.ct);
 
@@ -3221,7 +3246,7 @@ int main(int argc, char *argv[])
 		}
 		nfct_filter_dump_set_attr_u8(filter_dump,
 					     NFCT_FILTER_DUMP_L3NUM,
-					     family);
+					     cmd->family);
 
 		res = nfct_query(cth, NFCT_Q_DUMP_FILTER, filter_dump);
 
@@ -3268,7 +3293,7 @@ int main(int argc, char *argv[])
 		cth = nfct_open(CONNTRACK, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		res = nfct_query(cth, NFCT_Q_FLUSH_FILTER, &family);
+		res = nfct_query(cth, NFCT_Q_FLUSH_FILTER, &cmd->family);
 		nfct_close(cth);
 		fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
 		fprintf(stderr,"connection tracking table has been emptied.\n");
@@ -3278,7 +3303,7 @@ int main(int argc, char *argv[])
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		res = nfexp_query(cth, NFCT_Q_FLUSH, &family);
+		res = nfexp_query(cth, NFCT_Q_FLUSH, &cmd->family);
 		nfct_close(cth);
 		fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
 		fprintf(stderr,"expectation table has been emptied.\n");
@@ -3288,11 +3313,11 @@ int main(int argc, char *argv[])
 		if (options & CT_OPT_EVENT_MASK) {
 			unsigned int nl_events = 0;
 
-			if (event_mask & CT_EVENT_F_NEW)
+			if (cmd->event_mask & CT_EVENT_F_NEW)
 				nl_events |= NF_NETLINK_CONNTRACK_NEW;
-			if (event_mask & CT_EVENT_F_UPD)
+			if (cmd->event_mask & CT_EVENT_F_UPD)
 				nl_events |= NF_NETLINK_CONNTRACK_UPDATE;
-			if (event_mask & CT_EVENT_F_DEL)
+			if (cmd->event_mask & CT_EVENT_F_DEL)
 				nl_events |= NF_NETLINK_CONNTRACK_DESTROY;
 
 			res = nfct_mnl_socket_open(nl_events);
@@ -3306,6 +3331,8 @@ int main(int argc, char *argv[])
 			exit_error(OTHER_PROBLEM, "Can't open netlink socket");
 
 		if (options & CT_OPT_BUFFERSIZE) {
+			size_t socketbuffersize = cmd->socketbuffersize;
+
 			socklen_t socklen = sizeof(socketbuffersize);
 
 			res = setsockopt(mnl_socket_get_fd(sock.mnl),
@@ -3316,7 +3343,7 @@ int main(int argc, char *argv[])
 				setsockopt(mnl_socket_get_fd(sock.mnl),
 					   SOL_SOCKET, SO_RCVBUF,
 					   &socketbuffersize,
-					   socketbuffersize);
+					   sizeof(socketbuffersize));
 			}
 			getsockopt(mnl_socket_get_fd(sock.mnl), SOL_SOCKET,
 				   SO_RCVBUF, &socketbuffersize, &socklen);
@@ -3325,7 +3352,7 @@ int main(int argc, char *argv[])
 					socketbuffersize);
 		}
 
-		nfct_filter_init(family);
+		nfct_filter_init(cmd->family, &cmd->tmpl);
 
 		signal(SIGINT, event_sighandler);
 		signal(SIGTERM, event_sighandler);
@@ -3359,11 +3386,11 @@ int main(int argc, char *argv[])
 		if (options & CT_OPT_EVENT_MASK) {
 			unsigned int nl_events = 0;
 
-			if (event_mask & CT_EVENT_F_NEW)
+			if (cmd->event_mask & CT_EVENT_F_NEW)
 				nl_events |= NF_NETLINK_CONNTRACK_EXP_NEW;
-			if (event_mask & CT_EVENT_F_UPD)
+			if (cmd->event_mask & CT_EVENT_F_UPD)
 				nl_events |= NF_NETLINK_CONNTRACK_EXP_UPDATE;
-			if (event_mask & CT_EVENT_F_DEL)
+			if (cmd->event_mask & CT_EVENT_F_DEL)
 				nl_events |= NF_NETLINK_CONNTRACK_EXP_DESTROY;
 
 			cth = nfct_open(CONNTRACK, nl_events);
@@ -3423,7 +3450,7 @@ try_proc_count:
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
 		nfexp_callback_register(cth, NFCT_T_ALL, count_exp_cb, NULL);
-		res = nfexp_query(cth, NFCT_Q_DUMP, &family);
+		res = nfexp_query(cth, NFCT_Q_DUMP, &cmd->family);
 		nfct_close(cth);
 		printf("%d\n", counter);
 		break;
@@ -3472,7 +3499,7 @@ try_proc:
 	case CT_HELP:
 		usage(argv[0]);
 		if (options & CT_OPT_PROTO)
-			extension_help(h, protonum);
+			extension_help(h, cmd->protonum);
 		break;
 	default:
 		usage(argv[0]);
@@ -3481,17 +3508,17 @@ try_proc:
 
 	if (res < 0)
 		exit_error(OTHER_PROBLEM, "Operation failed: %s",
-			   err2str(errno, command));
+			   err2str(errno, cmd->command));
 
 	free_tmpl_objects();
 	free_options();
 	if (labelmap)
 		nfct_labelmap_destroy(labelmap);
 
-	if (command && exit_msg[cmd][0]) {
+	if (cmd->command && exit_msg[cmd->cmd][0]) {
 		fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
-		fprintf(stderr, exit_msg[cmd], counter);
-		if (counter == 0 && !(command & (CT_LIST | EXP_LIST)))
+		fprintf(stderr, exit_msg[cmd->cmd], counter);
+		if (counter == 0 && !(cmd->command & (CT_LIST | EXP_LIST)))
 			return EXIT_FAILURE;
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH conntrack-tools 2/3] conntrack: add struct ct_tmpl
  2021-01-14 22:31 [PATCH conntrack-tools 0/3] preparing support for command batch Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 1/3] conntrack: add struct ct_cmd Pablo Neira Ayuso
@ 2021-01-14 22:32 ` Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 3/3] conntrack: add do_command_ct() Pablo Neira Ayuso
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-01-14 22:32 UTC (permalink / raw)
  To: netfilter-devel; +Cc: mikhail.sennikovskii

Remove the global template object, add it to struct ct_cmd. This patch
prepares for the batch support.

The global cur_tmpl pointer is used to access the template from the
callbacks and the exit_error() path.

Note that it should be possible to remove this global cur_tmpl pointer
by passing the new command object as parameter to the callbacks and
exit_error().

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 231 +++++++++++++++++++++++++-----------------------
 1 file changed, 121 insertions(+), 110 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index 12c9608c1003..019299645a0d 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -79,7 +79,7 @@ struct u32_mask {
 };
 
 /* These are the template objects that are used to send commands. */
-static struct {
+struct ct_tmpl {
 	struct nf_conntrack *ct;
 	struct nf_expect *exp;
 	/* Expectations require the expectation tuple and the mask. */
@@ -97,35 +97,39 @@ static struct {
 
 	/* Allows setting/removing specific ctlabels */
 	struct nfct_bitmask *label_modify;
-} tmpl;
+};
+
+static struct ct_tmpl *cur_tmpl;
 
-static int alloc_tmpl_objects(void)
+static int alloc_tmpl_objects(struct ct_tmpl *tmpl)
 {
-	tmpl.ct = nfct_new();
-	tmpl.exptuple = nfct_new();
-	tmpl.mask = nfct_new();
-	tmpl.exp = nfexp_new();
+	tmpl->ct = nfct_new();
+	tmpl->exptuple = nfct_new();
+	tmpl->mask = nfct_new();
+	tmpl->exp = nfexp_new();
 
-	memset(&tmpl.mark, 0, sizeof(tmpl.mark));
+	memset(&tmpl->mark, 0, sizeof(tmpl->mark));
 
-	return tmpl.ct != NULL && tmpl.exptuple != NULL &&
-	       tmpl.mask != NULL && tmpl.exp != NULL;
+	cur_tmpl = tmpl;
+
+	return tmpl->ct != NULL && tmpl->exptuple != NULL &&
+	       tmpl->mask != NULL && tmpl->exp != NULL;
 }
 
-static void free_tmpl_objects(void)
+static void free_tmpl_objects(struct ct_tmpl *tmpl)
 {
-	if (tmpl.ct)
-		nfct_destroy(tmpl.ct);
-	if (tmpl.exptuple)
-		nfct_destroy(tmpl.exptuple);
-	if (tmpl.mask)
-		nfct_destroy(tmpl.mask);
-	if (tmpl.exp)
-		nfexp_destroy(tmpl.exp);
-	if (tmpl.label)
-		nfct_bitmask_destroy(tmpl.label);
-	if (tmpl.label_modify)
-		nfct_bitmask_destroy(tmpl.label_modify);
+	if (tmpl->ct)
+		nfct_destroy(tmpl->ct);
+	if (tmpl->exptuple)
+		nfct_destroy(tmpl->exptuple);
+	if (tmpl->mask)
+		nfct_destroy(tmpl->mask);
+	if (tmpl->exp)
+		nfexp_destroy(tmpl->exp);
+	if (tmpl->label)
+		nfct_bitmask_destroy(tmpl->label);
+	if (tmpl->label_modify)
+		nfct_bitmask_destroy(tmpl->label_modify);
 }
 
 enum ct_command {
@@ -945,7 +949,7 @@ exit_error(enum exittype status, const char *msg, ...)
 	if (status == PARAMETER_PROBLEM)
 		exit_tryhelp(status);
 	/* release template objects that were allocated in the setup stage. */
-	free_tmpl_objects();
+	free_tmpl_objects(cur_tmpl);
 	exit(status);
 }
 
@@ -1458,17 +1462,17 @@ usage(char *prog)
 static unsigned int output_mask;
 
 static int
-filter_label(const struct nf_conntrack *ct)
+filter_label(const struct nf_conntrack *ct, const struct ct_tmpl *tmpl)
 {
-	if (tmpl.label == NULL)
+	if (tmpl->label == NULL)
 		return 0;
 
 	const struct nfct_bitmask *ctb = nfct_get_attr(ct, ATTR_CONNLABELS);
 	if (ctb == NULL)
 		return 1;
 
-	for (unsigned int i = 0; i <= nfct_bitmask_maxbit(tmpl.label); i++) {
-		if (nfct_bitmask_test_bit(tmpl.label, i) &&
+	for (unsigned int i = 0; i <= nfct_bitmask_maxbit(tmpl->label); i++) {
+		if (nfct_bitmask_test_bit(tmpl->label, i) &&
 		    !nfct_bitmask_test_bit(ctb, i))
 				return 1;
 	}
@@ -1477,10 +1481,10 @@ filter_label(const struct nf_conntrack *ct)
 }
 
 static int
-filter_mark(const struct nf_conntrack *ct)
+filter_mark(const struct nf_conntrack *ct, const struct ct_tmpl *tmpl)
 {
 	if ((options & CT_OPT_MARK) &&
-	     !mark_cmp(&tmpl.mark, ct))
+	     !mark_cmp(&tmpl->mark, ct))
 		return 1;
 	return 0;
 }
@@ -1626,11 +1630,12 @@ filter_network(const struct nf_conntrack *ct)
 }
 
 static int
-nfct_filter(struct nf_conntrack *obj, struct nf_conntrack *ct)
+nfct_filter(struct nf_conntrack *obj, struct nf_conntrack *ct,
+	    const struct ct_tmpl *tmpl)
 {
 	if (filter_nat(obj, ct) ||
-	    filter_mark(ct) ||
-	    filter_label(ct) ||
+	    filter_mark(ct, tmpl) ||
+	    filter_label(ct, tmpl) ||
 	    filter_network(ct))
 		return 1;
 
@@ -1870,7 +1875,7 @@ static int event_cb(const struct nlmsghdr *nlh, void *data)
 
 	if ((filter_family != AF_UNSPEC &&
 	     filter_family != nfh->nfgen_family) ||
-	    nfct_filter(obj, ct))
+	    nfct_filter(obj, ct, cur_tmpl))
 		goto out;
 
 	if (output_mask & _O_SAVE) {
@@ -1930,7 +1935,7 @@ static int dump_cb(enum nf_conntrack_msg_type type,
 	unsigned int op_type = NFCT_O_DEFAULT;
 	unsigned int op_flags = 0;
 
-	if (nfct_filter(obj, ct))
+	if (nfct_filter(obj, ct, cur_tmpl))
 		return NFCT_CB_CONTINUE;
 
 	if (output_mask & _O_SAVE) {
@@ -1972,7 +1977,7 @@ static int delete_cb(enum nf_conntrack_msg_type type,
 	unsigned int op_type = NFCT_O_DEFAULT;
 	unsigned int op_flags = 0;
 
-	if (nfct_filter(obj, ct))
+	if (nfct_filter(obj, ct, cur_tmpl))
 		return NFCT_CB_CONTINUE;
 
 	res = nfct_query(ith, NFCT_Q_DESTROY, ct);
@@ -2058,7 +2063,8 @@ static struct nfct_bitmask *xnfct_bitmask_clone(const struct nfct_bitmask *a)
 	return b;
 }
 
-static void copy_label(struct nf_conntrack *tmp, const struct nf_conntrack *ct)
+static void copy_label(struct nf_conntrack *tmp, const struct nf_conntrack *ct,
+		       const struct ct_tmpl *tmpl)
 {
 	struct nfct_bitmask *ctb, *newmask;
 	unsigned int i;
@@ -2072,7 +2078,7 @@ static void copy_label(struct nf_conntrack *tmp, const struct nf_conntrack *ct)
 	if (options & CT_OPT_ADD_LABEL) {
 		if (ctb == NULL) {
 			nfct_set_attr(tmp, ATTR_CONNLABELS,
-					xnfct_bitmask_clone(tmpl.label_modify));
+					xnfct_bitmask_clone(tmpl->label_modify));
 			return;
 		}
 		/* If we send a bitmask shorter than the kernel sent to us, the bits we
@@ -2086,7 +2092,7 @@ static void copy_label(struct nf_conntrack *tmp, const struct nf_conntrack *ct)
 		newmask = nfct_bitmask_new(nfct_bitmask_maxbit(ctb));
 
 		for (i = 0; i <= nfct_bitmask_maxbit(ctb); i++) {
-			if (nfct_bitmask_test_bit(tmpl.label_modify, i)) {
+			if (nfct_bitmask_test_bit(tmpl->label_modify, i)) {
 				nfct_bitmask_set_bit(ctb, i);
 				nfct_bitmask_set_bit(newmask, i);
 			} else if (nfct_bitmask_test_bit(ctb, i)) {
@@ -2099,7 +2105,7 @@ static void copy_label(struct nf_conntrack *tmp, const struct nf_conntrack *ct)
 		nfct_set_attr(tmp, ATTR_CONNLABELS_MASK, newmask);
 	} else if (ctb != NULL) {
 		/* CT_OPT_DEL_LABEL */
-		if (tmpl.label_modify == NULL) {
+		if (tmpl->label_modify == NULL) {
 			newmask = nfct_bitmask_new(0);
 			if (newmask)
 				nfct_set_attr(tmp, ATTR_CONNLABELS, newmask);
@@ -2107,11 +2113,11 @@ static void copy_label(struct nf_conntrack *tmp, const struct nf_conntrack *ct)
 		}
 
 		for (i = 0; i <= nfct_bitmask_maxbit(ctb); i++) {
-			if (nfct_bitmask_test_bit(tmpl.label_modify, i))
+			if (nfct_bitmask_test_bit(tmpl->label_modify, i))
 				nfct_bitmask_unset_bit(ctb, i);
 		}
 
-		newmask = xnfct_bitmask_clone(tmpl.label_modify);
+		newmask = xnfct_bitmask_clone(tmpl->label_modify);
 		nfct_set_attr(tmp, ATTR_CONNLABELS_MASK, newmask);
 	}
 }
@@ -2124,7 +2130,7 @@ static int update_cb(enum nf_conntrack_msg_type type,
 	struct nf_conntrack *obj = data, *tmp;
 
 	if (filter_nat(obj, ct) ||
-	    filter_label(ct) ||
+	    filter_label(ct, cur_tmpl) ||
 	    filter_network(ct))
 		return NFCT_CB_CONTINUE;
 
@@ -2143,9 +2149,9 @@ static int update_cb(enum nf_conntrack_msg_type type,
 
 	nfct_copy(tmp, ct, NFCT_CP_ORIG);
 	nfct_copy(tmp, obj, NFCT_CP_META);
-	copy_mark(tmp, ct, &tmpl.mark);
+	copy_mark(tmp, ct, &cur_tmpl->mark);
 	copy_status(tmp, ct);
-	copy_label(tmp, ct);
+	copy_label(tmp, ct, cur_tmpl);
 
 	/* do not send NFCT_Q_UPDATE if ct appears unchanged */
 	if (nfct_cmp(tmp, ct, NFCT_CMP_ALL | NFCT_CMP_MASK)) {
@@ -2578,7 +2584,8 @@ static void labelmap_init(void)
 }
 
 static void
-nfct_network_attr_prepare(const int family, enum ct_direction dir)
+nfct_network_attr_prepare(const int family, enum ct_direction dir,
+			  const struct ct_tmpl *tmpl)
 {
 	const union ct_address *address, *netmask;
 	enum nf_conntrack_attr attr;
@@ -2587,8 +2594,8 @@ nfct_network_attr_prepare(const int family, enum ct_direction dir)
 
 	attr = famdir2attr[family == AF_INET6][dir];
 
-	address = nfct_get_attr(tmpl.ct, attr);
-	netmask = nfct_get_attr(tmpl.mask, attr);
+	address = nfct_get_attr(tmpl->ct, attr);
+	netmask = nfct_get_attr(tmpl->mask, attr);
 
 	switch(family) {
 	case AF_INET:
@@ -2603,11 +2610,11 @@ nfct_network_attr_prepare(const int family, enum ct_direction dir)
 	memcpy(&net->netmask, netmask, sizeof(union ct_address));
 
 	/* avoid exact source matching */
-	nfct_attr_unset(tmpl.ct, attr);
+	nfct_attr_unset(tmpl->ct, attr);
 }
 
 static void
-nfct_filter_init(const int family)
+nfct_filter_init(const int family, const struct ct_tmpl *tmpl)
 {
 	filter_family = family;
 	if (options & CT_OPT_MASK_SRC) {
@@ -2615,7 +2622,7 @@ nfct_filter_init(const int family)
 		if (!(options & CT_OPT_ORIG_SRC))
 			exit_error(PARAMETER_PROBLEM,
 			           "Can't use --mask-src without --src");
-		nfct_network_attr_prepare(family, DIR_SRC);
+		nfct_network_attr_prepare(family, DIR_SRC, tmpl);
 	}
 
 	if (options & CT_OPT_MASK_DST) {
@@ -2623,7 +2630,7 @@ nfct_filter_init(const int family)
 		if (!(options & CT_OPT_ORIG_DST))
 			exit_error(PARAMETER_PROBLEM,
 			           "Can't use --mask-dst without --dst");
-		nfct_network_attr_prepare(family, DIR_DST);
+		nfct_network_attr_prepare(family, DIR_DST, tmpl);
 	}
 }
 
@@ -2770,6 +2777,7 @@ struct ct_cmd {
 	int		family;
 	int		protonum;
 	size_t		socketbuffersize;
+	struct ct_tmpl	tmpl;
 };
 
 static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
@@ -2778,10 +2786,17 @@ 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;
+	struct ct_tmpl *tmpl;
 	int res = 0, partial;
 	union ct_address ad;
 	int c, cmd;
 
+	/* we release these objects in the exit_error() path. */
+	if (!alloc_tmpl_objects(&ct_cmd->tmpl))
+		exit_error(OTHER_PROBLEM, "out of memory");
+
+	tmpl = &ct_cmd->tmpl;
+
 	/* disable explicit missing arguments error output from getopt_long */
 	opterr = 0;
 
@@ -2835,17 +2850,17 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 		case 'd':
 		case 'r':
 		case 'q':
-			nfct_parse_addr_from_opt(c, optarg, tmpl.ct,
-						 tmpl.mask, &ad, &family);
+			nfct_parse_addr_from_opt(c, optarg, tmpl->ct,
+						 tmpl->mask, &ad, &family);
 			break;
 		case '[':
 		case ']':
-			nfct_parse_addr_from_opt(c, optarg, tmpl.exptuple,
-						 tmpl.mask, &ad, &family);
+			nfct_parse_addr_from_opt(c, optarg, tmpl->exptuple,
+						 tmpl->mask, &ad, &family);
 			break;
 		case '{':
 		case '}':
-			nfct_parse_addr_from_opt(c, optarg, tmpl.mask,
+			nfct_parse_addr_from_opt(c, optarg, tmpl->mask,
 						 NULL, &ad, &family);
 			break;
 		case 'p':
@@ -2860,18 +2875,18 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 			if (opts == NULL)
 				exit_error(OTHER_PROBLEM, "out of memory");
 
-			nfct_set_attr_u8(tmpl.ct, ATTR_L4PROTO, protonum);
+			nfct_set_attr_u8(tmpl->ct, ATTR_L4PROTO, protonum);
 			break;
 		case 't':
 			options |= CT_OPT_TIMEOUT;
-			nfct_set_attr_u32(tmpl.ct, ATTR_TIMEOUT, atol(optarg));
-			nfexp_set_attr_u32(tmpl.exp,
+			nfct_set_attr_u32(tmpl->ct, ATTR_TIMEOUT, atol(optarg));
+			nfexp_set_attr_u32(tmpl->exp,
 					   ATTR_EXP_TIMEOUT, atol(optarg));
 			break;
 		case 'u':
 			options |= CT_OPT_STATUS;
 			parse_parameter(optarg, &status, PARSE_STATUS);
-			nfct_set_attr_u32(tmpl.ct, ATTR_STATUS, status);
+			nfct_set_attr_u32(tmpl->ct, ATTR_STATUS, status);
 			break;
 		case 'e':
 			options |= CT_OPT_EVENT_MASK;
@@ -2904,18 +2919,18 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 						       &nat_address,
 						       &port_str);
 				nfct_parse_addr_from_opt(c, nat_address,
-							 tmpl.ct, NULL,
+							 tmpl->ct, NULL,
 							 &ad, &family);
 				if (c == 'j') {
 					/* Set details on both src and dst
 					 * with any-nat
 					 */
-					nfct_set_nat_details('g', tmpl.ct, &ad,
+					nfct_set_nat_details('g', tmpl->ct, &ad,
 							     port_str, family);
-					nfct_set_nat_details('n', tmpl.ct, &ad,
+					nfct_set_nat_details('n', tmpl->ct, &ad,
 							     port_str, family);
 				} else {
-					nfct_set_nat_details(c, tmpl.ct, &ad,
+					nfct_set_nat_details(c, tmpl->ct, &ad,
 							     port_str, family);
 				}
 			}
@@ -2924,23 +2939,23 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 		case '(':
 		case ')':
 			options |= opt2type[c];
-			nfct_set_attr_u16(tmpl.ct,
+			nfct_set_attr_u16(tmpl->ct,
 					  opt2attr[c],
 					  strtoul(optarg, NULL, 0));
 			break;
 		case 'i':
 		case 'c':
 			options |= opt2type[c];
-			nfct_set_attr_u32(tmpl.ct,
+			nfct_set_attr_u32(tmpl->ct,
 					  opt2attr[c],
 					  strtoul(optarg, NULL, 0));
 			break;
 		case 'm':
 			options |= opt2type[c];
-			parse_u32_mask(optarg, &tmpl.mark);
-			tmpl.filter_mark_kernel.val = tmpl.mark.value;
-			tmpl.filter_mark_kernel.mask = tmpl.mark.mask;
-			tmpl.filter_mark_kernel_set = true;
+			parse_u32_mask(optarg, &tmpl->mark);
+			tmpl->filter_mark_kernel.val = tmpl->mark.value;
+			tmpl->filter_mark_kernel.mask = tmpl->mark.mask;
+			tmpl->filter_mark_kernel_set = true;
 			break;
 		case 'l':
 		case '<':
@@ -2971,9 +2986,9 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 
 			/* join "-l foo -l bar" into single bitmask object */
 			if (c == 'l') {
-				merge_bitmasks(&tmpl.label, b);
+				merge_bitmasks(&tmpl->label, b);
 			} else {
-				merge_bitmasks(&tmpl.label_modify, b);
+				merge_bitmasks(&tmpl->label_modify, b);
 			}
 
 			free(optarg2);
@@ -3006,10 +3021,10 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 				   "unknown option `%s'", argv[optind-1]);
 			break;
 		default:
-			if (h && h->parse_opts 
-			    &&!h->parse_opts(c - h->option_offset, tmpl.ct,
-			    		     tmpl.exptuple, tmpl.mask,
-					     &l4flags))
+			if (h && h->parse_opts &&
+			    !h->parse_opts(c - h->option_offset, tmpl->ct,
+					   tmpl->exptuple, tmpl->mask,
+					   &l4flags))
 				exit_error(PARAMETER_PROBLEM, "parse error");
 			break;
 		}
@@ -3058,7 +3073,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 		}
 	}
 	if (!(command & CT_HELP) && h && h->final_check)
-		h->final_check(l4flags, cmd, tmpl.ct);
+		h->final_check(l4flags, cmd, tmpl->ct);
 
 	ct_cmd->command = command;
 	ct_cmd->cmd = cmd;
@@ -3074,10 +3089,6 @@ int main(int argc, char *argv[])
 	struct ct_cmd _cmd = {}, *cmd = &_cmd;
 	int res = 0;
 
-	/* we release these objects in the exit_error() path. */
-	if (!alloc_tmpl_objects())
-		exit_error(OTHER_PROBLEM, "out of memory");
-
 	register_tcp();
 	register_udp();
 	register_udplite();
@@ -3125,18 +3136,18 @@ int main(int argc, char *argv[])
 			exit_error(PARAMETER_PROBLEM, "Can't use -z with "
 						      "filtering parameters");
 
-		nfct_filter_init(cmd->family);
+		nfct_filter_init(cmd->family, &cmd->tmpl);
 
-		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, tmpl.ct);
+		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, cmd->tmpl.ct);
 
 		filter_dump = nfct_filter_dump_create();
 		if (filter_dump == NULL)
 			exit_error(OTHER_PROBLEM, "OOM");
 
-		if (tmpl.filter_mark_kernel_set) {
+		if (cmd->tmpl.filter_mark_kernel_set) {
 			nfct_filter_dump_set_attr(filter_dump,
 						  NFCT_FILTER_DUMP_MARK,
-						  &tmpl.filter_mark_kernel);
+						  &cmd->tmpl.filter_mark_kernel);
 		}
 		nfct_filter_dump_set_attr_u8(filter_dump,
 					     NFCT_FILTER_DUMP_L3NUM,
@@ -3175,37 +3186,37 @@ int main(int argc, char *argv[])
 
 	case CT_CREATE:
 		if ((options & CT_OPT_ORIG) && !(options & CT_OPT_REPL))
-		    	nfct_setobjopt(tmpl.ct, NFCT_SOPT_SETUP_REPLY);
+			nfct_setobjopt(cmd->tmpl.ct, NFCT_SOPT_SETUP_REPLY);
 		else if (!(options & CT_OPT_ORIG) && (options & CT_OPT_REPL))
-			nfct_setobjopt(tmpl.ct, NFCT_SOPT_SETUP_ORIGINAL);
+			nfct_setobjopt(cmd->tmpl.ct, NFCT_SOPT_SETUP_ORIGINAL);
 
 		if (options & CT_OPT_MARK)
-			nfct_set_attr_u32(tmpl.ct, ATTR_MARK, tmpl.mark.value);
+			nfct_set_attr_u32(cmd->tmpl.ct, ATTR_MARK, cmd->tmpl.mark.value);
 
 		if (options & CT_OPT_ADD_LABEL)
-			nfct_set_attr(tmpl.ct, ATTR_CONNLABELS,
-					xnfct_bitmask_clone(tmpl.label_modify));
+			nfct_set_attr(cmd->tmpl.ct, ATTR_CONNLABELS,
+					xnfct_bitmask_clone(cmd->tmpl.label_modify));
 
 		cth = nfct_open(CONNTRACK, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		res = nfct_query(cth, NFCT_Q_CREATE, tmpl.ct);
+		res = nfct_query(cth, NFCT_Q_CREATE, cmd->tmpl.ct);
 		if (res != -1)
 			counter++;
 		nfct_close(cth);
 		break;
 
 	case EXP_CREATE:
-		nfexp_set_attr(tmpl.exp, ATTR_EXP_MASTER, tmpl.ct);
-		nfexp_set_attr(tmpl.exp, ATTR_EXP_EXPECTED, tmpl.exptuple);
-		nfexp_set_attr(tmpl.exp, ATTR_EXP_MASK, tmpl.mask);
+		nfexp_set_attr(cmd->tmpl.exp, ATTR_EXP_MASTER, cmd->tmpl.ct);
+		nfexp_set_attr(cmd->tmpl.exp, ATTR_EXP_EXPECTED, cmd->tmpl.exptuple);
+		nfexp_set_attr(cmd->tmpl.exp, ATTR_EXP_MASK, cmd->tmpl.mask);
 
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		res = nfexp_query(cth, NFCT_Q_CREATE, tmpl.exp);
+		res = nfexp_query(cth, NFCT_Q_CREATE, cmd->tmpl.exp);
 		nfct_close(cth);
 		break;
 
@@ -3216,9 +3227,9 @@ int main(int argc, char *argv[])
 		if (!cth || !ith)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		nfct_filter_init(cmd->family);
+		nfct_filter_init(cmd->family, &cmd->tmpl);
 
-		nfct_callback_register(cth, NFCT_T_ALL, update_cb, tmpl.ct);
+		nfct_callback_register(cth, NFCT_T_ALL, update_cb, cmd->tmpl.ct);
 
 		res = nfct_query(cth, NFCT_Q_DUMP, &cmd->family);
 		nfct_close(ith);
@@ -3231,18 +3242,18 @@ int main(int argc, char *argv[])
 		if (!cth || !ith)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		nfct_filter_init(cmd->family);
+		nfct_filter_init(cmd->family, &cmd->tmpl);
 
-		nfct_callback_register(cth, NFCT_T_ALL, delete_cb, tmpl.ct);
+		nfct_callback_register(cth, NFCT_T_ALL, delete_cb, cmd->tmpl.ct);
 
 		filter_dump = nfct_filter_dump_create();
 		if (filter_dump == NULL)
 			exit_error(OTHER_PROBLEM, "OOM");
 
-		if (tmpl.filter_mark_kernel_set) {
+		if (cmd->tmpl.filter_mark_kernel_set) {
 			nfct_filter_dump_set_attr(filter_dump,
 						  NFCT_FILTER_DUMP_MARK,
-						  &tmpl.filter_mark_kernel);
+						  &cmd->tmpl.filter_mark_kernel);
 		}
 		nfct_filter_dump_set_attr_u8(filter_dump,
 					     NFCT_FILTER_DUMP_L3NUM,
@@ -3257,13 +3268,13 @@ int main(int argc, char *argv[])
 		break;
 
 	case EXP_DELETE:
-		nfexp_set_attr(tmpl.exp, ATTR_EXP_EXPECTED, tmpl.ct);
+		nfexp_set_attr(cmd->tmpl.exp, ATTR_EXP_EXPECTED, cmd->tmpl.ct);
 
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		res = nfexp_query(cth, NFCT_Q_DESTROY, tmpl.exp);
+		res = nfexp_query(cth, NFCT_Q_DESTROY, cmd->tmpl.exp);
 		nfct_close(cth);
 		break;
 
@@ -3272,20 +3283,20 @@ int main(int argc, char *argv[])
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, tmpl.ct);
-		res = nfct_query(cth, NFCT_Q_GET, tmpl.ct);
+		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, cmd->tmpl.ct);
+		res = nfct_query(cth, NFCT_Q_GET, cmd->tmpl.ct);
 		nfct_close(cth);
 		break;
 
 	case EXP_GET:
-		nfexp_set_attr(tmpl.exp, ATTR_EXP_MASTER, tmpl.ct);
+		nfexp_set_attr(cmd->tmpl.exp, ATTR_EXP_MASTER, cmd->tmpl.ct);
 
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
 		nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
-		res = nfexp_query(cth, NFCT_Q_GET, tmpl.exp);
+		res = nfexp_query(cth, NFCT_Q_GET, cmd->tmpl.exp);
 		nfct_close(cth);
 		break;
 
@@ -3377,7 +3388,7 @@ int main(int argc, char *argv[])
 					   strerror(errno));
 				break;
 			}
-			res = mnl_cb_run(buf, res, 0, 0, event_cb, tmpl.ct);
+			res = mnl_cb_run(buf, res, 0, 0, event_cb, cmd->tmpl.ct);
 		}
 		mnl_socket_close(sock.mnl);
 		break;
@@ -3510,7 +3521,7 @@ try_proc:
 		exit_error(OTHER_PROBLEM, "Operation failed: %s",
 			   err2str(errno, cmd->command));
 
-	free_tmpl_objects();
+	free_tmpl_objects(&cmd->tmpl);
 	free_options();
 	if (labelmap)
 		nfct_labelmap_destroy(labelmap);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH conntrack-tools 3/3] conntrack: add do_command_ct()
  2021-01-14 22:31 [PATCH conntrack-tools 0/3] preparing support for command batch Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 1/3] conntrack: add struct ct_cmd Pablo Neira Ayuso
  2021-01-14 22:32 ` [PATCH conntrack-tools 2/3] conntrack: add struct ct_tmpl Pablo Neira Ayuso
@ 2021-01-14 22:32 ` Pablo Neira Ayuso
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-01-14 22:32 UTC (permalink / raw)
  To: netfilter-devel; +Cc: mikhail.sennikovskii

Wrap the code to run the command around the do_command_ct() function.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index 019299645a0d..987d936e7ee2 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -1444,8 +1444,7 @@ split_address_and_port(const char *arg, char **address, char **port_str)
 	}
 }
 
-static void
-usage(char *prog)
+static void usage(const char *prog)
 {
 	fprintf(stdout, "Command line interface for the connection "
 			"tracking system. Version %s\n", VERSION);
@@ -3084,26 +3083,12 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 	ct_cmd->socketbuffersize = socketbuffersize;
 }
 
-int main(int argc, char *argv[])
+static int do_command_ct(const char *progname, struct ct_cmd *cmd)
 {
-	struct ct_cmd _cmd = {}, *cmd = &_cmd;
+	struct nfct_filter_dump *filter_dump;
 	int res = 0;
 
-	register_tcp();
-	register_udp();
-	register_udplite();
-	register_sctp();
-	register_dccp();
-	register_icmp();
-	register_icmpv6();
-	register_gre();
-	register_unknown();
-
-	do_parse(cmd, argc, argv);
-
 	switch(cmd->command) {
-	struct nfct_filter_dump *filter_dump;
-
 	case CT_LIST:
 		if (cmd->type == CT_TABLE_DYING) {
 			if (nfct_mnl_socket_open(0) < 0)
@@ -3508,12 +3493,12 @@ try_proc:
 		printf("%s v%s (conntrack-tools)\n", PROGNAME, VERSION);
 		break;
 	case CT_HELP:
-		usage(argv[0]);
+		usage(progname);
 		if (options & CT_OPT_PROTO)
 			extension_help(h, cmd->protonum);
 		break;
 	default:
-		usage(argv[0]);
+		usage(progname);
 		break;
 	}
 
@@ -3535,3 +3520,22 @@ try_proc:
 
 	return EXIT_SUCCESS;
 }
+
+int main(int argc, char *argv[])
+{
+	struct ct_cmd _cmd = {}, *cmd = &_cmd;
+
+	register_tcp();
+	register_udp();
+	register_udplite();
+	register_sctp();
+	register_dccp();
+	register_icmp();
+	register_icmpv6();
+	register_gre();
+	register_unknown();
+
+	do_parse(cmd, argc, argv);
+
+	return do_command_ct(argv[0], cmd);
+}
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-01-14 22:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-14 22:31 [PATCH conntrack-tools 0/3] preparing support for command batch Pablo Neira Ayuso
2021-01-14 22:32 ` [PATCH conntrack-tools 1/3] conntrack: add struct ct_cmd Pablo Neira Ayuso
2021-01-14 22:32 ` [PATCH conntrack-tools 2/3] conntrack: add struct ct_tmpl Pablo Neira Ayuso
2021-01-14 22:32 ` [PATCH conntrack-tools 3/3] conntrack: add do_command_ct() 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).