summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c12
-rw-r--r--src/netlink_delinearize.c4
-rw-r--r--src/netlink_linearize.c3
-rw-r--r--src/parser_bison.y50
-rw-r--r--src/scanner.l3
-rw-r--r--src/statement.c23
6 files changed, 89 insertions, 6 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index c60e0f11..8b113c8c 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2429,12 +2429,14 @@ static int stmt_evaluate_queue(struct eval_ctx *ctx, struct stmt *stmt)
static int stmt_evaluate_log(struct eval_ctx *ctx, struct stmt *stmt)
{
- if (stmt->log.flags & STMT_LOG_LEVEL &&
- (stmt->log.flags & STMT_LOG_GROUP ||
- stmt->log.flags & STMT_LOG_SNAPLEN ||
- stmt->log.flags & STMT_LOG_QTHRESHOLD)) {
- return stmt_error(ctx, stmt,
+ if (stmt->log.flags & (STMT_LOG_GROUP | STMT_LOG_SNAPLEN |
+ STMT_LOG_QTHRESHOLD)) {
+ if (stmt->log.flags & STMT_LOG_LEVEL)
+ return stmt_error(ctx, stmt,
"level and group are mutually exclusive");
+ if (stmt->log.logflags)
+ return stmt_error(ctx, stmt,
+ "flags and group are mutually exclusive");
}
return 0;
}
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 66d38caa..0ebe3683 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -738,6 +738,10 @@ static void netlink_parse_log(struct netlink_parse_ctx *ctx,
nftnl_expr_get_u32(nle, NFTNL_EXPR_LOG_LEVEL);
stmt->log.flags |= STMT_LOG_LEVEL;
}
+ if (nftnl_expr_is_set(nle, NFTNL_EXPR_LOG_FLAGS)) {
+ stmt->log.logflags =
+ nftnl_expr_get_u32(nle, NFTNL_EXPR_LOG_FLAGS);
+ }
ctx->stmt = stmt;
}
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 2bee6844..2945392b 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -833,6 +833,9 @@ static void netlink_gen_log_stmt(struct netlink_linearize_ctx *ctx,
if (stmt->log.flags & STMT_LOG_LEVEL)
nftnl_expr_set_u32(nle, NFTNL_EXPR_LOG_LEVEL,
stmt->log.level);
+ if (stmt->log.logflags)
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_LOG_FLAGS,
+ stmt->log.logflags);
}
nftnl_rule_add_expr(ctx->nlr, nle);
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 91955c18..981ffc81 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -20,6 +20,7 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <linux/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_log.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <libnftnl/common.h>
@@ -201,6 +202,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token EXPORT "export"
%token MONITOR "monitor"
+%token ALL "all"
+
%token ACCEPT "accept"
%token DROP "drop"
%token CONTINUE "continue"
@@ -268,6 +271,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token GATEWAY "gateway"
%token MTU "mtu"
+%token OPTIONS "options"
+
%token IP6 "ip6"
%token PRIORITY "priority"
%token FLOWLABEL "flowlabel"
@@ -481,7 +486,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%destructor { stmt_free($$); } meta_stmt
%type <stmt> log_stmt log_stmt_alloc
%destructor { stmt_free($$); } log_stmt log_stmt_alloc
-%type <val> level_type
+%type <val> level_type log_flags log_flags_tcp log_flag_tcp
%type <stmt> limit_stmt quota_stmt
%destructor { stmt_free($$); } limit_stmt quota_stmt
%type <val> limit_burst limit_mode time_unit quota_mode
@@ -1530,6 +1535,10 @@ log_arg : PREFIX string
$<stmt>0->log.level = $2;
$<stmt>0->log.flags |= STMT_LOG_LEVEL;
}
+ | FLAGS log_flags
+ {
+ $<stmt>0->log.logflags |= $2;
+ }
;
level_type : string
@@ -1558,6 +1567,45 @@ level_type : string
}
;
+log_flags : TCP log_flags_tcp
+ {
+ $$ = $2;
+ }
+ | IP OPTIONS
+ {
+ $$ = NF_LOG_IPOPT;
+ }
+ | SKUID
+ {
+ $$ = NF_LOG_UID;
+ }
+ | ETHER
+ {
+ $$ = NF_LOG_MACDECODE;
+ }
+ | ALL
+ {
+ $$ = NF_LOG_MASK;
+ }
+ ;
+
+log_flags_tcp : log_flags_tcp COMMA log_flag_tcp
+ {
+ $$ = $1 | $3;
+ }
+ | log_flag_tcp
+ ;
+
+log_flag_tcp : SEQUENCE
+ {
+ $$ = NF_LOG_TCPSEQ;
+ }
+ | OPTIONS
+ {
+ $$ = NF_LOG_TCPOPT;
+ }
+ ;
+
limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst
{
$$ = limit_stmt_alloc(&@$);
diff --git a/src/scanner.l b/src/scanner.l
index cd7398b4..625023f5 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -469,6 +469,9 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"notrack" { return NOTRACK; }
+"options" { return OPTIONS; }
+"all" { return ALL; }
+
"xml" { return XML; }
"json" { return JSON; }
diff --git a/src/statement.c b/src/statement.c
index 8ccd4891..e70eb51e 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -27,6 +27,7 @@
#include <netinet/in.h>
#include <linux/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_log.h>
struct stmt *stmt_alloc(const struct location *loc,
const struct stmt_ops *ops)
@@ -193,6 +194,28 @@ static void log_stmt_print(const struct stmt *stmt)
if ((stmt->log.flags & STMT_LOG_LEVEL) &&
stmt->log.level != LOG_WARNING)
printf(" level %s", log_level(stmt->log.level));
+
+ if ((stmt->log.logflags & NF_LOG_MASK) == NF_LOG_MASK) {
+ printf(" flags all");
+ } else {
+ if (stmt->log.logflags & (NF_LOG_TCPSEQ | NF_LOG_TCPOPT)) {
+ const char *delim = " ";
+
+ printf(" flags tcp");
+ if (stmt->log.logflags & NF_LOG_TCPSEQ) {
+ printf(" sequence");
+ delim = ",";
+ }
+ if (stmt->log.logflags & NF_LOG_TCPOPT)
+ printf("%soptions", delim);
+ }
+ if (stmt->log.logflags & NF_LOG_IPOPT)
+ printf(" flags ip options");
+ if (stmt->log.logflags & NF_LOG_UID)
+ printf(" flags skuid");
+ if (stmt->log.logflags & NF_LOG_MACDECODE)
+ printf(" flags ether");
+ }
}
static void log_stmt_destroy(struct stmt *stmt)