All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Cc: netfilter-devel@vger.kernel.org, kaber@trash.net
Subject: Re: [nft PATCH 2/3] src: add xt compat support
Date: Wed, 25 Mar 2015 20:44:41 +0100	[thread overview]
Message-ID: <20150325194441.GA26737@salvia> (raw)
In-Reply-To: <20150325191602.13491.63370.stgit@nfdev2.cica.es>

On Wed, Mar 25, 2015 at 08:16:02PM +0100, Arturo Borrero Gonzalez wrote:
> diff --git a/include/xt.h b/include/xt.h
> new file mode 100644
> index 0000000..414f3d1
> --- /dev/null
> +++ b/include/xt.h
> @@ -0,0 +1,100 @@
> +#ifndef _NFT_XT_H_
> +#define _NFT_XT_H_
> +
> +#include <arpa/inet.h>
> +#include <netinet/in.h>
> +#include <limits.h>
> +#include <net/if.h>
> +#include <net/ethernet.h>
> +
> +struct netlink_linearize_ctx;
> +struct netlink_parse_ctx;
> +struct nft_rule_expr;
> +struct rule_pp_ctx;
> +struct rule;
> +
> +#ifdef HAVE_LIBXTABLES
> +
> +#include <linux/netfilter_ipv4/ip_tables.h>
> +#include <linux/netfilter_ipv6/ip6_tables.h>
> +#include <linux/netfilter_arp/arp_tables.h>
> +
> +/* Fake ebt_entry */
> +struct ebt_entry {

I think you can avoid this if you:

#include <linux/netfilter_bridge/ebtables.h>

[...]
> +#else /* HAVE_LIBXTABLES */
> +union nft_entry {
> +	uint32_t	*nothing;
> +};

I'd suggest:

        #define nft_entry void

> +static inline void stmt_xt_postprocess(struct rule_pp_ctx rctx,
                                                             ^^^^

I think this needs to be *rctx.

Please, retest without libxtables support.

> +				       struct stmt *stmt, struct rule *rule) {}
> +
> +#endif /* HAVE_LIBXTABLES */
> +
> +#endif /* _NFT_XT_H_ */
> +xt_opts			:	/* empty */	{ $$ = NULL; }
> +			|	XTOPTS		{ $$ = $1; }
> +			;
> +
> +xt_name			:	STRING		{ $$ = $1; }
> +			|	STATE		{ $$ = xstrdup("state"); }
> +			|	COMMENT		{ $$ = xstrdup("comment"); }
> +			|	AH		{ $$ = xstrdup("ah"); }
> +			|	ESP		{ $$ = xstrdup("esp"); }
> +			|	TCP		{ $$ = xstrdup("tcp"); }
> +			|	UDP		{ $$ = xstrdup("udp"); }
> +			|	UDPLITE		{ $$ = xstrdup("udplite"); }
> +			|	SCTP		{ $$ = xstrdup("sctp"); }
> +			|	ICMP		{ $$ = xstrdup("icmp"); }
> +			|	IP		{ $$ = xstrdup("ip"); }
> +			|	VLAN		{ $$ = xstrdup("vlan"); }
> +			|	LOG		{ $$ = xstrdup("log"); }
> +			|	_802_3		{ $$ = xstrdup("802_3"); }

This _802_3 should not be clashing with anything else, the problem is
somewhere else.

> +			|	MARK		{ $$ = xstrdup("mark"); }
> +			;
> +
>  nf_nat_flags		:	nf_nat_flag
>  			|	nf_nat_flags	COMMA	nf_nat_flag
>  			{
> diff --git a/src/rule.c b/src/rule.c
> index 7114380..c7c5e20 100644
> --- a/src/rule.c
> +++ b/src/rule.c
> @@ -820,6 +820,7 @@ static void table_cleanup(struct table *table)
>  	}
>  }
>  
> +#include <xt.h>
>  static int do_list_table(struct netlink_ctx *ctx, struct cmd *cmd,
>  			 struct table *table)
>  {
> diff --git a/src/scanner.l b/src/scanner.l
> index 73c4f8b..33f0699 100644
> --- a/src/scanner.l
> +++ b/src/scanner.l
> @@ -113,6 +113,7 @@ hexstring	0[xX]{hexdigit}+
>  range		({decstring}?:{decstring}?)
>  letter		[a-zA-Z]
>  string		({letter})({letter}|{digit}|[/\-_\.])*
> +xtopts		\[({letter}|{digit}|[!/\-_\.\"\:\, ])*\]
>  quotedstring	\"[^"]*\"
>  comment		#.*$
>  slash		\/
> @@ -449,6 +450,12 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
>  "proto-dst"		{ return PROTO_DST; }
>  "label"			{ return LABEL; }
>  
> +"xt"			{ return XT; }
> +"match"			{ return MATCH; }
> +"target"		{ return TARGET; }
> +"watcher"		{ return WATCHER; }
> +"802_3"			{ return _802_3; }
> +
>  "xml"			{ return XML; }
>  "json"			{ return JSON; }
>  
> @@ -488,6 +495,11 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
>  				return STRING;
>  			}
>  
> +{xtopts}		{
> +				yylval->string = xstrdup(yytext);
> +				return XTOPTS;
> +			}
> +
>  \\{newline}		{
>  				reset_pos(yyget_extra(yyscanner), yylloc);
>  			}
> diff --git a/src/statement.c b/src/statement.c
> index d72c6e9..5092ea8 100644
> --- a/src/statement.c
> +++ b/src/statement.c
> @@ -23,6 +23,7 @@
>  #include <statement.h>
>  #include <utils.h>
>  #include <list.h>
> +#include <xt.h>
>  
>  #include <netinet/in.h>
>  #include <linux/netfilter/nf_nat.h>
> @@ -377,3 +378,44 @@ struct stmt *redir_stmt_alloc(const struct location *loc)
>  {
>  	return stmt_alloc(loc, &redir_stmt_ops);
>  }
> +
> +static const char *xt_type_name[NFT_XT_MAX] = {
> +	[NFT_XT_MATCH]	= "match",
> +	[NFT_XT_TARGET]	= "target",
> +	[NFT_XT_WATCHER]= "watcher",
> +};
> +
> +static const char *xt_stmt_to_type(enum nft_xt_type type)
> +{
> +	if (type > NFT_XT_MAX)
> +		return "unknown";
> +
> +	return xt_type_name[type];
> +}
> +
> +static void xt_stmt_print(const struct stmt *stmt)
> +{
> +	printf("xt %s %s ", xt_stmt_to_type(stmt->xt.type),
> +			    xt_stmt_name(stmt));
> +	xt_stmt_save(stmt);
> +}
> +
> +static void xt_stmt_destroy(struct stmt *stmt)
> +{
> +	xfree(stmt->xt.name);
> +	xfree(stmt->xt.opts);
> +
> +	xt_stmt_destroy_internals(stmt);
> +}
> +
> +static const struct stmt_ops xt_stmt_ops = {
> +	.type		= STMT_XT,
> +	.name		= "xt",
> +	.print		= xt_stmt_print,
> +	.destroy	= xt_stmt_destroy,
> +};
> +
> +struct stmt *xt_stmt_alloc(const struct location *loc)
> +{
> +	return stmt_alloc(loc, &xt_stmt_ops);
> +}
> diff --git a/src/xt.c b/src/xt.c
> new file mode 100644
> index 0000000..dcb461b
> --- /dev/null
> +++ b/src/xt.c
> @@ -0,0 +1,701 @@
> +/*
> + * Copyright (c) 2013-2015 Pablo Neira Ayuso <pablo@netfilter.org>
> + *
> + * This program is free software; you can redistribute it and/or modifyi
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <stdlib.h>
> +#include <time.h>
> +#include <string.h>
> +#include <xtables.h>
> +#include <utils.h>
> +#include <getopt.h>
> +#include <ctype.h>	/* for isspace */
> +#include <statement.h>
> +#include <rule.h>
> +#include <netlink.h>
> +#include <xt.h>
> +
> +#include <libmnl/libmnl.h>
> +#include <linux/netfilter/nfnetlink.h>
> +#include <linux/netfilter/nf_tables_compat.h>
> +#include <linux/netfilter_ipv4/ip_tables.h>
> +
> +#include <libnftnl/rule.h>
> +#include <libnftnl/expr.h>
> +
> +void xt_stmt_destroy_internals(const struct stmt *stmt)

xt_stmt_release ?

> +{
> +	switch (stmt->xt.type) {
> +	case NFT_XT_MATCH:
> +		if (!stmt->xt.match)
> +			break;
> +		if (stmt->xt.match->m)
> +			xfree(stmt->xt.match->m);
> +		/* this has been cloned */

I think you can remove this comment.

> +		xfree(stmt->xt.match);
> +		break;
> +	case NFT_XT_WATCHER:
> +	case NFT_XT_TARGET:
> +		if (!stmt->xt.target)
> +			break;
> +		if (stmt->xt.target->t)
> +			xfree(stmt->xt.target->t);
> +		/* this has been cloned */

Same here.

> +		xfree(stmt->xt.target);
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +const char *xt_stmt_name(const struct stmt *stmt)
> +{
> +	switch (stmt->xt.type) {
> +	case NFT_XT_MATCH:
> +		if (stmt->xt.match == NULL)
> +			break;
> +		if (stmt->xt.match->alias)
> +			return stmt->xt.match->alias(stmt->xt.match->m);
> +		break;
> +	case NFT_XT_TARGET:
> +	case NFT_XT_WATCHER:
> +		if (stmt->xt.target == NULL)
> +			break;
> +		if (stmt->xt.target->alias)
> +			return stmt->xt.target->alias(stmt->xt.target->t);
> +		break;
> +	default:
> +		return "unknown";
> +	}
> +
> +	return stmt->xt.name;
> +}
> +
> +void xt_stmt_save(const struct stmt *stmt)
> +{
> +#ifdef DEBUG
> +	switch (stmt->xt.type) {
> +	case NFT_XT_MATCH:
> +		if (stmt->xt.match)
> +			break;
> +		if (stmt->xt.opts)
> +			fprintf(stdout, "%s", stmt->xt.opts);
> +		return;
> +	case NFT_XT_WATCHER:
> +	case NFT_XT_TARGET:
> +		if (stmt->xt.target)
> +			break;
> +		if (stmt->xt.opts)
> +			fprintf(stdout, "%s", stmt->xt.opts);
> +		return;
> +	default:
> +		break;
> +	}
> +#endif /* DEBUG */

I think you can merge this.

> +
> +	printf("[");
> +
> +	switch (stmt->xt.type) {
> +	case NFT_XT_MATCH:

I think the DEBUG case needs this:

                if (stmt->xt.match == NULL && stmt->xt.opts)
                        fprintf(stdout, "%s", stmt->xt.opts);

> +		if (stmt->xt.match->save) {
> +			stmt->xt.match->save(&stmt->xt.entry,
> +					     stmt->xt.match->m);
> +		} else if (stmt->xt.match->print) {
> +			stmt->xt.match->print(&stmt->xt.entry,
> +					      stmt->xt.match->m, 0);
> +		}
> +		break;
> +	case NFT_XT_WATCHER:
> +	case NFT_XT_TARGET:
> +		if (stmt->xt.target->save)
> +			stmt->xt.target->save(NULL, stmt->xt.target->t);
> +		else if (stmt->xt.target->print)
> +			stmt->xt.target->print(NULL, stmt->xt.target->t, 0);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	printf(" ]");
> +}
> +
> +static void *xt_entry_x_alloc(struct xt_stmt *xt)

xt_entry_data_alloc() ?

> +{
> +
> +	uint32_t size = 0;
> +
> +	switch (xt->type) {
> +	case NFT_XT_MATCH:
> +		size = XT_ALIGN(sizeof(struct xt_entry_match)) +
> +		       xt->match->size;
> +		break;
> +	case NFT_XT_WATCHER:
> +	case NFT_XT_TARGET:
> +		size = XT_ALIGN(sizeof(struct xt_entry_target)) +
> +		       xt->target->size;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return xzalloc(size);
> +}
> +
> +static void nft_entry_setup(struct xt_stmt *xt, uint32_t af)
> +{
> +	switch (af) {
> +	case NFPROTO_IPV4:
> +		xt->entry.e4.ip.proto = xt->proto;
> +		break;
> +	case NFPROTO_IPV6:
> +		xt->entry.e6.ipv6.proto = xt->proto;
> +		break;
> +	case NFPROTO_BRIDGE:
> +		xt->entry.ebt.ethproto = xt->proto;
> +		break;
> +	case NFPROTO_ARP:
> +		/* XXX hardcoded, these are the only values accepted by arpt */
> +		xt->entry.arp.arp.arhln_mask = 0xff;
> +		xt->entry.arp.arp.arhln = 6;

If this is good for all extensions, then you can probably remove the
comment.

> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +static uint32_t xt_proto(const struct proto_ctx *pctx)
> +{
> +	const struct proto_desc *desc = NULL;
> +
> +	if (pctx->family == NFPROTO_BRIDGE) {
> +		desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
> +		if (desc == NULL)
> +			goto noproto;
> +		if (strcmp(desc->name, "ip") == 0)
> +			return __constant_htons(ETH_P_IP);
> +		if (strcmp(desc->name, "ip6") == 0)
> +			return __constant_htons(ETH_P_IPV6);
> +		goto noproto;

                return 0; instead ?

> +	}
> +
> +	desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
> +	if (desc == NULL)
> +		goto noproto;
> +	if (strcmp(desc->name, "tcp") == 0)
> +		return IPPROTO_TCP;
> +	else if (strcmp(desc->name, "udp") == 0)
> +		return IPPROTO_UDP;
> +	else if (strcmp(desc->name, "udplite") == 0)
> +		return IPPROTO_UDPLITE;
> +	else if (strcmp(desc->name, "sctp") == 0)
> +		return IPPROTO_SCTP;
> +	else if (strcmp(desc->name, "dccp") == 0)
> +		return IPPROTO_DCCP;
> +	else if (strcmp(desc->name, "esp") == 0)
> +		return IPPROTO_ESP;
> +	else
> +		BUG("xt with unknown protocol\n");
> +
> +noproto:
> +	return 0;
> +}
> +
> +static struct xtables_target *clone_target(struct xtables_target *t)

xt_target_clone() ?

> +{
> +	struct xtables_target *clone;
> +
> +	clone = xzalloc(sizeof(struct xtables_target));
> +	memcpy(clone, t, sizeof(struct xtables_target));
> +	return clone;
> +}
> +
> +static struct xtables_match *clone_match(struct xtables_match *m)

xt_match_clone() ?

> +{
> +	struct xtables_match *clone;
> +
> +	clone = xzalloc(sizeof(struct xtables_match));
> +	memcpy(clone, m, sizeof(struct xtables_match));
> +	return clone;
> +}
> +
> +/*
> + * Evaluation
> + */
> +
> +static struct option original_opts[] = {
> +	{ NULL },
> +};
> +
> +static int xt_target_to_binary(struct xt_stmt *xt, int argc, char *argv[],
> +			       uint32_t af)
> +{
> +	struct option *opt;
> +	unsigned int offset;
> +	int c;
> +
> +	xt->target->t = xt_entry_x_alloc(xt);
> +	nft_entry_setup(xt, af);
> +
> +	if (xt->target->x6_options != NULL)
> +		opt = xtables_options_xfrm(original_opts, NULL,
> +					   xt->target->x6_options,
> +					   &offset);
> +	else
> +		opt = xtables_merge_options(original_opts, NULL,
> +					    xt->target->extra_opts,
> +					    &offset);
> +
> +	if (xt->target->init != NULL)
> +		xt->target->init(xt->target->t);
> +
> +	/* Reset internal state of getopt_long. */
> +	optind = 0;
> +	/* Suppress error messages. */
> +	opterr = 0;
> +
> +	while ((c = getopt_long(argc, argv, "-:", opt, NULL)) != -1) {
> +
> +		c -= offset;
> +		xtables_option_tpcall(xt->target->option_offset + c,
> +				      argv, 0, xt->target, &xt->entry);
> +	}
> +
> +	/* Reset parsing flags */
> +	xt->target->tflags = 0;
> +	xfree(opt);
> +
> +	return 0;
> +}
> +
> +static int xt_match_to_binary(struct xt_stmt *xt, int argc, char *argv[],
> +			      uint32_t af)
> +{
> +	struct option *opt;
> +	unsigned int offset;
> +	bool invert = false;
> +	int c;
> +
> +	xt->match->m = xt_entry_x_alloc(xt);
> +	nft_entry_setup(xt, af);
> +
> +	if (xt->match->x6_options != NULL)
> +		opt = xtables_options_xfrm(original_opts, NULL,
> +					   xt->match->x6_options,
> +					   &offset);
> +	else
> +		opt = xtables_merge_options(original_opts, NULL,
> +					    xt->match->extra_opts,
> +					    &offset);
> +
> +	if (xt->match->init != NULL)
> +		xt->match->init(xt->match->m);
> +
> +	/* Reset internal state of getopt_long. */
> +	optind = 0;
> +	/* Suppress error messages. */
> +	opterr = 0;
> +
> +	while ((c = getopt_long(argc, argv, "-:", opt, NULL)) != -1) {
> +		switch (c) {
> +		case 1:
> +			invert = true;
> +			continue;
> +		default:
> +			break;
> +		}
> +
> +		if (optarg != NULL && optarg[0] == '!' && optarg[1] == '\0') {
> +			invert = true;
> +			optarg = argv[optind];
> +		}
> +
> +		c -= offset;
> +		xtables_option_mpcall(xt->match->option_offset + c,
> +				      argv, invert, xt->match,
> +				      &xt->entry);
> +		if (invert)
> +			invert = false;
> +	}
> +
> +	/* Reset parsing flags */
> +	xt->match->mflags = 0;
> +	xfree(opt);
> +
> +	return 0;
> +}
> +
> +/* An xt extension doesn't have more than arguments. */
> +#define MAX_ARG			64
> +
> +static int string_to_argv(const char *str, char *argv[], uint32_t argc_max)
> +{
> +	uint32_t i, k = 1, len = 0;
> +	bool atquote = false, dupquote = false;
> +
> +	if (str == NULL)
> +		return 0;
> +
> +	/* skip first/last char, are '[' and ']' */
> +	for (i = 1; i < strlen(str)-1; i++) {

                        strlen(str) - 1

> +		if (k == argc_max)
> +			goto err;
> +
> +		if (isspace(str[i]) && !atquote) {
> +			if (len <= 0)
> +				continue;
> +
> +			if (dupquote) {
> +				argv[k] = strndup(&str[i - len + 1], len - 2);
> +				dupquote = false;
> +			} else {
> +				argv[k] = strndup(&str[i - len], len);
> +			}
> +
> +			k++;
> +			len = 0;
> +		} else {
> +			len++;
> +		}
> +
> +		if (str[i] == '"') {
> +			if (!atquote)
> +				dupquote = true;
> +			atquote = !atquote;
> +		}
> +	}
> +	return k;
> +err:
> +	for (i = 0; i < k; i++)
> +		free(argv[i]);
> +	return -1;
> +}
> +
> +int stmt_evaluate_xt(struct eval_ctx *ctx, struct stmt *stmt)
> +{
> +	char *argv[MAX_ARG] = { "iptables" };
> +	struct xtables_match *mt;
> +	struct xtables_target *tg;
> +	int argc, i, err;
> +
> +	argc = string_to_argv(stmt->xt.opts, argv, MAX_ARG);
> +	if (argc < 0)
> +		return stmt_error(ctx, stmt, "too many xt options");
> +
> +	xtables_set_nfproto(ctx->pctx.family);
> +	stmt->xt.proto = xt_proto(&ctx->pctx);
> +
> +	if (stmt->xt.type == NFT_XT_WATCHER &&
> +	    ctx->pctx.family != NFPROTO_BRIDGE)
> +		return stmt_error(ctx, stmt,
> +				  "watcher only available from bridge family");
> +
> +	switch (stmt->xt.type) {
> +	case NFT_XT_MATCH:
> +		mt = xtables_find_match(stmt->xt.name, XTF_TRY_LOAD, NULL);
> +		if (!mt)
> +			return stmt_error(ctx, stmt, "unknown match %s",
> +					  stmt->xt.name);
> +
> +		stmt->xt.match = clone_match(mt);
> +		err = xt_match_to_binary(&stmt->xt, argc, argv,
> +					 ctx->pctx.family);
> +		break;
> +	case NFT_XT_TARGET:
> +	case NFT_XT_WATCHER:
> +		tg = xtables_find_target(stmt->xt.name, XTF_TRY_LOAD);
> +		if (!tg)
> +			return stmt_error(ctx, stmt, "unknown target %s",
> +					  stmt->xt.name);
> +
> +		stmt->xt.target = clone_target(tg);
> +		err = xt_target_to_binary(&stmt->xt, argc, argv,
> +					 ctx->pctx.family);
> +		break;
> +	default:
> +		BUG("Unknown xt type %d\n", stmt->xt.type);
> +	}
> +
> +	if (stmt->xt.type == NFT_XT_TARGET)
> +		stmt->flags |= STMT_F_TERMINAL;
> +
> +	for (i = 1; i < argc; i++)
> +		xfree(argv[i]);
> +
> +	if (err < 0)
> +		return stmt_error(ctx, stmt, "failed to parse");
> +
> +	return 0;
> +}
> +
> +/*
> + * Delinearization
> + */
> +
> +void netlink_parse_match(struct netlink_parse_ctx *ctx,
> +			 const struct location *loc,
> +			 const struct nft_rule_expr *nle)
> +{
> +	struct stmt *stmt;
> +	const char *name;
> +	struct xtables_match *mt;
> +	const char *mtinfo;
> +	struct xt_entry_match *m;
> +	uint32_t mt_len;
> +
> +	xtables_set_nfproto(ctx->table->handle.family);
> +
> +	name = nft_rule_expr_get_str(nle, NFT_EXPR_MT_NAME);
> +
> +	/* XXXX mem leak. When is this memory freed?
> +	 * - can't call xtables_rule_matches_free()
> +	 * - the same match could be in use by the next rule
> +	 * - use a wrapper struct with a refcount? lot of code overhead
> +	 */

This comment ?

> +	mt = xtables_find_match(name, XTF_TRY_LOAD, NULL);
> +	if (!mt)
> +		BUG("XT match %s not found\n", name);
> +
> +	mtinfo = nft_rule_expr_get(nle, NFT_EXPR_MT_INFO, &mt_len);
> +
> +	m = xzalloc(sizeof(struct xt_entry_match) + mt_len);
> +	memcpy(&m->data, mtinfo, mt_len);
> +
> +	m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
> +	m->u.user.revision = nft_rule_expr_get_u32(nle, NFT_EXPR_MT_REV);
> +
> +	stmt = xt_stmt_alloc(loc);
> +	stmt->xt.name = strdup(name);
> +	stmt->xt.type = NFT_XT_MATCH;
> +	stmt->xt.match = clone_match(mt);
> +	stmt->xt.match->m = m;
> +
> +	list_add_tail(&stmt->list, &ctx->rule->stmts);
> +}
> +
> +void netlink_parse_target(struct netlink_parse_ctx *ctx,
> +			  const struct location *loc,
> +			  const struct nft_rule_expr *nle)
> +{
> +	struct stmt *stmt;
> +	const char *name;
> +	struct xtables_target *tg;
> +	const void *tginfo;
> +	struct xt_entry_target *t;
> +	size_t size;
> +	uint32_t tg_len;
> +
> +	xtables_set_nfproto(ctx->table->handle.family);
> +
> +	name = nft_rule_expr_get_str(nle, NFT_EXPR_TG_NAME);
> +	tg = xtables_find_target(name, XTF_TRY_LOAD);
> +	if (!tg)
> +		BUG("XT target %s not found\n", name);
> +
> +	tginfo = nft_rule_expr_get(nle, NFT_EXPR_TG_INFO, &tg_len);
> +
> +	size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
> +	t = xzalloc(size);
> +	memcpy(&t->data, tginfo, tg_len);
> +	t->u.target_size = size;
> +	t->u.user.revision = nft_rule_expr_get_u32(nle, NFT_EXPR_TG_REV);
> +	strcpy(t->u.user.name, tg->name);
> +
> +	stmt = xt_stmt_alloc(loc);
> +	stmt->xt.name = strdup(name);
> +	stmt->xt.type = NFT_XT_TARGET;
> +	stmt->xt.target = clone_target(tg);
> +	stmt->xt.target->t = t;
> +
> +	list_add_tail(&stmt->list, &ctx->rule->stmts);
> +}
> +
> +static bool is_watcher(uint32_t family, struct stmt *stmt)
> +{
> +	if (family != NFPROTO_BRIDGE)
> +		return false;
> +
> +	if (stmt->xt.type != NFT_XT_TARGET)
> +		return false;
> +
> +	/* this has to be hardcoded :-( */
> +	if (strcmp(stmt->xt.name, "log") == 0)
> +		return true;
> +	if (strcmp(stmt->xt.name, "nflog") == 0)
> +		return true;
> +	if (strcmp(stmt->xt.name, "uflog") == 0)

ulog ?

> +		return true;
> +
> +	return false;
> +}

  reply	other threads:[~2015-03-25 19:40 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-25 19:15 [nft PATCH 1/3] src: expose delinearize/linearize structures and stmt_error() Arturo Borrero Gonzalez
2015-03-25 19:16 ` [nft PATCH 2/3] src: add xt compat support Arturo Borrero Gonzalez
2015-03-25 19:44   ` Pablo Neira Ayuso [this message]
2015-03-27 12:00     ` Arturo Borrero Gonzalez
2015-03-27 12:31       ` Pablo Neira Ayuso
2015-03-27 12:31         ` Patrick McHardy
2015-03-27 12:59         ` Arturo Borrero Gonzalez
2015-03-27 13:13           ` Pablo Neira Ayuso
2015-03-27 13:14             ` Patrick McHardy
2015-03-30 10:19               ` Arturo Borrero Gonzalez
2015-03-25 19:16 ` [nft PATCH 3/3] tests: regression: add xt compat tests Arturo Borrero Gonzalez
2015-03-25 19:23 ` [nft PATCH 1/3] src: expose delinearize/linearize structures and stmt_error() Patrick McHardy

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=20150325194441.GA26737@salvia \
    --to=pablo@netfilter.org \
    --cc=arturo.borrero.glez@gmail.com \
    --cc=kaber@trash.net \
    --cc=netfilter-devel@vger.kernel.org \
    /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.