netfilter: nf_tables: prepare for expressions associated to set elements
[firefly-linux-kernel-4.4.55.git] / net / netfilter / nf_tables_api.c
index e97bee59fe08e450f67e3a2c27983e0d5d952551..8830811550ec5c970a15e3b730c4f186912724ac 100644 (file)
@@ -2904,6 +2904,9 @@ const struct nft_set_ext_type nft_set_ext_types[] = {
        [NFT_SET_EXT_DATA]              = {
                .align  = __alignof__(u32),
        },
+       [NFT_SET_EXT_EXPR]              = {
+               .align  = __alignof__(struct nft_expr),
+       },
        [NFT_SET_EXT_FLAGS]             = {
                .len    = sizeof(u8),
                .align  = __alignof__(u8),
@@ -2990,6 +2993,10 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
                          set->dlen) < 0)
                goto nla_put_failure;
 
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
+           nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
+               goto nla_put_failure;
+
        if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
            nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
                         htonl(*nft_set_ext_flags(ext))))
@@ -3276,6 +3283,8 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem)
        nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
        if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
                nft_data_uninit(nft_set_ext_data(ext), set->dtype);
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
+               nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
 
        kfree(elem);
 }