]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
set: support for NFTNL_SET_EXPR
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 17 Mar 2020 13:14:05 +0000 (14:14 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 17 Mar 2020 13:14:27 +0000 (14:14 +0100)
This patch adds support for the NFTA_SET_EXPR netlink attribute.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/libnftnl/set.h
include/libnftnl/udata.h
include/linux/netfilter/nf_tables.h
include/set.h
src/set.c

index 6843adfa0c1e84ba4b96b2cd503d7d28eac1612e..5138bb99b426fca3d05c64dd1713971de55a1164 100644 (file)
@@ -30,6 +30,7 @@ enum nftnl_set_attr {
        NFTNL_SET_OBJ_TYPE,
        NFTNL_SET_HANDLE,
        NFTNL_SET_DESC_CONCAT,
+       NFTNL_SET_EXPR,
        __NFTNL_SET_MAX
 };
 #define NFTNL_SET_MAX (__NFTNL_SET_MAX - 1)
index 8044041189b1c2bf7dd506737a79715a279c89d4..1d57bc3dce16ef1a59279f353bbfa37de31e910b 100644 (file)
@@ -24,6 +24,7 @@ enum nftnl_udata_set_types {
        NFTNL_UDATA_SET_MERGE_ELEMENTS,
        NFTNL_UDATA_SET_KEY_TYPEOF,
        NFTNL_UDATA_SET_DATA_TYPEOF,
+       NFTNL_UDATA_SET_EXPR,
        __NFTNL_UDATA_SET_MAX
 };
 #define NFTNL_UDATA_SET_MAX (__NFTNL_UDATA_SET_MAX - 1)
index 57e83e152bf3cf210ef6a120d7fab00edbf9980e..2d291f6eab6245d80ac94ebd7b03eb33fedf49ef 100644 (file)
@@ -342,6 +342,7 @@ enum nft_set_field_attributes {
  * @NFTA_SET_USERDATA: user data (NLA_BINARY)
  * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*)
  * @NFTA_SET_HANDLE: set handle (NLA_U64)
+ * @NFTA_SET_EXPR: set expression (NLA_NESTED: nft_expr_attributes)
  */
 enum nft_set_attributes {
        NFTA_SET_UNSPEC,
@@ -361,6 +362,7 @@ enum nft_set_attributes {
        NFTA_SET_PAD,
        NFTA_SET_OBJ_TYPE,
        NFTA_SET_HANDLE,
+       NFTA_SET_EXPR,
        __NFTA_SET_MAX
 };
 #define NFTA_SET_MAX           (__NFTA_SET_MAX - 1)
index 895ffdb48bdb6b1e1f546adeef42d36a8f4ef4bb..66ac129836de07bb5d769ee956d387f2ae9a5085 100644 (file)
@@ -33,6 +33,7 @@ struct nftnl_set {
        uint32_t                flags;
        uint32_t                gc_interval;
        uint64_t                timeout;
+       struct nftnl_expr       *expr;
 };
 
 struct nftnl_set_list;
index 651dcfa56022daf69b62a42ebff594ed9e9f9571..15fa29d5f02cd5fc202c6b3917fdc0f3ec7825eb 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -51,6 +51,8 @@ void nftnl_set_free(const struct nftnl_set *s)
                xfree(s->name);
        if (s->flags & (1 << NFTNL_SET_USERDATA))
                xfree(s->user.data);
+       if (s->flags & (1 << NFTNL_SET_EXPR))
+               nftnl_expr_free(s->expr);
 
        list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
                list_del(&elem->head);
@@ -96,6 +98,9 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
        case NFTNL_SET_USERDATA:
                xfree(s->user.data);
                break;
+       case NFTNL_SET_EXPR:
+               nftnl_expr_free(s->expr);
+               break;
        default:
                return;
        }
@@ -195,6 +200,12 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
                memcpy(s->user.data, data, data_len);
                s->user.len = data_len;
                break;
+       case NFTNL_SET_EXPR:
+               if (s->flags & (1 << NFTNL_SET_EXPR))
+                       nftnl_expr_free(s->expr);
+
+               s->expr = (void *)data;
+               break;
        }
        s->flags |= (1 << attr);
        return 0;
@@ -283,6 +294,8 @@ const void *nftnl_set_get_data(const struct nftnl_set *s, uint16_t attr,
        case NFTNL_SET_USERDATA:
                *data_len = s->user.len;
                return s->user.data;
+       case NFTNL_SET_EXPR:
+               return s->expr;
        }
        return NULL;
 }
@@ -432,6 +445,13 @@ void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
                mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
        if (s->flags & (1 << NFTNL_SET_USERDATA))
                mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
+       if (s->flags & (1 << NFTNL_SET_EXPR)) {
+               struct nlattr *nest1;
+
+               nest1 = mnl_attr_nest_start(nlh, NFTA_SET_EXPR);
+               nftnl_expr_build_payload(nlh, s->expr);
+               mnl_attr_nest_end(nlh, nest1);
+       }
 }
 
 
@@ -635,6 +655,13 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
                if (ret < 0)
                        return ret;
        }
+       if (tb[NFTA_SET_EXPR]) {
+               s->expr = nftnl_expr_parse(tb[NFTA_SET_EXPR]);
+               if (!s->expr)
+                       return -1;
+
+               s->flags |= (1 << NFTNL_SET_EXPR);
+       }
 
        s->family = nfg->nfgen_family;
        s->flags |= (1 << NFTNL_SET_FAMILY);