14#include <libmnl/libmnl.h>
15#include <linux/netfilter/nf_tables.h>
16#include <libnftnl/expr.h>
17#include <libnftnl/rule.h>
20 union nftnl_data_reg data_from;
21 union nftnl_data_reg data_to;
22 enum nft_registers sreg;
23 enum nft_range_ops op;
26static int nftnl_expr_range_set(
struct nftnl_expr *e, uint16_t type,
27 const void *data, uint32_t data_len)
32 case NFTNL_EXPR_RANGE_SREG:
33 memcpy(&range->sreg, data, data_len);
35 case NFTNL_EXPR_RANGE_OP:
36 memcpy(&range->op, data, data_len);
38 case NFTNL_EXPR_RANGE_FROM_DATA:
39 return nftnl_data_cpy(&range->data_from, data, data_len);
40 case NFTNL_EXPR_RANGE_TO_DATA:
41 return nftnl_data_cpy(&range->data_to, data, data_len);
46static const void *nftnl_expr_range_get(
const struct nftnl_expr *e,
47 uint16_t type, uint32_t *data_len)
52 case NFTNL_EXPR_RANGE_SREG:
53 *data_len =
sizeof(range->sreg);
55 case NFTNL_EXPR_RANGE_OP:
56 *data_len =
sizeof(range->op);
58 case NFTNL_EXPR_RANGE_FROM_DATA:
59 *data_len = range->data_from.len;
60 return &range->data_from.val;
61 case NFTNL_EXPR_RANGE_TO_DATA:
62 *data_len = range->data_to.len;
63 return &range->data_to.val;
68static int nftnl_expr_range_cb(
const struct nlattr *attr,
void *data)
70 const struct nlattr **tb = data;
71 int type = mnl_attr_get_type(attr);
73 if (mnl_attr_type_valid(attr, NFTA_RANGE_MAX) < 0)
79 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
82 case NFTA_RANGE_FROM_DATA:
83 case NFTA_RANGE_TO_DATA:
84 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
94nftnl_expr_range_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
98 if (e->flags & (1 << NFTNL_EXPR_RANGE_SREG))
99 mnl_attr_put_u32(nlh, NFTA_RANGE_SREG, htonl(range->sreg));
100 if (e->flags & (1 << NFTNL_EXPR_RANGE_OP))
101 mnl_attr_put_u32(nlh, NFTA_RANGE_OP, htonl(range->op));
102 if (e->flags & (1 << NFTNL_EXPR_RANGE_FROM_DATA)) {
105 nest = mnl_attr_nest_start(nlh, NFTA_RANGE_FROM_DATA);
106 mnl_attr_put(nlh, NFTA_DATA_VALUE, range->data_from.len,
107 range->data_from.val);
108 mnl_attr_nest_end(nlh, nest);
110 if (e->flags & (1 << NFTNL_EXPR_RANGE_TO_DATA)) {
113 nest = mnl_attr_nest_start(nlh, NFTA_RANGE_TO_DATA);
114 mnl_attr_put(nlh, NFTA_DATA_VALUE, range->data_to.len,
116 mnl_attr_nest_end(nlh, nest);
121nftnl_expr_range_parse(
struct nftnl_expr *e,
struct nlattr *attr)
124 struct nlattr *tb[NFTA_RANGE_MAX+1] = {};
127 if (mnl_attr_parse_nested(attr, nftnl_expr_range_cb, tb) < 0)
130 if (tb[NFTA_RANGE_SREG]) {
131 range->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_RANGE_SREG]));
132 e->flags |= (1 << NFTA_RANGE_SREG);
134 if (tb[NFTA_RANGE_OP]) {
135 range->op = ntohl(mnl_attr_get_u32(tb[NFTA_RANGE_OP]));
136 e->flags |= (1 << NFTA_RANGE_OP);
138 if (tb[NFTA_RANGE_FROM_DATA]) {
139 ret = nftnl_parse_data(&range->data_from,
140 tb[NFTA_RANGE_FROM_DATA], NULL);
141 e->flags |= (1 << NFTA_RANGE_FROM_DATA);
143 if (tb[NFTA_RANGE_TO_DATA]) {
144 ret = nftnl_parse_data(&range->data_to,
145 tb[NFTA_RANGE_TO_DATA], NULL);
146 e->flags |= (1 << NFTA_RANGE_TO_DATA);
152static const char *expr_range_str[] = {
153 [NFT_RANGE_EQ] =
"eq",
154 [NFT_RANGE_NEQ] =
"neq",
157static const char *range2str(uint32_t op)
159 if (op > NFT_RANGE_NEQ)
162 return expr_range_str[op];
165static int nftnl_expr_range_snprintf(
char *buf,
size_t remain,
166 uint32_t flags,
const struct nftnl_expr *e)
171 ret = snprintf(buf, remain,
"%s reg %u ",
172 range2str(range->op), range->sreg);
173 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
175 ret = nftnl_data_reg_snprintf(buf + offset, remain, &range->data_from,
177 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
179 ret = nftnl_data_reg_snprintf(buf + offset, remain, &range->data_to,
181 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
186static struct attr_policy range_attr_policy[__NFTNL_EXPR_RANGE_MAX] = {
187 [NFTNL_EXPR_RANGE_SREG] = { .maxlen =
sizeof(uint32_t) },
188 [NFTNL_EXPR_RANGE_OP] = { .maxlen =
sizeof(uint32_t) },
189 [NFTNL_EXPR_RANGE_FROM_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
190 [NFTNL_EXPR_RANGE_TO_DATA] = { .maxlen = NFT_DATA_VALUE_MAXLEN },
193struct expr_ops expr_ops_range = {
196 .nftnl_max_attr = __NFTNL_EXPR_RANGE_MAX - 1,
197 .attr_policy = range_attr_policy,
198 .set = nftnl_expr_range_set,
199 .get = nftnl_expr_range_get,
200 .parse = nftnl_expr_range_parse,
201 .build = nftnl_expr_range_build,
202 .output = nftnl_expr_range_snprintf,