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>
29 enum nft_registers sreg;
30 enum nft_registers dreg;
31 char set_name[IFNAMSIZ];
36 nftnl_expr_lookup_set(
struct nftnl_expr *e, uint16_t type,
37 const void *data, uint32_t data_len)
42 case NFTNL_EXPR_LOOKUP_SREG:
43 lookup->sreg = *((uint32_t *)data);
45 case NFTNL_EXPR_LOOKUP_DREG:
46 lookup->dreg = *((uint32_t *)data);
48 case NFTNL_EXPR_LOOKUP_SET:
49 snprintf(lookup->set_name,
sizeof(lookup->set_name),
"%s",
52 case NFTNL_EXPR_LOOKUP_SET_ID:
53 lookup->set_id = *((uint32_t *)data);
62 nftnl_expr_lookup_get(
const struct nftnl_expr *e, uint16_t type,
68 case NFTNL_EXPR_LOOKUP_SREG:
69 *data_len =
sizeof(lookup->sreg);
71 case NFTNL_EXPR_LOOKUP_DREG:
72 *data_len =
sizeof(lookup->dreg);
74 case NFTNL_EXPR_LOOKUP_SET:
75 return lookup->set_name;
76 case NFTNL_EXPR_LOOKUP_SET_ID:
77 return &lookup->set_id;
82 static int nftnl_expr_lookup_cb(
const struct nlattr *attr,
void *data)
84 const struct nlattr **tb = data;
85 int type = mnl_attr_get_type(attr);
87 if (mnl_attr_type_valid(attr, NFTA_LOOKUP_MAX) < 0)
91 case NFTA_LOOKUP_SREG:
92 case NFTA_LOOKUP_DREG:
93 case NFTA_LOOKUP_SET_ID:
94 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
98 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
108 nftnl_expr_lookup_build(
struct nlmsghdr *nlh,
struct nftnl_expr *e)
112 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SREG))
113 mnl_attr_put_u32(nlh, NFTA_LOOKUP_SREG, htonl(lookup->sreg));
114 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_DREG))
115 mnl_attr_put_u32(nlh, NFTA_LOOKUP_DREG, htonl(lookup->dreg));
116 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SET))
117 mnl_attr_put_strz(nlh, NFTA_LOOKUP_SET, lookup->set_name);
118 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SET_ID)) {
119 mnl_attr_put_u32(nlh, NFTA_LOOKUP_SET_ID,
120 htonl(lookup->set_id));
125 nftnl_expr_lookup_parse(
struct nftnl_expr *e,
struct nlattr *attr)
128 struct nlattr *tb[NFTA_LOOKUP_MAX+1] = {};
131 if (mnl_attr_parse_nested(attr, nftnl_expr_lookup_cb, tb) < 0)
134 if (tb[NFTA_LOOKUP_SREG]) {
135 lookup->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SREG]));
136 e->flags |= (1 << NFTNL_EXPR_LOOKUP_SREG);
138 if (tb[NFTA_LOOKUP_DREG]) {
139 lookup->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_DREG]));
140 e->flags |= (1 << NFTNL_EXPR_LOOKUP_DREG);
142 if (tb[NFTA_LOOKUP_SET]) {
143 strcpy(lookup->set_name, mnl_attr_get_str(tb[NFTA_LOOKUP_SET]));
144 e->flags |= (1 << NFTNL_EXPR_LOOKUP_SET);
146 if (tb[NFTA_LOOKUP_SET_ID]) {
148 ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID]));
149 e->flags |= (1 << NFTNL_EXPR_LOOKUP_SET_ID);
156 nftnl_expr_lookup_json_parse(
struct nftnl_expr *e, json_t *root,
157 struct nftnl_parse_err *err)
160 const char *set_name;
163 set_name = nftnl_jansson_parse_str(root,
"set", err);
164 if (set_name != NULL)
165 nftnl_expr_set_str(e, NFTNL_EXPR_LOOKUP_SET, set_name);
167 if (nftnl_jansson_parse_reg(root,
"sreg", NFTNL_TYPE_U32, &sreg, err) == 0)
168 nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_SREG, sreg);
170 if (nftnl_jansson_parse_reg(root,
"dreg", NFTNL_TYPE_U32, &dreg, err) == 0)
171 nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_DREG, dreg);
181 nftnl_expr_lookup_xml_parse(
struct nftnl_expr *e, mxml_node_t *tree,
182 struct nftnl_parse_err *err)
185 const char *set_name;
188 set_name = nftnl_mxml_str_parse(tree,
"set", MXML_DESCEND_FIRST,
189 NFTNL_XML_MAND, err);
190 if (set_name != NULL)
191 nftnl_expr_set_str(e, NFTNL_EXPR_LOOKUP_SET, set_name);
193 if (nftnl_mxml_reg_parse(tree,
"sreg", &sreg, MXML_DESCEND, NFTNL_XML_MAND,
195 nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_SREG, sreg);
197 if (nftnl_mxml_reg_parse(tree,
"dreg", &dreg, MXML_DESCEND, NFTNL_XML_OPT,
199 nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_DREG, dreg);
209 nftnl_expr_lookup_export(
char *buf,
size_t size,
210 struct nftnl_expr *e,
int type)
213 NFTNL_BUF_INIT(b, buf, size);
215 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SET))
216 nftnl_buf_str(&b, type, l->set_name, SET);
217 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SREG))
218 nftnl_buf_u32(&b, type, l->sreg, SREG);
219 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_DREG))
220 nftnl_buf_u32(&b, type, l->dreg, DREG);
222 return nftnl_buf_done(&b);
226 nftnl_expr_lookup_snprintf_default(
char *buf,
size_t size,
227 struct nftnl_expr *e)
229 int len = size, offset = 0, ret;
232 ret = snprintf(buf, len,
"reg %u set %s ", l->sreg, l->set_name);
233 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
236 if (e->flags & (1 << NFTNL_EXPR_LOOKUP_DREG)) {
237 ret = snprintf(buf+offset, len,
"dreg %u ", l->dreg);
238 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
245 nftnl_expr_lookup_snprintf(
char *buf,
size_t size, uint32_t type,
246 uint32_t flags,
struct nftnl_expr *e)
250 case NFTNL_OUTPUT_DEFAULT:
251 return nftnl_expr_lookup_snprintf_default(buf, size, e);
252 case NFTNL_OUTPUT_XML:
253 case NFTNL_OUTPUT_JSON:
254 return nftnl_expr_lookup_export(buf, size, e, type);
261 struct expr_ops expr_ops_lookup = {
264 .max_attr = NFTA_LOOKUP_MAX,
265 .set = nftnl_expr_lookup_set,
266 .get = nftnl_expr_lookup_get,
267 .parse = nftnl_expr_lookup_parse,
268 .build = nftnl_expr_lookup_build,
269 .snprintf = nftnl_expr_lookup_snprintf,
270 .xml_parse = nftnl_expr_lookup_xml_parse,
271 .json_parse = nftnl_expr_lookup_json_parse,