- if (ref) {
- nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE,
- nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE));
+ if (ref && !nftnl_rule_is_set(ref, NFTNL_RULE_HANDLE)) {
+ /* replacing a new rule, hijack its obj_update */
+ struct obj_update *n = obj_update_by_rule(h, ref);
+
+ if (!n) {
+ errno = ENOENT;
+ return 0;
+ }
+ if (n->type != NFT_COMPAT_RULE_APPEND &&
+ n->type != NFT_COMPAT_RULE_INSERT) {
+ errno = EINVAL;
+ return 0;
+ }
+ copy_nftnl_rule_attr(r, ref, NFTNL_RULE_POSITION);
+ copy_nftnl_rule_attr(r, ref, NFTNL_RULE_ID);
+ nftnl_chain_rule_del(ref);
+ nftnl_rule_free(ref);
+ n->rule = r;
+ return 1;
+ } else if (ref) {
+ copy_nftnl_rule_attr(r, ref, NFTNL_RULE_HANDLE);