]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
osf: add version fingerprint support
authorFernando Fernandez Mancera <ffmancera@riseup.net>
Wed, 27 Mar 2019 10:37:56 +0000 (11:37 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 8 Apr 2019 21:46:50 +0000 (23:46 +0200)
Add support for version fingerprint in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl skip name "Linux"
osf ttl skip version "Linux:4.20"
}
}

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/expression.h
include/linux/netfilter/nf_tables.h
include/osf.h
src/netlink_delinearize.c
src/netlink_linearize.c
src/osf.c
src/parser_bison.y

index 6d72f64c4fea68eb3e8290881520ad05b3a38661..6416ac090d9fd2d2ceff9747120fb01ca0d8e034 100644 (file)
@@ -350,6 +350,7 @@ struct expr {
                struct {
                        /* EXPR_OSF */
                        uint8_t                 ttl;
+                       uint32_t                flags;
                } osf;
        };
 };
index 37036be07296d4293b541d677f987f848e28b428..09a7b9edd0b9649e795e6c6d92bb1f687bb1e1bf 100644 (file)
@@ -944,15 +944,21 @@ enum nft_socket_keys {
  *
  * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
  * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ * @NFTA_OSF_FLAGS: flags (NLA_U32)
  */
 enum nft_osf_attributes {
        NFTA_OSF_UNSPEC,
        NFTA_OSF_DREG,
        NFTA_OSF_TTL,
+       NFTA_OSF_FLAGS,
        __NFTA_OSF_MAX
 };
 #define NFT_OSF_MAX            (__NFTA_OSF_MAX - 1)
 
+enum nft_osf_flags {
+       NFT_OSF_F_VERSION       = 1 << 0,       /* check fingerprint version */
+};
+
 /**
  * enum nft_ct_keys - nf_tables ct expression keys
  *
index 23ea34d371402e43367ba1d43625ff722102e4a1..8f6f5840620e21d6a2d3ccfe109e93b10ada3f10 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
-struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl,
+                           const uint32_t flags);
 
 extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
 
index d0eaf5b622037585bbccee1f2005a534d3273c14..9a2d63dfd990acf544b68f53380024ea3e809c61 100644 (file)
@@ -655,10 +655,12 @@ static void netlink_parse_osf(struct netlink_parse_ctx *ctx,
 {
        enum nft_registers dreg;
        struct expr *expr;
+       uint32_t flags;
        uint8_t ttl;
 
        ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
-       expr = osf_expr_alloc(loc, ttl);
+       flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_OSF_FLAGS);
+       expr = osf_expr_alloc(loc, ttl, flags);
 
        dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
        netlink_set_register(ctx, dreg, expr);
index 61149bffcc83c71ff9b6a8fb22162c80c7334dcb..8df82d5af4f2051a8a22247c5a0e8bcb452456eb 100644 (file)
@@ -228,6 +228,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx *ctx,
        nle = alloc_nft_expr("osf");
        netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
        nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
+       nftnl_expr_set_u32(nle, NFTNL_EXPR_OSF_FLAGS, expr->osf.flags);
        nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
index 9252934dbcfae8fbc4e26e2db2bc678d732ddc6e..f0c22393cd85061aeb5e7d178f658623730da73e 100644 (file)
--- a/src/osf.c
+++ b/src/osf.c
@@ -19,17 +19,22 @@ static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
        const char *ttl_str = osf_ttl_int_to_str(expr->osf.ttl);
 
-       nft_print(octx, "osf %sname", ttl_str);
+       if (expr->osf.flags & NFT_OSF_F_VERSION)
+               nft_print(octx, "osf %sversion", ttl_str);
+       else
+               nft_print(octx, "osf %sname", ttl_str);
 }
 
 static void osf_expr_clone(struct expr *new, const struct expr *expr)
 {
        new->osf.ttl = expr->osf.ttl;
+       new->osf.flags = expr->osf.flags;
 }
 
 static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
-       return e1->osf.ttl == e2->osf.ttl;
+       return (e1->osf.ttl == e2->osf.ttl) &&
+              (e1->osf.flags == e2->osf.flags);
 }
 
 const struct expr_ops osf_expr_ops = {
@@ -41,7 +46,8 @@ const struct expr_ops osf_expr_ops = {
        .json           = osf_expr_json,
 };
 
-struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl)
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl,
+                           const uint32_t flags)
 {
        unsigned int len = NFT_OSF_MAXGENRELEN * BITS_PER_BYTE;
        const struct datatype *type = &string_type;
@@ -50,6 +56,7 @@ struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl)
        expr = expr_alloc(loc, EXPR_OSF, type,
                          BYTEORDER_HOST_ENDIAN, len);
        expr->osf.ttl = ttl;
+       expr->osf.flags = flags;
 
        return expr;
 }
index 343df12a3281f4c5ef5d1307287771a711093eda..0a9679c32e0f9644e802487089879ab6e59f6946 100644 (file)
@@ -3196,9 +3196,13 @@ fib_tuple                :       fib_flag        DOT     fib_tuple
                        |       fib_flag
                        ;
 
-osf_expr               :       OSF     osf_ttl         NAME
+osf_expr               :       OSF     osf_ttl         HDRVERSION
                        {
-                               $$ = osf_expr_alloc(&@$, $2);
+                               $$ = osf_expr_alloc(&@$, $2, NFT_OSF_F_VERSION);
+                       }
+                       |       OSF     osf_ttl         NAME
+                       {
+                               $$ = osf_expr_alloc(&@$, $2, 0);
                        }
                        ;