Re: Moving from ipset to nftables

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

 



On 06/01/2019 23:05, Florian Westphal wrote:
> Mikhail Morfikov <mmorfikov@xxxxxxxxx> wrote:
>> #  time nft list table raw-set > /dev/null
>> nft list table raw-set > /dev/null  1.41s user 4.11s system 97% cpu 5.666 total
>>
>> Almost 5s for returning the following output?
>>
>> # nft list table raw
>> table ip raw {
>>         chain PREROUTING {
>>                 type filter hook prerouting priority -300; policy accept;
>>                 jump notrack-in
>>         }
>>
>>         chain OUTPUT {
>>                 type filter hook output priority -300; policy accept;
>>         }
>>
>>         chain notrack-in {
>>                 iifname "lo" counter packets 1209 bytes 84124 notrack
>>         }
>> }
> 
> Agree, this is silly.
> 
>> Is there something I could do to speed this up?
> 
> Unfortunately not, right now nft dumps everything and filters in
> userspace.  We need to propagate "table name" to the cache init
> function, but maybe more changes are needed to make this work
> (caching infra is tricky).
> 
> This patch is a starting point, but it doesn't work correctly
> with libnftables/interactive mode (nft -i):
> 
> nft -i
> list table ip filter
> list table ip raw  # fails, as cache is deemed up to date, but
>                    # first command only updated the filter table.
> 
> diff --git a/include/mnl.h b/include/mnl.h
> --- a/include/mnl.h
> +++ b/include/mnl.h
> @@ -49,6 +49,7 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, const struct cmd *cmd,
>  int mnl_nft_table_del(struct netlink_ctx *ctx, const struct cmd *cmd);
>  
>  struct nftnl_table_list *mnl_nft_table_dump(struct netlink_ctx *ctx,
> +					    const char *table,
>  					    int family);
>  
>  int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
> diff --git a/include/rule.h b/include/rule.h
> index dc5e5b87f933..e54346f0b097 100644
> --- a/include/rule.h
> +++ b/include/rule.h
> @@ -631,7 +631,7 @@ extern struct error_record *rule_postprocess(struct rule *rule);
>  struct netlink_ctx;
>  extern int do_command(struct netlink_ctx *ctx, struct cmd *cmd);
>  
> -extern int cache_update(struct nft_ctx *ctx, enum cmd_ops cmd,
> +extern int cache_update(struct nft_ctx *ctx, const struct cmd *cmd,
>  			struct list_head *msgs);
>  extern void cache_flush(struct nft_ctx *ctx, enum cmd_ops cmd,
>  			struct list_head *msgs);
> diff --git a/src/evaluate.c b/src/evaluate.c
> index 0bda431d5a16..3af1194f341a 100644
> --- a/src/evaluate.c
> +++ b/src/evaluate.c
> @@ -236,7 +236,7 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
>  		}
>  		break;
>  	case SYMBOL_SET:
> -		ret = cache_update(ctx->nft, ctx->cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, ctx->cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3129,9 +3129,12 @@ static int rule_translate_index(struct eval_ctx *ctx, struct rule *rule)
>  	uint64_t index = 0;
>  	struct rule *r;
>  	int ret;
> +	struct cmd c = {
> +		.op = CMD_LIST,
> +	};
>  
>  	/* update cache with CMD_LIST so that rules are fetched, too */
> -	ret = cache_update(ctx->nft, CMD_LIST, ctx->msgs);
> +	ret = cache_update(ctx->nft, &c, ctx->msgs);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -3353,13 +3356,13 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)
>  
>  	switch (cmd->obj) {
>  	case CMD_OBJ_SETELEM:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
>  		return setelem_evaluate(ctx, &cmd->expr);
>  	case CMD_OBJ_SET:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3369,7 +3372,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)
>  		handle_merge(&cmd->rule->handle, &cmd->handle);
>  		return rule_evaluate(ctx, cmd->rule);
>  	case CMD_OBJ_CHAIN:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3377,7 +3380,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)
>  	case CMD_OBJ_TABLE:
>  		return table_evaluate(ctx, cmd->table);
>  	case CMD_OBJ_FLOWTABLE:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3401,7 +3404,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd)
>  
>  	switch (cmd->obj) {
>  	case CMD_OBJ_SETELEM:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3429,7 +3432,7 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd)
>  	struct set *set;
>  	int ret;
>  
> -	ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +	ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -3492,7 +3495,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
>  	struct set *set;
>  	int ret;
>  
> -	ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +	ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -3587,7 +3590,7 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd)
>  {
>  	int ret;
>  
> -	ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +	ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -3625,7 +3628,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
>  		/* Chains don't hold sets */
>  		break;
>  	case CMD_OBJ_SET:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3640,7 +3643,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
>  
>  		return 0;
>  	case CMD_OBJ_MAP:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3655,7 +3658,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
>  
>  		return 0;
>  	case CMD_OBJ_METER:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3682,7 +3685,7 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd)
>  
>  	switch (cmd->obj) {
>  	case CMD_OBJ_CHAIN:
> -		ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -3779,7 +3782,7 @@ static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd)
>  	uint32_t event;
>  	int ret;
>  
> -	ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
> +	ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -3807,7 +3810,7 @@ static int cmd_evaluate_export(struct eval_ctx *ctx, struct cmd *cmd)
>  		return cmd_error(ctx, &cmd->location,
>  				 "JSON export is no longer supported, use 'nft -j list ruleset' instead");
>  
> -	return cache_update(ctx->nft, cmd->op, ctx->msgs);
> +	return cache_update(ctx->nft, cmd, ctx->msgs);
>  }
>  
>  static int cmd_evaluate_import(struct eval_ctx *ctx, struct cmd *cmd)
> diff --git a/src/libnftables.c b/src/libnftables.c
> index bd79cd6091d2..ed84c37d25cf 100644
> --- a/src/libnftables.c
> +++ b/src/libnftables.c
> @@ -420,11 +420,14 @@ err:
>  int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename)
>  {
>  	struct cmd *cmd, *next;
> +	static const struct cmd invalid_cmd = {
> +		.op = CMD_INVALID,
> +	};
>  	LIST_HEAD(msgs);
>  	LIST_HEAD(cmds);
>  	int rc;
>  
> -	rc = cache_update(nft, CMD_INVALID, &msgs);
> +	rc = cache_update(nft, &invalid_cmd, &msgs);
>  	if (rc < 0)
>  		return -1;
>  
> diff --git a/src/mnl.c b/src/mnl.c
> index c3d16774f71f..e400f0838c4b 100644
> --- a/src/mnl.c
> +++ b/src/mnl.c
> @@ -704,19 +704,36 @@ err_free:
>  }
>  
>  struct nftnl_table_list *mnl_nft_table_dump(struct netlink_ctx *ctx,
> +					    const char *table,
>  					    int family)
>  {
>  	char buf[MNL_SOCKET_BUFFER_SIZE];
>  	struct nftnl_table_list *nlt_list;
> +	struct nftnl_table *nlt;
>  	struct nlmsghdr *nlh;
> +	uint16_t flags;
>  	int ret;
>  
>  	nlt_list = nftnl_table_list_alloc();
>  	if (nlt_list == NULL)
>  		return NULL;
>  
> +	nlt = nftnl_table_alloc();
> +	if (nlt == NULL)
> +		memory_allocation_error();
> +
> +	if (table) {
> +		nftnl_table_set_str(nlt, NFTNL_TABLE_NAME, table);
> +		flags = NLM_F_ACK;
> +	} else {
> +		flags = NLM_F_DUMP;
> +	}
> +
>  	nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, family,
> -				    NLM_F_DUMP, ctx->seqnum);
> +				    flags, ctx->seqnum);
> +
> +	nftnl_table_nlmsg_build_payload(nlh, nlt);
> +	nftnl_table_free(nlt);
>  
>  	ret = nft_mnl_talk(ctx, nlh, nlh->nlmsg_len, table_cb, nlt_list);
>  	if (ret < 0)
> diff --git a/src/netlink.c b/src/netlink.c
> index f67f63907075..cdce70675a47 100644
> --- a/src/netlink.c
> +++ b/src/netlink.c
> @@ -463,7 +463,7 @@ int netlink_list_tables(struct netlink_ctx *ctx, const struct handle *h)
>  {
>  	struct nftnl_table_list *table_cache;
>  
> -	table_cache = mnl_nft_table_dump(ctx, h->family);
> +	table_cache = mnl_nft_table_dump(ctx, h->table.name, h->family);
>  	if (table_cache == NULL) {
>  		if (errno == EINTR)
>  			return -1;
> diff --git a/src/rule.c b/src/rule.c
> index e15a20b30bbd..f690df280306 100644
> --- a/src/rule.c
> +++ b/src/rule.c
> @@ -134,7 +134,8 @@ void handle_merge(struct handle *dst, const struct handle *src)
>  		dst->index = src->index;
>  }
>  
> -static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h,
> +static int cache_init_tables(struct netlink_ctx *ctx,
> +			     const struct handle *h,
>  			     struct nft_cache *cache)
>  {
>  	int ret;
> @@ -203,24 +204,21 @@ static int cache_init_objects(struct netlink_ctx *ctx, enum cmd_ops cmd)
>  	return 0;
>  }
>  
> -static int cache_init(struct netlink_ctx *ctx, enum cmd_ops cmd)
> +static int cache_init(struct netlink_ctx *ctx, const struct cmd *cmd)
>  {
> -	struct handle handle = {
> -		.family = NFPROTO_UNSPEC,
> -	};
>  	int ret;
>  
> -	ret = cache_init_tables(ctx, &handle, &ctx->nft->cache);
> +	ret = cache_init_tables(ctx, &cmd->handle, &ctx->nft->cache);
>  	if (ret < 0)
>  		return ret;
> -	ret = cache_init_objects(ctx, cmd);
> +	ret = cache_init_objects(ctx, cmd->op);
>  	if (ret < 0)
>  		return ret;
>  
>  	return 0;
>  }
>  
> -int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs)
> +int cache_update(struct nft_ctx *nft, const struct cmd *cmd, struct list_head *msgs)
>  {
>  	uint16_t genid;
>  	int ret;
> @@ -1477,7 +1475,7 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl)
>  	if (nft_output_echo(&ctx->nft->output)) {
>  		int ret;
>  
> -		ret = cache_update(ctx->nft, cmd->obj, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> @@ -1528,7 +1526,7 @@ static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd)
>  	if (nft_output_echo(&ctx->nft->output)) {
>  		int ret;
>  
> -		ret = cache_update(ctx->nft, cmd->obj, ctx->msgs);
> +		ret = cache_update(ctx->nft, cmd, ctx->msgs);
>  		if (ret < 0)
>  			return ret;
>  
> 
It looks like this patch can't be applied anymore:

< git:(master 01e5c6f0) > $ quilt push
Applying patch patch
patching file include/mnl.h
Hunk #1 succeeded at 50 (offset 1 line).
patching file include/rule.h
Hunk #1 FAILED at 631.
1 out of 1 hunk FAILED -- rejects in file include/rule.h
patching file src/evaluate.c
Hunk #1 FAILED at 238.
Hunk #2 FAILED at 3131.
Hunk #3 FAILED at 3355.
Hunk #4 FAILED at 3371.
Hunk #5 FAILED at 3379.
Hunk #6 FAILED at 3403.
Hunk #7 FAILED at 3431.
Hunk #8 FAILED at 3494.
Hunk #9 FAILED at 3589.
Hunk #10 FAILED at 3627.
Hunk #11 FAILED at 3642.
Hunk #12 FAILED at 3657.
Hunk #13 FAILED at 3684.
Hunk #14 FAILED at 3781.
Hunk #15 FAILED at 3809.
15 out of 15 hunks FAILED -- rejects in file src/evaluate.c
patching file src/libnftables.c
Hunk #1 FAILED at 420.
1 out of 1 hunk FAILED -- rejects in file src/libnftables.c
patching file src/mnl.c
Hunk #1 succeeded at 749 (offset 49 lines).
patching file src/netlink.c
Hunk #1 succeeded at 471 (offset 8 lines).
patching file src/rule.c
Hunk #1 succeeded at 135 (offset 1 line).
Hunk #2 FAILED at 204.
Hunk #3 FAILED at 1480.
Hunk #4 FAILED at 1531.
3 out of 4 hunks FAILED -- rejects in file src/rule.c
Patch fix-speed.path does not apply (enforce with -f)

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux