17#include <linux/netfilter/nf_tables.h>
18#include <linux/netfilter/nf_log.h>
21#include <libmnl/libmnl.h>
22#include <libnftnl/expr.h>
23#include <libnftnl/rule.h>
34static int nftnl_expr_log_set(
struct nftnl_expr *e, uint16_t type,
35 const void *data, uint32_t data_len)
40 case NFTNL_EXPR_LOG_PREFIX:
41 if (log->flags & (1 << NFTNL_EXPR_LOG_PREFIX))
44 log->prefix = strdup(data);
48 case NFTNL_EXPR_LOG_GROUP:
49 memcpy(&log->group, data,
sizeof(log->group));
51 case NFTNL_EXPR_LOG_SNAPLEN:
52 memcpy(&log->snaplen, data,
sizeof(log->snaplen));
54 case NFTNL_EXPR_LOG_QTHRESHOLD:
55 memcpy(&log->qthreshold, data,
sizeof(log->qthreshold));
57 case NFTNL_EXPR_LOG_LEVEL:
58 memcpy(&log->level, data,
sizeof(log->level));
60 case NFTNL_EXPR_LOG_FLAGS:
61 memcpy(&log->flags, data,
sizeof(log->flags));
70nftnl_expr_log_get(
const struct nftnl_expr *e, uint16_t type,
76 case NFTNL_EXPR_LOG_PREFIX:
77 *data_len = strlen(log->prefix)+1;
79 case NFTNL_EXPR_LOG_GROUP:
80 *data_len =
sizeof(log->group);
82 case NFTNL_EXPR_LOG_SNAPLEN:
83 *data_len =
sizeof(log->snaplen);
85 case NFTNL_EXPR_LOG_QTHRESHOLD:
86 *data_len =
sizeof(log->qthreshold);
87 return &log->qthreshold;
88 case NFTNL_EXPR_LOG_LEVEL:
89 *data_len =
sizeof(log->level);
91 case NFTNL_EXPR_LOG_FLAGS:
92 *data_len =
sizeof(log->flags);
98static int nftnl_expr_log_cb(
const struct nlattr *attr,
void *data)
100 const struct nlattr **tb = data;
101 int type = mnl_attr_get_type(attr);
103 if (mnl_attr_type_valid(attr, NFTA_LOG_MAX) < 0)
107 case NFTA_LOG_PREFIX:
108 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
112 case NFTA_LOG_QTHRESHOLD:
113 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
116 case NFTA_LOG_SNAPLEN:
119 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
129nftnl_expr_log_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
133 if (e->flags & (1 << NFTNL_EXPR_LOG_PREFIX))
134 mnl_attr_put_strz(nlh, NFTA_LOG_PREFIX, log->prefix);
135 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP))
136 mnl_attr_put_u16(nlh, NFTA_LOG_GROUP, htons(log->group));
137 if (e->flags & (1 << NFTNL_EXPR_LOG_SNAPLEN))
138 mnl_attr_put_u32(nlh, NFTA_LOG_SNAPLEN, htonl(log->snaplen));
139 if (e->flags & (1 << NFTNL_EXPR_LOG_QTHRESHOLD))
140 mnl_attr_put_u16(nlh, NFTA_LOG_QTHRESHOLD, htons(log->qthreshold));
141 if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL))
142 mnl_attr_put_u32(nlh, NFTA_LOG_LEVEL, htonl(log->level));
143 if (e->flags & (1 << NFTNL_EXPR_LOG_FLAGS))
144 mnl_attr_put_u32(nlh, NFTA_LOG_FLAGS, htonl(log->flags));
148nftnl_expr_log_parse(
struct nftnl_expr *e,
struct nlattr *attr)
151 struct nlattr *tb[NFTA_LOG_MAX+1] = {};
153 if (mnl_attr_parse_nested(attr, nftnl_expr_log_cb, tb) < 0)
156 if (tb[NFTA_LOG_PREFIX]) {
160 log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX]));
163 e->flags |= (1 << NFTNL_EXPR_LOG_PREFIX);
165 if (tb[NFTA_LOG_GROUP]) {
166 log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP]));
167 e->flags |= (1 << NFTNL_EXPR_LOG_GROUP);
169 if (tb[NFTA_LOG_SNAPLEN]) {
170 log->snaplen = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_SNAPLEN]));
171 e->flags |= (1 << NFTNL_EXPR_LOG_SNAPLEN);
173 if (tb[NFTA_LOG_QTHRESHOLD]) {
174 log->qthreshold = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_QTHRESHOLD]));
175 e->flags |= (1 << NFTNL_EXPR_LOG_QTHRESHOLD);
177 if (tb[NFTA_LOG_LEVEL]) {
178 log->level = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_LEVEL]));
179 e->flags |= (1 << NFTNL_EXPR_LOG_LEVEL);
181 if (tb[NFTA_LOG_FLAGS]) {
182 log->flags = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_FLAGS]));
183 e->flags |= (1 << NFTNL_EXPR_LOG_FLAGS);
190nftnl_expr_log_snprintf(
char *buf,
size_t remain,
191 uint32_t flags,
const struct nftnl_expr *e)
196 if (e->flags & (1 << NFTNL_EXPR_LOG_PREFIX)) {
197 ret = snprintf(buf, remain,
"prefix %s ", log->prefix);
198 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
201 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP)) {
202 ret = snprintf(buf + offset, remain,
203 "group %u snaplen %u qthreshold %u ",
204 log->group, log->snaplen, log->qthreshold);
205 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
207 if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL)) {
208 ret = snprintf(buf + offset, remain,
"level %u ",
210 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
212 if (e->flags & (1 << NFTNL_EXPR_LOG_FLAGS)) {
213 if (log->flags & NF_LOG_TCPSEQ) {
214 ret = snprintf(buf + offset, remain,
"tcpseq ");
215 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
217 if (log->flags & NF_LOG_TCPOPT) {
218 ret = snprintf(buf + offset, remain,
"tcpopt ");
219 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
221 if (log->flags & NF_LOG_IPOPT) {
222 ret = snprintf(buf + offset, remain,
"ipopt ");
223 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
225 if (log->flags & NF_LOG_UID) {
226 ret = snprintf(buf + offset, remain,
"uid ");
227 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
229 if (log->flags & NF_LOG_MACDECODE) {
230 ret = snprintf(buf + offset, remain,
232 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
240static void nftnl_expr_log_free(
const struct nftnl_expr *e)
247struct expr_ops expr_ops_log = {
250 .max_attr = NFTA_LOG_MAX,
251 .free = nftnl_expr_log_free,
252 .set = nftnl_expr_log_set,
253 .get = nftnl_expr_log_get,
254 .parse = nftnl_expr_log_parse,
255 .build = nftnl_expr_log_build,
256 .output = nftnl_expr_log_snprintf,