*
  * @NFTA_VERDICT_CODE: nf_tables verdict (NLA_U32: enum nft_verdicts)
  * @NFTA_VERDICT_CHAIN: jump target chain name (NLA_STRING)
+ * @NFTA_VERDICT_CHAIN_ID: jump target chain ID (NLA_U32)
  */
 enum nft_verdict_attributes {
        NFTA_VERDICT_UNSPEC,
        NFTA_VERDICT_CODE,
        NFTA_VERDICT_CHAIN,
+       NFTA_VERDICT_CHAIN_ID,
        __NFTA_VERDICT_MAX
 };
 #define NFTA_VERDICT_MAX       (__NFTA_VERDICT_MAX - 1)
 
        [NFTA_VERDICT_CODE]     = { .type = NLA_U32 },
        [NFTA_VERDICT_CHAIN]    = { .type = NLA_STRING,
                                    .len = NFT_CHAIN_MAXNAMELEN - 1 },
+       [NFTA_VERDICT_CHAIN_ID] = { .type = NLA_U32 },
 };
 
 static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
                break;
        case NFT_JUMP:
        case NFT_GOTO:
-               if (!tb[NFTA_VERDICT_CHAIN])
+               if (tb[NFTA_VERDICT_CHAIN]) {
+                       chain = nft_chain_lookup(ctx->net, ctx->table,
+                                                tb[NFTA_VERDICT_CHAIN],
+                                                genmask);
+               } else if (tb[NFTA_VERDICT_CHAIN_ID]) {
+                       chain = nft_chain_lookup_byid(ctx->net,
+                                                     tb[NFTA_VERDICT_CHAIN_ID]);
+                       if (IS_ERR(chain))
+                               return PTR_ERR(chain);
+               } else {
                        return -EINVAL;
-               chain = nft_chain_lookup(ctx->net, ctx->table,
-                                        tb[NFTA_VERDICT_CHAIN], genmask);
+               }
+
                if (IS_ERR(chain))
                        return PTR_ERR(chain);
                if (nft_is_base_chain(chain))