From fdda1fad8853b92bac726cbe162b58a5b73c8b4d Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Wed, 27 Mar 2019 11:37:56 +0100 Subject: osf: add version fingerprint support 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 Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 4 +++- src/netlink_linearize.c | 1 + src/osf.c | 13 ++++++++++--- src/parser_bison.y | 8 ++++++-- 4 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index d0eaf5b6..9a2d63df 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -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); diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 61149bff..8df82d5a 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -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); } diff --git a/src/osf.c b/src/osf.c index 9252934d..f0c22393 100644 --- 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; } diff --git a/src/parser_bison.y b/src/parser_bison.y index 343df12a..0a9679c3 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -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); } ; -- cgit v1.2.3