libnftnl 1.2.9
obj/quota.c
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * (C) 2012-2016 by Pablo Neira Ayuso <pablo@netfilter.org>
4 */
5
6#include <stdio.h>
7#include <stdint.h>
8#include <arpa/inet.h>
9#include <errno.h>
10#include <inttypes.h>
11
12#include <linux/netfilter/nf_tables.h>
13
14#include "internal.h"
15#include <libmnl/libmnl.h>
16#include <libnftnl/object.h>
17
18#include "obj.h"
19
20static int nftnl_obj_quota_set(struct nftnl_obj *e, uint16_t type,
21 const void *data, uint32_t data_len)
22{
23 struct nftnl_obj_quota *quota = nftnl_obj_data(e);
24
25 switch (type) {
26 case NFTNL_OBJ_QUOTA_BYTES:
27 memcpy(&quota->bytes, data, data_len);
28 break;
29 case NFTNL_OBJ_QUOTA_CONSUMED:
30 memcpy(&quota->consumed, data, data_len);
31 break;
32 case NFTNL_OBJ_QUOTA_FLAGS:
33 memcpy(&quota->flags, data, data_len);
34 break;
35 }
36 return 0;
37}
38
39static const void *nftnl_obj_quota_get(const struct nftnl_obj *e,
40 uint16_t type, uint32_t *data_len)
41{
42 struct nftnl_obj_quota *quota = nftnl_obj_data(e);
43
44 switch (type) {
45 case NFTNL_OBJ_QUOTA_BYTES:
46 *data_len = sizeof(quota->bytes);
47 return &quota->bytes;
48 case NFTNL_OBJ_QUOTA_CONSUMED:
49 *data_len = sizeof(quota->consumed);
50 return &quota->consumed;
51 case NFTNL_OBJ_QUOTA_FLAGS:
52 *data_len = sizeof(quota->flags);
53 return &quota->flags;
54 }
55 return NULL;
56}
57
58static int nftnl_obj_quota_cb(const struct nlattr *attr, void *data)
59{
60 int type = mnl_attr_get_type(attr);
61 const struct nlattr **tb = data;
62
63 if (mnl_attr_type_valid(attr, NFTA_QUOTA_MAX) < 0)
64 return MNL_CB_OK;
65
66 switch(type) {
67 case NFTA_QUOTA_BYTES:
68 case NFTA_QUOTA_CONSUMED:
69 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
70 abi_breakage();
71 break;
72 case NFTA_QUOTA_FLAGS:
73 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
74 abi_breakage();
75 break;
76 }
77
78 tb[type] = attr;
79 return MNL_CB_OK;
80}
81
82static void
83nftnl_obj_quota_build(struct nlmsghdr *nlh, const struct nftnl_obj *e)
84{
85 struct nftnl_obj_quota *quota = nftnl_obj_data(e);
86
87 if (e->flags & (1 << NFTNL_OBJ_QUOTA_BYTES))
88 mnl_attr_put_u64(nlh, NFTA_QUOTA_BYTES, htobe64(quota->bytes));
89 if (e->flags & (1 << NFTNL_OBJ_QUOTA_CONSUMED))
90 mnl_attr_put_u64(nlh, NFTA_QUOTA_CONSUMED,
91 htobe64(quota->consumed));
92 if (e->flags & (1 << NFTNL_OBJ_QUOTA_FLAGS))
93 mnl_attr_put_u32(nlh, NFTA_QUOTA_FLAGS, htonl(quota->flags));
94}
95
96static int
97nftnl_obj_quota_parse(struct nftnl_obj *e, struct nlattr *attr)
98{
99 struct nftnl_obj_quota *quota = nftnl_obj_data(e);
100 struct nlattr *tb[NFTA_QUOTA_MAX + 1] = {};
101
102 if (mnl_attr_parse_nested(attr, nftnl_obj_quota_cb, tb) < 0)
103 return -1;
104
105 if (tb[NFTA_QUOTA_BYTES]) {
106 quota->bytes = be64toh(mnl_attr_get_u64(tb[NFTA_QUOTA_BYTES]));
107 e->flags |= (1 << NFTNL_OBJ_QUOTA_BYTES);
108 }
109 if (tb[NFTA_QUOTA_CONSUMED]) {
110 quota->consumed =
111 be64toh(mnl_attr_get_u64(tb[NFTA_QUOTA_CONSUMED]));
112 e->flags |= (1 << NFTNL_OBJ_QUOTA_CONSUMED);
113 }
114 if (tb[NFTA_QUOTA_FLAGS]) {
115 quota->flags = ntohl(mnl_attr_get_u32(tb[NFTA_QUOTA_FLAGS]));
116 e->flags |= (1 << NFTNL_OBJ_QUOTA_FLAGS);
117 }
118
119 return 0;
120}
121
122static int nftnl_obj_quota_snprintf(char *buf, size_t len,
123 uint32_t flags,
124 const struct nftnl_obj *e)
125{
126 struct nftnl_obj_quota *quota = nftnl_obj_data(e);
127
128 return snprintf(buf, len, "bytes %"PRIu64" flags %u ",
129 quota->bytes, quota->flags);
130}
131
132static struct attr_policy obj_quota_attr_policy[__NFTNL_OBJ_QUOTA_MAX] = {
133 [NFTNL_OBJ_QUOTA_BYTES] = { .maxlen = sizeof(uint64_t) },
134 [NFTNL_OBJ_QUOTA_CONSUMED] = { .maxlen = sizeof(uint64_t) },
135 [NFTNL_OBJ_QUOTA_FLAGS] = { .maxlen = sizeof(uint32_t) },
136};
137
138struct obj_ops obj_ops_quota = {
139 .name = "quota",
140 .type = NFT_OBJECT_QUOTA,
141 .alloc_len = sizeof(struct nftnl_obj_quota),
142 .nftnl_max_attr = __NFTNL_OBJ_QUOTA_MAX - 1,
143 .attr_policy = obj_quota_attr_policy,
144 .set = nftnl_obj_quota_set,
145 .get = nftnl_obj_quota_get,
146 .parse = nftnl_obj_quota_parse,
147 .build = nftnl_obj_quota_build,
148 .output = nftnl_obj_quota_snprintf,
149};