@@ -105,6 +105,7 @@ struct obj_ops {
uint32_t type;
size_t alloc_len;
int nftnl_max_attr;
+ struct attr_policy *attr_policy;
int (*set)(struct nftnl_obj *e, uint16_t type, const void *data, uint32_t data_len);
const void *(*get)(const struct nftnl_obj *e, uint16_t type, uint32_t *data_len);
int (*parse)(struct nftnl_obj *e, struct nlattr *attr);
@@ -116,11 +116,17 @@ static int nftnl_obj_counter_snprintf(char *buf, size_t len, uint32_t flags,
ctr->pkts, ctr->bytes);
}
+static struct attr_policy obj_ctr_attr_policy[__NFTNL_OBJ_CTR_MAX] = {
+ [NFTNL_OBJ_CTR_BYTES] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_CTR_PKTS] = { .maxlen = sizeof(uint64_t) },
+};
+
struct obj_ops obj_ops_counter = {
.name = "counter",
.type = NFT_OBJECT_COUNTER,
.alloc_len = sizeof(struct nftnl_obj_counter),
.nftnl_max_attr = __NFTNL_OBJ_CTR_MAX - 1,
+ .attr_policy = obj_ctr_attr_policy,
.set = nftnl_obj_counter_set,
.get = nftnl_obj_counter_get,
.parse = nftnl_obj_counter_parse,
@@ -185,11 +185,21 @@ static int nftnl_obj_ct_expect_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy
+obj_ct_expect_attr_policy[__NFTNL_OBJ_CT_EXPECT_MAX] = {
+ [NFTNL_OBJ_CT_EXPECT_L3PROTO] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_EXPECT_L4PROTO] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_CT_EXPECT_DPORT] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_EXPECT_TIMEOUT] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_CT_EXPECT_SIZE] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_ct_expect = {
.name = "ct_expect",
.type = NFT_OBJECT_CT_EXPECT,
.alloc_len = sizeof(struct nftnl_obj_ct_expect),
.nftnl_max_attr = __NFTNL_OBJ_CT_EXPECT_MAX - 1,
+ .attr_policy = obj_ct_expect_attr_policy,
.set = nftnl_obj_ct_expect_set,
.get = nftnl_obj_ct_expect_get,
.parse = nftnl_obj_ct_expect_parse,
@@ -139,11 +139,22 @@ static int nftnl_obj_ct_helper_snprintf(char *buf, size_t len,
helper->name, helper->l3proto, helper->l4proto);
}
+/* from kernel's include/net/netfilter/nf_conntrack_helper.h */
+#define NF_CT_HELPER_NAME_LEN 16
+
+static struct attr_policy
+obj_ct_helper_attr_policy[__NFTNL_OBJ_CT_HELPER_MAX] = {
+ [NFTNL_OBJ_CT_HELPER_NAME] = { .maxlen = NF_CT_HELPER_NAME_LEN },
+ [NFTNL_OBJ_CT_HELPER_L3PROTO] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_HELPER_L4PROTO] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_ct_helper = {
.name = "ct_helper",
.type = NFT_OBJECT_CT_HELPER,
.alloc_len = sizeof(struct nftnl_obj_ct_helper),
.nftnl_max_attr = __NFTNL_OBJ_CT_HELPER_MAX - 1,
+ .attr_policy = obj_ct_helper_attr_policy,
.set = nftnl_obj_ct_helper_set,
.get = nftnl_obj_ct_helper_get,
.parse = nftnl_obj_ct_helper_parse,
@@ -308,11 +308,18 @@ static int nftnl_obj_ct_timeout_snprintf(char *buf, size_t remain,
return offset;
}
+static struct attr_policy
+obj_ct_timeout_attr_policy[__NFTNL_OBJ_CT_TIMEOUT_MAX] = {
+ [NFTNL_OBJ_CT_TIMEOUT_L3PROTO] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_CT_TIMEOUT_L4PROTO] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_ct_timeout = {
.name = "ct_timeout",
.type = NFT_OBJECT_CT_TIMEOUT,
.alloc_len = sizeof(struct nftnl_obj_ct_timeout),
.nftnl_max_attr = __NFTNL_OBJ_CT_TIMEOUT_MAX - 1,
+ .attr_policy = obj_ct_timeout_attr_policy,
.set = nftnl_obj_ct_timeout_set,
.get = nftnl_obj_ct_timeout_get,
.parse = nftnl_obj_ct_timeout_parse,
@@ -157,11 +157,20 @@ static int nftnl_obj_limit_snprintf(char *buf, size_t len,
limit->burst, limit->type, limit->flags);
}
+static struct attr_policy obj_limit_attr_policy[__NFTNL_OBJ_LIMIT_MAX] = {
+ [NFTNL_OBJ_LIMIT_RATE] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_LIMIT_UNIT] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_LIMIT_BURST] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_LIMIT_TYPE] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_LIMIT_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct obj_ops obj_ops_limit = {
.name = "limit",
.type = NFT_OBJECT_LIMIT,
.alloc_len = sizeof(struct nftnl_obj_limit),
.nftnl_max_attr = __NFTNL_OBJ_LIMIT_MAX - 1,
+ .attr_policy = obj_limit_attr_policy,
.set = nftnl_obj_limit_set,
.get = nftnl_obj_limit_get,
.parse = nftnl_obj_limit_parse,
@@ -133,11 +133,18 @@ static int nftnl_obj_quota_snprintf(char *buf, size_t len,
quota->bytes, quota->flags);
}
+static struct attr_policy obj_quota_attr_policy[__NFTNL_OBJ_QUOTA_MAX] = {
+ [NFTNL_OBJ_QUOTA_BYTES] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_QUOTA_CONSUMED] = { .maxlen = sizeof(uint64_t) },
+ [NFTNL_OBJ_QUOTA_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct obj_ops obj_ops_quota = {
.name = "quota",
.type = NFT_OBJECT_QUOTA,
.alloc_len = sizeof(struct nftnl_obj_quota),
.nftnl_max_attr = __NFTNL_OBJ_QUOTA_MAX - 1,
+ .attr_policy = obj_quota_attr_policy,
.set = nftnl_obj_quota_set,
.get = nftnl_obj_quota_get,
.parse = nftnl_obj_quota_parse,
@@ -105,11 +105,16 @@ static int nftnl_obj_secmark_snprintf(char *buf, size_t len,
return snprintf(buf, len, "context %s ", secmark->ctx);
}
+static struct attr_policy obj_secmark_attr_policy[__NFTNL_OBJ_SECMARK_MAX] = {
+ [NFTNL_OBJ_SECMARK_CTX] = { .maxlen = NFT_SECMARK_CTX_MAXLEN },
+};
+
struct obj_ops obj_ops_secmark = {
.name = "secmark",
.type = NFT_OBJECT_SECMARK,
.alloc_len = sizeof(struct nftnl_obj_secmark),
.nftnl_max_attr = __NFTNL_OBJ_SECMARK_MAX - 1,
+ .attr_policy = obj_secmark_attr_policy,
.set = nftnl_obj_secmark_set,
.get = nftnl_obj_secmark_get,
.parse = nftnl_obj_secmark_parse,
@@ -132,11 +132,18 @@ static int nftnl_obj_synproxy_snprintf(char *buf, size_t len,
return offset;
}
+static struct attr_policy obj_synproxy_attr_policy[__NFTNL_OBJ_SYNPROXY_MAX] = {
+ [NFTNL_OBJ_SYNPROXY_MSS] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_SYNPROXY_WSCALE] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_SYNPROXY_FLAGS] = { .maxlen = sizeof(uint32_t) },
+};
+
struct obj_ops obj_ops_synproxy = {
.name = "synproxy",
.type = NFT_OBJECT_SYNPROXY,
.alloc_len = sizeof(struct nftnl_obj_synproxy),
.nftnl_max_attr = __NFTNL_OBJ_SYNPROXY_MAX - 1,
+ .attr_policy = obj_synproxy_attr_policy,
.set = nftnl_obj_synproxy_set,
.get = nftnl_obj_synproxy_get,
.parse = nftnl_obj_synproxy_parse,
@@ -536,11 +536,31 @@ static int nftnl_obj_tunnel_snprintf(char *buf, size_t len,
return snprintf(buf, len, "id %u ", tun->id);
}
+static struct attr_policy obj_tunnel_attr_policy[__NFTNL_OBJ_TUNNEL_MAX] = {
+ [NFTNL_OBJ_TUNNEL_ID] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_IPV4_SRC] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_IPV4_DST] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_IPV6_SRC] = { .maxlen = sizeof(struct in6_addr) },
+ [NFTNL_OBJ_TUNNEL_IPV6_DST] = { .maxlen = sizeof(struct in6_addr) },
+ [NFTNL_OBJ_TUNNEL_IPV6_FLOWLABEL] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_SPORT] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_TUNNEL_DPORT] = { .maxlen = sizeof(uint16_t) },
+ [NFTNL_OBJ_TUNNEL_FLAGS] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_TOS] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_TUNNEL_TTL] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_TUNNEL_VXLAN_GBP] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_VERSION] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_V1_INDEX] = { .maxlen = sizeof(uint32_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_V2_HWID] = { .maxlen = sizeof(uint8_t) },
+ [NFTNL_OBJ_TUNNEL_ERSPAN_V2_DIR] = { .maxlen = sizeof(uint8_t) },
+};
+
struct obj_ops obj_ops_tunnel = {
.name = "tunnel",
.type = NFT_OBJECT_TUNNEL,
.alloc_len = sizeof(struct nftnl_obj_tunnel),
.nftnl_max_attr = __NFTNL_OBJ_TUNNEL_MAX - 1,
+ .attr_policy = obj_tunnel_attr_policy,
.set = nftnl_obj_tunnel_set,
.get = nftnl_obj_tunnel_get,
.parse = nftnl_obj_tunnel_parse,
Just like with struct expr_ops::attr_policy, enable object types to inform about restrictions on attribute use. This way generic object code may perform sanity checks before dispatching to object ops. Signed-off-by: Phil Sutter <phil@nwl.cc> --- include/obj.h | 1 + src/obj/counter.c | 6 ++++++ src/obj/ct_expect.c | 10 ++++++++++ src/obj/ct_helper.c | 11 +++++++++++ src/obj/ct_timeout.c | 7 +++++++ src/obj/limit.c | 9 +++++++++ src/obj/quota.c | 7 +++++++ src/obj/secmark.c | 5 +++++ src/obj/synproxy.c | 7 +++++++ src/obj/tunnel.c | 20 ++++++++++++++++++++ 10 files changed, 83 insertions(+)