[PATCH xtables] xtables-compat: append all errors into single line

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

 



iptables-restore < /tmp/bogus
iptables-restore v1.6.2: iptables-restore:
line 49: RULE_APPEND failed (No such file or directory): rule in chain FOOBAR
line 2023: RULE_APPEND failed (Invalid argument): rule in chain TESTSNAT

This is a followup commit to 437746c7b528f ("xtables: extended error reporting").

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 iptables/nft.c | 56 +++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/iptables/nft.c b/iptables/nft.c
index e33d00f4259c..6c68600fd979 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -273,11 +273,11 @@ struct obj_update {
 	} error;
 };
 
-static void mnl_show_error(const struct nft_handle *h,
-			   const struct obj_update *o,
-			   const struct mnl_err *err)
+static int mnl_append_error(const struct nft_handle *h,
+			    const struct obj_update *o,
+			    const struct mnl_err *err,
+			    char *buf, unsigned int len)
 {
-	const char *prog = xt_params->program_name;
 	static const char *type_name[] = {
 		[NFT_COMPAT_TABLE_ADD] = "TABLE_ADD",
 		[NFT_COMPAT_TABLE_FLUSH] = "TABLE_FLUSH",
@@ -296,8 +296,12 @@ static void mnl_show_error(const struct nft_handle *h,
 	char errmsg[256];
 	char tcr[128];
 
-	snprintf(errmsg, sizeof(errmsg), "%s: line %u: %s failed (%s): ",
-		 prog, o->error.lineno, type_name[o->type], strerror(err->err));
+	if (o->error.lineno)
+		snprintf(errmsg, sizeof(errmsg), "\nline %u: %s failed (%s)",
+			 o->error.lineno, type_name[o->type], strerror(err->err));
+	else
+		snprintf(errmsg, sizeof(errmsg), "%s failed (%s)",
+			 type_name[o->type], strerror(err->err));
 
 	switch (o->type) {
 	case NFT_COMPAT_TABLE_ADD:
@@ -331,7 +335,7 @@ static void mnl_show_error(const struct nft_handle *h,
 		break;
 	}
 
-	fprintf(stderr, "%s: %s", errmsg, tcr);
+	return snprintf(buf, len, "%s: %s", errmsg, tcr);
 }
 
 static int batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr)
@@ -2396,6 +2400,8 @@ static int nft_action(struct nft_handle *h, int action)
 {
 	struct obj_update *n, *tmp;
 	struct mnl_err *err, *ne;
+	unsigned int buflen, i, len;
+	char errmsg[1024];
 	uint32_t seq = 1;
 	int ret = 0;
 
@@ -2481,26 +2487,38 @@ static int nft_action(struct nft_handle *h, int action)
 
 	ret = mnl_batch_talk(h->nl, h->batch, &h->err_list);
 
-	list_for_each_entry_safe(err, ne, &h->err_list, head) {
-		list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
-			bool next_err = false;
+	i = 0;
+	buflen = sizeof(errmsg);
+	if (!list_empty(&h->err_list)) {
+		len = snprintf(errmsg, buflen + i, "%s: ", xt_params->program_name);
+		if (len > 0) {
+			i += len;
+			buflen -= len;
+		}
+	}
+
+	list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
+		list_for_each_entry_safe(err, ne, &h->err_list, head) {
+			if (err->seqnum > n->seq)
+				break;
 
 			if (err->seqnum == n->seq) {
-				mnl_show_error(h, n, err);
-				next_err = true;
+				len = mnl_append_error(h, n, err, errmsg + i, buflen);
+				if (len > 0 && len <= buflen) {
+					buflen -= len;
+					i += len;
+				}
 			}
-			batch_obj_del(h, n);
-			if (next_err)
-				break;
+			mnl_err_list_free(err);
 		}
-		mnl_err_list_free(err);
-	}
-
-	list_for_each_entry_safe(n, tmp, &h->obj_list, head)
 		batch_obj_del(h, n);
+	}
 
 	mnl_batch_reset(h->batch);
 
+	if (i)
+		xtables_error(RESOURCE_PROBLEM, "%s", errmsg);
+
 	return ret == 0 ? 1 : 0;
 }
 
-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux