/*
 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
 */

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdbool.h>
#include <errno.h>
#include <netdb.h>	/* getprotobynumber */
#include <time.h>
#include <stdarg.h>
#include <inttypes.h>

#include <xtables.h>
#include <libiptc/libxtc.h>
#include <libiptc/xtcshared.h>

#include <stdlib.h>
#include <string.h>

#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <netinet/ip6.h>

#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables_compat.h>

#include <libmnl/libmnl.h>
#include <libnftables/table.h>
#include <libnftables/chain.h>
#include <libnftables/rule.h>
#include <libnftables/expr.h>

#include <netinet/in.h>	/* inet_ntoa */
#include <arpa/inet.h>

#include "nft.h"
#include "xshared.h" /* proto_to_name */
#include "nft-shared.h"
#include "xtables-config-parser.h"

static void *nft_fn;

int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
	     int (*cb)(const struct nlmsghdr *nlh, void *data),
	     void *data)
{
	int ret;
	char buf[MNL_SOCKET_BUFFER_SIZE];

	if (mnl_socket_sendto(h->nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		return -1;
	}

	ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, h->seq, h->portid, cb, data);
		if (ret <= 0)
			break;

		ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		return -1;
	}

	return 0;
}

struct builtin_table xtables_ipv4[TABLES_MAX] = {
	[RAW] = {
		.name	= "raw",
		.chains = {
			{
				.name	= "PREROUTING",
				.type	= "filter",
				.prio	= -300,	/* NF_IP_PRI_RAW */
				.hook	= NF_INET_PRE_ROUTING,
			},
			{
				.name	= "OUTPUT",
				.type	= "filter",
				.prio	= -300,	/* NF_IP_PRI_RAW */
				.hook	= NF_INET_LOCAL_OUT,
			},
		},
	},
	[MANGLE] = {
		.name	= "mangle",
		.chains = {
			{
				.name	= "PREROUTING",
				.type	= "filter",
				.prio	= -150,	/* NF_IP_PRI_MANGLE */
				.hook	= NF_INET_PRE_ROUTING,
			},
			{
				.name	= "INPUT",
				.type	= "filter",
				.prio	= -150,	/* NF_IP_PRI_MANGLE */
				.hook	= NF_INET_LOCAL_IN,
			},
			{
				.name	= "FORWARD",
				.type	= "filter",
				.prio	= -150,	/* NF_IP_PRI_MANGLE */
				.hook	= NF_INET_FORWARD,
			},
			{
				.name	= "OUTPUT",
				.type	= "route",
				.prio	= -150,	/* NF_IP_PRI_MANGLE */
				.hook	= NF_INET_LOCAL_OUT,
			},
			{
				.name	= "POSTROUTING",
				.type	= "filter",
				.prio	= -150,	/* NF_IP_PRI_MANGLE */
				.hook	= NF_INET_POST_ROUTING,
			},
		},
	},
	[FILTER] = {
		.name	= "filter",
		.chains = {
			{
				.name	= "INPUT",
				.type	= "filter",
				.prio	= 0,	/* NF_IP_PRI_FILTER */
				.hook	= NF_INET_LOCAL_IN,
			},
			{
				.name	= "FORWARD",
				.type	= "filter",
				.prio	= 0,	/* NF_IP_PRI_FILTER */
				.hook	= NF_INET_FORWARD,
			},
			{
				.name	= "OUTPUT",
				.type	= "filter",
				.prio	= 0,	/* NF_IP_PRI_FILTER */
				.hook	= NF_INET_LOCAL_OUT,
			},
		},
	},
	[SECURITY] = {
		.name	= "security",
		.chains = {
			{
				.name	= "INPUT",
				.type	= "filter",
				.prio	= 150,	/* NF_IP_PRI_SECURITY */
				.hook	= NF_INET_LOCAL_IN,
			},
			{
				.name	= "FORWARD",
				.type	= "filter",
				.prio	= 150,	/* NF_IP_PRI_SECURITY */
				.hook	= NF_INET_FORWARD,
			},
			{
				.name	= "OUTPUT",
				.type	= "filter",
				.prio	= 150,	/* NF_IP_PRI_SECURITY */
				.hook	= NF_INET_LOCAL_OUT,
			},
		},
	},
	[NAT] = {
		.name	= "nat",
		.chains = {
			{
				.name	= "PREROUTING",
				.type	= "nat",
				.prio	= -100, /* NF_IP_PRI_NAT_DST */
				.hook	= NF_INET_PRE_ROUTING,
			},
			{
				.name	= "INPUT",
				.type	= "nat",
				.prio	= 100, /* NF_IP_PRI_NAT_SRC */
				.hook	= NF_INET_LOCAL_IN,
			},
			{
				.name	= "POSTROUTING",
				.type	= "nat",
				.prio	= 100, /* NF_IP_PRI_NAT_SRC */
				.hook	= NF_INET_POST_ROUTING,
			},
			{
				.name	= "OUTPUT",
				.type	= "nat",
				.prio	= -100, /* NF_IP_PRI_NAT_DST */
				.hook	= NF_INET_LOCAL_OUT,
			},
		},
	},
};

#include <linux/netfilter_arp.h>

struct builtin_table xtables_arp[TABLES_MAX] = {
	[FILTER] = {
	.name   = "filter",
	.chains = {
			{
				.name   = "INPUT",
				.type   = "filter",
				.prio   = NF_IP_PRI_FILTER,
				.hook   = NF_ARP_IN,
			},
			{
				.name   = "FORWARD",
				.type   = "filter",
				.prio   = NF_IP_PRI_FILTER,
				.hook   = NF_ARP_FORWARD,
			},
			{
				.name   = "OUTPUT",
				.type   = "filter",
				.prio   = NF_IP_PRI_FILTER,
				.hook   = NF_ARP_OUT,
			},
		},
	},
};

int
nft_table_builtin_add(struct nft_handle *h, struct builtin_table *_t,
			bool dormant)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_table *t;
	int ret;

	t = nft_table_alloc();
	if (t == NULL)
		return -1;

	nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)_t->name);
	if (dormant) {
		nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS,
					NFT_TABLE_F_DORMANT);
	}

	nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family,
					NLM_F_ACK|NLM_F_EXCL, h->seq);
	nft_table_nlmsg_build_payload(nlh, t);
	nft_table_free(t);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0) {
		if (errno != EEXIST)
			perror("mnl-talk:nft_table_init_one");
	}
	return ret;
}

struct nft_chain *
nft_chain_builtin_alloc(struct builtin_table *table,
			struct builtin_chain *chain, int policy)
{
	struct nft_chain *c;

	c = nft_chain_alloc();
	if (c == NULL)
		return NULL;

	nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table->name);
	nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain->name);
	nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, chain->hook);
	nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_PRIO, chain->prio);
	nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy);
	nft_chain_attr_set(c, NFT_CHAIN_ATTR_TYPE, (char *)chain->type);

	return c;
}

void
nft_chain_builtin_add(struct nft_handle *h, struct builtin_table *table,
		      struct builtin_chain *chain, int policy)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_chain *c;

	c = nft_chain_builtin_alloc(table, chain, policy);
	if (c == NULL)
		return;

	/* NLM_F_CREATE requests module autoloading */
	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family,
					NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE,
					h->seq);
	nft_chain_nlmsg_build_payload(nlh, c);
	nft_chain_free(c);

	if (mnl_talk(h, nlh, NULL, NULL) < 0) {
		if (errno != EEXIST)
			perror("mnl_talk:nft_chain_builtin_add");
	}
}

/* find if built-in table already exists */
struct builtin_table *
nft_table_builtin_find(struct nft_handle *h, const char *table)
{
	int i;
	bool found = false;

	for (i=0; i<TABLES_MAX; i++) {
		if (h->tables[i].name == NULL)
			break;

		if (strcmp(h->tables[i].name, table) != 0)
			continue;

		found = true;
		break;
	}

	return found ? &h->tables[i] : NULL;
}

/* find if built-in chain already exists */
struct builtin_chain *
nft_chain_builtin_find(struct builtin_table *t, const char *chain)
{
	int i;
	bool found = false;

	for (i=0; i<NF_IP_NUMHOOKS && t->chains[i].name != NULL; i++) {
		if (strcmp(t->chains[i].name, chain) != 0)
			continue;

		found = true;
		break;
	}
	return found ? &t->chains[i] : NULL;
}

static void
__nft_chain_builtin_init(struct nft_handle *h,
			 struct builtin_table *table, const char *chain,
			 int policy)
{
	int i, default_policy;

	/* Initialize all built-in chains. Exception, for e one received as
	 * parameter, set the default policy as requested.
	 */
	for (i=0; i<NF_IP_NUMHOOKS && table->chains[i].name != NULL; i++) {
		if (chain && strcmp(table->chains[i].name, chain) == 0)
			default_policy = policy;
		else
			default_policy = NF_ACCEPT;

		nft_chain_builtin_add(h, table, &table->chains[i],
					default_policy);
	}
}

int
nft_chain_builtin_init(struct nft_handle *h, const char *table,
		       const char *chain, int policy)
{
	int ret = 0;
	struct builtin_table *t;

	t = nft_table_builtin_find(h, table);
	if (t == NULL) {
		ret = -1;
		goto out;
	}
	if (nft_table_builtin_add(h, t, false) < 0) {
		/* Built-in table already initialized, skip. */
		if (errno == EEXIST)
			goto out;
	}
	__nft_chain_builtin_init(h, t, chain, policy);
out:
	return ret;
}

static bool nft_chain_builtin(struct nft_chain *c)
{
	/* Check if this chain has hook number, in that case is built-in.
	 * Should we better export the flags to user-space via nf_tables?
	 */
	return nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM) != NULL;
}

int nft_init(struct nft_handle *h, struct builtin_table *t)
{
	h->nl = mnl_socket_open(NETLINK_NETFILTER);
	if (h->nl == NULL) {
		perror("mnl_socket_open");
		return -1;
	}

	if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0) {
		perror("mnl_socket_bind");
		return -1;
	}
	h->portid = mnl_socket_get_portid(h->nl);
	h->tables = t;

	return 0;
}

void nft_fini(struct nft_handle *h)
{
	mnl_socket_close(h->nl);
}

int nft_table_add(struct nft_handle *h, const struct nft_table *t)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;

	nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family,
					NLM_F_ACK|NLM_F_EXCL, h->seq);
	nft_table_nlmsg_build_payload(nlh, t);

	return mnl_talk(h, nlh, NULL, NULL);
}

int nft_chain_add(struct nft_handle *h, const struct nft_chain *c)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;

	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family,
					NLM_F_ACK|NLM_F_EXCL, h->seq);
	nft_chain_nlmsg_build_payload(nlh, c);

	return mnl_talk(h, nlh, NULL, NULL);
}

int nft_table_set_dormant(struct nft_handle *h, const char *table)
{
	int ret = 0, i;
	struct builtin_table *t;

	t = nft_table_builtin_find(h, table);
	if (t == NULL) {
		ret = -1;
		goto out;
	}
	/* Add this table as dormant */
	if (nft_table_builtin_add(h, t, true) < 0) {
		/* Built-in table already initialized, skip. */
		if (errno == EEXIST)
			goto out;
	}
	for (i=0; t->chains[i].name != NULL && i<NF_INET_NUMHOOKS; i++)
		__nft_chain_builtin_init(h, t, t->chains[i].name, NF_ACCEPT);
out:
	return ret;
}

int nft_table_wake_dormant(struct nft_handle *h, const char *table)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_table *t;

	t = nft_table_alloc();
	if (t == NULL)
		return -1;

	nft_table_attr_set(t, NFT_TABLE_ATTR_NAME, (char *)table);
	nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, 0);

	nlh = nft_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family,
					NLM_F_ACK, h->seq);
	nft_table_nlmsg_build_payload(nlh, t);
	nft_table_free(t);

	return mnl_talk(h, nlh, NULL, NULL);
}

static void nft_chain_print_debug(struct nft_chain *c, struct nlmsghdr *nlh)
{
#ifdef NLDEBUG
	char tmp[1024];

	nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0);
	printf("DEBUG: chain: %s", tmp);
	mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
#endif
}

static int
__nft_chain_set(struct nft_handle *h, const char *table,
		const char *chain, int policy,
		const struct xt_counters *counters)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_chain *c;
	struct builtin_table *_t;
	struct builtin_chain *_c;
	int ret;

	_t = nft_table_builtin_find(h, table);
	/* if this built-in table does not exists, create it */
	if (_t != NULL)
		nft_table_builtin_add(h, _t, false);

	_c = nft_chain_builtin_find(_t, chain);
	if (_c != NULL) {
		/* This is a built-in chain */
		c = nft_chain_builtin_alloc(_t, _c, policy);
		if (c == NULL)
			return -1;
	} else {
		errno = ENOENT;
		return -1;
	}

	if (counters) {
		nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES,
					counters->bcnt);
		nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS,
					counters->pcnt);
	}

	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family,
					NLM_F_ACK, h->seq);
	nft_chain_nlmsg_build_payload(nlh, c);

	nft_chain_print_debug(c, nlh);

	nft_chain_free(c);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0)
		perror("mnl_talk:__nft_chain_policy");

	return ret;
}

int nft_chain_set(struct nft_handle *h, const char *table,
		  const char *chain, const char *policy,
		  const struct xt_counters *counters)
{
	int ret = -1;

	nft_fn = nft_chain_set;

	if (strcmp(policy, "DROP") == 0)
		ret = __nft_chain_set(h, table, chain, NF_DROP, counters);
	else if (strcmp(policy, "ACCEPT") == 0)
		ret = __nft_chain_set(h, table, chain, NF_ACCEPT, counters);

	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

static int __add_match(struct nft_rule_expr *e, struct xt_entry_match *m)
{
	void *info;

	nft_rule_expr_set(e, NFT_EXPR_MT_NAME, m->u.user.name, strlen(m->u.user.name));
	nft_rule_expr_set_u32(e, NFT_EXPR_MT_REV, m->u.user.revision);

	info = calloc(1, m->u.match_size);
	if (info == NULL)
		return -ENOMEM;

	memcpy(info, m->data, m->u.match_size);
	nft_rule_expr_set(e, NFT_EXPR_MT_INFO, info, m->u.match_size - sizeof(*m));

	return 0;
}

static int add_match(struct nft_rule *r, struct xt_entry_match *m)
{
	struct nft_rule_expr *expr;
	int ret;

	expr = nft_rule_expr_alloc("match");
	if (expr == NULL)
		return -ENOMEM;

	ret = __add_match(expr, m);
	nft_rule_add_expr(r, expr);

	return ret;
}

static int __add_target(struct nft_rule_expr *e, struct xt_entry_target *t)
{
	void *info = NULL;

	nft_rule_expr_set(e, NFT_EXPR_TG_NAME, t->u.user.name,
			  strlen(t->u.user.name));
	nft_rule_expr_set_u32(e, NFT_EXPR_TG_REV, t->u.user.revision);

	if (info == NULL) {
		info = calloc(1, t->u.target_size);
		if (info == NULL)
			return -ENOMEM;

		memcpy(info, t->data, t->u.target_size);
	}

	nft_rule_expr_set(e, NFT_EXPR_TG_INFO, info, t->u.target_size - sizeof(*t));

	return 0;
}

int add_target(struct nft_rule *r, struct xt_entry_target *t)
{
	struct nft_rule_expr *expr;
	int ret;

	expr = nft_rule_expr_alloc("target");
	if (expr == NULL)
		return -ENOMEM;

	ret = __add_target(expr, t);
	nft_rule_add_expr(r, expr);

	return ret;
}

int add_jumpto(struct nft_rule *r, const char *name, int verdict)
{
	struct nft_rule_expr *expr;

	expr = nft_rule_expr_alloc("immediate");
	if (expr == NULL)
		return -ENOMEM;

	nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT);
	nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict);
	nft_rule_expr_set_str(expr, NFT_EXPR_IMM_CHAIN, (char *)name);
	nft_rule_add_expr(r, expr);

	return 0;
}

int add_verdict(struct nft_rule *r, int verdict)
{
	struct nft_rule_expr *expr;

	expr = nft_rule_expr_alloc("immediate");
	if (expr == NULL)
		return -ENOMEM;

	nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, NFT_REG_VERDICT);
	nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_VERDICT, verdict);
	nft_rule_add_expr(r, expr);

	return 0;
}

static void nft_rule_print_debug(struct nft_rule *r, struct nlmsghdr *nlh)
{
#ifdef NLDEBUG
	char tmp[1024];

	nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0);
	printf("DEBUG: rule: %s", tmp);
	mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
#endif
}

int add_counters(struct nft_rule *r, uint64_t packets, uint64_t bytes)
{
	struct nft_rule_expr *expr;

	expr = nft_rule_expr_alloc("counter");
	if (expr == NULL)
		return -ENOMEM;

	nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_BYTES, packets);
	nft_rule_expr_set_u64(expr, NFT_EXPR_CTR_PACKETS, bytes);

	nft_rule_add_expr(r, expr);

	return 0;
}

void add_compat(struct nft_rule *r, uint32_t proto, bool inv)
{
	nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_PROTO, proto);
	nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_FLAGS,
			      inv ? NFT_RULE_COMPAT_F_INV : 0);
}

static struct nft_rule *
nft_rule_new(struct nft_handle *h, const char *chain, const char *table,
	     struct iptables_command_state *cs)
{
	struct nft_rule *r;
	int ret = 0, ip_flags = 0;
	struct xtables_rule_match *matchp;

	r = nft_rule_alloc();
	if (r == NULL)
		return NULL;

	nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, h->family);
	nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table);
	nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain);

	ip_flags = h->ops->add(r, cs);

	for (matchp = cs->matches; matchp; matchp = matchp->next) {
		if (add_match(r, matchp->match->m) < 0)
			goto err;
	}

	/* Counters need to me added before the target, otherwise they are
	 * increased for each rule because of the way nf_tables works.
	 */
	if (add_counters(r, cs->counters.pcnt, cs->counters.bcnt) < 0)
		goto err;

	/* If no target at all, add nothing (default to continue) */
	if (cs->target != NULL) {
		/* Standard target? */
		if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
			ret = add_verdict(r, NF_ACCEPT);
		else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
			ret = add_verdict(r, NF_DROP);
		else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
			ret = add_verdict(r, NFT_RETURN);
		else
			ret = add_target(r, cs->target->t);
	} else if (strlen(cs->jumpto) > 0) {
		/* Not standard, then it's a go / jump to chain */
		if (ip_flags & IPT_F_GOTO)
			ret = add_jumpto(r, cs->jumpto, NFT_GOTO);
		else
			ret = add_jumpto(r, cs->jumpto, NFT_JUMP);
	}

	if (ret < 0)
		goto err;

	return r;
err:
	nft_rule_free(r);
	return NULL;
}

int
nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
		struct iptables_command_state *cs, uint64_t handle,
		bool verbose)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_rule *r;
	uint16_t flags = NLM_F_ACK|NLM_F_CREATE;
	int ret = 1;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, chain, NF_ACCEPT);

	nft_fn = nft_rule_append;

	r = nft_rule_new(h, chain, table, cs);
	if (r == NULL) {
		ret = 0;
		goto err;
	}

	if (handle > 0) {
		nft_rule_attr_set(r, NFT_RULE_ATTR_HANDLE, &handle);
		flags |= NLM_F_REPLACE;
	} else
		flags |= NLM_F_APPEND;

	if (h->commit) {
		nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
				      NFT_RULE_F_COMMIT);
	}
	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, h->family,
				       flags, h->seq);

	nft_rule_nlmsg_build_payload(nlh, r);

	nft_rule_print_debug(r, nlh);

	nft_rule_free(r);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0)
		perror("mnl_talk:nft_rule_append");

err:
	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

void
nft_rule_print_save(const struct iptables_command_state *cs,
		    struct nft_rule *r, enum nft_rule_print type,
		    unsigned int format)
{
	const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);
	int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);
	struct xtables_rule_match *matchp;
	struct nft_family_ops *ops;
	int ip_flags = 0;

	/* print chain name */
	switch(type) {
	case NFT_RULE_APPEND:
		printf("-A %s ", chain);
		break;
	case NFT_RULE_DEL:
		printf("-D %s ", chain);
		break;
	}

	ops = nft_family_ops_lookup(family);
	ip_flags = ops->save_firewall(cs, format);

	for (matchp = cs->matches; matchp; matchp = matchp->next) {
		if (matchp->match->alias) {
			printf("-m %s",
			       matchp->match->alias(matchp->match->m));
		} else
			printf("-m %s", matchp->match->name);

		if (matchp->match->save != NULL)
			matchp->match->save(NULL, matchp->match->m);
		printf(" ");
	}

	if (cs->target != NULL) {
		if (cs->target->alias) {
			printf("-j %s", cs->target->alias(cs->target->t));
		} else
			printf("-j %s", cs->jumpto);

		if (cs->target->save != NULL)
			cs->target->save(NULL, cs->target->t);
	} else if (strlen(cs->jumpto) > 0)
		printf("-%c %s", ip_flags & IPT_F_GOTO ? 'g' : 'j',
								cs->jumpto);

	printf("\n");
}

static int nft_chain_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nft_chain *c;
	struct nft_chain_list *list = data;

	c = nft_chain_alloc();
	if (c == NULL) {
		perror("OOM");
		goto err;
	}

	if (nft_chain_nlmsg_parse(nlh, c) < 0) {
		perror("nft_rule_nlmsg_parse");
		goto out;
	}

	nft_chain_list_add_tail(c, list);

	return MNL_CB_OK;
out:
	nft_chain_free(c);
err:
	return MNL_CB_OK;
}

static struct nft_chain_list *nft_chain_list_get(struct nft_handle *h)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	int ret;
	struct nft_chain_list *list;

	list = nft_chain_list_alloc();
	if (list == NULL) {
		errno = ENOMEM;
		return NULL;
	}

	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
					NLM_F_DUMP, h->seq);

	ret = mnl_talk(h, nlh, nft_chain_list_cb, list);
	if (ret < 0)
		perror("mnl_talk:nft_chain_list_get");

	return list;
}

struct nft_chain_list *nft_chain_dump(struct nft_handle *h)
{
	return nft_chain_list_get(h);
}

static const char *policy_name[NF_ACCEPT+1] = {
	[NF_DROP] = "DROP",
	[NF_ACCEPT] = "ACCEPT",
};

static void nft_chain_print_save(struct nft_chain *c, bool basechain)
{
	const char *chain = nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);
	uint64_t pkts = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS);
	uint64_t bytes = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES);

	/* print chain name */
	if (basechain) {
		uint32_t pol = NF_ACCEPT;

		/* no default chain policy? don't crash, display accept */
		if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_POLICY))
			pol = nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY);

		printf(":%s %s [%"PRIu64":%"PRIu64"]\n", chain, policy_name[pol],
					     pkts, bytes);
	} else
		printf(":%s - [%"PRIu64":%"PRIu64"]\n", chain, pkts, bytes);
}

int nft_chain_save(struct nft_handle *h, struct nft_chain_list *list,
		   const char *table)
{
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		return 0;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *chain_table =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		bool basechain = false;

		if (strcmp(table, chain_table) != 0)
			goto next;

		basechain = nft_chain_builtin(c);
		nft_chain_print_save(c, basechain);
next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);
	nft_chain_list_free(list);

	return 1;
}

static int nft_rule_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nft_rule *r;
	struct nft_rule_list *list = data;

	r = nft_rule_alloc();
	if (r == NULL) {
		perror("OOM");
		goto err;
	}

	if (nft_rule_nlmsg_parse(nlh, r) < 0) {
		perror("nft_rule_nlmsg_parse");
		goto out;
	}

	nft_rule_list_add_tail(r, list);

	return MNL_CB_OK;
out:
	nft_rule_free(r);
	nft_rule_list_free(list);
err:
	return MNL_CB_OK;
}

static struct nft_rule_list *nft_rule_list_get(struct nft_handle *h)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_rule_list *list;
	int ret;

	list = nft_rule_list_alloc();
	if (list == NULL)
		return 0;

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family,
					NLM_F_DUMP, h->seq);

	ret = mnl_talk(h, nlh, nft_rule_list_cb, list);
	if (ret < 0) {
		perror("mnl_talk:nft_rule_save");
		nft_rule_list_free(list);
		return NULL;
	}

	return list;
}

int nft_rule_save(struct nft_handle *h, const char *table, bool counters)
{
	struct nft_rule_list *list;
	struct nft_rule_list_iter *iter;
	struct nft_rule *r;

	list = nft_rule_list_get(h);
	if (list == NULL)
		return 0;

	iter = nft_rule_list_iter_create(list);
	if (iter == NULL)
		return 0;

	r = nft_rule_list_iter_next(iter);
	while (r != NULL) {
		const char *rule_table =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE);
		struct iptables_command_state cs = {};

		if (strcmp(table, rule_table) != 0)
			goto next;

		nft_rule_to_iptables_command_state(r, &cs);

		nft_rule_print_save(&cs, r, NFT_RULE_APPEND,
				    counters ? 0 : FMT_NOCOUNTS);

next:
		r = nft_rule_list_iter_next(iter);
	}

	nft_rule_list_iter_destroy(iter);
	nft_rule_list_free(list);

	/* the core expects 1 for success and 0 for error */
	return 1;
}

static void
__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_rule *r;

	r = nft_rule_alloc();
	if (r == NULL)
		return;

	nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table);
	nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain);

	if (h->commit) {
		nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
					 NFT_RULE_F_COMMIT);
	}

	/* Delete all rules in this table + chain */
	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELRULE, h->family,
					NLM_F_ACK, h->seq);
	nft_rule_nlmsg_build_payload(nlh, r);
	nft_rule_free(r);

	if (mnl_talk(h, nlh, NULL, NULL) < 0) {
		if (errno != EEXIST)
			perror("mnl_talk:__nft_rule_flush");
	}
}

int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
{
	int ret;
	struct nft_chain_list *list;
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;

	nft_fn = nft_rule_flush;

	list = nft_chain_list_get(h);
	if (list == NULL) {
		ret = 0;
		goto err;
	}

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		goto err;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *table_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		const char *chain_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);

		if (strcmp(table, table_name) != 0)
			goto next;

		if (chain != NULL && strcmp(chain, chain_name) != 0)
			goto next;

		__nft_rule_flush(h, table_name, chain_name);

		if (chain != NULL)
			break;
next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);
err:
	nft_chain_list_free(list);

	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_chain *c;
	int ret;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);

	c = nft_chain_alloc();
	if (c == NULL)
		return 0;

	nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table);
	nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain);

	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family,
					NLM_F_ACK|NLM_F_EXCL, h->seq);
	nft_chain_nlmsg_build_payload(nlh, c);
	nft_chain_free(c);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0) {
		if (errno != EEXIST)
			perror("mnl_talk:nft_chain_add");
	}

	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

static int __nft_chain_del(struct nft_handle *h, struct nft_chain *c)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	int ret;

	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN, h->family,
					NLM_F_ACK, h->seq);
	nft_chain_nlmsg_build_payload(nlh, c);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0) {
		if (errno != EEXIST && errno != ENOENT)
			perror("mnl_talk:__nft_chain_del");
	}

	return ret;
}

int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table)
{
	struct nft_chain_list *list;
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;
	int ret = 0;
	int deleted_ctr = 0;

	list = nft_chain_list_get(h);
	if (list == NULL)
		goto err;

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		goto err;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *table_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		const char *chain_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);

		/* don't delete built-in chain */
		if (nft_chain_builtin(c))
			goto next;

		if (strcmp(table, table_name) != 0)
			goto next;

		if (chain != NULL && strcmp(chain, chain_name) != 0)
			goto next;

		ret = __nft_chain_del(h, c);
		if (ret < 0)
			break;

		deleted_ctr++;

		if (chain != NULL)
			break;
next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);
err:
	nft_chain_list_free(list);

	/* chain not found */
	if (ret < 0 && deleted_ctr == 0)
		errno = ENOENT;

	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

struct nft_chain *
nft_chain_list_find(struct nft_chain_list *list,
		    const char *table, const char *chain)
{
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		return NULL;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *table_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		const char *chain_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);

		if (strcmp(table, table_name) != 0)
			goto next;

		if (strcmp(chain, chain_name) != 0)
			goto next;

		nft_chain_list_iter_destroy(iter);
		return c;
next:
		c = nft_chain_list_iter_next(iter);
	}
	nft_chain_list_iter_destroy(iter);
	return NULL;
}

static struct nft_chain *
nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
{
	struct nft_chain_list *list;

	list = nft_chain_list_get(h);
	if (list == NULL)
		return NULL;

	return nft_chain_list_find(list, table, chain);
}

int nft_chain_user_rename(struct nft_handle *h,const char *chain,
			  const char *table, const char *newname)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_chain *c;
	uint64_t handle;
	int ret;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);

	/* Find the old chain to be renamed */
	c = nft_chain_find(h, table, chain);
	if (c == NULL) {
		errno = ENOENT;
		return -1;
	}
	handle = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_HANDLE);

	/* Now prepare the new name for the chain */
	c = nft_chain_alloc();
	if (c == NULL)
		return -1;

	nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table);
	nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)newname);
	nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_HANDLE, handle);

	nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family,
					NLM_F_ACK, h->seq);
	nft_chain_nlmsg_build_payload(nlh, c);
	nft_chain_free(c);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0) {
		if (errno != EEXIST)
			perror("mnl_talk:nft_chain_rename");
	}

	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

static int nft_table_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nft_table *t;
	struct nft_table_list *list = data;

	t = nft_table_alloc();
	if (t == NULL) {
		perror("OOM");
		goto err;
	}

	if (nft_table_nlmsg_parse(nlh, t) < 0) {
		perror("nft_rule_nlmsg_parse");
		goto out;
	}

	nft_table_list_add_tail(t, list);

	return MNL_CB_OK;
out:
	nft_table_free(t);
err:
	return MNL_CB_OK;
}

static struct nft_table_list *nft_table_list_get(struct nft_handle *h)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	int ret;
	struct nft_table_list *list;

	list = nft_table_list_alloc();
	if (list == NULL)
		return 0;

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family,
					NLM_F_DUMP, h->seq);

	ret = mnl_talk(h, nlh, nft_table_list_cb, list);
	if (ret < 0)
		perror("mnl_talk:nft_table_list_get");

	return list;
}

bool nft_table_find(struct nft_handle *h, const char *tablename)
{
	struct nft_table_list *list;
	struct nft_table_list_iter *iter;
	struct nft_table *t;
	bool ret = false;

	list = nft_table_list_get(h);
	if (list == NULL)
		goto err;

	iter = nft_table_list_iter_create(list);
	if (iter == NULL)
		goto err;

	t = nft_table_list_iter_next(iter);
	while (t != NULL) {
		const char *this_tablename =
			nft_table_attr_get(t, NFT_TABLE_ATTR_NAME);

		if (strcmp(tablename, this_tablename) == 0)
			return true;

		t = nft_table_list_iter_next(iter);
	}

	nft_table_list_free(list);

err:
	return ret;
}

int nft_for_each_table(struct nft_handle *h,
		       int (*func)(struct nft_handle *h, const char *tablename, bool counters),
		       bool counters)
{
	int ret = 1;
	struct nft_table_list *list;
	struct nft_table_list_iter *iter;
	struct nft_table *t;

	list = nft_table_list_get(h);
	if (list == NULL) {
		ret = 0;
		goto err;
	}

	iter = nft_table_list_iter_create(list);
	if (iter == NULL)
		return 0;

	t = nft_table_list_iter_next(iter);
	while (t != NULL) {
		const char *tablename =
			nft_table_attr_get(t, NFT_TABLE_ATTR_NAME);

		func(h, tablename, counters);

		t = nft_table_list_iter_next(iter);
	}

	nft_table_list_free(list);

err:
	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

int nft_table_purge_chains(struct nft_handle *h, const char *this_table,
			   struct nft_chain_list *chain_list)
{
	struct nft_chain_list_iter *iter;
	struct nft_chain *chain_obj;

	iter = nft_chain_list_iter_create(chain_list);
	if (iter == NULL)
		return 0;

	chain_obj = nft_chain_list_iter_next(iter);
	while (chain_obj != NULL) {
		const char *table =
			nft_chain_attr_get_str(chain_obj, NFT_CHAIN_ATTR_TABLE);

		if (strcmp(this_table, table) != 0)
			goto next;

		if (nft_chain_builtin(chain_obj))
			goto next;

		if ( __nft_chain_del(h, chain_obj) < 0) {
			if (errno != EBUSY)
				return -1;
		}
next:
		chain_obj = nft_chain_list_iter_next(iter);
	}
	nft_chain_list_iter_destroy(iter);

	return 0;
}

static bool
compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2)
{
	struct xtables_rule_match *mp1;
	struct xtables_rule_match *mp2;

	for (mp1 = mt1, mp2 = mt2; mp1 && mp2; mp1 = mp1->next, mp2 = mp2->next) {
		struct xt_entry_match *m1 = mp1->match->m;
		struct xt_entry_match *m2 = mp2->match->m;

		if (strcmp(m1->u.user.name, m2->u.user.name) != 0) {
			DEBUGP("mismatching match name\n");
			return false;
		}

		if (m1->u.user.match_size != m2->u.user.match_size) {
			DEBUGP("mismatching match size\n");
			return false;
		}

		if (memcmp(m1->data, m2->data,
			   m1->u.user.match_size - sizeof(*m1)) != 0) {
			DEBUGP("mismatch match data\n");
			return false;
		}
	}

	/* Both cursors should be NULL */
	if (mp1 != mp2) {
		DEBUGP("mismatch matches amount\n");
		return false;
	}

	return true;
}

static bool
compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
{
	if (tg1 == NULL && tg2 == NULL)
		return true;

	if ((tg1 == NULL && tg2 != NULL) || (tg1 != NULL && tg2 == NULL))
		return false;

	if (strcmp(tg1->t->u.user.name, tg2->t->u.user.name) != 0)
		return false;

	if (memcmp(tg1->t->data, tg2->t->data,
		   tg1->t->u.user.target_size - sizeof(*tg1->t)) != 0) {
		return false;
	}

	return true;
}

static void
__nft_rule_del(struct nft_handle *h, struct nft_rule *r)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	int ret;

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_DELRULE, h->family,
					NLM_F_ACK, h->seq);
	nft_rule_nlmsg_build_payload(nlh, r);

	nft_rule_print_debug(r, nlh);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0)
		perror("mnl_talk:nft_rule_del");
}

struct nft_rule_list *nft_rule_list_create(struct nft_handle *h)
{
	return nft_rule_list_get(h);
}

void nft_rule_list_destroy(struct nft_rule_list *list)
{
	nft_rule_list_free(list);
}

static struct nft_rule *
nft_rule_find(struct nft_rule_list *list, const char *chain, const char *table,
	      struct iptables_command_state *cs, int rulenum)
{
	struct nft_rule *r;
	struct nft_rule_list_iter *iter;
	int rule_ctr = 0;
	bool found = false;

	iter = nft_rule_list_iter_create(list);
	if (iter == NULL)
		return 0;

	r = nft_rule_list_iter_next(iter);
	while (r != NULL) {
		const char *rule_table =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE);
		const char *rule_chain =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);
		const struct nft_family_ops *ops = nft_family_ops_lookup(
				nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY));
		struct iptables_command_state this = {};

		if (strcmp(table, rule_table) != 0 ||
		    strcmp(chain, rule_chain) != 0) {
			DEBUGP("different chain / table\n");
			goto next;
		}

		if (rulenum >= 0) {
			/* Delete by rule number case */
			if (rule_ctr != rulenum)
				goto next;
			found = true;
			break;
		} else {
			/* Delete by matching rule case */
			nft_rule_to_iptables_command_state(r, &this);

			DEBUGP("comparing with... ");
#ifdef DEBUG_DEL
			nft_rule_print_save(&this, r, NFT_RULE_APPEND, 0);
#endif
			if (!ops->is_same(cs, &this))
				goto next;

			if (!compare_matches(cs->matches, this.matches)) {
				DEBUGP("Different matches\n");
				goto next;
			}

			if (!compare_targets(cs->target, this.target)) {
				DEBUGP("Different target\n");
				goto next;
			}

			if (strcmp(cs->jumpto, this.jumpto) != 0) {
				DEBUGP("Different verdict\n");
				goto next;
			}

			found = true;
			break;
		}
next:
		rule_ctr++;
		r = nft_rule_list_iter_next(iter);
	}

	nft_rule_list_iter_destroy(iter);

	return found ? r : NULL;
}

int nft_rule_check(struct nft_handle *h, const char *chain,
		   const char *table, struct iptables_command_state *e,
		   bool verbose)
{
	struct nft_rule_list *list;
	int ret;

	nft_fn = nft_rule_check;

	list = nft_rule_list_create(h);
	if (list == NULL)
		return 0;

	ret = nft_rule_find(list, chain, table, e, -1) ? 1 : 0;
	if (ret == 0)
		errno = ENOENT;

	nft_rule_list_destroy(list);

	return ret;
}

int nft_rule_delete(struct nft_handle *h, const char *chain,
		    const char *table, struct iptables_command_state *cs,
		    bool verbose)
{
	int ret = 0;
	struct nft_rule *r;
	struct nft_rule_list *list;

	nft_fn = nft_rule_delete;

	list = nft_rule_list_create(h);
	if (list == NULL)
		return 0;

	r = nft_rule_find(list, chain, table, cs, -1);
	if (r != NULL) {
		ret = 1;

		if (h->commit) {
			nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
						 NFT_RULE_F_COMMIT);
		}
		DEBUGP("deleting rule\n");
		__nft_rule_del(h, r);
	} else
		errno = ENOENT;

	nft_rule_list_destroy(list);

	return ret;
}

static int
nft_rule_add(struct nft_handle *h, const char *chain,
	     const char *table, struct iptables_command_state *cs,
	     uint64_t handle, bool verbose)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_rule *r;
	int ret = 1;

	r = nft_rule_new(h, chain, table, cs);
	if (r == NULL) {
		ret = 0;
		goto err;
	}
	if (handle > 0)
		nft_rule_attr_set_u64(r, NFT_RULE_ATTR_POSITION, handle);

	if (h->commit) {
		nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
				      NFT_RULE_F_COMMIT);
	}
	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, h->family,
				       NLM_F_ACK|NLM_F_CREATE, h->seq);
	nft_rule_nlmsg_build_payload(nlh, r);
	nft_rule_print_debug(r, nlh);
	nft_rule_free(r);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0)
		perror("mnl_talk:nft_rule_add_num");

err:
	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

int nft_rule_insert(struct nft_handle *h, const char *chain,
		    const char *table, struct iptables_command_state *cs,
		    int rulenum, bool verbose)
{
	struct nft_rule_list *list;
	struct nft_rule *r;
	uint64_t handle = 0;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, chain, NF_ACCEPT);

	nft_fn = nft_rule_insert;

	if (rulenum > 0) {
		list = nft_rule_list_create(h);
		if (list == NULL)
			goto err;

		r = nft_rule_find(list, chain, table, cs, rulenum);
		if (r == NULL) {
			errno = ENOENT;
			goto err;
		}

		handle = nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE);
		DEBUGP("adding after rule handle %"PRIu64"\n", handle);

		nft_rule_list_destroy(list);
	}

	return nft_rule_add(h, chain, table, cs, handle, verbose);
err:
	nft_rule_list_destroy(list);
	return 0;
}

int nft_rule_delete_num(struct nft_handle *h, const char *chain,
			const char *table, int rulenum, bool verbose)
{
	int ret = 0;
	struct nft_rule *r;
	struct nft_rule_list *list;

	nft_fn = nft_rule_delete_num;

	list = nft_rule_list_create(h);
	if (list == NULL)
		return 0;

	r = nft_rule_find(list, chain, table, NULL, rulenum);
	if (r != NULL) {
		ret = 1;

		if (h->commit) {
			nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
						 NFT_RULE_F_COMMIT);
		}
		DEBUGP("deleting rule by number %d\n", rulenum);
		__nft_rule_del(h, r);
	} else
		errno = ENOENT;

	nft_rule_list_destroy(list);

	return ret;
}

int nft_rule_replace(struct nft_handle *h, const char *chain,
		     const char *table, struct iptables_command_state *cs,
		     int rulenum, bool verbose)
{
	int ret = 0;
	struct nft_rule *r;
	struct nft_rule_list *list;

	nft_fn = nft_rule_replace;

	list = nft_rule_list_create(h);
	if (list == NULL)
		return 0;

	r = nft_rule_find(list, chain, table, cs, rulenum);
	if (r != NULL) {
		DEBUGP("replacing rule with handle=%llu\n",
			(unsigned long long)
			nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE));

		if (h->commit) {
			nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
						 NFT_RULE_F_COMMIT);
		}
		ret = nft_rule_append(h, chain, table, cs,
				      nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE),
				      verbose);
	} else
		errno = ENOENT;

	nft_rule_list_destroy(list);

	return ret;
}

static void
print_header(unsigned int format, const char *chain, const char *pol,
	     const struct xt_counters *counters, bool basechain, uint32_t refs)
{
	printf("Chain %s", chain);
	if (basechain) {
		printf(" (policy %s", pol);
		if (!(format & FMT_NOCOUNTS)) {
			fputc(' ', stdout);
			xtables_print_num(counters->pcnt, (format|FMT_NOTABLE));
			fputs("packets, ", stdout);
			xtables_print_num(counters->bcnt, (format|FMT_NOTABLE));
			fputs("bytes", stdout);
		}
		printf(")\n");
	} else {
		printf(" (%u references)\n", refs);
	}

	if (format & FMT_LINENUMBERS)
		printf(FMT("%-4s ", "%s "), "num");
	if (!(format & FMT_NOCOUNTS)) {
		if (format & FMT_KILOMEGAGIGA) {
			printf(FMT("%5s ","%s "), "pkts");
			printf(FMT("%5s ","%s "), "bytes");
		} else {
			printf(FMT("%8s ","%s "), "pkts");
			printf(FMT("%10s ","%s "), "bytes");
		}
	}
	if (!(format & FMT_NOTARGET))
		printf(FMT("%-9s ","%s "), "target");
	fputs(" prot ", stdout);
	if (format & FMT_OPTIONS)
		fputs("opt", stdout);
	if (format & FMT_VIA) {
		printf(FMT(" %-6s ","%s "), "in");
		printf(FMT("%-6s ","%s "), "out");
	}
	printf(FMT(" %-19s ","%s "), "source");
	printf(FMT(" %-19s "," %s "), "destination");
	printf("\n");
}

static int
__nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
		int rulenum, unsigned int format,
		void (*cb)(struct nft_rule *r, unsigned int num,
			   unsigned int format))
{
	struct nft_rule_list *list;
	struct nft_rule_list_iter *iter;
	struct nft_rule *r;
	int rule_ctr = 0, ret = 0;

	list = nft_rule_list_get(h);
	if (list == NULL)
		return 0;

	iter = nft_rule_list_iter_create(list);
	if (iter == NULL)
		goto err;

	r = nft_rule_list_iter_next(iter);
	while (r != NULL) {
		const char *rule_table =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE);
		const char *rule_chain =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);

		rule_ctr++;

		if (strcmp(table, rule_table) != 0 ||
		    strcmp(chain, rule_chain) != 0)
			goto next;

		if (rulenum > 0 && rule_ctr != rulenum) {
			/* List by rule number case */
			goto next;
		}

		cb(r, rule_ctr, format);
		if (rulenum > 0 && rule_ctr == rulenum) {
			ret = 1;
			break;
		}

next:
		r = nft_rule_list_iter_next(iter);
	}

	nft_rule_list_iter_destroy(iter);
err:
	nft_rule_list_free(list);

	if (ret == 0)
		errno = ENOENT;

	return ret;
}

int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
		  int rulenum, unsigned int format)
{
	const struct nft_family_ops *ops;
	struct nft_chain_list *list;
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;
	bool found = false;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, NULL, NF_ACCEPT);

	ops = nft_family_ops_lookup(h->family);

	if (chain && rulenum) {
		__nft_rule_list(h, chain, table,
				rulenum, format, ops->print_firewall);
		return 1;
	}

	list = nft_chain_dump(h);

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		goto err;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *chain_table =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		const char *chain_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);
		uint32_t policy =
			nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY);
		uint32_t refs =
			nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_USE);
		struct xt_counters ctrs = {
			.pcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS),
			.bcnt = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES),
		};
		bool basechain = false;

		if (nft_chain_attr_get(c, NFT_CHAIN_ATTR_HOOKNUM))
			basechain = true;

		if (strcmp(table, chain_table) != 0)
			goto next;
		if (chain && strcmp(chain, chain_name) != 0)
			goto next;

		if (found)
			printf("\n");

		print_header(format, chain_name, policy_name[policy],
				     &ctrs, basechain, refs);

		__nft_rule_list(h, chain_name, table,
				rulenum, format, ops->print_firewall);

		/* we printed the chain we wanted, stop processing. */
		if (chain)
			break;

		found = true;

next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);
err:
	nft_chain_list_free(list);

	return 1;
}

static void
list_save(struct nft_rule *r, unsigned int num, unsigned int format)
{
	struct iptables_command_state cs = {};

	nft_rule_to_iptables_command_state(r, &cs);

	nft_rule_print_save(&cs, r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS));
}

static int
nft_rule_list_chain_save(struct nft_handle *h, const char *chain,
			 const char *table, struct nft_chain_list *list,
			 int counters)
{
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		return 0;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *chain_table =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		const char *chain_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);
		uint32_t policy =
			nft_chain_attr_get_u32(c, NFT_CHAIN_ATTR_POLICY);

		if (strcmp(table, chain_table) != 0 ||
		    (chain && strcmp(chain, chain_name) != 0))
			goto next;

		/* this is a base chain */
		if (nft_chain_builtin(c)) {
			printf("-P %s %s", chain_name, policy_name[policy]);

			if (counters) {
				printf(" -c %"PRIu64" %"PRIu64"\n",
					nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_PACKETS),
					nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_BYTES));
			} else
				printf("\n");
		} else {
			printf("-N %s\n", chain_name);
		}
next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);

	return 1;
}

int nft_rule_list_save(struct nft_handle *h, const char *chain,
		       const char *table, int rulenum, int counters)
{
	struct nft_chain_list *list;
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;
	int ret = 1;

	list = nft_chain_dump(h);

	/* Dump policies and custom chains first */
	if (!rulenum)
		nft_rule_list_chain_save(h, chain, table, list, counters);

	/* Now dump out rules in this table */
	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		goto err;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *chain_table =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE);
		const char *chain_name =
			nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME);

		if (strcmp(table, chain_table) != 0)
			goto next;
		if (chain && strcmp(chain, chain_name) != 0)
			goto next;

		ret = __nft_rule_list(h, chain_name, table, rulenum,
				      counters ? 0 : FMT_NOCOUNTS, list_save);

		/* we printed the chain we wanted, stop processing. */
		if (chain)
			break;
next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);
err:
	nft_chain_list_free(list);

	return ret;
}

int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
			   const char *table, int rulenum)
{
	struct iptables_command_state cs = {};
	struct nft_rule_list *list;
	struct nft_rule *r;
	int ret = 0;

	nft_fn = nft_rule_delete;

	list = nft_rule_list_create(h);
	if (list == NULL)
		return 0;

	r = nft_rule_find(list, chain, table, NULL, rulenum);
	if (r == NULL) {
		errno = ENOENT;
		ret = 1;
		goto error;
	}

	nft_rule_to_iptables_command_state(r, &cs);

	cs.counters.pcnt = cs.counters.bcnt = 0;

	ret =  nft_rule_append(h, chain, table, &cs,
			       nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE),
			       false);

error:
	nft_rule_list_destroy(list);

	return ret;
}

static int nft_action(struct nft_handle *h, int type)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	uint32_t seq;
	int ret;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_NFTABLES<< 8) | type;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_seq = seq = time(NULL);

	struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = h->family;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = 0;

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0) {
		if (errno != EEXIST)
			perror("mnl-talk:nft_commit");
	}
	return ret == 0 ? 1 : 0;
}

int nft_commit(struct nft_handle *h)
{
	return nft_action(h, NFT_MSG_COMMIT);
}

int nft_abort(struct nft_handle *h)
{
	return nft_action(h, NFT_MSG_ABORT);
}

int nft_compatible_revision(const char *name, uint8_t rev, int opt)
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	uint32_t portid, seq, type;
	int ret = 0;

	if (opt == IPT_SO_GET_REVISION_MATCH ||
	    opt == IP6T_SO_GET_REVISION_MATCH)
		type = 0;
	else
		type = 1;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_seq = seq = time(NULL);

	struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_INET;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = 0;

	mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name);
	mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev));
	mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type));

	DEBUGP("requesting `%s' rev=%d type=%d via nft_compat\n",
		name, rev, type);

	nl = mnl_socket_open(NETLINK_NETFILTER);
	if (nl == NULL) {
		perror("mnl_socket_open");
		return 0;
	}

	if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
		perror("mnl_socket_bind");
		goto err;
	}
	portid = mnl_socket_get_portid(nl);

	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		goto err;
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	if (ret == -1) {
		perror("mnl_socket_recvfrom");
		goto err;
	}

	ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
	if (ret == -1) {
		perror("mnl_cb_run");
		goto err;
	}

err:
	mnl_socket_close(nl);

	return ret < 0 ? 0 : 1;
}

/* Translates errno numbers into more human-readable form than strerror. */
const char *nft_strerror(int err)
{
	unsigned int i;
	static struct table_struct {
		void *fn;
		int err;
		const char *message;
	} table[] =
	  {
	    { nft_chain_user_del, ENOTEMPTY, "Chain is not empty" },
	    { nft_chain_user_del, EINVAL, "Can't delete built-in chain" },
	    { nft_chain_user_del, EMLINK,
	      "Can't delete chain with references left" },
	    { nft_chain_user_add, EEXIST, "Chain already exists" },
	    { nft_rule_add, E2BIG, "Index of insertion too big" },
	    { nft_rule_replace, E2BIG, "Index of replacement too big" },
	    { nft_rule_delete_num, E2BIG, "Index of deletion too big" },
/*	    { TC_READ_COUNTER, E2BIG, "Index of counter too big" },
	    { TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */
	    { nft_rule_add, ELOOP, "Loop found in table" },
	    { nft_rule_add, EINVAL, "Target problem" },
	    /* ENOENT for DELETE probably means no matching rule */
	    { nft_rule_delete, ENOENT,
	      "Bad rule (does a matching rule exist in that chain?)" },
	    { nft_chain_set, ENOENT, "Bad built-in chain name" },
	    { nft_chain_set, EINVAL, "Bad policy name" },
	    { NULL, EPERM, "Permission denied (you must be root)" },
	    { NULL, 0, "Incompatible with this kernel" },
	    { NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" },
	    { NULL, ENOSYS, "Will be implemented real soon.  I promise ;)" },
	    { NULL, ENOMEM, "Memory allocation problem" },
	    { NULL, ENOENT, "No chain/target/match by that name" },
	  };

	for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
		if ((!table[i].fn || table[i].fn == nft_fn)
		    && table[i].err == err)
			return table[i].message;
	}

	return strerror(err);
}

static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);

	if (flags & NFT_LOAD_VERBOSE)
		vfprintf(stderr, fmt, args);

	va_end(args);
}

int nft_xtables_config_load(struct nft_handle *h, const char *filename,
			    uint32_t flags)
{
	struct nft_table_list *table_list = nft_table_list_alloc();
	struct nft_chain_list *chain_list = nft_chain_list_alloc();
	struct nft_table_list_iter *titer;
	struct nft_chain_list_iter *citer;
	struct nft_table *table;
	struct nft_chain *chain;
	uint32_t table_family, chain_family;
	bool found = false;

	if (xtables_config_parse(filename, table_list, chain_list) < 0) {
		if (errno == ENOENT) {
			xtables_config_perror(flags,
				"configuration file `%s' does not exists\n",
				filename);
		} else {
			xtables_config_perror(flags,
				"Fatal error parsing config file: %s\n",
				 strerror(errno));
		}
		return -1;
	}

	/* Stage 1) create tables */
	titer = nft_table_list_iter_create(table_list);
	while ((table = nft_table_list_iter_next(titer)) != NULL) {
		table_family = nft_table_attr_get_u32(table,
						      NFT_TABLE_ATTR_FAMILY);
		if (h->family != table_family)
			continue;

		found = true;

		if (nft_table_add(h, table) < 0) {
			if (errno == EEXIST) {
				xtables_config_perror(flags,
					"table `%s' already exists, skipping\n",
					(char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
			} else {
				xtables_config_perror(flags,
					"table `%s' cannot be create, reason `%s'. Exitting\n",
					(char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME),
					strerror(errno));
				nft_table_list_iter_destroy(titer);
				nft_table_list_free(table_list);
				return -1;
			}
			continue;
		}
		xtables_config_perror(flags, "table `%s' has been created\n",
			(char *)nft_table_attr_get(table, NFT_TABLE_ATTR_NAME));
	}
	nft_table_list_iter_destroy(titer);
	nft_table_list_free(table_list);

	if (!found)
		return -1;

	/* Stage 2) create chains */
	citer = nft_chain_list_iter_create(chain_list);
	while ((chain = nft_chain_list_iter_next(citer)) != NULL) {
		chain_family = nft_chain_attr_get_u32(chain,
						      NFT_CHAIN_ATTR_TABLE);
		if (h->family != chain_family)
			continue;

		if (nft_chain_add(h, chain) < 0) {
			if (errno == EEXIST) {
				xtables_config_perror(flags,
					"chain `%s' already exists in table `%s', skipping\n",
					(char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
					(char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE));
			} else {
				xtables_config_perror(flags,
					"chain `%s' cannot be create, reason `%s'. Exitting\n",
					(char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
					strerror(errno));
				nft_chain_list_iter_destroy(citer);
				nft_chain_list_free(chain_list);
				return -1;
			}
			continue;
		}

		xtables_config_perror(flags,
			"chain `%s' in table `%s' has been created\n",
			(char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_NAME),
			(char *)nft_chain_attr_get(chain, NFT_CHAIN_ATTR_TABLE));
	}
	nft_chain_list_iter_destroy(citer);
	nft_chain_list_free(chain_list);

	return 0;
}

int nft_chain_zero_counters(struct nft_handle *h, const char *chain, 
			    const char *table)
{
	struct nft_chain_list *list;
	struct nft_chain_list_iter *iter;
	struct nft_chain *c;
	struct nlmsghdr *nlh;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	int ret = 0;

	list = nft_chain_list_get(h);
	if (list == NULL)
		goto err;

	iter = nft_chain_list_iter_create(list);
	if (iter == NULL)
		goto err;

	c = nft_chain_list_iter_next(iter);
	while (c != NULL) {
		const char *chain_name =
			nft_chain_attr_get(c, NFT_CHAIN_ATTR_NAME);
		const char *chain_table =
			nft_chain_attr_get(c, NFT_CHAIN_ATTR_TABLE);

		if (strcmp(table, chain_table) != 0)
			goto next;

		if (chain != NULL && strcmp(chain, chain_name) != 0)
			goto next;

		nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, 0);
		nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, 0);

		nft_chain_attr_unset(c, NFT_CHAIN_ATTR_HANDLE);

		nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN,
						h->family, NLM_F_ACK, h->seq);

		nft_chain_nlmsg_build_payload(nlh, c);

		ret = mnl_talk(h, nlh, NULL, NULL);
		if (ret < 0)
			perror("mnl_talk:nft_chain_zero_counters");

		if (chain != NULL)
			break;
next:
		c = nft_chain_list_iter_next(iter);
	}

	nft_chain_list_iter_destroy(iter);

err:
	nft_chain_list_free(list);

	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

/*
 * XXX These are almost copy and paste of the original functions, but adapted
 * to ARP. These functions should go away with some refactoring of the
 * existing infrastructure.
 */
static struct nft_rule *
nft_arp_rule_new(struct nft_handle *h, const char *chain, const char *table,
	     struct arpt_entry *fw)
{
	struct xt_entry_target *t;
	char *targname;
	struct nft_rule *r;
	int ret = 0;

	t = nft_arp_get_target(fw);
	targname = t->u.user.name;

	r = nft_rule_alloc();
	if (r == NULL)
		return NULL;

	nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, h->family);
	nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, (char *)table);
	nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, (char *)chain);

	h->ops->add(r, fw);

	/* Counters need to me added before the target, otherwise they are
	 * increased for each rule because of the way nf_tables works.
	 */
	if (add_counters(r, fw->counters.pcnt, fw->counters.bcnt) < 0)
		goto err;

	/* Standard target? */
	if (strcmp(targname, XTC_LABEL_ACCEPT) == 0)
		ret = add_verdict(r, NF_ACCEPT);
	else if (strcmp(targname, XTC_LABEL_DROP) == 0)
		ret = add_verdict(r, NF_DROP);
	else if (strcmp(targname, XTC_LABEL_RETURN) == 0)
		ret = add_verdict(r, NFT_RETURN);
	else if (xtables_find_target(targname, XTF_TRY_LOAD) != NULL)
		ret = add_target(r, t);
	else
		ret = add_jumpto(r, targname, NFT_JUMP);

	if (ret < 0)
		goto err;

	return r;
err:
	nft_rule_free(r);
	return NULL;

}

static void
nft_arp_rule_print_debug(struct nft_rule *r, struct nlmsghdr *nlh) {
#ifdef NLDEBUG
	char tmp[1024];

	nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0);
	printf("DEBUG: rule: %s", tmp);
	mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
#endif
}

static int
nft_arp_rule_add(struct nft_handle *h, const char *chain,
		 const char *table, struct arpt_entry *fw,
		 uint64_t handle, bool verbose)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_rule *r;
	int ret = 1;

	r = nft_arp_rule_new(h, chain, table, fw);
	if (r == NULL) {
		ret = 0;
		goto err;
	}
	if (handle > 0)
			nft_rule_attr_set_u64(r, NFT_RULE_ATTR_POSITION, handle);

	if (h->commit) {
		nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
				      NFT_RULE_F_COMMIT);
	}

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, h->family,
				       NLM_F_ACK|NLM_F_CREATE, h->seq);
	nft_rule_nlmsg_build_payload(nlh, r);
	nft_arp_rule_print_debug(r, nlh);
	nft_rule_free(r);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0)
		perror("mnl_talk:nft_arp_rule_add");

err:
	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

int nft_arp_rule_append(struct nft_handle *h, const char *chain,
			const char *table, struct arpt_entry *fw, bool verbose)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct nft_rule *r;
	uint16_t flags = NLM_F_ACK|NLM_F_CREATE;
	int ret = 1;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, chain, NF_ACCEPT);

	nft_fn = nft_arp_rule_append;

	r = nft_arp_rule_new(h, chain, table, fw);
	if (r == NULL) {
		ret = 0;
		goto err;
	}

	/*if (handle > 0) {
		nft_rule_attr_set(r, NFT_RULE_ATTR_HANDLE, &handle);
		flags |= NLM_F_REPLACE;
	} else
		flags |= NLM_F_APPEND;*/

	flags |= NLM_F_APPEND;

	if (h->commit) {
		nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FLAGS,
				      NFT_RULE_F_COMMIT);
	}

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, h->family,
				       flags, h->seq);
	nft_rule_nlmsg_build_payload(nlh, r);
	nft_arp_rule_print_debug(r, nlh);
	nft_rule_free(r);

	ret = mnl_talk(h, nlh, NULL, NULL);
	if (ret < 0)
		perror("mnl_talk:nft_arp_rule_append");

err:
	/* the core expects 1 for success and 0 for error */
	return ret == 0 ? 1 : 0;
}

static struct nft_rule *
nft_arp_rule_find(struct nft_rule_list *list, const char *chain,
		  const char *table, struct arpt_entry *fw, int rulenum)
{
	struct nft_rule *r;
	struct nft_rule_list_iter *iter;
	int rule_ctr = 0;
	bool found = false;

	iter = nft_rule_list_iter_create(list);
	if (iter == NULL)
		return 0;

	r = nft_rule_list_iter_next(iter);
	while (r != NULL) {
		const char *rule_table =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE);
		const char *rule_chain =
			nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);
		const struct nft_family_ops *ops = nft_family_ops_lookup(
				nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY));
		struct arpt_entry this = {};

		if (strcmp(table, rule_table) != 0 ||
		    strcmp(chain, rule_chain) != 0) {
			DEBUGP("different chain / table\n");
			goto next;
		}

		if (rulenum >= 0) {
			/* Delete by rule number case */
			if (rule_ctr != rulenum)
				goto next;
			found = true;
			break;
		} else {
			struct xt_entry_target *t_fw, *t_this;
			char *targname_fw, *targname_this;
			struct xtables_target *target_fw, *target_this;

			/* Delete by matching rule case */
			nft_rule_to_arpt_entry(r, &this);

			DEBUGP("comparing with... ");
#ifdef DEBUG_DEL
			nft_rule_print_save(&this, r, NFT_RULE_APPEND, 0);
#endif

			if (!ops->is_same(fw, &this))
				goto next;

			t_fw = nft_arp_get_target(fw);
			t_this = nft_arp_get_target(&this);

			targname_fw = t_fw->u.user.name;
			targname_this = t_this->u.user.name;

			target_fw = xtables_find_target(targname_fw, XTF_TRY_LOAD);
			target_this = xtables_find_target(targname_this, XTF_TRY_LOAD);

			if (target_fw != NULL && target_this != NULL) {
				if (!compare_targets(target_fw, target_this)) {
					DEBUGP("Different target\n");
					goto next;
				}
			} else {
				if (strcmp(targname_fw, targname_this) != 0) {
					DEBUGP("Different verdict\n");
					goto next;
				}
			}

			found = true;
			break;
		}
next:
		rule_ctr++;
		r = nft_rule_list_iter_next(iter);
	}

	nft_rule_list_iter_destroy(iter);

	return found ? r : NULL;
}

int nft_arp_rule_insert(struct nft_handle *h, const char *chain,
			const char *table, struct arpt_entry *fw,
			int rulenum, bool verbose)
{
	struct nft_rule_list *list;
	struct nft_rule *r;
	uint64_t handle = 0;

	/* If built-in chains don't exist for this table, create them */
	if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
		nft_chain_builtin_init(h, table, chain, NF_ACCEPT);

	nft_fn = nft_arp_rule_insert;

	if (rulenum > 0) {
		list = nft_rule_list_create(h);
		if (list == NULL)
			goto err;

		r = nft_arp_rule_find(list, chain, table, fw, rulenum);
		if (r == NULL) {
			errno = ENOENT;
			goto err;
		}

		handle = nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE);
		DEBUGP("adding after rule handle %"PRIu64"\n", handle);

		nft_rule_list_destroy(list);
	}

	return nft_arp_rule_add(h, chain, table, fw, handle, verbose);
err:
	nft_rule_list_destroy(list);
	return 0;
}
