12 #include <arpa/inet.h>
14 #include <libmnl/libmnl.h>
16 #include <linux/netfilter/nf_tables.h>
18 #include <libnftnl/expr.h>
19 #include <libnftnl/rule.h>
25 struct nftnl_expr *expr;
28 static void nftnl_expr_inner_free(
const struct nftnl_expr *e)
33 nftnl_expr_free(inner->expr);
37 nftnl_expr_inner_set(
struct nftnl_expr *e, uint16_t type,
38 const void *data, uint32_t data_len)
43 case NFTNL_EXPR_INNER_TYPE:
44 memcpy(&inner->type, data, data_len);
46 case NFTNL_EXPR_INNER_FLAGS:
47 memcpy(&inner->flags, data, data_len);
49 case NFTNL_EXPR_INNER_HDRSIZE:
50 memcpy(&inner->hdrsize, data, data_len);
52 case NFTNL_EXPR_INNER_EXPR:
54 nftnl_expr_free(inner->expr);
56 inner->expr = (
void *)data;
63 nftnl_expr_inner_get(
const struct nftnl_expr *e, uint16_t type,
69 case NFTNL_EXPR_INNER_FLAGS:
70 *data_len =
sizeof(inner->flags);
72 case NFTNL_EXPR_INNER_TYPE:
73 *data_len =
sizeof(inner->type);
75 case NFTNL_EXPR_INNER_HDRSIZE:
76 *data_len =
sizeof(inner->hdrsize);
77 return &inner->hdrsize;
78 case NFTNL_EXPR_INNER_EXPR:
85 nftnl_expr_inner_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
90 mnl_attr_put_u32(nlh, NFTA_INNER_NUM, htonl(0));
91 if (e->flags & (1 << NFTNL_EXPR_INNER_TYPE))
92 mnl_attr_put_u32(nlh, NFTA_INNER_TYPE, htonl(inner->type));
93 if (e->flags & (1 << NFTNL_EXPR_INNER_FLAGS))
94 mnl_attr_put_u32(nlh, NFTA_INNER_FLAGS, htonl(inner->flags));
95 if (e->flags & (1 << NFTNL_EXPR_INNER_HDRSIZE))
96 mnl_attr_put_u32(nlh, NFTA_INNER_HDRSIZE, htonl(inner->hdrsize));
97 if (e->flags & (1 << NFTNL_EXPR_INNER_EXPR)) {
98 nest = mnl_attr_nest_start(nlh, NFTA_INNER_EXPR);
99 nftnl_expr_build_payload(nlh, inner->expr);
100 mnl_attr_nest_end(nlh, nest);
104 static int nftnl_inner_parse_cb(
const struct nlattr *attr,
void *data)
106 const struct nlattr **tb = data;
107 int type = mnl_attr_get_type(attr);
109 if (mnl_attr_type_valid(attr, NFTA_INNER_MAX) < 0)
114 case NFTA_INNER_TYPE:
115 case NFTA_INNER_HDRSIZE:
116 case NFTA_INNER_FLAGS:
117 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
120 case NFTA_INNER_EXPR:
121 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
132 nftnl_expr_inner_parse(
struct nftnl_expr *e,
struct nlattr *attr)
135 struct nlattr *tb[NFTA_INNER_MAX + 1] = {};
136 struct nftnl_expr *expr;
139 err = mnl_attr_parse_nested(attr, nftnl_inner_parse_cb, tb);
143 if (tb[NFTA_INNER_HDRSIZE]) {
145 ntohl(mnl_attr_get_u32(tb[NFTA_INNER_HDRSIZE]));
146 e->flags |= (1 << NFTNL_EXPR_INNER_HDRSIZE);
148 if (tb[NFTA_INNER_FLAGS]) {
150 ntohl(mnl_attr_get_u32(tb[NFTA_INNER_FLAGS]));
151 e->flags |= (1 << NFTNL_EXPR_INNER_FLAGS);
153 if (tb[NFTA_INNER_TYPE]) {
155 ntohl(mnl_attr_get_u32(tb[NFTA_INNER_TYPE]));
156 e->flags |= (1 << NFTNL_EXPR_INNER_TYPE);
158 if (tb[NFTA_INNER_EXPR]) {
159 expr = nftnl_expr_parse(tb[NFTA_INNER_EXPR]);
164 nftnl_expr_free(inner->expr);
167 e->flags |= (1 << NFTNL_EXPR_INNER_EXPR);
174 nftnl_expr_inner_snprintf(
char *buf,
size_t remain, uint32_t flags,
175 const struct nftnl_expr *e)
181 ret = snprintf(buf, remain,
"type %u hdrsize %u flags %x [",
182 inner->type, inner->hdrsize, inner->flags);
183 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
185 ret = snprintf(buf + offset, remain,
" %s ", inner->expr->ops->name);
186 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
188 ret = nftnl_expr_snprintf(buf + offset, remain, inner->expr,
189 NFTNL_OUTPUT_DEFAULT, 0);
190 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
192 ret = snprintf(buf + offset, remain,
"] ");
193 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
198 static struct attr_policy inner_attr_policy[__NFTNL_EXPR_INNER_MAX] = {
199 [NFTNL_EXPR_INNER_TYPE] = { .maxlen =
sizeof(uint32_t) },
200 [NFTNL_EXPR_INNER_FLAGS] = { .maxlen =
sizeof(uint32_t) },
201 [NFTNL_EXPR_INNER_HDRSIZE] = { .maxlen =
sizeof(uint32_t) },
202 [NFTNL_EXPR_INNER_EXPR] = { .maxlen = 0 },
205 struct expr_ops expr_ops_inner = {
208 .nftnl_max_attr = __NFTNL_EXPR_INNER_MAX - 1,
209 .attr_policy = inner_attr_policy,
210 .free = nftnl_expr_inner_free,
211 .set = nftnl_expr_inner_set,
212 .get = nftnl_expr_inner_get,
213 .parse = nftnl_expr_inner_parse,
214 .build = nftnl_expr_inner_build,
215 .output = nftnl_expr_inner_snprintf,