17 #include <arpa/inet.h>
19 #include <libmnl/libmnl.h>
20 #include <linux/netfilter/nf_tables.h>
21 #include <libnftnl/rule.h>
22 #include <libnftnl/expr.h>
31 enum nft_registers sreg;
32 enum nft_registers dreg;
33 char set_name[IFNAMSIZ];
38 nft_rule_expr_lookup_set(
struct nft_rule_expr *e, uint16_t type,
39 const void *data, uint32_t data_len)
44 case NFT_EXPR_LOOKUP_SREG:
45 lookup->sreg = *((uint32_t *)data);
47 case NFT_EXPR_LOOKUP_DREG:
48 lookup->dreg = *((uint32_t *)data);
50 case NFT_EXPR_LOOKUP_SET:
51 snprintf(lookup->set_name,
sizeof(lookup->set_name),
"%s",
54 case NFT_EXPR_LOOKUP_SET_ID:
55 lookup->set_id = *((uint32_t *)data);
64 nft_rule_expr_lookup_get(
const struct nft_rule_expr *e, uint16_t type,
70 case NFT_EXPR_LOOKUP_SREG:
71 *data_len =
sizeof(lookup->sreg);
73 case NFT_EXPR_LOOKUP_DREG:
74 *data_len =
sizeof(lookup->dreg);
76 case NFT_EXPR_LOOKUP_SET:
77 return lookup->set_name;
78 case NFT_EXPR_LOOKUP_SET_ID:
79 return &lookup->set_id;
84 static int nft_rule_expr_lookup_cb(
const struct nlattr *attr,
void *data)
86 const struct nlattr **tb = data;
87 int type = mnl_attr_get_type(attr);
89 if (mnl_attr_type_valid(attr, NFTA_LOOKUP_MAX) < 0)
93 case NFTA_LOOKUP_SREG:
94 case NFTA_LOOKUP_DREG:
95 case NFTA_LOOKUP_SET_ID:
96 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
97 perror(
"mnl_attr_validate");
101 case NFTA_LOOKUP_SET:
102 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
103 perror(
"mnl_attr_validate");
114 nft_rule_expr_lookup_build(
struct nlmsghdr *nlh,
struct nft_rule_expr *e)
118 if (e->flags & (1 << NFT_EXPR_LOOKUP_SREG))
119 mnl_attr_put_u32(nlh, NFTA_LOOKUP_SREG, htonl(lookup->sreg));
120 if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG))
121 mnl_attr_put_u32(nlh, NFTA_LOOKUP_DREG, htonl(lookup->dreg));
122 if (e->flags & (1 << NFT_EXPR_LOOKUP_SET))
123 mnl_attr_put_strz(nlh, NFTA_LOOKUP_SET, lookup->set_name);
124 if (e->flags & (1 << NFT_EXPR_LOOKUP_SET_ID)) {
125 mnl_attr_put_u32(nlh, NFTA_LOOKUP_SET_ID,
126 htonl(lookup->set_id));
131 nft_rule_expr_lookup_parse(
struct nft_rule_expr *e,
struct nlattr *attr)
134 struct nlattr *tb[NFTA_LOOKUP_MAX+1] = {};
137 if (mnl_attr_parse_nested(attr, nft_rule_expr_lookup_cb, tb) < 0)
140 if (tb[NFTA_LOOKUP_SREG]) {
141 lookup->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SREG]));
142 e->flags |= (1 << NFT_EXPR_LOOKUP_SREG);
144 if (tb[NFTA_LOOKUP_DREG]) {
145 lookup->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_DREG]));
146 e->flags |= (1 << NFT_EXPR_LOOKUP_DREG);
148 if (tb[NFTA_LOOKUP_SET]) {
149 strcpy(lookup->set_name, mnl_attr_get_str(tb[NFTA_LOOKUP_SET]));
150 e->flags |= (1 << NFT_EXPR_LOOKUP_SET);
152 if (tb[NFTA_LOOKUP_SET_ID]) {
154 ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID]));
155 e->flags |= (1 << NFT_EXPR_LOOKUP_SET_ID);
162 nft_rule_expr_lookup_json_parse(
struct nft_rule_expr *e, json_t *root,
163 struct nft_parse_err *err)
166 const char *set_name;
169 set_name = nft_jansson_parse_str(root,
"set", err);
170 if (set_name != NULL)
171 nft_rule_expr_set_str(e, NFT_EXPR_LOOKUP_SET, set_name);
173 if (nft_jansson_parse_reg(root,
"sreg", NFT_TYPE_U32, &sreg, err) == 0)
174 nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_SREG, sreg);
176 if (nft_jansson_parse_reg(root,
"dreg", NFT_TYPE_U32, &dreg, err) == 0)
177 nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, dreg);
187 nft_rule_expr_lookup_xml_parse(
struct nft_rule_expr *e, mxml_node_t *tree,
188 struct nft_parse_err *err)
191 const char *set_name;
194 set_name = nft_mxml_str_parse(tree,
"set", MXML_DESCEND_FIRST,
196 if (set_name != NULL)
197 nft_rule_expr_set_str(e, NFT_EXPR_LOOKUP_SET, set_name);
199 if (nft_mxml_reg_parse(tree,
"sreg", &sreg, MXML_DESCEND, NFT_XML_MAND,
201 nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_SREG, sreg);
203 if (nft_mxml_reg_parse(tree,
"dreg", &dreg, MXML_DESCEND, NFT_XML_OPT,
205 nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, dreg);
215 nft_rule_expr_lookup_snprintf_json(
char *buf,
size_t size,
216 struct nft_rule_expr *e)
218 int len = size, offset = 0, ret;
221 if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) {
222 ret = snprintf(buf, len,
"\"set\":\"%s\",", l->set_name);
223 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
225 if (e->flags & (1 << NFT_EXPR_LOOKUP_SREG)) {
226 ret = snprintf(buf + offset, len,
"\"sreg\":%u,", l->sreg);
227 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
229 if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) {
230 ret = snprintf(buf + offset, len,
"\"dreg\":%u,", l->dreg);
231 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
241 nft_rule_expr_lookup_snprintf_xml(
char *buf,
size_t size,
242 struct nft_rule_expr *e)
244 int len = size, offset = 0, ret;
247 if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) {
248 ret = snprintf(buf, len,
"<set>%s</set>", l->set_name);
249 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
251 if (e->flags & (1 << NFT_EXPR_LOOKUP_SREG)) {
252 ret = snprintf(buf + offset, len,
"<sreg>%u</sreg>", l->sreg);
253 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
255 if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) {
256 ret = snprintf(buf + offset, len,
"<dreg>%u</dreg>", l->dreg);
257 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
264 nft_rule_expr_lookup_snprintf_default(
char *buf,
size_t size,
265 struct nft_rule_expr *e)
267 int len = size, offset = 0, ret;
270 ret = snprintf(buf, len,
"reg %u set %s ", l->sreg, l->set_name);
271 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
274 if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) {
275 ret = snprintf(buf+offset, len,
"dreg %u ", l->dreg);
276 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
283 nft_rule_expr_lookup_snprintf(
char *buf,
size_t size, uint32_t type,
284 uint32_t flags,
struct nft_rule_expr *e)
288 case NFT_OUTPUT_DEFAULT:
289 return nft_rule_expr_lookup_snprintf_default(buf, size, e);
291 return nft_rule_expr_lookup_snprintf_xml(buf, size, e);
292 case NFT_OUTPUT_JSON:
293 return nft_rule_expr_lookup_snprintf_json(buf, size, e);
300 struct expr_ops expr_ops_lookup = {
303 .max_attr = NFTA_LOOKUP_MAX,
304 .set = nft_rule_expr_lookup_set,
305 .get = nft_rule_expr_lookup_get,
306 .parse = nft_rule_expr_lookup_parse,
307 .build = nft_rule_expr_lookup_build,
308 .snprintf = nft_rule_expr_lookup_snprintf,
309 .xml_parse = nft_rule_expr_lookup_xml_parse,
310 .json_parse = nft_rule_expr_lookup_json_parse,
313 static void __init expr_lookup_init(
void)
315 nft_expr_ops_register(&expr_ops_lookup);