]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: Expose socket mark via socket expression
authorMáté Eckl <ecklm94@gmail.com>
Wed, 1 Aug 2018 18:09:22 +0000 (20:09 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 3 Aug 2018 10:25:59 +0000 (12:25 +0200)
This can be used like ct mark or meta mark except it cannot be set. doc
and tests are included.

Signed-off-by: Máté Eckl <ecklm94@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/primary-expression.txt
include/linux/netfilter/nf_tables.h
src/evaluate.c
src/parser_bison.y
src/parser_json.c
src/socket.c
tests/py/inet/socket.t
tests/py/inet/socket.t.json
tests/py/inet/socket.t.payload

index 50093b492eb48cf2430d1ee69611151f4fa5c5a7..88ea7edfe4837b391ee7310aa7bbdc64f2b23651 100644 (file)
@@ -143,6 +143,7 @@ or non-zero bound listening socket (possibly with a non-local address).
 |transparent|
 Value of the IP_TRANSPARENT socket option in the found socket. It can be 0 or 1.|
 boolean (1 bit)
+|mark| Value of the socket mark (SOL_SOCKET, SO_MARK). | mark
 |==================
 
 .Using socket expression
@@ -154,6 +155,22 @@ table inet x {
         socket transparent 1 mark set 0x00000001 accept
     }
 }
+
+# Trace packets that corresponds to a socket with a mark value of 15
+table inet x {
+    chain y {
+        type filter hook prerouting priority -150; policy accept;
+        socket mark 0x0000000f nftrace set 1
+    }
+}
+
+# Set packet mark to socket mark
+table inet x {
+    chain y {
+        type filter hook prerouting priority -150; policy accept;
+        tcp dport 8080 mark set socket mark
+    }
+}
 ----------------------
 
 FIB EXPRESSIONS
index d98cebb0c484715a5675e0fa9479f456f2c91550..ea374ae6755681e1eb016d67afbdd637aa18d9e9 100644 (file)
@@ -923,11 +923,12 @@ enum nft_socket_attributes {
 /*
  * enum nft_socket_keys - nf_tables socket expression keys
  *
- * @NFT_SOCKET_TRANSPARENT: Value of the IP(V6)_TRANSPARENT socket option_
+ * @NFT_SOCKET_TRANSPARENT: Value of the IP(V6)_TRANSPARENT socket option
+ * @NFT_SOCKET_MARK: Value of the socket mark
  */
 enum nft_socket_keys {
        NFT_SOCKET_TRANSPARENT,
-
+       NFT_SOCKET_MARK,
        __NFT_SOCKET_MAX
 };
 #define NFT_SOCKET_MAX (__NFT_SOCKET_MAX - 1)
index da95cdf9b7ff14ac112a5e082647b9a5382b08af..b793c125a5ca95a0e42d404081e5a13b8916c705 100644 (file)
@@ -1715,8 +1715,12 @@ static int expr_evaluate_meta(struct eval_ctx *ctx, struct expr **exprp)
 
 static int expr_evaluate_socket(struct eval_ctx *ctx, struct expr **expr)
 {
+       int maxval = 0;
+
+       if((*expr)->socket.key == NFT_SOCKET_TRANSPARENT)
+               maxval = 1;
        __expr_set_context(&ctx->ectx, (*expr)->dtype, (*expr)->byteorder,
-                          (*expr)->len, 1);
+                          (*expr)->len, maxval);
        return 0;
 }
 
index fe3c10bab30bb9eefe9a1b6ce42585d2bcca9761..827b0580899b73bc34bf71a53585fdea86129b25 100644 (file)
@@ -2531,6 +2531,7 @@ primary_stmt_expr :       symbol_expr             { $$ = $1; }
                        |       hash_expr               { $$ = $1; }
                        |       payload_expr            { $$ = $1; }
                        |       keyword_expr            { $$ = $1; }
+                       |       socket_expr             { $$ = $1; }
                        ;
 
 shift_stmt_expr                :       primary_stmt_expr
@@ -3618,7 +3619,8 @@ socket_expr               :       SOCKET  socket_key
                        }
                        ;
 
-socket_key             : TRANSPARENT { $$ = NFT_SOCKET_TRANSPARENT; }
+socket_key             :       TRANSPARENT     { $$ = NFT_SOCKET_TRANSPARENT; }
+                       |       MARK            { $$ = NFT_SOCKET_MARK; }
                        ;
 
 offset_opt             :       /* empty */     { $$ = 0; }
index 8f29aaf71f13643967ac180a27bf8bdaaa9d1d63..80364d97b88e938a1b638ef37fef681b292a4d36 100644 (file)
@@ -358,6 +358,8 @@ static struct expr *json_parse_socket_expr(struct json_ctx *ctx,
 
        if (!strcmp(key, "transparent"))
                keyval = NFT_SOCKET_TRANSPARENT;
+       else if (!strcmp(key, "mark"))
+               keyval = NFT_SOCKET_MARK;
 
        if (keyval == -1) {
                json_error(ctx, "Invalid socket key value.");
index 7cfe5a9d2bc6ce026ca9de3c1fe2fa371a857b9e..d90b0416e62c7b858dd14f17574ab16d0619417f 100644 (file)
 #include <json.h>
 
 const struct socket_template socket_templates[] = {
-       [NFT_SOCKET_TRANSPARENT]        = {.token = "transparent",
-                                          .dtype = &integer_type,
-                                          .len = BITS_PER_BYTE,
-                                          .byteorder = BYTEORDER_HOST_ENDIAN,
-                                         }
+       [NFT_SOCKET_TRANSPARENT] = {
+               .token          = "transparent",
+               .dtype          = &integer_type,
+               .len            = BITS_PER_BYTE,
+               .byteorder      = BYTEORDER_HOST_ENDIAN,
+       },
+       [NFT_SOCKET_MARK] = {
+               .token          = "mark",
+               .dtype          = &mark_type,
+               .len            = 4 * BITS_PER_BYTE,
+               .byteorder      = BYTEORDER_HOST_ENDIAN,
+       },
 };
 
 static void socket_expr_print(const struct expr *expr, struct output_ctx *octx)
index 8edfa78d8403b179f1254496b233402ce649c5ec..91846e8ef4e1036d14a90ff8a489560d226c1708 100644 (file)
@@ -7,3 +7,5 @@
 socket transparent 0;ok
 socket transparent 1;ok
 socket transparent 2;fail
+
+socket mark 0x00000005;ok
index c1ac1d12ddfb832f50be7dbc7f22d4d3f878d23c..235c3e94b84c837721b7cf00cfac21cfa7032615 100644 (file)
     }
 ]
 
+# socket mark 0x00000005
+[
+    {
+        "match": {
+            "left": {
+                "socket": {
+                    "key": "mark"
+                }
+            },
+            "right": 5
+        }
+    }
+]
+
index acad2ace9091d5983231521c25fbc4f7a48f8236..687b7a456f89c790967e792f51ccea7f65bb835f 100644 (file)
@@ -28,3 +28,18 @@ inet sockin sockchain
   [ socket load transparent => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
+# socket mark 0x00000005
+ip sockip4 sockchain 
+  [ socket load mark => reg 1 ]
+  [ cmp eq reg 1 0x00000005 ]
+
+# socket mark 0x00000005
+ip6 sockip6 sockchain 
+  [ socket load mark => reg 1 ]
+  [ cmp eq reg 1 0x00000005 ]
+
+# socket mark 0x00000005
+inet sockin sockchain 
+  [ socket load mark => reg 1 ]
+  [ cmp eq reg 1 0x00000005 ]
+