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, data_len);
51 case NFTNL_EXPR_LOG_SNAPLEN:
52 memcpy(&log->snaplen, data, data_len);
54 case NFTNL_EXPR_LOG_QTHRESHOLD:
55 memcpy(&log->qthreshold, data, data_len);
57 case NFTNL_EXPR_LOG_LEVEL:
58 memcpy(&log->level, data, data_len);
60 case NFTNL_EXPR_LOG_FLAGS:
61 memcpy(&log->flags, data, data_len);
68nftnl_expr_log_get(
const struct nftnl_expr *e, uint16_t type,
74 case NFTNL_EXPR_LOG_PREFIX:
75 *data_len = strlen(log->prefix)+1;
77 case NFTNL_EXPR_LOG_GROUP:
78 *data_len =
sizeof(log->group);
80 case NFTNL_EXPR_LOG_SNAPLEN:
81 *data_len =
sizeof(log->snaplen);
83 case NFTNL_EXPR_LOG_QTHRESHOLD:
84 *data_len =
sizeof(log->qthreshold);
85 return &log->qthreshold;
86 case NFTNL_EXPR_LOG_LEVEL:
87 *data_len =
sizeof(log->level);
89 case NFTNL_EXPR_LOG_FLAGS:
90 *data_len =
sizeof(log->flags);
96static int nftnl_expr_log_cb(
const struct nlattr *attr,
void *data)
98 const struct nlattr **tb = data;
99 int type = mnl_attr_get_type(attr);
101 if (mnl_attr_type_valid(attr, NFTA_LOG_MAX) < 0)
105 case NFTA_LOG_PREFIX:
106 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
110 case NFTA_LOG_QTHRESHOLD:
111 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
114 case NFTA_LOG_SNAPLEN:
117 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
127nftnl_expr_log_build(
struct nlmsghdr *nlh,
const struct nftnl_expr *e)
131 if (e->flags & (1 << NFTNL_EXPR_LOG_PREFIX))
132 mnl_attr_put_strz(nlh, NFTA_LOG_PREFIX, log->prefix);
133 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP))
134 mnl_attr_put_u16(nlh, NFTA_LOG_GROUP, htons(log->group));
135 if (e->flags & (1 << NFTNL_EXPR_LOG_SNAPLEN))
136 mnl_attr_put_u32(nlh, NFTA_LOG_SNAPLEN, htonl(log->snaplen));
137 if (e->flags & (1 << NFTNL_EXPR_LOG_QTHRESHOLD))
138 mnl_attr_put_u16(nlh, NFTA_LOG_QTHRESHOLD, htons(log->qthreshold));
139 if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL))
140 mnl_attr_put_u32(nlh, NFTA_LOG_LEVEL, htonl(log->level));
141 if (e->flags & (1 << NFTNL_EXPR_LOG_FLAGS))
142 mnl_attr_put_u32(nlh, NFTA_LOG_FLAGS, htonl(log->flags));
146nftnl_expr_log_parse(
struct nftnl_expr *e,
struct nlattr *attr)
149 struct nlattr *tb[NFTA_LOG_MAX+1] = {};
151 if (mnl_attr_parse_nested(attr, nftnl_expr_log_cb, tb) < 0)
154 if (tb[NFTA_LOG_PREFIX]) {
158 log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX]));
161 e->flags |= (1 << NFTNL_EXPR_LOG_PREFIX);
163 if (tb[NFTA_LOG_GROUP]) {
164 log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP]));
165 e->flags |= (1 << NFTNL_EXPR_LOG_GROUP);
167 if (tb[NFTA_LOG_SNAPLEN]) {
168 log->snaplen = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_SNAPLEN]));
169 e->flags |= (1 << NFTNL_EXPR_LOG_SNAPLEN);
171 if (tb[NFTA_LOG_QTHRESHOLD]) {
172 log->qthreshold = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_QTHRESHOLD]));
173 e->flags |= (1 << NFTNL_EXPR_LOG_QTHRESHOLD);
175 if (tb[NFTA_LOG_LEVEL]) {
176 log->level = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_LEVEL]));
177 e->flags |= (1 << NFTNL_EXPR_LOG_LEVEL);
179 if (tb[NFTA_LOG_FLAGS]) {
180 log->flags = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_FLAGS]));
181 e->flags |= (1 << NFTNL_EXPR_LOG_FLAGS);
188nftnl_expr_log_snprintf(
char *buf,
size_t remain,
189 uint32_t flags,
const struct nftnl_expr *e)
194 if (e->flags & (1 << NFTNL_EXPR_LOG_PREFIX)) {
195 ret = snprintf(buf, remain,
"prefix %s ", log->prefix);
196 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
199 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP)) {
200 ret = snprintf(buf + offset, remain,
201 "group %u snaplen %u qthreshold %u ",
202 log->group, log->snaplen, log->qthreshold);
203 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
205 if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL)) {
206 ret = snprintf(buf + offset, remain,
"level %u ",
208 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
210 if (e->flags & (1 << NFTNL_EXPR_LOG_FLAGS)) {
211 if (log->flags & NF_LOG_TCPSEQ) {
212 ret = snprintf(buf + offset, remain,
"tcpseq ");
213 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
215 if (log->flags & NF_LOG_TCPOPT) {
216 ret = snprintf(buf + offset, remain,
"tcpopt ");
217 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
219 if (log->flags & NF_LOG_IPOPT) {
220 ret = snprintf(buf + offset, remain,
"ipopt ");
221 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
223 if (log->flags & NF_LOG_UID) {
224 ret = snprintf(buf + offset, remain,
"uid ");
225 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
227 if (log->flags & NF_LOG_MACDECODE) {
228 ret = snprintf(buf + offset, remain,
230 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
238static void nftnl_expr_log_free(
const struct nftnl_expr *e)
245static struct attr_policy log_attr_policy[__NFTNL_EXPR_LOG_MAX] = {
246 [NFTNL_EXPR_LOG_PREFIX] = { .maxlen = NF_LOG_PREFIXLEN },
247 [NFTNL_EXPR_LOG_GROUP] = { .maxlen =
sizeof(uint16_t) },
248 [NFTNL_EXPR_LOG_SNAPLEN] = { .maxlen =
sizeof(uint32_t) },
249 [NFTNL_EXPR_LOG_QTHRESHOLD] = { .maxlen =
sizeof(uint16_t) },
250 [NFTNL_EXPR_LOG_LEVEL] = { .maxlen =
sizeof(uint32_t) },
251 [NFTNL_EXPR_LOG_FLAGS] = { .maxlen =
sizeof(uint32_t) },
254struct expr_ops expr_ops_log = {
257 .nftnl_max_attr = __NFTNL_EXPR_LOG_MAX - 1,
258 .attr_policy = log_attr_policy,
259 .free = nftnl_expr_log_free,
260 .set = nftnl_expr_log_set,
261 .get = nftnl_expr_log_get,
262 .parse = nftnl_expr_log_parse,
263 .build = nftnl_expr_log_build,
264 .output = nftnl_expr_log_snprintf,