All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Phil Sutter <phil@nwl.cc>,
	netfilter-devel@vger.kernel.org, Florian Westphal <fw@strlen.de>
Subject: Re: RFC: Ideas about possible solutions for nfbz#949
Date: Tue, 30 May 2017 14:08:36 +0200	[thread overview]
Message-ID: <20170530120836.GA3010@salvia> (raw)
In-Reply-To: <20170530110424.xilg6ph3aqstopyl@base.sg13b.nwl.cc>

[-- Attachment #1: Type: text/plain, Size: 2500 bytes --]

On Tue, May 30, 2017 at 01:04:24PM +0200, Phil Sutter wrote:
[...]
> On Mon, May 29, 2017 at 07:52:18PM +0200, Pablo Neira Ayuso wrote:
[...]
> > > My idea was to build something like the protocol dependencies we have
> > > for e.g. TCP header fields but with ICMP, a given header field might be
> > > present in multiple message types (e.g. icmp6_id is present in echo
> > > request as well as reply).
> > 
> > You mean adding more instructions when generating bytecode? This has
> > runtime overhead, just to provide context for just listing the
> > ruleset. I would prefer we skip this.
> 
> Yes, that is questionable. But it is a matter of definition in my PoV. A
> user saying 'icmp6 id 2' might not be aware that all possible icmp6
> packets might match, not only those making use of the ID field. Right
> now it feels like we want a low-level 'icmp6 offset X mask y' and a
> high-level 'icmp6 echo direction any id 2' but that's probably out of
> scope here.

If the user just specifies 'icmp6 id 2', we should reject this and ask
for a specific icmp type.

> > > I already considered inserting a match for icmp6 type against an
> > > anonymous set (like 'icmp6 type { echo-request, echo-reply }'), but
> > > having this as an implicit dependency and resolving with previous
> > > matches, etc. becomes pretty complex.
> > > 
> > > Do you think I should try following a different approach (via userdata
> > > e.g.)?
> > 
> > I think you should try adding some context structure to the
> > expr_print(), this context can be used to interpret this offset based
> > on the icmp type.
> > 
> > Someone (Elise?) send me a patch to add this context structure, just
> > to prepare introduction, but she got stuck in the context update
> > logic at some point. I can find such patch so you only have to figure
> > out how to annotate the information we need in this context structure.
> 
> Yes, that would be great. Having something to get me started is always
> very helpful. :)

I'm attaching what Elise sent me for review.

This is just an initial patch to add some context structure for
expr_print(), so it's pretty much the simple initial step.

Not telling here you have to use 'struct proto_ctx' specifically, I
guess we need some print_ctx structure for this to annotate that we
have seen "icmp type" already, so offset interpretation is based on

I would need to spend more time here to provide a more specific design
for this, so if you can come back with initial ideas, that would be
good.

[-- Attachment #2: 0001-First-part-of-icmp-print-patch.patch --]
[-- Type: text/x-diff, Size: 19307 bytes --]

>From b4531696ec0c2c9407c9a7655f9cb133280294ff Mon Sep 17 00:00:00 2001
From: Elise Lennion <elise.lennion@gmail.com>
Date: Tue, 17 Jan 2017 21:53:15 -0200
Subject: [PATCH] First part of icmp print patch.

Signed-off-by: Elise Lennion <elise.lennion@gmail.com>
---
 include/expression.h |  5 ++--
 src/ct.c             |  5 ++--
 src/evaluate.c       |  2 +-
 src/expression.c     | 70 +++++++++++++++++++++++++++++++---------------------
 src/exthdr.c         |  3 ++-
 src/fib.c            |  3 ++-
 src/hash.c           |  5 ++--
 src/meta.c           |  5 ++--
 src/netlink.c        |  6 ++---
 src/numgen.c         |  3 ++-
 src/payload.c        |  7 +++---
 src/rt.c             |  3 ++-
 src/rule.c           |  2 +-
 src/segtree.c        |  2 +-
 src/statement.c      | 40 +++++++++++++++---------------
 15 files changed, 92 insertions(+), 69 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index ec90265..8010f34 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -157,7 +157,8 @@ struct expr_ops {
 	void			(*set_type)(const struct expr *expr,
 					    const struct datatype *dtype,
 					    enum byteorder byteorder);
-	void			(*print)(const struct expr *expr);
+	void			(*print)(const struct expr *expr,
+					 const struct proto_ctx *ctx);
 	bool			(*cmp)(const struct expr *e1,
 				       const struct expr *e2);
 	void			(*pctx_update)(struct proto_ctx *ctx,
@@ -324,7 +325,7 @@ extern struct expr *expr_alloc(const struct location *loc,
 extern struct expr *expr_clone(const struct expr *expr);
 extern struct expr *expr_get(struct expr *expr);
 extern void expr_free(struct expr *expr);
-extern void expr_print(const struct expr *expr);
+extern void expr_print(const struct expr *expr, const struct proto_ctx *ctx);
 extern bool expr_cmp(const struct expr *e1, const struct expr *e2);
 extern void expr_describe(const struct expr *expr);
 
diff --git a/src/ct.c b/src/ct.c
index 31c7a4b..20bbeea 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -236,7 +236,8 @@ static const struct ct_template ct_templates[] = {
 					      BYTEORDER_HOST_ENDIAN, 64),
 };
 
-static void ct_expr_print(const struct expr *expr)
+static void ct_expr_print(const struct expr *expr,
+			  const struct proto_ctx *ctx)
 {
 	const struct symbolic_constant *s;
 
@@ -398,7 +399,7 @@ void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr)
 static void ct_stmt_print(const struct stmt *stmt)
 {
 	printf("ct %s set ", ct_templates[stmt->ct.key].token);
-	expr_print(stmt->ct.expr);
+	expr_print(stmt->ct.expr, NULL);
 }
 
 static const struct stmt_ops ct_stmt_ops = {
diff --git a/src/evaluate.c b/src/evaluate.c
index bcbced1..d0f2421 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1622,7 +1622,7 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
 		struct error_record *erec;
 		erec = erec_create(EREC_INFORMATIONAL, &(*expr)->location,
 				   "Evaluate %s", (*expr)->ops->name);
-		erec_print(stdout, erec); expr_print(*expr); printf("\n\n");
+		erec_print(stdout, erec); expr_print(*expr, NULL); printf("\n\n");
 	}
 #endif
 
diff --git a/src/expression.c b/src/expression.c
index 1567870..17f7911 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -70,9 +70,9 @@ void expr_free(struct expr *expr)
 	xfree(expr);
 }
 
-void expr_print(const struct expr *expr)
+void expr_print(const struct expr *expr, const struct proto_ctx *ctx)
 {
-	expr->ops->print(expr);
+	expr->ops->print(expr, ctx);
 }
 
 bool expr_cmp(const struct expr *e1, const struct expr *e2)
@@ -160,7 +160,8 @@ int __fmtstring(4, 5) expr_binary_error(struct list_head *msgs,
 	return -1;
 }
 
-static void verdict_expr_print(const struct expr *expr)
+static void verdict_expr_print(const struct expr *expr,
+			       const struct proto_ctx *ctx)
 {
 	datatype_print(expr);
 }
@@ -213,7 +214,8 @@ struct expr *verdict_expr_alloc(const struct location *loc,
 	return expr;
 }
 
-static void symbol_expr_print(const struct expr *expr)
+static void symbol_expr_print(const struct expr *expr,
+			      const struct proto_ctx *ctx)
 {
 	printf("%s%s", expr->scope != NULL ? "$" : "", expr->identifier);
 }
@@ -252,7 +254,8 @@ struct expr *symbol_expr_alloc(const struct location *loc,
 	return expr;
 }
 
-static void constant_expr_print(const struct expr *expr)
+static void constant_expr_print(const struct expr *expr,
+				const struct proto_ctx *ctx)
 {
 	datatype_print(expr);
 }
@@ -394,9 +397,10 @@ struct expr *bitmask_expr_to_binops(struct expr *expr)
 	return binop;
 }
 
-static void prefix_expr_print(const struct expr *expr)
+static void prefix_expr_print(const struct expr *expr,
+			      const struct proto_ctx *ctx)
 {
-	expr_print(expr->prefix);
+	expr_print(expr->prefix, NULL);
 	printf("/%u", expr->prefix_len);
 }
 
@@ -458,11 +462,12 @@ const char *expr_op_symbols[] = {
 	[OP_LOOKUP]	= NULL,
 };
 
-static void unary_expr_print(const struct expr *expr)
+static void unary_expr_print(const struct expr *expr,
+			     const struct proto_ctx *ctx)
 {
 	if (expr_op_symbols[expr->op] != NULL)
 		printf("%s(", expr_op_symbols[expr->op]);
-	expr_print(expr->arg);
+	expr_print(expr->arg, NULL);
 	printf(")");
 }
 
@@ -515,7 +520,7 @@ static void binop_arg_print(const struct expr *op, const struct expr *arg)
 
 	if (prec)
 		printf("(");
-	expr_print(arg);
+	expr_print(arg, NULL);
 	if (prec)
 		printf(")");
 }
@@ -529,7 +534,8 @@ static bool must_print_eq_op(const struct expr *expr)
 	return expr->left->ops->type == EXPR_BINOP;
 }
 
-static void binop_expr_print(const struct expr *expr)
+static void binop_expr_print(const struct expr *expr,
+			     const struct proto_ctx *ctx)
 {
 	binop_arg_print(expr, expr->left);
 
@@ -595,11 +601,12 @@ struct expr *relational_expr_alloc(const struct location *loc, enum ops op,
 	return expr;
 }
 
-static void range_expr_print(const struct expr *expr)
+static void range_expr_print(const struct expr *expr,
+			     const struct proto_ctx *ctx)
 {
-	expr_print(expr->left);
+	expr_print(expr->left, NULL);
 	printf("-");
-	expr_print(expr->right);
+	expr_print(expr->right, NULL);
 }
 
 static void range_expr_clone(struct expr *new, const struct expr *expr)
@@ -677,7 +684,7 @@ static void compound_expr_print(const struct expr *expr, const char *delim)
 
 	list_for_each_entry(i, &expr->expressions, list) {
 		printf("%s", d);
-		expr_print(i);
+		expr_print(i, NULL);
 		d = delim;
 	}
 }
@@ -700,7 +707,8 @@ static void concat_expr_destroy(struct expr *expr)
 	compound_expr_destroy(expr);
 }
 
-static void concat_expr_print(const struct expr *expr)
+static void concat_expr_print(const struct expr *expr,
+			      const struct proto_ctx *ctx)
 {
 	compound_expr_print(expr, " . ");
 }
@@ -718,7 +726,8 @@ struct expr *concat_expr_alloc(const struct location *loc)
 	return compound_expr_alloc(loc, &concat_expr_ops);
 }
 
-static void list_expr_print(const struct expr *expr)
+static void list_expr_print(const struct expr *expr,
+			    const struct proto_ctx *ctx)
 {
 	compound_expr_print(expr, ",");
 }
@@ -736,7 +745,8 @@ struct expr *list_expr_alloc(const struct location *loc)
 	return compound_expr_alloc(loc, &list_expr_ops);
 }
 
-static void set_expr_print(const struct expr *expr)
+static void set_expr_print(const struct expr *expr,
+			   const struct proto_ctx *ctx)
 {
 	printf("{ ");
 	compound_expr_print(expr, ", ");
@@ -767,11 +777,12 @@ struct expr *set_expr_alloc(const struct location *loc)
 	return compound_expr_alloc(loc, &set_expr_ops);
 }
 
-static void mapping_expr_print(const struct expr *expr)
+static void mapping_expr_print(const struct expr *expr,
+			       const struct proto_ctx *ctx)
 {
-	expr_print(expr->left);
+	expr_print(expr->left, NULL);
 	printf(" : ");
-	expr_print(expr->right);
+	expr_print(expr->right, NULL);
 }
 
 static void mapping_expr_set_type(const struct expr *expr,
@@ -814,15 +825,16 @@ struct expr *mapping_expr_alloc(const struct location *loc,
 	return expr;
 }
 
-static void map_expr_print(const struct expr *expr)
+static void map_expr_print(const struct expr *expr,
+			   const struct proto_ctx *ctx)
 {
-	expr_print(expr->map);
+	expr_print(expr->map, NULL);
 	if (expr->mappings->ops->type == EXPR_SET_REF &&
 	    expr->mappings->set->datatype->type == TYPE_VERDICT)
 		printf(" vmap ");
 	else
 		printf(" map ");
-	expr_print(expr->mappings);
+	expr_print(expr->mappings, NULL);
 }
 
 static void map_expr_clone(struct expr *new, const struct expr *expr)
@@ -856,13 +868,14 @@ struct expr *map_expr_alloc(const struct location *loc, struct expr *arg,
 	return expr;
 }
 
-static void set_ref_expr_print(const struct expr *expr)
+static void set_ref_expr_print(const struct expr *expr,
+			       const struct proto_ctx *ctx)
 {
 	if (expr->set->flags & NFT_SET_ANONYMOUS) {
 		if (expr->set->flags & NFT_SET_EVAL)
 			printf("table %s", expr->set->handle.set);
 		else
-			expr_print(expr->set->init);
+			expr_print(expr->set->init, NULL);
 	} else {
 		printf("@%s", expr->set->handle.set);
 	}
@@ -896,9 +909,10 @@ struct expr *set_ref_expr_alloc(const struct location *loc, struct set *set)
 	return expr;
 }
 
-static void set_elem_expr_print(const struct expr *expr)
+static void set_elem_expr_print(const struct expr *expr,
+				const struct proto_ctx *ctx)
 {
-	expr_print(expr->key);
+	expr_print(expr->key, NULL);
 	if (expr->timeout) {
 		printf(" timeout ");
 		time_print(expr->timeout / 1000);
diff --git a/src/exthdr.c b/src/exthdr.c
index c641d4a..a5fb58b 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -22,7 +22,8 @@
 #include <headers.h>
 #include <expression.h>
 
-static void exthdr_expr_print(const struct expr *expr)
+static void exthdr_expr_print(const struct expr *expr,
+			      const struct proto_ctx *ctx)
 {
 	printf("%s %s", expr->exthdr.desc->name, expr->exthdr.tmpl->token);
 }
diff --git a/src/fib.c b/src/fib.c
index c65677c..aafeec0 100644
--- a/src/fib.c
+++ b/src/fib.c
@@ -71,7 +71,8 @@ static void __fib_expr_print_f(unsigned int *flags, unsigned int f, const char *
 		printf(" . ");
 }
 
-static void fib_expr_print(const struct expr *expr)
+static void fib_expr_print(const struct expr *expr,
+			   const struct proto_ctx *ctx)
 {
 	unsigned int flags = expr->fib.flags;
 
diff --git a/src/hash.c b/src/hash.c
index d26b2ed..61b2ae0 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -15,10 +15,11 @@
 #include <hash.h>
 #include <utils.h>
 
-static void hash_expr_print(const struct expr *expr)
+static void hash_expr_print(const struct expr *expr,
+		            const struct proto_ctx *ctx)
 {
 	printf("jhash ");
-	expr_print(expr->hash.expr);
+	expr_print(expr->hash.expr, NULL);
 	printf(" mod %u", expr->hash.mod);
 	if (expr->hash.seed)
 		printf(" seed 0x%x", expr->hash.seed);
diff --git a/src/meta.c b/src/meta.c
index cb7c136..00284cf 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -464,7 +464,8 @@ static bool meta_key_is_qualified(enum nft_meta_keys key)
 	}
 }
 
-static void meta_expr_print(const struct expr *expr)
+static void meta_expr_print(const struct expr *expr,
+		            const struct proto_ctx *ctx)
 {
 	if (meta_key_is_qualified(expr->meta.key))
 		printf("meta %s", meta_templates[expr->meta.key].token);
@@ -591,7 +592,7 @@ static void meta_stmt_print(const struct stmt *stmt)
 	else
 		printf("%s set ", meta_templates[stmt->meta.key].token);
 
-	expr_print(stmt->meta.expr);
+	expr_print(stmt->meta.expr, NULL);
 }
 
 static const struct stmt_ops meta_stmt_ops = {
diff --git a/src/netlink.c b/src/netlink.c
index 4135f25..439dd2f 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -2184,7 +2184,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type,
 			goto out;
 		}
 		printf("element %s %s %s ", family2str(family), table, setname);
-		expr_print(dummyset->init);
+		expr_print(dummyset->init, NULL);
 		printf("\n");
 
 		set_free(dummyset);
@@ -2546,7 +2546,7 @@ static void trace_print_expr(const struct nftnl_trace *nlt, unsigned int attr,
 				   len * BITS_PER_BYTE, data);
 	rel  = relational_expr_alloc(&netlink_location, OP_EQ, lhs, rhs);
 
-	expr_print(rel);
+	expr_print(rel, NULL);
 	printf(" ");
 	expr_free(rel);
 }
@@ -2563,7 +2563,7 @@ static void trace_print_verdict(const struct nftnl_trace *nlt)
 	expr = verdict_expr_alloc(&netlink_location, verdict, chain);
 
 	printf("verdict ");
-	expr_print(expr);
+	expr_print(expr, NULL);
 	expr_free(expr);
 }
 
diff --git a/src/numgen.c b/src/numgen.c
index 5c1d00a..9f17cdc 100644
--- a/src/numgen.c
+++ b/src/numgen.c
@@ -28,7 +28,8 @@ static const char *numgen_type_str(enum nft_ng_types type)
 	return numgen_type[type];
 }
 
-static void numgen_expr_print(const struct expr *expr)
+static void numgen_expr_print(const struct expr *expr,
+		              const struct proto_ctx *ctx)
 {
 	printf("numgen %s mod %u", numgen_type_str(expr->numgen.type),
 	       expr->numgen.mod);
diff --git a/src/payload.c b/src/payload.c
index af533b2..a0f0816 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -38,7 +38,8 @@ bool payload_is_known(const struct expr *expr)
 	       tmpl != &proto_unknown_template;
 }
 
-static void payload_expr_print(const struct expr *expr)
+static void payload_expr_print(const struct expr *expr,
+		               const struct proto_ctx *ctx)
 {
 	const struct proto_desc *desc;
 	const struct proto_hdr_template *tmpl;
@@ -164,9 +165,9 @@ unsigned int payload_hdr_field(const struct expr *expr)
 
 static void payload_stmt_print(const struct stmt *stmt)
 {
-	expr_print(stmt->payload.expr);
+	expr_print(stmt->payload.expr, NULL);
 	printf(" set ");
-	expr_print(stmt->payload.val);
+	expr_print(stmt->payload.val, NULL);
 }
 
 static const struct stmt_ops payload_stmt_ops = {
diff --git a/src/rt.c b/src/rt.c
index 232c1dc..455eac0 100644
--- a/src/rt.c
+++ b/src/rt.c
@@ -75,7 +75,8 @@ static const struct rt_template rt_templates[] = {
 					      true),
 };
 
-static void rt_expr_print(const struct expr *expr)
+static void rt_expr_print(const struct expr *expr,
+			  const struct proto_ctx *ctx)
 {
 	printf("rt %s", rt_templates[expr->rt.key].token);
 }
diff --git a/src/rule.c b/src/rule.c
index f2ffd4b..327988a 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -351,7 +351,7 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts)
 
 	if (set->init != NULL && set->init->size > 0) {
 		printf("%s%selements = ", opts->tab, opts->tab);
-		expr_print(set->init);
+		expr_print(set->init, NULL);
 		printf("%s", opts->nl);
 	}
 	printf("%s}%s", opts->tab, opts->nl);
diff --git a/src/segtree.c b/src/segtree.c
index 8df82a8..456a9ea 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -563,7 +563,7 @@ int set_to_intervals(struct list_head *errs, struct set *set,
 	}
 
 	if (segtree_debug()) {
-		expr_print(init);
+		expr_print(init, NULL);
 		pr_gmp_debug("\n");
 	}
 	return 0;
diff --git a/src/statement.c b/src/statement.c
index 25bed65..7e2e448 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -67,7 +67,7 @@ void stmt_print(const struct stmt *stmt)
 
 static void expr_stmt_print(const struct stmt *stmt)
 {
-	expr_print(stmt->expr);
+	expr_print(stmt->expr, NULL);
 }
 
 static void expr_stmt_destroy(struct stmt *stmt)
@@ -111,11 +111,11 @@ static void flow_stmt_print(const struct stmt *stmt)
 {
 	printf("flow ");
 	if (stmt->flow.set) {
-		expr_print(stmt->flow.set);
+		expr_print(stmt->flow.set, NULL);
 		printf(" ");
 	}
 	printf("{ ");
-	expr_print(stmt->flow.key);
+	expr_print(stmt->flow.key, NULL);
 	printf(" ");
 	stmt_print(stmt->flow.stmt);
 	printf("} ");
@@ -182,7 +182,7 @@ static const char *objref_type_name(uint32_t type)
 static void objref_stmt_print(const struct stmt *stmt)
 {
 	printf("%s name ", objref_type_name(stmt->objref.type));
-	expr_print(stmt->objref.expr);
+	expr_print(stmt->objref.expr, NULL);
 }
 
 static const struct stmt_ops objref_stmt_ops = {
@@ -364,7 +364,7 @@ static void queue_stmt_print(const struct stmt *stmt)
 	printf("queue");
 	if (stmt->queue.queue != NULL) {
 		printf(" num ");
-		expr_print(stmt->queue.queue);
+		expr_print(stmt->queue.queue, NULL);
 	}
 	if (stmt->queue.flags & NFT_QUEUE_FLAG_BYPASS) {
 		printf("%sbypass", delim);
@@ -428,7 +428,7 @@ static void reject_stmt_print(const struct stmt *stmt)
 		if (stmt->reject.icmp_code == NFT_REJECT_ICMPX_PORT_UNREACH)
 			break;
 		printf(" with icmpx type ");
-		expr_print(stmt->reject.expr);
+		expr_print(stmt->reject.expr, NULL);
 		break;
 	case NFT_REJECT_ICMP_UNREACH:
 		switch (stmt->reject.family) {
@@ -436,13 +436,13 @@ static void reject_stmt_print(const struct stmt *stmt)
 			if (stmt->reject.icmp_code == ICMP_PORT_UNREACH)
 				break;
 			printf(" with icmp type ");
-			expr_print(stmt->reject.expr);
+			expr_print(stmt->reject.expr, NULL);
 			break;
 		case NFPROTO_IPV6:
 			if (stmt->reject.icmp_code == ICMP6_DST_UNREACH_NOPORT)
 				break;
 			printf(" with icmpv6 type ");
-			expr_print(stmt->reject.expr);
+			expr_print(stmt->reject.expr, NULL);
 			break;
 		}
 		break;
@@ -494,24 +494,24 @@ static void nat_stmt_print(const struct stmt *stmt)
 			if (stmt->nat.addr->ops->type == EXPR_VALUE &&
 			    stmt->nat.addr->dtype->type == TYPE_IP6ADDR) {
 				printf("[");
-				expr_print(stmt->nat.addr);
+				expr_print(stmt->nat.addr, NULL);
 				printf("]");
 			} else if (stmt->nat.addr->ops->type == EXPR_RANGE &&
 				   stmt->nat.addr->left->dtype->type == TYPE_IP6ADDR) {
 				printf("[");
-				expr_print(stmt->nat.addr->left);
+				expr_print(stmt->nat.addr->left, NULL);
 				printf("]-[");
-				expr_print(stmt->nat.addr->right);
+				expr_print(stmt->nat.addr->right, NULL);
 				printf("]");
 			}
 		} else {
-			expr_print(stmt->nat.addr);
+			expr_print(stmt->nat.addr, NULL);
 		}
 	}
 
 	if (stmt->nat.proto) {
 		printf(":");
-		expr_print(stmt->nat.proto);
+		expr_print(stmt->nat.proto, NULL);
 	}
 
 	print_nf_nat_flags(stmt->nat.flags);
@@ -541,7 +541,7 @@ static void masq_stmt_print(const struct stmt *stmt)
 
 	if (stmt->masq.proto) {
 		printf(" to :");
-		expr_print(stmt->masq.proto);
+		expr_print(stmt->masq.proto, NULL);
 	}
 
 	print_nf_nat_flags(stmt->masq.flags);
@@ -570,7 +570,7 @@ static void redir_stmt_print(const struct stmt *stmt)
 
 	if (stmt->redir.proto) {
 		printf(" to :");
-		expr_print(stmt->redir.proto);
+		expr_print(stmt->redir.proto, NULL);
 	}
 
 	print_nf_nat_flags(stmt->redir.flags);
@@ -601,9 +601,9 @@ static const char * const set_stmt_op_names[] = {
 static void set_stmt_print(const struct stmt *stmt)
 {
 	printf("set %s ", set_stmt_op_names[stmt->set.op]);
-	expr_print(stmt->set.key);
+	expr_print(stmt->set.key, NULL);
 	printf(" ");
-	expr_print(stmt->set.set);
+	expr_print(stmt->set.set, NULL);
 }
 
 static void set_stmt_destroy(struct stmt *stmt)
@@ -629,11 +629,11 @@ static void dup_stmt_print(const struct stmt *stmt)
 	printf("dup");
 	if (stmt->dup.to != NULL) {
 		printf(" to ");
-		expr_print(stmt->dup.to);
+		expr_print(stmt->dup.to, NULL);
 
 		if (stmt->dup.dev != NULL) {
 			printf(" device ");
-			expr_print(stmt->dup.dev);
+			expr_print(stmt->dup.dev, NULL);
 		}
 	}
 }
@@ -659,7 +659,7 @@ struct stmt *dup_stmt_alloc(const struct location *loc)
 static void fwd_stmt_print(const struct stmt *stmt)
 {
 	printf("fwd to ");
-	expr_print(stmt->fwd.to);
+	expr_print(stmt->fwd.to, NULL);
 }
 
 static void fwd_stmt_destroy(struct stmt *stmt)
-- 
2.7.4


  reply	other threads:[~2017-05-30 12:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-10 15:34 RFC: Ideas about possible solutions for nfbz#949 Phil Sutter
2017-05-29 17:52 ` Pablo Neira Ayuso
2017-05-30 11:04   ` Phil Sutter
2017-05-30 12:08     ` Pablo Neira Ayuso [this message]
2017-06-23 14:03       ` Phil Sutter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170530120836.GA3010@salvia \
    --to=pablo@netfilter.org \
    --cc=fw@strlen.de \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=phil@nwl.cc \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.