]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft: prepare for dynamic register allocation
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 24 Apr 2022 20:19:20 +0000 (22:19 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 2 May 2022 11:16:28 +0000 (13:16 +0200)
Store the register that has been allocated and pass it on to the next
expression. NFT_REG_1 is still used.

No functional changes are expected.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft-arp.c
iptables/nft-bridge.c
iptables/nft-ipv4.c
iptables/nft-shared.c
iptables/nft-shared.h
iptables/nft.c

index 8c5ce3525dd5e27d50799b68943344a932a2ec2c..65bd965eb69f6290e24140858de538b4a5a7ae30 100644 (file)
@@ -73,18 +73,22 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r,
 
        if (fw->arp.arhrd != 0 ||
            fw->arp.invflags & IPT_INV_ARPHRD) {
+               uint8_t reg;
+
                op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD);
                add_payload(h, r, offsetof(struct arphdr, ar_hrd), 2,
-                           NFT_PAYLOAD_NETWORK_HEADER);
-               add_cmp_u16(r, fw->arp.arhrd, op);
+                           NFT_PAYLOAD_NETWORK_HEADER, &reg);
+               add_cmp_u16(r, fw->arp.arhrd, op, reg);
        }
 
        if (fw->arp.arpro != 0 ||
            fw->arp.invflags & IPT_INV_PROTO) {
+               uint8_t reg;
+
                op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO);
                add_payload(h, r, offsetof(struct arphdr, ar_pro), 2,
-                           NFT_PAYLOAD_NETWORK_HEADER);
-               add_cmp_u16(r, fw->arp.arpro, op);
+                           NFT_PAYLOAD_NETWORK_HEADER, &reg);
+               add_cmp_u16(r, fw->arp.arpro, op, reg);
        }
 
        if (fw->arp.arhln != 0 ||
@@ -98,10 +102,12 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r,
 
        if (fw->arp.arpop != 0 ||
            fw->arp.invflags & IPT_INV_ARPOP) {
+               uint8_t reg;
+
                op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP);
                add_payload(h, r, offsetof(struct arphdr, ar_op), 2,
-                           NFT_PAYLOAD_NETWORK_HEADER);
-               add_cmp_u16(r, fw->arp.arpop, op);
+                           NFT_PAYLOAD_NETWORK_HEADER, &reg);
+               add_cmp_u16(r, fw->arp.arpop, op, reg);
        }
 
        if (need_devaddr(&fw->arp.src_devaddr)) {
index 888d4b6baa57713acac1b2b62fe0814a6293ec47..106bcc72889f6e74c648132b344853a38f77f21b 100644 (file)
@@ -69,28 +69,30 @@ static void add_logical_iniface(struct nft_handle *h, struct nftnl_rule *r,
                                char *iface, uint32_t op)
 {
        int iface_len;
+       uint8_t reg;
 
        iface_len = strlen(iface);
 
-       add_meta(h, r, NFT_META_BRI_IIFNAME);
+       add_meta(h, r, NFT_META_BRI_IIFNAME, &reg);
        if (iface[iface_len - 1] == '+')
-               add_cmp_ptr(r, op, iface, iface_len - 1);
+               add_cmp_ptr(r, op, iface, iface_len - 1, reg);
        else
-               add_cmp_ptr(r, op, iface, iface_len + 1);
+               add_cmp_ptr(r, op, iface, iface_len + 1, reg);
 }
 
 static void add_logical_outiface(struct nft_handle *h, struct nftnl_rule *r,
                                 char *iface, uint32_t op)
 {
        int iface_len;
+       uint8_t reg;
 
        iface_len = strlen(iface);
 
-       add_meta(h, r, NFT_META_BRI_OIFNAME);
+       add_meta(h, r, NFT_META_BRI_OIFNAME, &reg);
        if (iface[iface_len - 1] == '+')
-               add_cmp_ptr(r, op, iface, iface_len - 1);
+               add_cmp_ptr(r, op, iface, iface_len - 1, reg);
        else
-               add_cmp_ptr(r, op, iface, iface_len + 1);
+               add_cmp_ptr(r, op, iface, iface_len + 1, reg);
 }
 
 static int _add_action(struct nftnl_rule *r, struct iptables_command_state *cs)
@@ -141,10 +143,12 @@ static int nft_bridge_add(struct nft_handle *h,
        }
 
        if ((fw->bitmask & EBT_NOPROTO) == 0) {
+               uint8_t reg;
+
                op = nft_invflags2cmp(fw->invflags, EBT_IPROTO);
                add_payload(h, r, offsetof(struct ethhdr, h_proto), 2,
-                           NFT_PAYLOAD_LL_HEADER);
-               add_cmp_u16(r, fw->ethproto, op);
+                           NFT_PAYLOAD_LL_HEADER, &reg);
+               add_cmp_u16(r, fw->ethproto, op, reg);
        }
 
        add_compat(r, fw->ethproto, fw->invflags & EBT_IPROTO);
index 76a0e0de378c3b25d36cd8bc0602ceb893aeb950..59c4a41f1a05f607537e990f09f92590ae6fd364 100644 (file)
@@ -63,17 +63,19 @@ static int nft_ipv4_add(struct nft_handle *h, struct nftnl_rule *r,
                         sizeof(struct in_addr), op);
        }
        if (cs->fw.ip.flags & IPT_F_FRAG) {
+               uint8_t reg;
+
                add_payload(h, r, offsetof(struct iphdr, frag_off), 2,
-                           NFT_PAYLOAD_NETWORK_HEADER);
+                           NFT_PAYLOAD_NETWORK_HEADER, &reg);
                /* get the 13 bits that contain the fragment offset */
-               add_bitwise_u16(r, htons(0x1fff), 0);
+               add_bitwise_u16(h, r, htons(0x1fff), 0, reg, &reg);
 
                /* if offset is non-zero, this is a fragment */
                op = NFT_CMP_NEQ;
                if (cs->fw.ip.invflags & IPT_INV_FRAG)
                        op = NFT_CMP_EQ;
 
-               add_cmp_u16(r, 0, op);
+               add_cmp_u16(r, 0, op, reg);
        }
 
        add_compat(r, cs->fw.ip.proto, cs->fw.ip.invflags & XT_INV_PROTO);
index 52821684445b64992077b67a8c432057364fb379..27e95c1ae4f38dd9d06022848ed84a378a03c598 100644 (file)
@@ -40,74 +40,89 @@ extern struct nft_family_ops nft_family_ops_ipv6;
 extern struct nft_family_ops nft_family_ops_arp;
 extern struct nft_family_ops nft_family_ops_bridge;
 
-void add_meta(struct nft_handle *h, struct nftnl_rule *r, uint32_t key)
+void add_meta(struct nft_handle *h, struct nftnl_rule *r, uint32_t key,
+             uint8_t *dreg)
 {
        struct nftnl_expr *expr;
+       uint8_t reg;
 
        expr = nftnl_expr_alloc("meta");
        if (expr == NULL)
                return;
 
+       reg = NFT_REG_1;
        nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, key);
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
-
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, reg);
        nftnl_rule_add_expr(r, expr);
+
+       *dreg = reg;
 }
 
 void add_payload(struct nft_handle *h, struct nftnl_rule *r,
-                int offset, int len, uint32_t base)
+                int offset, int len, uint32_t base, uint8_t *dreg)
 {
        struct nftnl_expr *expr;
+       uint8_t reg;
 
        expr = nftnl_expr_alloc("payload");
        if (expr == NULL)
                return;
 
+       reg = NFT_REG_1;
        nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_BASE, base);
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_DREG, NFT_REG_1);
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_DREG, reg);
        nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_OFFSET, offset);
        nftnl_expr_set_u32(expr, NFTNL_EXPR_PAYLOAD_LEN, len);
-
        nftnl_rule_add_expr(r, expr);
+
+       *dreg = reg;
 }
 
 /* bitwise operation is = sreg & mask ^ xor */
-void add_bitwise_u16(struct nftnl_rule *r, uint16_t mask, uint16_t xor)
+void add_bitwise_u16(struct nft_handle *h, struct nftnl_rule *r,
+                    uint16_t mask, uint16_t xor, uint8_t sreg, uint8_t *dreg)
 {
        struct nftnl_expr *expr;
+       uint8_t reg;
 
        expr = nftnl_expr_alloc("bitwise");
        if (expr == NULL)
                return;
 
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_SREG, NFT_REG_1);
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_DREG, NFT_REG_1);
+       reg = NFT_REG_1;
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_SREG, sreg);
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_DREG, reg);
        nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_LEN, sizeof(uint16_t));
        nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_MASK, &mask, sizeof(uint16_t));
        nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_XOR, &xor, sizeof(uint16_t));
-
        nftnl_rule_add_expr(r, expr);
+
+       *dreg = reg;
 }
 
-void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len)
+void add_bitwise(struct nft_handle *h, struct nftnl_rule *r,
+                uint8_t *mask, size_t len, uint8_t sreg, uint8_t *dreg)
 {
        struct nftnl_expr *expr;
        uint32_t xor[4] = { 0 };
+       uint8_t reg = *dreg;
 
        expr = nftnl_expr_alloc("bitwise");
        if (expr == NULL)
                return;
 
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_SREG, NFT_REG_1);
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_DREG, NFT_REG_1);
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_SREG, sreg);
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_DREG, reg);
        nftnl_expr_set_u32(expr, NFTNL_EXPR_BITWISE_LEN, len);
        nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_MASK, mask, len);
        nftnl_expr_set(expr, NFTNL_EXPR_BITWISE_XOR, &xor, len);
-
        nftnl_rule_add_expr(r, expr);
+
+       *dreg = reg;
 }
 
-void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len)
+void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len,
+                uint8_t sreg)
 {
        struct nftnl_expr *expr;
 
@@ -115,56 +130,59 @@ void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len)
        if (expr == NULL)
                return;
 
-       nftnl_expr_set_u32(expr, NFTNL_EXPR_CMP_SREG, NFT_REG_1);
+       nftnl_expr_set_u32(expr, NFTNL_EXPR_CMP_SREG, sreg);
        nftnl_expr_set_u32(expr, NFTNL_EXPR_CMP_OP, op);
        nftnl_expr_set(expr, NFTNL_EXPR_CMP_DATA, data, len);
-
        nftnl_rule_add_expr(r, expr);
 }
 
-void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op)
+void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op, uint8_t sreg)
 {
-       add_cmp_ptr(r, op, &val, sizeof(val));
+       add_cmp_ptr(r, op, &val, sizeof(val), sreg);
 }
 
-void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op)
+void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op, uint8_t sreg)
 {
-       add_cmp_ptr(r, op, &val, sizeof(val));
+       add_cmp_ptr(r, op, &val, sizeof(val), sreg);
 }
 
-void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op)
+void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op, uint8_t sreg)
 {
-       add_cmp_ptr(r, op, &val, sizeof(val));
+       add_cmp_ptr(r, op, &val, sizeof(val), sreg);
 }
 
 void add_iniface(struct nft_handle *h, struct nftnl_rule *r,
                 char *iface, uint32_t op)
 {
        int iface_len;
+       uint8_t reg;
 
        iface_len = strlen(iface);
 
-       add_meta(h, r, NFT_META_IIFNAME);
+       add_meta(h, r, NFT_META_IIFNAME, &reg);
        if (iface[iface_len - 1] == '+') {
                if (iface_len > 1)
-                       add_cmp_ptr(r, op, iface, iface_len - 1);
-       } else
-               add_cmp_ptr(r, op, iface, iface_len + 1);
+                       add_cmp_ptr(r, op, iface, iface_len - 1, reg);
+       } else {
+               add_cmp_ptr(r, op, iface, iface_len + 1, reg);
+       }
 }
 
 void add_outiface(struct nft_handle *h, struct nftnl_rule *r,
                  char *iface, uint32_t op)
 {
        int iface_len;
+       uint8_t reg;
 
        iface_len = strlen(iface);
 
-       add_meta(h, r, NFT_META_OIFNAME);
+       add_meta(h, r, NFT_META_OIFNAME, &reg);
        if (iface[iface_len - 1] == '+') {
                if (iface_len > 1)
-                       add_cmp_ptr(r, op, iface, iface_len - 1);
-       } else
-               add_cmp_ptr(r, op, iface, iface_len + 1);
+                       add_cmp_ptr(r, op, iface, iface_len - 1, reg);
+       } else {
+               add_cmp_ptr(r, op, iface, iface_len + 1, reg);
+       }
 }
 
 void add_addr(struct nft_handle *h, struct nftnl_rule *r,
@@ -173,6 +191,7 @@ void add_addr(struct nft_handle *h, struct nftnl_rule *r,
 {
        const unsigned char *m = mask;
        bool bitwise = false;
+       uint8_t reg;
        int i, j;
 
        for (i = 0; i < len; i++) {
@@ -187,26 +206,30 @@ void add_addr(struct nft_handle *h, struct nftnl_rule *r,
        if (!bitwise)
                len = i;
 
-       add_payload(h, r, offset, len, base);
+       add_payload(h, r, offset, len, base, &reg);
 
        if (bitwise)
-               add_bitwise(r, mask, len);
+               add_bitwise(h, r, mask, len, reg, &reg);
 
-       add_cmp_ptr(r, op, data, len);
+       add_cmp_ptr(r, op, data, len, reg);
 }
 
 void add_proto(struct nft_handle *h, struct nftnl_rule *r,
               int offset, size_t len, uint8_t proto, uint32_t op)
 {
-       add_payload(h, r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
-       add_cmp_u8(r, proto, op);
+       uint8_t reg;
+
+       add_payload(h, r, offset, len, NFT_PAYLOAD_NETWORK_HEADER, &reg);
+       add_cmp_u8(r, proto, op, reg);
 }
 
 void add_l4proto(struct nft_handle *h, struct nftnl_rule *r,
                 uint8_t proto, uint32_t op)
 {
-       add_meta(h, r, NFT_META_L4PROTO);
-       add_cmp_u8(r, proto, op);
+       uint8_t reg;
+
+       add_meta(h, r, NFT_META_L4PROTO, &reg);
+       add_cmp_u8(r, proto, op, reg);
 }
 
 bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
index 0bdb6848d853eea6711230366bb84902401a89f0..b04049047116745f2dc258c7cc33288e25fa9735 100644 (file)
@@ -132,14 +132,14 @@ struct nft_family_ops {
                             int rulenum);
 };
 
-void add_meta(struct nft_handle *h, struct nftnl_rule *r, uint32_t key);
-void add_payload(struct nft_handle *h, struct nftnl_rule *r, int offset, int len, uint32_t base);
-void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len);
-void add_bitwise_u16(struct nftnl_rule *r, uint16_t mask, uint16_t xor);
-void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len);
-void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op);
-void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op);
-void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op);
+void add_meta(struct nft_handle *h, struct nftnl_rule *r, uint32_t key, uint8_t *dreg);
+void add_payload(struct nft_handle *h, struct nftnl_rule *r, int offset, int len, uint32_t base, uint8_t *dreg);
+void add_bitwise(struct nft_handle *h, struct nftnl_rule *r, uint8_t *mask, size_t len, uint8_t sreg, uint8_t *dreg);
+void add_bitwise_u16(struct nft_handle *h, struct nftnl_rule *r, uint16_t mask, uint16_t xor, uint8_t sreg, uint8_t *dreg);
+void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len, uint8_t sreg);
+void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op, uint8_t sreg);
+void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op, uint8_t sreg);
+void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op, uint8_t sreg);
 void add_iniface(struct nft_handle *h, struct nftnl_rule *r, char *iface, uint32_t op);
 void add_outiface(struct nft_handle *h, struct nftnl_rule *r, char *iface, uint32_t op);
 void add_addr(struct nft_handle *h, struct nftnl_rule *r, enum nft_payload_bases base, int offset,
index 987b3c957b98372c62dfab6b0de7ee339a939523..bdfef0244b38eb9f27dbb2c81a3bb7ef45f90882 100644 (file)
@@ -1090,16 +1090,22 @@ static struct nftnl_set *add_anon_set(struct nft_handle *h, const char *table,
 }
 
 static struct nftnl_expr *
-gen_payload(uint32_t base, uint32_t offset, uint32_t len, uint32_t dreg)
+gen_payload(struct nft_handle *h, uint32_t base, uint32_t offset, uint32_t len,
+           uint8_t *dreg)
 {
        struct nftnl_expr *e = nftnl_expr_alloc("payload");
+       uint8_t reg;
 
        if (!e)
                return NULL;
+
+       reg = NFT_REG_1;
        nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_BASE, base);
        nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET, offset);
        nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_LEN, len);
-       nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_DREG, dreg);
+       nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_DREG, reg);
+       *dreg = reg;
+
        return e;
 }
 
@@ -1144,6 +1150,7 @@ static int __add_nft_among(struct nft_handle *h, const char *table,
        struct nftnl_expr *e;
        struct nftnl_set *s;
        uint32_t flags = 0;
+       uint8_t reg;
        int idx = 0;
 
        if (ip) {
@@ -1184,21 +1191,22 @@ static int __add_nft_among(struct nft_handle *h, const char *table,
                nftnl_set_elem_add(s, elem);
        }
 
-       e = gen_payload(NFT_PAYLOAD_LL_HEADER,
-                       eth_addr_off[dst], ETH_ALEN, NFT_REG_1);
+       e = gen_payload(h, NFT_PAYLOAD_LL_HEADER,
+                       eth_addr_off[dst], ETH_ALEN, &reg);
        if (!e)
                return -ENOMEM;
        nftnl_rule_add_expr(r, e);
 
        if (ip) {
-               e = gen_payload(NFT_PAYLOAD_NETWORK_HEADER, ip_addr_off[dst],
-                               sizeof(struct in_addr), NFT_REG32_02);
+               e = gen_payload(h, NFT_PAYLOAD_NETWORK_HEADER, ip_addr_off[dst],
+                               sizeof(struct in_addr), &reg);
                if (!e)
                        return -ENOMEM;
                nftnl_rule_add_expr(r, e);
        }
 
-       e = gen_lookup(NFT_REG_1, "__set%d", set_id, inv);
+       reg = NFT_REG_1;
+       e = gen_lookup(reg, "__set%d", set_id, inv);
        if (!e)
                return -ENOMEM;
        nftnl_rule_add_expr(r, e);
@@ -1215,9 +1223,10 @@ static int add_nft_among(struct nft_handle *h,
        if ((data->src.cnt && data->src.ip) ||
            (data->dst.cnt && data->dst.ip)) {
                uint16_t eth_p_ip = htons(ETH_P_IP);
+               uint8_t reg;
 
-               add_meta(h, r, NFT_META_PROTOCOL);
-               add_cmp_ptr(r, NFT_CMP_EQ, &eth_p_ip, 2);
+               add_meta(h, r, NFT_META_PROTOCOL, &reg);
+               add_cmp_ptr(r, NFT_CMP_EQ, &eth_p_ip, 2, reg);
        }
 
        if (data->src.cnt)
@@ -1233,17 +1242,17 @@ static int add_nft_among(struct nft_handle *h,
 static int expr_gen_range_cmp16(struct nftnl_rule *r,
                                uint16_t lo,
                                uint16_t hi,
-                               bool invert)
+                               bool invert, uint8_t reg)
 {
        struct nftnl_expr *e;
 
        if (lo == hi) {
-               add_cmp_u16(r, htons(lo), invert ? NFT_CMP_NEQ : NFT_CMP_EQ);
+               add_cmp_u16(r, htons(lo), invert ? NFT_CMP_NEQ : NFT_CMP_EQ, reg);
                return 0;
        }
 
        if (lo == 0 && hi < 0xffff) {
-               add_cmp_u16(r, htons(hi) , invert ? NFT_CMP_GT : NFT_CMP_LTE);
+               add_cmp_u16(r, htons(hi) , invert ? NFT_CMP_GT : NFT_CMP_LTE, reg);
                return 0;
        }
 
@@ -1251,7 +1260,7 @@ static int expr_gen_range_cmp16(struct nftnl_rule *r,
        if (!e)
                return -ENOMEM;
 
-       nftnl_expr_set_u32(e, NFTNL_EXPR_RANGE_SREG, NFT_REG_1);
+       nftnl_expr_set_u32(e, NFTNL_EXPR_RANGE_SREG, reg);
        nftnl_expr_set_u32(e, NFTNL_EXPR_RANGE_OP, invert ? NFT_RANGE_NEQ : NFT_RANGE_EQ);
 
        lo = htons(lo);
@@ -1269,6 +1278,7 @@ static int add_nft_tcpudp(struct nft_handle *h,struct nftnl_rule *r,
 {
        struct nftnl_expr *expr;
        uint8_t op = NFT_CMP_EQ;
+       uint8_t reg;
        int ret;
 
        if (src[0] && src[0] == src[1] &&
@@ -1279,36 +1289,33 @@ static int add_nft_tcpudp(struct nft_handle *h,struct nftnl_rule *r,
                if (invert_src)
                        op = NFT_CMP_NEQ;
 
-               expr = gen_payload(NFT_PAYLOAD_TRANSPORT_HEADER, 0, 4,
-                                  NFT_REG_1);
+               expr = gen_payload(h, NFT_PAYLOAD_TRANSPORT_HEADER, 0, 4, &reg);
                if (!expr)
                        return -ENOMEM;
 
                nftnl_rule_add_expr(r, expr);
-               add_cmp_u32(r, htonl(combined), op);
+               add_cmp_u32(r, htonl(combined), op, reg);
                return 0;
        }
 
        if (src[0] || src[1] < 0xffff) {
-               expr = gen_payload(NFT_PAYLOAD_TRANSPORT_HEADER,
-                                  0, 2, NFT_REG_1);
+               expr = gen_payload(h, NFT_PAYLOAD_TRANSPORT_HEADER, 0, 2, &reg);
                if (!expr)
                        return -ENOMEM;
 
                nftnl_rule_add_expr(r, expr);
-               ret = expr_gen_range_cmp16(r, src[0], src[1], invert_src);
+               ret = expr_gen_range_cmp16(r, src[0], src[1], invert_src, reg);
                if (ret)
                        return ret;
        }
 
        if (dst[0] || dst[1] < 0xffff) {
-               expr = gen_payload(NFT_PAYLOAD_TRANSPORT_HEADER,
-                                  2, 2, NFT_REG_1);
+               expr = gen_payload(h, NFT_PAYLOAD_TRANSPORT_HEADER, 2, 2, &reg);
                if (!expr)
                        return -ENOMEM;
 
                nftnl_rule_add_expr(r, expr);
-               ret = expr_gen_range_cmp16(r, dst[0], dst[1], invert_dst);
+               ret = expr_gen_range_cmp16(r, dst[0], dst[1], invert_dst, reg);
                if (ret)
                        return ret;
        }
@@ -1349,22 +1356,22 @@ static int add_nft_udp(struct nft_handle *h, struct nftnl_rule *r,
                              udp->dpts, udp->invflags & XT_UDP_INV_DSTPT);
 }
 
-static int add_nft_tcpflags(struct nftnl_rule *r,
+static int add_nft_tcpflags(struct nft_handle *h, struct nftnl_rule *r,
                            uint8_t cmp, uint8_t mask,
                            bool invert)
 {
        struct nftnl_expr *e;
+       uint8_t reg;
 
-       e = gen_payload(NFT_PAYLOAD_TRANSPORT_HEADER,
-                       13, 1, NFT_REG_1);
+       e = gen_payload(h, NFT_PAYLOAD_TRANSPORT_HEADER, 13, 1, &reg);
 
        if (!e)
                return -ENOMEM;
 
        nftnl_rule_add_expr(r, e);
 
-       add_bitwise(r, &mask, 1);
-       add_cmp_u8(r, cmp, invert ? NFT_CMP_NEQ : NFT_CMP_EQ);
+       add_bitwise(h, r, &mask, 1, reg, &reg);
+       add_cmp_u8(r, cmp, invert ? NFT_CMP_NEQ : NFT_CMP_EQ, reg);
 
        return 0;
 }
@@ -1396,7 +1403,7 @@ static int add_nft_tcp(struct nft_handle *h, struct nftnl_rule *r,
        }
 
        if (tcp->flg_mask) {
-               int ret = add_nft_tcpflags(r, tcp->flg_cmp, tcp->flg_mask,
+               int ret = add_nft_tcpflags(h, r, tcp->flg_cmp, tcp->flg_mask,
                                           tcp->invflags & XT_TCP_INV_FLAGS);
 
                if (ret < 0)
@@ -1411,18 +1418,19 @@ static int add_nft_mark(struct nft_handle *h, struct nftnl_rule *r,
                        struct xt_entry_match *m)
 {
        struct xt_mark_mtinfo1 *mark = (void *)m->data;
+       uint8_t reg;
        int op;
 
-       add_meta(h, r, NFT_META_MARK);
+       add_meta(h, r, NFT_META_MARK, &reg);
        if (mark->mask != 0xffffffff)
-               add_bitwise(r, (uint8_t *)&mark->mask, sizeof(uint32_t));
+               add_bitwise(h, r, (uint8_t *)&mark->mask, sizeof(uint32_t), reg, &reg);
 
        if (mark->invert)
                op = NFT_CMP_NEQ;
        else
                op = NFT_CMP_EQ;
 
-       add_cmp_u32(r, mark->mark, op);
+       add_cmp_u32(r, mark->mark, op, reg);
 
        return 0;
 }