Adding a new keyword "secmark_raw" seems to do the trick a bit. But somewhere it is still unsupported: $ nft --debug=netlink add rule inet filter output meta secmark_raw set ct secmark_raw inet filter output [ ct load secmark => reg 1 ] [ meta set secmark with reg 1 ] Error: Could not process rule: Operation not supported add rule inet filter output meta secmark_raw set ct secmark_raw ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Is the netlink debug output ok? kernel patch: --- net/netfilter/nft_ct.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 1435ffc5..78831416 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -296,6 +296,14 @@ static void nft_ct_set_eval(const struct nft_expr *expr, } break; #endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + case NFT_CT_SECMARK: + if (ct->secmark != value) { + ct->secmark = value; + nf_conntrack_event_cache(IPCT_SECMARK, ct); + } + break; +#endif #ifdef CONFIG_NF_CONNTRACK_LABELS case NFT_CT_LABELS: nf_connlabels_replace(ct, @@ -562,6 +570,13 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, return -EINVAL; len = sizeof(u32); break; +#endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + case NFT_CT_SECMARK: + if (tb[NFTA_CT_DIRECTION]) + return -EINVAL; + len = sizeof(u32); + break; #endif default: return -EOPNOTSUPP; -- 2.19.0 nftables patch: --- src/ct.c | 2 ++ src/meta.c | 2 ++ src/parser_bison.y | 25 +++++++++++++++++-------- src/scanner.l | 1 + 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/ct.c b/src/ct.c index 1d50382..e62c255 100644 --- a/src/ct.c +++ b/src/ct.c @@ -291,6 +291,8 @@ const struct ct_template ct_templates[__NFT_CT_MAX] = { BYTEORDER_HOST_ENDIAN, 16), [NFT_CT_EVENTMASK] = CT_TEMPLATE("event", &ct_event_type, BYTEORDER_HOST_ENDIAN, 32), + [NFT_CT_SECMARK] = CT_TEMPLATE("secmark", &integer_type, + BYTEORDER_HOST_ENDIAN, 32), }; static void ct_print(enum nft_ct_keys key, int8_t dir, uint8_t nfproto, diff --git a/src/meta.c b/src/meta.c index 19066a1..76be247 100644 --- a/src/meta.c +++ b/src/meta.c @@ -444,6 +444,8 @@ const struct meta_template meta_templates[] = { BYTEORDER_BIG_ENDIAN), /* avoid conversion; doesn't have endianess */ [NFT_META_SECPATH] = META_TEMPLATE("secpath", &boolean_type, BITS_PER_BYTE, BYTEORDER_HOST_ENDIAN), + [NFT_META_SECMARK] = META_TEMPLATE("secmark", &integer_type, + 32, BYTEORDER_HOST_ENDIAN), }; static bool meta_key_is_qualified(enum nft_meta_keys key) diff --git a/src/parser_bison.y b/src/parser_bison.y index a42bc05..2d5a87d 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -452,6 +452,7 @@ int nft_lex(void *, void *, void *); %token SECMARK "secmark" %token SECMARKS "secmarks" +%token SECMARK_RAW "secmark_raw" %token NANOSECOND "nanosecond" %token MICROSECOND "microsecond" @@ -697,7 +698,7 @@ int nft_lex(void *, void *, void *); %type <expr> meta_expr %destructor { expr_free($$); } meta_expr -%type <val> meta_key meta_key_qualified meta_key_unqualified numgen_type +%type <val> meta_key meta_key_qualified meta_key_unqualified meta_key_object numgen_type %type <expr> socket_expr %destructor { expr_free($$); } socket_expr @@ -3596,7 +3597,7 @@ meta_key_qualified : LENGTH { $$ = NFT_META_LEN; } | PROTOCOL { $$ = NFT_META_PROTOCOL; } | PRIORITY { $$ = NFT_META_PRIORITY; } | RANDOM { $$ = NFT_META_PRANDOM; } - | SECMARK { $$ = NFT_META_SECMARK; } + | SECMARK_RAW { $$ = NFT_META_SECMARK; } ; meta_key_unqualified : MARK { $$ = NFT_META_MARK; } @@ -3621,7 +3622,18 @@ meta_key_unqualified : MARK { $$ = NFT_META_MARK; } | CGROUP { $$ = NFT_META_CGROUP; } ; +meta_key_object : SECMARK { $$ = NFT_META_SECMARK; } + ; + meta_stmt : META meta_key SET stmt_expr + { + $$ = meta_stmt_alloc(&@$, $2, $4); + } + | meta_key_unqualified SET stmt_expr + { + $$ = meta_stmt_alloc(&@$, $1, $3); + } + | META meta_key_object SET stmt_expr { switch ($2) { case NFT_META_SECMARK: @@ -3630,14 +3642,10 @@ meta_stmt : META meta_key SET stmt_expr $$->objref.expr = $4; break; default: - $$ = meta_stmt_alloc(&@$, $2, $4); - break; + erec_queue(error(&@2, "invalid meta object name '%s'\n", $2), state->msgs); + YYERROR; } } - | meta_key_unqualified SET stmt_expr - { - $$ = meta_stmt_alloc(&@$, $1, $3); - } | META STRING SET stmt_expr { struct error_record *erec; @@ -3766,6 +3774,7 @@ ct_key : L3PROTOCOL { $$ = NFT_CT_L3PROTOCOL; } | PROTO_DST { $$ = NFT_CT_PROTO_DST; } | LABEL { $$ = NFT_CT_LABELS; } | EVENT { $$ = NFT_CT_EVENTMASK; } + | SECMARK_RAW { $$ = NFT_CT_SECMARK; } | ct_key_dir_optional ; diff --git a/src/scanner.l b/src/scanner.l index 9a5bd30..c42f3d7 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -549,6 +549,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "secmark" { return SECMARK; } "secmarks" { return SECMARKS; } +"secmark_raw" { return SECMARK_RAW; } {addrstring} { yylval->string = xstrdup(yytext); -- 2.19.0