17 #include <arpa/inet.h>
19 #include <libmnl/libmnl.h>
20 #include <linux/netfilter/nf_tables.h>
21 #include <libnftnl/expr.h>
22 #include <libnftnl/rule.h>
25 enum nft_registers sreg;
26 enum nft_registers dreg;
27 enum nft_byteorder_ops op;
33 nftnl_expr_byteorder_set(
struct nftnl_expr *e, uint16_t type,
34 const void *data, uint32_t data_len)
39 case NFTNL_EXPR_BYTEORDER_SREG:
40 byteorder->sreg = *((uint32_t *)data);
42 case NFTNL_EXPR_BYTEORDER_DREG:
43 byteorder->dreg = *((uint32_t *)data);
45 case NFTNL_EXPR_BYTEORDER_OP:
46 byteorder->op = *((uint32_t *)data);
48 case NFTNL_EXPR_BYTEORDER_LEN:
49 byteorder->len = *((
unsigned int *)data);
51 case NFTNL_EXPR_BYTEORDER_SIZE:
52 byteorder->size = *((
unsigned int *)data);
61 nftnl_expr_byteorder_get(
const struct nftnl_expr *e, uint16_t type,
67 case NFTNL_EXPR_BYTEORDER_SREG:
68 *data_len =
sizeof(byteorder->sreg);
69 return &byteorder->sreg;
70 case NFTNL_EXPR_BYTEORDER_DREG:
71 *data_len =
sizeof(byteorder->dreg);
72 return &byteorder->dreg;
73 case NFTNL_EXPR_BYTEORDER_OP:
74 *data_len =
sizeof(byteorder->op);
75 return &byteorder->op;
76 case NFTNL_EXPR_BYTEORDER_LEN:
77 *data_len =
sizeof(byteorder->len);
78 return &byteorder->len;
79 case NFTNL_EXPR_BYTEORDER_SIZE:
80 *data_len =
sizeof(byteorder->size);
81 return &byteorder->size;
86 static int nftnl_expr_byteorder_cb(
const struct nlattr *attr,
void *data)
88 const struct nlattr **tb = data;
89 int type = mnl_attr_get_type(attr);
91 if (mnl_attr_type_valid(attr, NFTA_BYTEORDER_MAX) < 0)
95 case NFTA_BYTEORDER_SREG:
96 case NFTA_BYTEORDER_DREG:
97 case NFTA_BYTEORDER_OP:
98 case NFTA_BYTEORDER_LEN:
99 case NFTA_BYTEORDER_SIZE:
100 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
110 nftnl_expr_byteorder_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
114 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_SREG)) {
115 mnl_attr_put_u32(nlh, NFTA_BYTEORDER_SREG,
116 htonl(byteorder->sreg));
118 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_DREG)) {
119 mnl_attr_put_u32(nlh, NFTA_BYTEORDER_DREG,
120 htonl(byteorder->dreg));
122 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_OP)) {
123 mnl_attr_put_u32(nlh, NFTA_BYTEORDER_OP,
124 htonl(byteorder->op));
126 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_LEN)) {
127 mnl_attr_put_u32(nlh, NFTA_BYTEORDER_LEN,
128 htonl(byteorder->len));
130 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_SIZE)) {
131 mnl_attr_put_u32(nlh, NFTA_BYTEORDER_SIZE,
132 htonl(byteorder->size));
137 nftnl_expr_byteorder_parse(
struct nftnl_expr *e,
struct nlattr *attr)
140 struct nlattr *tb[NFTA_BYTEORDER_MAX+1] = {};
143 if (mnl_attr_parse_nested(attr, nftnl_expr_byteorder_cb, tb) < 0)
146 if (tb[NFTA_BYTEORDER_SREG]) {
148 ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_SREG]));
149 e->flags |= (1 << NFTNL_EXPR_BYTEORDER_SREG);
151 if (tb[NFTA_BYTEORDER_DREG]) {
153 ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_DREG]));
154 e->flags |= (1 << NFTNL_EXPR_BYTEORDER_DREG);
156 if (tb[NFTA_BYTEORDER_OP]) {
158 ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_OP]));
159 e->flags |= (1 << NFTNL_EXPR_BYTEORDER_OP);
161 if (tb[NFTA_BYTEORDER_LEN]) {
163 ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_LEN]));
164 e->flags |= (1 << NFTNL_EXPR_BYTEORDER_LEN);
166 if (tb[NFTA_BYTEORDER_SIZE]) {
168 ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_SIZE]));
169 e->flags |= (1 << NFTNL_EXPR_BYTEORDER_SIZE);
175 static char *expr_byteorder_str[] = {
176 [NFT_BYTEORDER_HTON] =
"hton",
177 [NFT_BYTEORDER_NTOH] =
"ntoh",
180 static const char *bo2str(uint32_t type)
182 if (type > NFT_BYTEORDER_HTON)
185 return expr_byteorder_str[type];
188 static inline int nftnl_str2ntoh(
const char *op)
190 if (strcmp(op,
"ntoh") == 0)
191 return NFT_BYTEORDER_NTOH;
192 else if (strcmp(op,
"hton") == 0)
193 return NFT_BYTEORDER_HTON;
201 nftnl_expr_byteorder_json_parse(
struct nftnl_expr *e, json_t *root,
202 struct nftnl_parse_err *err)
206 uint32_t sreg, dreg, len, size;
209 if (nftnl_jansson_parse_reg(root,
"sreg", NFTNL_TYPE_U32, &sreg, err) == 0)
210 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_SREG, sreg);
212 if (nftnl_jansson_parse_reg(root,
"dreg", NFTNL_TYPE_U32, &dreg, err) == 0)
213 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_DREG, dreg);
215 op = nftnl_jansson_parse_str(root,
"op", err);
217 ntoh = nftnl_str2ntoh(op);
221 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_OP, ntoh);
224 if (nftnl_jansson_parse_val(root,
"len", NFTNL_TYPE_U32, &len, err) == 0)
225 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_LEN, len);
227 if (nftnl_jansson_parse_val(root,
"size", NFTNL_TYPE_U32, &size, err) == 0)
228 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_SIZE, size);
238 nftnl_expr_byteorder_xml_parse(
struct nftnl_expr *e, mxml_node_t *tree,
239 struct nftnl_parse_err *err)
244 uint32_t sreg, dreg, len, size;
246 if (nftnl_mxml_reg_parse(tree,
"sreg", &sreg, MXML_DESCEND_FIRST,
247 NFTNL_XML_MAND, err) == 0)
248 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_SREG, sreg);
250 if (nftnl_mxml_reg_parse(tree,
"dreg", &dreg, MXML_DESCEND, NFTNL_XML_MAND,
252 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_DREG, dreg);
254 op = nftnl_mxml_str_parse(tree,
"op", MXML_DESCEND_FIRST, NFTNL_XML_MAND,
257 ntoh = nftnl_str2ntoh(op);
261 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_OP, ntoh);
264 if (nftnl_mxml_num_parse(tree,
"len", MXML_DESCEND_FIRST, BASE_DEC,
265 &len, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
266 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_LEN, len);
268 if (nftnl_mxml_num_parse(tree,
"size", MXML_DESCEND_FIRST, BASE_DEC,
269 &size, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
270 nftnl_expr_set_u32(e, NFTNL_EXPR_BYTEORDER_SIZE, size);
279 static int nftnl_expr_byteorder_export(
char *buf,
size_t size,
280 const struct nftnl_expr *e,
int type)
283 NFTNL_BUF_INIT(b, buf, size);
285 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_SREG))
286 nftnl_buf_u32(&b, type, byteorder->sreg, SREG);
287 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_DREG))
288 nftnl_buf_u32(&b, type, byteorder->dreg, DREG);
289 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_OP))
290 nftnl_buf_str(&b, type, bo2str(byteorder->op), OP);
291 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_LEN))
292 nftnl_buf_u32(&b, type, byteorder->len, LEN);
293 if (e->flags & (1 << NFTNL_EXPR_BYTEORDER_SIZE))
294 nftnl_buf_u32(&b, type, byteorder->size, SIZE);
296 return nftnl_buf_done(&b);
299 static int nftnl_expr_byteorder_snprintf_default(
char *buf,
size_t size,
300 const struct nftnl_expr *e)
303 int len = size, offset = 0, ret;
305 ret = snprintf(buf, len,
"reg %u = %s(reg %u, %u, %u) ",
306 byteorder->dreg, bo2str(byteorder->op),
307 byteorder->sreg, byteorder->size, byteorder->len);
308 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
314 nftnl_expr_byteorder_snprintf(
char *buf,
size_t size, uint32_t type,
315 uint32_t flags,
const struct nftnl_expr *e)
318 case NFTNL_OUTPUT_DEFAULT:
319 return nftnl_expr_byteorder_snprintf_default(buf, size, e);
320 case NFTNL_OUTPUT_XML:
321 case NFTNL_OUTPUT_JSON:
322 return nftnl_expr_byteorder_export(buf, size, e, type);
329 struct expr_ops expr_ops_byteorder = {
332 .max_attr = NFTA_BYTEORDER_MAX,
333 .set = nftnl_expr_byteorder_set,
334 .get = nftnl_expr_byteorder_get,
335 .parse = nftnl_expr_byteorder_parse,
336 .build = nftnl_expr_byteorder_build,
337 .snprintf = nftnl_expr_byteorder_snprintf,
338 .xml_parse = nftnl_expr_byteorder_xml_parse,
339 .json_parse = nftnl_expr_byteorder_json_parse,