From patchwork Tue Apr 7 18:00:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Leiva X-Patchwork-Id: 1267552 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=s+lmS4bB; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48xZw00Gk9z9sR4 for ; Wed, 8 Apr 2020 04:01:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726523AbgDGSBD (ORCPT ); Tue, 7 Apr 2020 14:01:03 -0400 Received: from mail-oi1-f176.google.com ([209.85.167.176]:34200 "EHLO mail-oi1-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726393AbgDGSBD (ORCPT ); Tue, 7 Apr 2020 14:01:03 -0400 Received: by mail-oi1-f176.google.com with SMTP id d3so2322649oic.1 for ; Tue, 07 Apr 2020 11:01:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=p4Nc0Li+/kD37w7veUXAXlgTSuUYGKPmFqGcLi8n2Fw=; b=s+lmS4bBB86dAUKPuLnVzD/Oqv8IiIgo12m+BhiR5DVl3F97nXgWRov2UxmtUzNEX5 nbACIgBiDx5LzvzJvqIr8Je7bgigoheILfFbIA3z6lu6ka1nSgCl+KYtH5Dm54Gf8W5o 9IVyXR5SjJZJq71oRz0Gm3a1CN697xTqjCaaqHVzh0AsrUPAiXRj33TJU85UYw1HGSJ5 //d5Tivw22dYyDZPRTtrwE1jjgxLA16f3Mm0YqmBFai7DRJIcwIvcWg3Zk9+HUdLjlvq N85NnStabiGR01Y/n4JSrjmcHW5sxFK99FoKvUTvjTVD3mtyXL0ySWx1d6hKGRheokw4 bPvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=p4Nc0Li+/kD37w7veUXAXlgTSuUYGKPmFqGcLi8n2Fw=; b=PD2zp0Cm49OtFvkOwLBJ6Cl8sxEpCTHn8dBuS+vRsiG6cX2kV2HJSZR4sffG1ejO8l QnMk8X8mWjoPNKjbXwl3fci/otEF1bRnAJDjVOTiow3GMl7X0E3Irm6G5qNlqipfgFQJ Eb96vPy2MxBmu5oIFVuyevkCvy48K5mD2rjALXpFCBtFotUHpdWG/AT5DlhW2yiusnd3 gnihIZ7Jqe/G8l1GWleub8MrQSKKIOj0NHB4oEcLHdeCgpdilDEHmF+t8oPGHVO4M9Aw A+GxaGLpPJvKmcgHin35Sd6rL163AerB2J0iPSo6cmFLthlUpscxAStoLkXGv1WAsqhC WG4Q== X-Gm-Message-State: AGi0PubFf18lvmlRLJESA5DfHModwbvbkYJ6tHXPZbSThcCDvimMFBV7 flJ/xYUFI7oBWYGi5JHhwIm8V5mN X-Google-Smtp-Source: APiQypKLyBvuuj8WkcNOGy62NcLC6Tsm4r3zANjnd2AFUXlh4E09JQZD0G568LHZc9y3uoeKtwM9wg== X-Received: by 2002:a05:6808:6cb:: with SMTP id m11mr52518oih.130.1586282461706; Tue, 07 Apr 2020 11:01:01 -0700 (PDT) Received: from localhost.localdomain (CableLink-187-161-107-10.PCs.InterCable.net. [187.161.107.10]) by smtp.gmail.com with ESMTPSA id 186sm5358619ooi.30.2020.04.07.11.01.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 11:01:01 -0700 (PDT) From: Alberto Leiva Popper To: netfilter-devel@vger.kernel.org Cc: Alberto Leiva Popper Subject: [libnftnl PATCH 1/2] expr: add jool support Date: Tue, 7 Apr 2020 13:00:50 -0500 Message-Id: <20200407180050.19095-1-ydahhrk@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Jool statements are used to send packets to the Jool kernel module, which is an IP/ICMP translator: www.jool.mx This feature was requested in Jool's bug tracker: https://github.com/NICMx/Jool/issues/285 Signed-off-by: Alberto Leiva Popper --- include/libnftnl/expr.h | 5 ++ src/Makefile.am | 1 + src/expr/jool.c | 193 ++++++++++++++++++++++++++++++++++++++++ src/expr_ops.c | 2 + 4 files changed, 201 insertions(+) create mode 100644 src/expr/jool.c diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h index cfe456d..5349e15 100644 --- a/include/libnftnl/expr.h +++ b/include/libnftnl/expr.h @@ -299,6 +299,11 @@ enum { NFTNL_EXPR_SYNPROXY_FLAGS, }; +enum { + NFTNL_EXPR_JOOL_TYPE = NFTNL_EXPR_BASE, + NFTNL_EXPR_JOOL_INSTANCE, +}; + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/Makefile.am b/src/Makefile.am index 90b1967..2c1c964 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,6 +57,7 @@ libnftnl_la_SOURCES = utils.c \ expr/hash.c \ expr/socket.c \ expr/synproxy.c \ + expr/jool.c \ expr/osf.c \ expr/xfrm.c \ obj/counter.c \ diff --git a/src/expr/jool.c b/src/expr/jool.c new file mode 100644 index 0000000..bd680c7 --- /dev/null +++ b/src/expr/jool.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include +#include +#include + +enum nft_jool_attributes { + NFTA_JOOL_UNSPEC, + NFTA_JOOL_TYPE, + NFTA_JOOL_INSTANCE, + __NFTA_JOOL_MAX, +}; + +#define NFTA_JOOL_MAX (__NFTA_JOOL_MAX - 1) + +struct nftnl_expr_jool { + const char *instance; + uint8_t type; +}; + +#define XT_SIIT (1 << 0) +#define XT_NAT64 (1 << 1) + +static int +nftnl_expr_jool_set(struct nftnl_expr *e, uint16_t type, + const void *data, uint32_t data_len) +{ + struct nftnl_expr_jool *jool = nftnl_expr_data(e); + + switch(type) { + case NFTNL_EXPR_JOOL_TYPE: + memcpy(&jool->type, data, sizeof(jool->type)); + break; + case NFTNL_EXPR_JOOL_INSTANCE: + jool->instance = strdup(data); + if (!jool->instance) + return -1; + break; + default: + return -1; + } + return 0; +} + +static const void * +nftnl_expr_jool_get(const struct nftnl_expr *e, uint16_t type, + uint32_t *data_len) +{ + struct nftnl_expr_jool *jool = nftnl_expr_data(e); + + switch(type) { + case NFTNL_EXPR_JOOL_TYPE: + *data_len = sizeof(jool->type); + return &jool->type; + case NFTNL_EXPR_JOOL_INSTANCE: + *data_len = strlen(jool->instance) + 1; + return jool->instance; + } + return NULL; +} + +static int +nftnl_expr_jool_cb(const struct nlattr *attr, void *data) +{ + const struct nlattr **tb = data; + int type = mnl_attr_get_type(attr); + + if (mnl_attr_type_valid(attr, NFTA_JOOL_MAX) < 0) + return MNL_CB_OK; + + switch(type) { + case NFTNL_EXPR_JOOL_TYPE: + if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) + abi_breakage(); + break; + case NFTNL_EXPR_JOOL_INSTANCE: + if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) + abi_breakage(); + break; + } + + tb[type] = attr; + return MNL_CB_OK; +} + +static void +nftnl_expr_jool_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) +{ + struct nftnl_expr_jool *jool = nftnl_expr_data(e); + + if (e->flags & (1 << NFTNL_EXPR_JOOL_TYPE)) + mnl_attr_put_u8(nlh, NFTA_JOOL_TYPE, jool->type); + if (e->flags & (1 << NFTNL_EXPR_JOOL_INSTANCE)) + mnl_attr_put_strz(nlh, NFTA_JOOL_INSTANCE, jool->instance); +} + +static int +nftnl_expr_jool_parse(struct nftnl_expr *e, struct nlattr *attr) +{ + struct nftnl_expr_jool *jool = nftnl_expr_data(e); + struct nlattr *tb[NFTA_JOOL_MAX+1] = {}; + + if (mnl_attr_parse_nested(attr, nftnl_expr_jool_cb, tb) < 0) + return -1; + + if (tb[NFTA_JOOL_TYPE]) { + jool->type = mnl_attr_get_u8(tb[NFTA_JOOL_TYPE]); + e->flags |= (1 << NFTNL_EXPR_JOOL_TYPE); + } + if (tb[NFTA_JOOL_INSTANCE]) { + jool->instance = + strdup(mnl_attr_get_str(tb[NFTA_JOOL_INSTANCE])); + if (!jool->instance) + return -1; + e->flags |= (1 << NFTNL_EXPR_JOOL_INSTANCE); + } + + return 0; +} + +static const char *jt2str(uint8_t xt) +{ + switch (xt) { + case XT_SIIT: + return "siit"; + case XT_NAT64: + return "nat64"; + default: + return "unknown"; + } +} + +static int +nftnl_expr_jool_snprintf_default(char *buf, size_t size, + const struct nftnl_expr *e) +{ + struct nftnl_expr_jool *jool = nftnl_expr_data(e); + int ret, remain = size, offset = 0; + + if (nftnl_expr_is_set(e, NFTNL_EXPR_JOOL_TYPE)) { + ret = snprintf(buf + offset, remain, "type %s ", + jt2str(jool->type)); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + + if (e->flags & (1 << NFTNL_EXPR_JOOL_INSTANCE)) { + ret = snprintf(buf, size, "instance %s ", jool->instance); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + + return offset; +} + +static int +nftnl_expr_jool_snprintf(char *buf, size_t len, uint32_t type, + uint32_t flags, const struct nftnl_expr *e) +{ + switch(type) { + case NFTNL_OUTPUT_DEFAULT: + return nftnl_expr_jool_snprintf_default(buf, len, e); + case NFTNL_OUTPUT_XML: + case NFTNL_OUTPUT_JSON: + default: + break; + } + return -1; +} + +static void +nftnl_expr_jool_free(const struct nftnl_expr *e) +{ + struct nftnl_expr_jool *jool = nftnl_expr_data(e); + + xfree(jool->instance); +} + +struct expr_ops expr_ops_jool = { + .name = "jool", + .alloc_len = sizeof(struct nftnl_expr_jool), + .max_attr = NFTA_JOOL_MAX, + .free = nftnl_expr_jool_free, + .set = nftnl_expr_jool_set, + .get = nftnl_expr_jool_get, + .parse = nftnl_expr_jool_parse, + .build = nftnl_expr_jool_build, + .snprintf = nftnl_expr_jool_snprintf, +}; diff --git a/src/expr_ops.c b/src/expr_ops.c index 3538dd6..80b9a86 100644 --- a/src/expr_ops.c +++ b/src/expr_ops.c @@ -38,6 +38,7 @@ extern struct expr_ops expr_ops_fib; extern struct expr_ops expr_ops_flow; extern struct expr_ops expr_ops_socket; extern struct expr_ops expr_ops_synproxy; +extern struct expr_ops expr_ops_jool; extern struct expr_ops expr_ops_tunnel; extern struct expr_ops expr_ops_osf; extern struct expr_ops expr_ops_xfrm; @@ -82,6 +83,7 @@ static struct expr_ops *expr_ops[] = { &expr_ops_flow, &expr_ops_socket, &expr_ops_synproxy, + &expr_ops_jool, &expr_ops_tunnel, &expr_ops_osf, &expr_ops_xfrm, From patchwork Tue Apr 7 18:01:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Leiva X-Patchwork-Id: 1267553 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=FENWRjAE; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48xZws3TxSz9sQx for ; Wed, 8 Apr 2020 04:01:49 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726528AbgDGSBt (ORCPT ); Tue, 7 Apr 2020 14:01:49 -0400 Received: from mail-ot1-f65.google.com ([209.85.210.65]:34565 "EHLO mail-ot1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726393AbgDGSBs (ORCPT ); Tue, 7 Apr 2020 14:01:48 -0400 Received: by mail-ot1-f65.google.com with SMTP id m2so4108897otr.1 for ; Tue, 07 Apr 2020 11:01:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=krSFrM2rn6yIeERZnwPDBQz2Vv1eUV4I06gqO7th6cY=; b=FENWRjAE5f4MDgWheoUDW7r4+od23mztohtenyuYBa0DQUFlDiajoEEBm15hAj/VKU wnivisKDWdzY/neN8I0BRfl7LI6vwgUJRLevxuSe69APrAwr5id5BOcxciJYa3DJmtkJ tiFhAiIjIUkkjb3kVzJm+ycwG0U2tRdFC9IlGanvwSjq493dy9xy5QJhyGFDWpSITm8T OJF6A1/kkjBaNz05Ks/NNuozM/K52/Dh9iHmq/ypHR3Erul0wnwddURVjDE7NkVhZix8 eZzs+yP7XOz2N8t3FETShYGozQy0WAwkpkz71t9INizJn64cDWD4aCbPWNiz2hQe/u9L aeHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=krSFrM2rn6yIeERZnwPDBQz2Vv1eUV4I06gqO7th6cY=; b=UrR7eRoKmtuj9j7NWxr1Un7zwt/IYH5RduUgQ7+zWHyC3CDtX/n7C1ljYbQpJD2515 U7XkXI1jNPSd+ZYPcnwJIWHv9Qz4MUMaYiv6Z4gpSEYdmt00Dyh/TMayilnAN0fIMhsQ AXSr+4fRd9mrqQmqp1zyQrvuPay98FAigi7aftcNH8Xoy0gEAr6ynErIIaWKe7R5SXaB UeLIbmWgmtEQxrlAwKSQ5XoFCVc8bR8zgWEpEgxYU0C2BUhrETbkG3NX6cauRnqQMv1S vcLWUzuZgrmxMCAuoKG2lmPPVibRs6S2w5QjYaU1JhYqAx/DcMUy6KZBdAM8nwDErBZI RkWQ== X-Gm-Message-State: AGi0PubiiBEetTtcHj8UZokTI8aAvTCHk0QxMwtprC+GZwjYI4k31F4k aOfTfP+m51RPL7N8Se7td6UT+P9o X-Google-Smtp-Source: APiQypKw2n2Xflq4Iit6NAhesE2YI9BKOMlzG8HUUi9SPO6uBeJAthQMqLgLOkUTwlJll6+x7OJdXA== X-Received: by 2002:a05:6830:3151:: with SMTP id c17mr2767449ots.310.1586282491846; Tue, 07 Apr 2020 11:01:31 -0700 (PDT) Received: from localhost.localdomain (CableLink-187-161-107-10.PCs.InterCable.net. [187.161.107.10]) by smtp.gmail.com with ESMTPSA id p25sm4382747oth.49.2020.04.07.11.01.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 11:01:31 -0700 (PDT) From: Alberto Leiva Popper To: netfilter-devel@vger.kernel.org Cc: Alberto Leiva Popper Subject: [nft PATCH 2/2] expr: add jool expressions Date: Tue, 7 Apr 2020 13:01:24 -0500 Message-Id: <20200407180124.19169-1-ydahhrk@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Jool statements are used to send packets to the Jool kernel module, which is an IP/ICMP translator: www.jool.mx Sample usage: modprobe jool jool instance add "name" --iptables -6 64:ff9b::/96 sudo nft add rule inet table1 chain1 jool nat64 "name" This feature was requested in Jool's bug tracker: https://github.com/NICMx/Jool/issues/285 Signed-off-by: Alberto Leiva Popper --- include/statement.h | 15 +++++++++++++++ src/evaluate.c | 1 + src/netlink_delinearize.c | 15 +++++++++++++++ src/netlink_linearize.c | 15 +++++++++++++++ src/parser_bison.y | 31 +++++++++++++++++++++++++++++++ src/scanner.l | 2 ++ src/statement.c | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 112 insertions(+) diff --git a/include/statement.h b/include/statement.h index 8fb459ca..8f4cb0fd 100644 --- a/include/statement.h +++ b/include/statement.h @@ -253,6 +253,18 @@ struct xt_stmt { extern struct stmt *xt_stmt_alloc(const struct location *loc); +enum nft_jool_type { + NFT_JOOL_SIIT = (1 << 0), + NFT_JOOL_NAT64 = (1 << 1), +}; + +struct jool_stmt { + enum nft_jool_type type; + const char *instance; +}; + +extern struct stmt *jool_stmt_alloc(const struct location *loc); + /** * enum stmt_types - statement types * @@ -281,6 +293,7 @@ extern struct stmt *xt_stmt_alloc(const struct location *loc); * @STMT_CONNLIMIT: connection limit statement * @STMT_MAP: map statement * @STMT_SYNPROXY: synproxy statement + * @STMT_JOOL: Jool statement */ enum stmt_types { STMT_INVALID, @@ -309,6 +322,7 @@ enum stmt_types { STMT_CONNLIMIT, STMT_MAP, STMT_SYNPROXY, + STMT_JOOL, }; /** @@ -374,6 +388,7 @@ struct stmt { struct flow_stmt flow; struct map_stmt map; struct synproxy_stmt synproxy; + struct jool_stmt jool; }; }; diff --git a/src/evaluate.c b/src/evaluate.c index fcc79386..592a3cc8 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -3353,6 +3353,7 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) case STMT_QUOTA: case STMT_NOTRACK: case STMT_FLOW_OFFLOAD: + case STMT_JOOL: return 0; case STMT_EXPRESSION: return stmt_evaluate_expr(ctx, stmt); diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 79efda12..58a802f8 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -1106,6 +1106,20 @@ out_err: xfree(stmt); } +static void netlink_parse_jool(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nftnl_expr *nle) +{ + struct stmt *stmt; + + stmt = jool_stmt_alloc(loc); + stmt->jool.type = nftnl_expr_get_u8(nle, NFTNL_EXPR_JOOL_TYPE); + stmt->jool.instance = xstrdup(nftnl_expr_get_str(nle, + NFTNL_EXPR_JOOL_INSTANCE)); + + ctx->stmt = stmt; +} + static void netlink_parse_synproxy(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) @@ -1594,6 +1608,7 @@ static const struct { { .name = "flow_offload", .parse = netlink_parse_flow_offload }, { .name = "xfrm", .parse = netlink_parse_xfrm }, { .name = "synproxy", .parse = netlink_parse_synproxy }, + { .name = "jool", .parse = netlink_parse_jool }, }; static int netlink_parse_expr(const struct nftnl_expr *nle, diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index e70e63b3..c0597f39 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -1434,6 +1434,19 @@ static void netlink_gen_meter_stmt(struct netlink_linearize_ctx *ctx, nftnl_rule_add_expr(ctx->nlr, nle); } +static void netlink_gen_jool_stmt(struct netlink_linearize_ctx *ctx, + const struct stmt *stmt) +{ + struct nftnl_expr *nle; + + nle = alloc_nft_expr("jool"); + + nftnl_expr_set_u8(nle, NFTNL_EXPR_JOOL_TYPE, stmt->jool.type); + nftnl_expr_set_str(nle, NFTNL_EXPR_JOOL_INSTANCE, stmt->jool.instance); + + nftnl_rule_add_expr(ctx->nlr, nle); +} + static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, const struct stmt *stmt) { @@ -1487,6 +1500,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, return netlink_gen_objref_stmt(ctx, stmt); case STMT_MAP: return netlink_gen_map_stmt(ctx, stmt); + case STMT_JOOL: + return netlink_gen_jool_stmt(ctx, stmt); default: BUG("unknown statement type %s\n", stmt->ops->name); } diff --git a/src/parser_bison.y b/src/parser_bison.y index 3e8d6bd6..0999172c 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -523,6 +523,8 @@ int nft_lex(void *, void *, void *); %token FULLY_RANDOM "fully-random" %token PERSISTENT "persistent" +%token JOOL "jool" + %token QUEUE "queue" %token QUEUENUM "num" %token BYPASS "bypass" @@ -642,6 +644,8 @@ int nft_lex(void *, void *, void *); %destructor { stmt_free($$); } tproxy_stmt %type synproxy_stmt synproxy_stmt_alloc %destructor { stmt_free($$); } synproxy_stmt synproxy_stmt_alloc +%type jool_stmt jool_stmt_alloc +%destructor { stmt_free($$); } jool_stmt jool_stmt_alloc %type queue_stmt queue_stmt_alloc @@ -2492,6 +2496,7 @@ stmt : verdict_stmt | set_stmt | map_stmt | synproxy_stmt + | jool_stmt ; verdict_stmt : verdict_expr @@ -3014,6 +3019,32 @@ synproxy_sack : /* empty */ { $$ = 0; } } ; +jool_stmt : jool_stmt_alloc jool_opts + ; + +jool_stmt_alloc : JOOL + { + $$ = jool_stmt_alloc(&@$); + } + ; + +jool_opts : string string + { + if (!strcmp("siit", $1)) + $0->jool.type = NFT_JOOL_SIIT; + else if (!strcmp("nat64", $1)) + $0->jool.type = NFT_JOOL_NAT64; + else { + erec_queue(error(&@1, "invalid jool type (expected siit or nat64)"), + state->msgs); + xfree($1); + YYERROR; + } + xfree($1); + $0->jool.instance = $2; + } + ; + primary_stmt_expr : symbol_expr { $$ = $1; } | integer_expr { $$ = $1; } | boolean_expr { $$ = $1; } diff --git a/src/scanner.l b/src/scanner.l index 45699c85..9e8d637c 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -375,6 +375,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "fully-random" { return FULLY_RANDOM; } "persistent" { return PERSISTENT; } +"jool" { return JOOL; } + "ll" { return LL_HDR; } "nh" { return NETWORK_HDR; } "th" { return TRANSPORT_HDR; } diff --git a/src/statement.c b/src/statement.c index 182edac8..4ec27658 100644 --- a/src/statement.c +++ b/src/statement.c @@ -942,3 +942,36 @@ struct stmt *synproxy_stmt_alloc(const struct location *loc) { return stmt_alloc(loc, &synproxy_stmt_ops); } + +static void jool_stmt_print(const struct stmt *stmt, struct output_ctx *octx) +{ + const char *type = ""; + + switch (stmt->jool.type) { + case NFT_JOOL_SIIT: + type = "siit"; + break; + case NFT_JOOL_NAT64: + type = "nat64"; + break; + } + + nft_print(octx, "jool \"%s\" \"%s\"", type, stmt->jool.instance); +} + +static void jool_stmt_destroy(struct stmt *stmt) +{ + xfree(stmt->jool.instance); +} + +static const struct stmt_ops jool_stmt_ops = { + .type = STMT_JOOL, + .name = "jool", + .print = jool_stmt_print, + .destroy = jool_stmt_destroy, +}; + +struct stmt *jool_stmt_alloc(const struct location *loc) +{ + return stmt_alloc(loc, &jool_stmt_ops); +}