@@ -1186,7 +1186,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
int
nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
- void *data, uint64_t handle, bool verbose)
+ void *data, struct nftnl_rule *ref, bool verbose)
{
struct nftnl_chain *c;
struct nftnl_rule *r;
@@ -1202,8 +1202,9 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
if (r == NULL)
return 0;
- if (handle > 0) {
- nftnl_rule_set(r, NFTNL_RULE_HANDLE, &handle);
+ if (ref) {
+ nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE,
+ nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE));
type = NFT_COMPAT_RULE_REPLACE;
} else
type = NFT_COMPAT_RULE_APPEND;
@@ -1216,12 +1217,17 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
if (verbose)
h->ops->print_rule(r, 0, FMT_PRINT_RULE);
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
- return 0;
+ if (ref) {
+ nftnl_chain_rule_insert_at(r, ref);
+ nftnl_chain_rule_del(r);
+ } else {
+ c = nft_chain_find(h, table, chain);
+ if (!c) {
+ errno = ENOENT;
+ return 0;
+ }
+ nftnl_chain_rule_add_tail(r, c);
}
- nftnl_chain_rule_add_tail(r, c);
return 1;
}
@@ -2107,7 +2113,7 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
r = nft_rule_find(h, c, data, rulenum - 1);
if (r != NULL)
return nft_rule_append(h, chain, table, data,
- 0, verbose);
+ NULL, verbose);
errno = ENOENT;
goto err;
@@ -2179,11 +2185,7 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
(unsigned long long)
nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE));
- nftnl_rule_list_del(r);
-
- ret = nft_rule_append(h, chain, table, data,
- nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE),
- verbose);
+ ret = nft_rule_append(h, chain, table, data, r, verbose);
} else
errno = ENOENT;
@@ -2459,9 +2461,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
cs.counters.pcnt = cs.counters.bcnt = 0;
- ret = nft_rule_append(h, chain, table, &cs,
- nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE),
- false);
+ ret = nft_rule_append(h, chain, table, &cs, r, false);
error:
return ret;
@@ -98,7 +98,7 @@ bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain
*/
struct nftnl_rule;
-int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, uint64_t handle, bool verbose);
+int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, struct nftnl_rule *ref, bool verbose);
int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
@@ -826,7 +826,7 @@ append_entry(struct nft_handle *h,
for (j = 0; j < ndaddrs; j++) {
cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
if (append) {
- ret = nft_rule_append(h, chain, table, cs, 0,
+ ret = nft_rule_append(h, chain, table, cs, NULL,
verbose);
} else {
ret = nft_rule_insert(h, chain, table, cs,
@@ -171,7 +171,7 @@ append_entry(struct nft_handle *h,
int ret = 1;
if (append)
- ret = nft_rule_append(h, chain, table, cs, 0, verbose);
+ ret = nft_rule_append(h, chain, table, cs, NULL, verbose);
else
ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose);
@@ -406,7 +406,7 @@ add_entry(const char *chain,
if (append) {
ret = nft_rule_append(h, chain, table,
- cs, 0,
+ cs, NULL,
verbose);
} else {
ret = nft_rule_insert(h, chain, table,
@@ -426,7 +426,7 @@ add_entry(const char *chain,
&d.mask.v6[j], sizeof(struct in6_addr));
if (append) {
ret = nft_rule_append(h, chain, table,
- cs, 0,
+ cs, NULL,
verbose);
} else {
ret = nft_rule_insert(h, chain, table,
When replacing a rule, the replacement was simply appended to the chain's rule list. Instead, insert it where the rule it replaces was. This also fixes for zero counters command to remove the old rule from cache. Signed-off-by: Phil Sutter <phil@nwl.cc> --- iptables/nft.c | 34 +++++++++++++++++----------------- iptables/nft.h | 2 +- iptables/xtables-arp.c | 2 +- iptables/xtables-eb.c | 2 +- iptables/xtables.c | 4 ++-- 5 files changed, 22 insertions(+), 22 deletions(-)