15 #include <arpa/inet.h>
17 #include <linux/netfilter/nf_tables.h>
20 #include <libmnl/libmnl.h>
21 #include <libnftnl/expr.h>
22 #include <libnftnl/rule.h>
32 static int nft_rule_expr_log_set(
struct nft_rule_expr *e, uint16_t type,
33 const void *data, uint32_t data_len)
38 case NFT_EXPR_LOG_PREFIX:
42 log->prefix = strdup(data);
44 case NFT_EXPR_LOG_GROUP:
45 log->group = *((uint16_t *)data);
47 case NFT_EXPR_LOG_SNAPLEN:
48 log->snaplen = *((uint32_t *)data);
50 case NFT_EXPR_LOG_QTHRESHOLD:
51 log->qthreshold = *((uint16_t *)data);
60 nft_rule_expr_log_get(
const struct nft_rule_expr *e, uint16_t type,
66 case NFT_EXPR_LOG_PREFIX:
67 *data_len = strlen(log->prefix)+1;
69 case NFT_EXPR_LOG_GROUP:
70 *data_len =
sizeof(log->group);
72 case NFT_EXPR_LOG_SNAPLEN:
73 *data_len =
sizeof(log->snaplen);
75 case NFT_EXPR_LOG_QTHRESHOLD:
76 *data_len =
sizeof(log->qthreshold);
77 return &log->qthreshold;
82 static int nft_rule_expr_log_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_LOG_MAX) < 0)
92 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
93 perror(
"mnl_attr_validate");
98 case NFTA_LOG_QTHRESHOLD:
99 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
100 perror(
"mnl_attr_validate");
104 case NFTA_LOG_SNAPLEN:
105 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
106 perror(
"mnl_attr_validate");
117 nft_rule_expr_log_build(
struct nlmsghdr *nlh,
struct nft_rule_expr *e)
121 if (e->flags & (1 << NFT_EXPR_LOG_PREFIX))
122 mnl_attr_put_strz(nlh, NFTA_LOG_PREFIX, log->prefix);
123 if (e->flags & (1 << NFT_EXPR_LOG_GROUP))
124 mnl_attr_put_u16(nlh, NFTA_LOG_GROUP, htons(log->group));
125 if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN))
126 mnl_attr_put_u32(nlh, NFTA_LOG_SNAPLEN, htonl(log->snaplen));
127 if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD))
128 mnl_attr_put_u16(nlh, NFTA_LOG_QTHRESHOLD, htons(log->qthreshold));
132 nft_rule_expr_log_parse(
struct nft_rule_expr *e,
struct nlattr *attr)
135 struct nlattr *tb[NFTA_LOG_MAX+1] = {};
137 if (mnl_attr_parse_nested(attr, nft_rule_expr_log_cb, tb) < 0)
140 if (tb[NFTA_LOG_PREFIX]) {
144 log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX]));
145 e->flags |= (1 << NFT_EXPR_LOG_PREFIX);
147 if (tb[NFTA_LOG_GROUP]) {
148 log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP]));
149 e->flags |= (1 << NFT_EXPR_LOG_GROUP);
151 if (tb[NFTA_LOG_SNAPLEN]) {
152 log->snaplen = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_SNAPLEN]));
153 e->flags |= (1 << NFT_EXPR_LOG_SNAPLEN);
155 if (tb[NFTA_LOG_QTHRESHOLD]) {
156 log->qthreshold = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_QTHRESHOLD]));
157 e->flags |= (1 << NFT_EXPR_LOG_QTHRESHOLD);
163 static int nft_rule_expr_log_json_parse(
struct nft_rule_expr *e, json_t *root,
164 struct nft_parse_err *err)
169 uint16_t group, qthreshold;
171 prefix = nft_jansson_parse_str(root,
"prefix", err);
173 nft_rule_expr_set_str(e, NFT_EXPR_LOG_PREFIX, prefix);
175 if (nft_jansson_parse_val(root,
"group", NFT_TYPE_U16, &group,
177 nft_rule_expr_set_u16(e, NFT_EXPR_LOG_GROUP, group);
179 if (nft_jansson_parse_val(root,
"snaplen", NFT_TYPE_U32, &snaplen,
181 nft_rule_expr_set_u32(e, NFT_EXPR_LOG_SNAPLEN, snaplen);
183 if (nft_jansson_parse_val(root,
"qthreshold", NFT_TYPE_U16,
184 &qthreshold, err) == 0)
185 nft_rule_expr_set_u16(e, NFT_EXPR_LOG_QTHRESHOLD, qthreshold);
194 static int nft_rule_expr_log_xml_parse(
struct nft_rule_expr *e,
196 struct nft_parse_err *err)
201 uint16_t group, qthreshold;
203 prefix = nft_mxml_str_parse(tree,
"prefix", MXML_DESCEND_FIRST,
206 nft_rule_expr_set_str(e, NFT_EXPR_LOG_PREFIX, prefix);
208 if (nft_mxml_num_parse(tree,
"group", MXML_DESCEND_FIRST, BASE_DEC,
209 &group, NFT_TYPE_U16, NFT_XML_MAND, err) == 0)
210 nft_rule_expr_set_u16(e, NFT_EXPR_LOG_GROUP, group);
212 if (nft_mxml_num_parse(tree,
"snaplen", MXML_DESCEND_FIRST, BASE_DEC,
213 &snaplen, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
214 nft_rule_expr_set_u32(e, NFT_EXPR_LOG_SNAPLEN, snaplen);
216 if (nft_mxml_num_parse(tree,
"qthreshold", MXML_DESCEND_FIRST, BASE_DEC,
217 &qthreshold, NFT_TYPE_U16, NFT_XML_MAND,
219 nft_rule_expr_set_u16(e, NFT_EXPR_LOG_QTHRESHOLD, qthreshold);
228 static int nft_rule_expr_log_snprintf_default(
char *buf,
size_t len,
229 struct nft_rule_expr *e)
233 return snprintf(buf, len,
"prefix '%s' group %u snaplen %u"
235 log->prefix, log->group, log->snaplen, log->qthreshold);
238 static int nft_rule_expr_log_snprintf_xml(
char *buf,
size_t size,
239 struct nft_rule_expr *e)
241 int ret, len = size, offset = 0;
244 if (e->flags & (1 << NFT_EXPR_LOG_PREFIX)) {
245 ret = snprintf(buf + offset, len,
"<prefix>%s</prefix>",
247 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
249 if (e->flags & (1 << NFT_EXPR_LOG_GROUP)) {
250 ret = snprintf(buf + offset, len,
"<group>%u</group>",
252 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
254 if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN)) {
255 ret = snprintf(buf + offset, len,
"<snaplen>%u</snaplen>",
257 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
259 if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD)) {
260 ret = snprintf(buf + offset, len,
"<qthreshold>%u</qthreshold>",
262 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
268 static int nft_rule_expr_log_snprintf_json(
char *buf,
size_t len,
269 struct nft_rule_expr *e)
271 int ret, size = len, offset = 0;
274 if (e->flags & (1 << NFT_EXPR_LOG_PREFIX)) {
275 ret = snprintf(buf + offset, len,
"\"prefix\":\"%s\",",
277 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
279 if (e->flags & (1 << NFT_EXPR_LOG_GROUP)) {
280 ret = snprintf(buf + offset, len,
"\"group\":%u,",
282 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
284 if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN)) {
285 ret = snprintf(buf + offset, len,
"\"snaplen\":%u,",
287 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
289 if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD)) {
290 ret = snprintf(buf + offset, len,
"\"qthreshold\":%u,",
292 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
303 nft_rule_expr_log_snprintf(
char *buf,
size_t len, uint32_t type,
304 uint32_t flags,
struct nft_rule_expr *e)
307 case NFT_OUTPUT_DEFAULT:
308 return nft_rule_expr_log_snprintf_default(buf, len, e);
310 return nft_rule_expr_log_snprintf_xml(buf, len, e);
311 case NFT_OUTPUT_JSON:
312 return nft_rule_expr_log_snprintf_json(buf, len, e);
319 static void nft_rule_expr_log_free(
struct nft_rule_expr *e)
326 struct expr_ops expr_ops_log = {
329 .max_attr = NFTA_LOG_MAX,
330 .free = nft_rule_expr_log_free,
331 .set = nft_rule_expr_log_set,
332 .get = nft_rule_expr_log_get,
333 .parse = nft_rule_expr_log_parse,
334 .build = nft_rule_expr_log_build,
335 .snprintf = nft_rule_expr_log_snprintf,
336 .xml_parse = nft_rule_expr_log_xml_parse,
337 .json_parse = nft_rule_expr_log_json_parse,
340 static void __init expr_log_init(
void)
342 nft_expr_ops_register(&expr_ops_log);