summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libnftnl/object.h1
-rw-r--r--include/libnftnl/udata.h6
-rw-r--r--include/linux/netfilter/nf_tables.h2
-rw-r--r--include/obj.h5
-rw-r--r--src/libnftnl.map4
-rw-r--r--src/object.c26
6 files changed, 44 insertions, 0 deletions
diff --git a/include/libnftnl/object.h b/include/libnftnl/object.h
index 4c23774..9bd83a5 100644
--- a/include/libnftnl/object.h
+++ b/include/libnftnl/object.h
@@ -19,6 +19,7 @@ enum {
NFTNL_OBJ_FAMILY,
NFTNL_OBJ_USE,
NFTNL_OBJ_HANDLE,
+ NFTNL_OBJ_USERDATA,
NFTNL_OBJ_BASE = 16,
__NFTNL_OBJ_MAX
};
diff --git a/include/libnftnl/udata.h b/include/libnftnl/udata.h
index ba6b3ab..2e38fcc 100644
--- a/include/libnftnl/udata.h
+++ b/include/libnftnl/udata.h
@@ -22,6 +22,12 @@ enum nftnl_udata_rule_types {
};
#define NFTNL_UDATA_RULE_MAX (__NFTNL_UDATA_RULE_MAX - 1)
+enum nftnl_udata_obj_types {
+ NFTNL_UDATA_OBJ_COMMENT,
+ __NFTNL_UDATA_OBJ_MAX
+};
+#define NFTNL_UDATA_OBJ_MAX (__NFTNL_UDATA_OBJ_MAX - 1)
+
#define NFTNL_UDATA_COMMENT_MAXLEN 128
enum nftnl_udata_set_types {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index d508154..8099777 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1542,6 +1542,7 @@ enum nft_ct_expectation_attributes {
* @NFTA_OBJ_DATA: stateful object data (NLA_NESTED)
* @NFTA_OBJ_USE: number of references to this expression (NLA_U32)
* @NFTA_OBJ_HANDLE: object handle (NLA_U64)
+ * @NFTA_OBJ_USERDATA: user data (NLA_BINARY)
*/
enum nft_object_attributes {
NFTA_OBJ_UNSPEC,
@@ -1552,6 +1553,7 @@ enum nft_object_attributes {
NFTA_OBJ_USE,
NFTA_OBJ_HANDLE,
NFTA_OBJ_PAD,
+ NFTA_OBJ_USERDATA,
__NFTA_OBJ_MAX
};
#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
diff --git a/include/obj.h b/include/obj.h
index 10f806c..d9e856a 100644
--- a/include/obj.h
+++ b/include/obj.h
@@ -22,6 +22,11 @@ struct nftnl_obj {
uint32_t flags;
uint64_t handle;
+ struct {
+ void *data;
+ uint32_t len;
+ } user;
+
union {
struct nftnl_obj_counter {
uint64_t pkts;
diff --git a/src/libnftnl.map b/src/libnftnl.map
index 6042479..ceafa3f 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -368,3 +368,7 @@ LIBNFTNL_14 {
nftnl_flowtable_set_array;
nftnl_flowtable_get_array;
} LIBNFTNL_13;
+
+LIBNFTNL_15 {
+ nftnl_obj_get_data;
+} LIBNFTNL_14;
diff --git a/src/object.c b/src/object.c
index 4f58272..008bade 100644
--- a/src/object.c
+++ b/src/object.c
@@ -57,6 +57,8 @@ void nftnl_obj_free(const struct nftnl_obj *obj)
xfree(obj->table);
if (obj->flags & (1 << NFTNL_OBJ_NAME))
xfree(obj->name);
+ if (obj->flags & (1 << NFTNL_OBJ_USERDATA))
+ xfree(obj->user.data);
xfree(obj);
}
@@ -103,6 +105,16 @@ void nftnl_obj_set_data(struct nftnl_obj *obj, uint16_t attr,
case NFTNL_OBJ_HANDLE:
memcpy(&obj->handle, data, sizeof(obj->handle));
break;
+ case NFTNL_OBJ_USERDATA:
+ if (obj->flags & (1 << NFTNL_OBJ_USERDATA))
+ xfree(obj->user.data);
+
+ obj->user.data = malloc(data_len);
+ if (!obj->user.data)
+ return;
+ memcpy(obj->user.data, data, data_len);
+ obj->user.len = data_len;
+ break;
default:
if (obj->ops)
obj->ops->set(obj, attr, data, data_len);
@@ -174,6 +186,9 @@ const void *nftnl_obj_get_data(struct nftnl_obj *obj, uint16_t attr,
case NFTNL_OBJ_HANDLE:
*data_len = sizeof(uint64_t);
return &obj->handle;
+ case NFTNL_OBJ_USERDATA:
+ *data_len = obj->user.len;
+ return obj->user.data;
default:
if (obj->ops)
return obj->ops->get(obj, attr, data_len);
@@ -235,6 +250,8 @@ void nftnl_obj_nlmsg_build_payload(struct nlmsghdr *nlh,
mnl_attr_put_u32(nlh, NFTA_OBJ_TYPE, htonl(obj->ops->type));
if (obj->flags & (1 << NFTNL_OBJ_HANDLE))
mnl_attr_put_u64(nlh, NFTA_OBJ_HANDLE, htobe64(obj->handle));
+ if (obj->flags & (1 << NFTNL_OBJ_USERDATA))
+ mnl_attr_put(nlh, NFTA_OBJ_USERDATA, obj->user.len, obj->user.data);
if (obj->ops) {
struct nlattr *nest = mnl_attr_nest_start(nlh, NFTA_OBJ_DATA);
@@ -269,6 +286,10 @@ static int nftnl_obj_parse_attr_cb(const struct nlattr *attr, void *data)
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+ case NFTA_OBJ_USERDATA:
+ if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
+ abi_breakage();
+ break;
}
tb[type] = attr;
@@ -315,6 +336,11 @@ int nftnl_obj_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_obj *obj)
obj->handle = be64toh(mnl_attr_get_u64(tb[NFTA_OBJ_HANDLE]));
obj->flags |= (1 << NFTNL_OBJ_HANDLE);
}
+ if (tb[NFTA_OBJ_USERDATA]) {
+ nftnl_obj_set_data(obj, NFTNL_OBJ_USERDATA,
+ mnl_attr_get_payload(tb[NFTA_OBJ_USERDATA]),
+ mnl_attr_get_payload_len(tb[NFTA_OBJ_USERDATA]));
+ }
obj->family = nfg->nfgen_family;
obj->flags |= (1 << NFTNL_OBJ_FAMILY);