* [PATCH nft,v1 1/2] src: add tunnel support
@ 2019-07-25 9:13 Pablo Neira Ayuso
2019-07-25 9:14 ` [PATCH nft,v1 2/2] src: add tunnel expression support Pablo Neira Ayuso
0 siblings, 1 reply; 3+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-25 9:13 UTC (permalink / raw)
To: netfilter-devel
This patch adds support to attach tunnel metadata.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/rule.h | 15 +++++++++++
src/evaluate.c | 23 ++++++++++++++++
src/mnl.c | 38 +++++++++++++++++++++++++++
src/netlink.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/parser_bison.y | 50 ++++++++++++++++++++++++++++++++---
src/rule.c | 21 +++++++++++++++
src/scanner.l | 4 ++-
7 files changed, 224 insertions(+), 4 deletions(-)
diff --git a/include/rule.h b/include/rule.h
index ee881b9ccd17..00c16e39e980 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -406,6 +406,18 @@ struct secmark {
char ctx[NFT_SECMARK_CTX_MAXLEN];
};
+struct tunnel {
+ const char *type;
+ uint32_t id;
+ struct expr *src;
+ struct expr *dst;
+ uint32_t label;
+ uint16_t sport;
+ uint16_t dport;
+ uint8_t tos;
+ uint8_t ttl;
+};
+
/**
* struct obj - nftables stateful object statement
*
@@ -426,6 +438,7 @@ struct obj {
struct quota quota;
struct ct_helper ct_helper;
struct limit limit;
+ struct tunnel tunnel;
struct ct_timeout ct_timeout;
struct secmark secmark;
struct ct_expect ct_expect;
@@ -558,6 +571,8 @@ enum cmd_obj {
CMD_OBJ_CT_HELPERS,
CMD_OBJ_LIMIT,
CMD_OBJ_LIMITS,
+ CMD_OBJ_TUNNEL,
+ CMD_OBJ_TUNNELS,
CMD_OBJ_FLOWTABLE,
CMD_OBJ_FLOWTABLES,
CMD_OBJ_CT_TIMEOUT,
diff --git a/src/evaluate.c b/src/evaluate.c
index 48c65cd2f35a..0c2a8d0a9571 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3520,9 +3520,31 @@ static int ct_timeout_evaluate(struct eval_ctx *ctx, struct obj *obj)
return 0;
}
+static int tunnel_evaluate(struct eval_ctx *ctx, struct obj *obj)
+{
+ if (obj->tunnel.src != NULL) {
+ __expr_set_context(&ctx->ectx, &ipaddr_type,
+ BYTEORDER_BIG_ENDIAN,
+ sizeof(struct in_addr) * BITS_PER_BYTE, 0);
+ if (expr_evaluate(ctx, &obj->tunnel.src) < 0)
+ return -1;
+ }
+ if (obj->tunnel.dst != NULL) {
+ __expr_set_context(&ctx->ectx, &ipaddr_type,
+ BYTEORDER_BIG_ENDIAN,
+ sizeof(struct in_addr) * BITS_PER_BYTE, 0);
+ if (expr_evaluate(ctx, &obj->tunnel.dst) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
static int obj_evaluate(struct eval_ctx *ctx, struct obj *obj)
{
switch (obj->type) {
+ case NFT_OBJECT_TUNNEL:
+ return tunnel_evaluate(ctx, obj);
case NFT_OBJECT_CT_TIMEOUT:
return ct_timeout_evaluate(ctx, obj);
case NFT_OBJECT_CT_EXPECT:
@@ -3604,6 +3626,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_QUOTA:
case CMD_OBJ_CT_HELPER:
case CMD_OBJ_LIMIT:
+ case CMD_OBJ_TUNNEL:
case CMD_OBJ_CT_TIMEOUT:
case CMD_OBJ_SECMARK:
case CMD_OBJ_CT_EXPECT:
diff --git a/src/mnl.c b/src/mnl.c
index eab8d5486437..e9021e4515ae 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -951,6 +951,7 @@ int mnl_nft_obj_add(struct netlink_ctx *ctx, const struct cmd *cmd,
unsigned int flags)
{
struct obj *obj = cmd->object;
+ struct nft_data_linearize nld;
struct nftnl_obj *nlo;
struct nlmsghdr *nlh;
@@ -985,6 +986,43 @@ int mnl_nft_obj_add(struct netlink_ctx *ctx, const struct cmd *cmd,
nftnl_obj_set_u32(nlo, NFTNL_OBJ_LIMIT_TYPE, obj->limit.type);
nftnl_obj_set_u32(nlo, NFTNL_OBJ_LIMIT_FLAGS, obj->limit.flags);
break;
+ case NFT_OBJECT_TUNNEL:
+ nftnl_obj_set_u64(nlo, NFTNL_OBJ_TUNNEL_ID, obj->tunnel.id);
+ if (obj->tunnel.sport)
+ nftnl_obj_set_u16(nlo, NFTNL_OBJ_TUNNEL_SPORT,
+ obj->tunnel.sport);
+ if (obj->tunnel.dport)
+ nftnl_obj_set_u16(nlo, NFTNL_OBJ_TUNNEL_DPORT,
+ obj->tunnel.dport);
+ if (obj->tunnel.tos)
+ nftnl_obj_set_u16(nlo, NFTNL_OBJ_TUNNEL_TOS,
+ obj->tunnel.tos);
+ if (obj->tunnel.ttl)
+ nftnl_obj_set_u16(nlo, NFTNL_OBJ_TUNNEL_TTL,
+ obj->tunnel.ttl);
+ if (obj->tunnel.src) {
+ netlink_gen_data(obj->tunnel.src, &nld);
+ if (nld.len == sizeof(struct in_addr)) {
+ nftnl_obj_set_u32(nlo,
+ NFTNL_OBJ_TUNNEL_IPV4_SRC,
+ nld.value[0]);
+ }
+ } else {
+ nftnl_obj_set(nlo, NFTNL_OBJ_TUNNEL_IPV6_SRC,
+ nld.value);
+ }
+ if (obj->tunnel.dst) {
+ netlink_gen_data(obj->tunnel.dst, &nld);
+ if (nld.len == sizeof(struct in_addr)) {
+ nftnl_obj_set_u32(nlo,
+ NFTNL_OBJ_TUNNEL_IPV4_DST,
+ nld.value[0]);
+ } else {
+ nftnl_obj_set(nlo, NFTNL_OBJ_TUNNEL_IPV6_DST,
+ nld.value);
+ }
+ }
+ break;
case NFT_OBJECT_CT_HELPER:
nftnl_obj_set_str(nlo, NFTNL_OBJ_CT_HELPER_NAME,
obj->ct_helper.name);
diff --git a/src/netlink.c b/src/netlink.c
index 14b0df410726..bcb5ecc6bb32 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -936,6 +936,51 @@ void netlink_dump_obj(struct nftnl_obj *nln, struct netlink_ctx *ctx)
fprintf(fp, "\n");
}
+static struct in6_addr all_zeroes;
+
+static struct expr *netlink_obj_tunnel_parse_addr(struct nftnl_obj *nlo,
+ int attr)
+{
+ struct nft_data_delinearize nld;
+ const struct datatype *dtype;
+ const uint32_t *addr6;
+ struct expr *expr;
+ uint32_t addr;
+
+ memset(&nld, 0, sizeof(nld));
+
+ switch (attr) {
+ case NFTNL_OBJ_TUNNEL_IPV4_SRC:
+ case NFTNL_OBJ_TUNNEL_IPV4_DST:
+ addr = nftnl_obj_get_u32(nlo, attr);
+ if (!addr)
+ return NULL;
+
+ dtype = &ipaddr_type;
+ nld.value = &addr;
+ nld.len = sizeof(struct in_addr);
+ break;
+ case NFTNL_OBJ_TUNNEL_IPV6_SRC:
+ case NFTNL_OBJ_TUNNEL_IPV6_DST:
+ addr6 = nftnl_obj_get(nlo, attr);
+ if (!memcmp(addr6, &all_zeroes, sizeof(all_zeroes)))
+ return NULL;
+
+ dtype = &ip6addr_type;
+ nld.value = addr6;
+ nld.len = sizeof(struct in6_addr);
+ break;
+ default:
+ return NULL;
+ }
+
+ expr = netlink_alloc_value(&netlink_location, &nld);
+ expr->dtype = dtype;
+ expr->byteorder = BYTEORDER_BIG_ENDIAN;
+
+ return expr;
+}
+
struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
struct nftnl_obj *nlo)
{
@@ -1008,6 +1053,38 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
obj->ct_expect.size =
nftnl_obj_get_u8(nlo, NFTNL_OBJ_CT_EXPECT_SIZE);
break;
+ case NFT_OBJECT_TUNNEL:
+ obj->tunnel.id = nftnl_obj_get_u64(nlo, NFTNL_OBJ_TUNNEL_ID);
+ obj->tunnel.sport =
+ nftnl_obj_get_u16(nlo, NFTNL_OBJ_TUNNEL_SPORT);
+ obj->tunnel.dport =
+ nftnl_obj_get_u16(nlo, NFTNL_OBJ_TUNNEL_DPORT);
+ obj->tunnel.tos =
+ nftnl_obj_get_u16(nlo, NFTNL_OBJ_TUNNEL_TOS) >> 2;
+ obj->tunnel.ttl =
+ nftnl_obj_get_u16(nlo, NFTNL_OBJ_TUNNEL_TTL);
+
+ if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_IPV4_SRC)) {
+ obj->tunnel.src =
+ netlink_obj_tunnel_parse_addr(nlo,
+ NFTNL_OBJ_TUNNEL_IPV4_SRC);
+ }
+ if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_IPV4_DST)) {
+ obj->tunnel.dst =
+ netlink_obj_tunnel_parse_addr(nlo,
+ NFTNL_OBJ_TUNNEL_IPV4_DST);
+ }
+ if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_IPV6_SRC)) {
+ obj->tunnel.src =
+ netlink_obj_tunnel_parse_addr(nlo,
+ NFTNL_OBJ_TUNNEL_IPV6_SRC);
+ }
+ if (nftnl_obj_is_set(nlo, NFTNL_OBJ_TUNNEL_IPV6_DST)) {
+ obj->tunnel.dst =
+ netlink_obj_tunnel_parse_addr(nlo,
+ NFTNL_OBJ_TUNNEL_IPV6_DST);
+ }
+ break;
}
obj->type = type;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 53e669521efa..d3b64b641700 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -459,6 +459,7 @@ int nft_lex(void *, void *, void *);
%token COUNTERS "counters"
%token QUOTAS "quotas"
%token LIMITS "limits"
+%token TUNNELS "tunnels"
%token HELPERS "helpers"
%token LOG "log"
@@ -589,7 +590,7 @@ int nft_lex(void *, void *, void *);
%type <flowtable> flowtable_block_alloc flowtable_block
%destructor { flowtable_free($$); } flowtable_block_alloc
-%type <obj> obj_block_alloc counter_block quota_block ct_helper_block ct_timeout_block ct_expect_block limit_block secmark_block
+%type <obj> obj_block_alloc counter_block quota_block ct_helper_block ct_timeout_block ct_expect_block tunnel_block limit_block secmark_block
%destructor { obj_free($$); } obj_block_alloc
%type <list> stmt_list
@@ -697,8 +698,8 @@ int nft_lex(void *, void *, void *);
%type <expr> and_rhs_expr exclusive_or_rhs_expr inclusive_or_rhs_expr
%destructor { expr_free($$); } and_rhs_expr exclusive_or_rhs_expr inclusive_or_rhs_expr
-%type <obj> counter_obj quota_obj ct_obj_alloc limit_obj secmark_obj
-%destructor { obj_free($$); } counter_obj quota_obj ct_obj_alloc limit_obj secmark_obj
+%type <obj> counter_obj quota_obj ct_obj_alloc limit_obj tunnel_obj secmark_obj
+%destructor { obj_free($$); } counter_obj quota_obj ct_obj_alloc limit_obj tunnel_obj secmark_obj
%type <expr> relational_expr
%destructor { expr_free($$); } relational_expr
@@ -1009,6 +1010,10 @@ add_cmd : TABLE table_spec
{
$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SECMARK, &$2, &@$, $3);
}
+ | TUNNEL obj_spec tunnel_obj '{' tunnel_block '}' stmt_separator
+ {
+ $$ = cmd_alloc_obj_ct(CMD_ADD, CMD_OBJ_TUNNEL, &$2, &@$, $3);
+ }
;
replace_cmd : RULE ruleid_spec rule
@@ -1102,6 +1107,10 @@ create_cmd : TABLE table_spec
{
$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_SECMARK, &$2, &@$, $3);
}
+ | TUNNEL obj_spec tunnel_obj '{' tunnel_block '}' stmt_separator
+ {
+ $$ = cmd_alloc_obj_ct(CMD_CREATE, CMD_OBJ_TUNNEL, &$2, &@$, $3);
+ }
;
insert_cmd : RULE rule_position rule
@@ -1589,6 +1598,15 @@ table_block : /* empty */ { $$ = $<table>-1; }
list_add_tail(&$4->list, &$1->objs);
$$ = $1;
}
+ | table_block TUNNEL obj_identifier obj_block_alloc '{' tunnel_block '}' stmt_separator
+ {
+ $4->location = @3;
+ $4->type = NFT_OBJECT_TUNNEL;
+ handle_merge(&$4->handle, &$3);
+ handle_free(&$3);
+ list_add_tail(&$4->list, &$1->objs);
+ $$ = $1;
+ }
;
chain_block_alloc : /* empty */
@@ -3698,6 +3716,32 @@ limit_obj : limit_config
}
;
+tunnel_config : TYPE string stmt_separator { $<obj>0->tunnel.type = $2; }
+ | ID NUM stmt_separator { $<obj>0->tunnel.id = $2; }
+ | IP SADDR expr stmt_separator { $<obj>0->tunnel.src = $3; }
+ | IP DADDR expr stmt_separator { $<obj>0->tunnel.dst = $3; }
+ | SPORT NUM stmt_separator { $<obj>0->tunnel.sport = $2; }
+ | DPORT NUM stmt_separator { $<obj>0->tunnel.dport = $2; }
+ | DSCP NUM stmt_separator { $<obj>0->tunnel.tos = $2 << 2; }
+ | TTL NUM stmt_separator { $<obj>0->tunnel.ttl = $2; }
+ ;
+
+tunnel_block : /* empty */ { $$ = $<obj>-1; }
+ | tunnel_block common_block
+ | tunnel_block stmt_separator
+ | tunnel_block tunnel_config
+ {
+ $$ = $1;
+ }
+ ;
+
+tunnel_obj :
+ {
+ $$ = obj_alloc(&@$);
+ $$->type = NFT_OBJECT_TUNNEL;
+ }
+ ;
+
relational_expr : expr /* implicit */ rhs_expr
{
$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
diff --git a/src/rule.c b/src/rule.c
index 293606576044..b99786ba967a 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1442,6 +1442,7 @@ void cmd_free(struct cmd *cmd)
case CMD_OBJ_CT_TIMEOUT:
case CMD_OBJ_CT_EXPECT:
case CMD_OBJ_LIMIT:
+ case CMD_OBJ_TUNNEL:
case CMD_OBJ_SECMARK:
obj_free(cmd->object);
break;
@@ -1533,6 +1534,7 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl)
case CMD_OBJ_CT_TIMEOUT:
case CMD_OBJ_CT_EXPECT:
case CMD_OBJ_LIMIT:
+ case CMD_OBJ_TUNNEL:
case CMD_OBJ_SECMARK:
return mnl_nft_obj_add(ctx, cmd, flags);
case CMD_OBJ_FLOWTABLE:
@@ -1617,6 +1619,8 @@ static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd)
return mnl_nft_obj_del(ctx, cmd, NFT_OBJECT_CT_EXPECT);
case CMD_OBJ_LIMIT:
return mnl_nft_obj_del(ctx, cmd, NFT_OBJECT_LIMIT);
+ case CMD_OBJ_TUNNEL:
+ return mnl_nft_obj_del(ctx, cmd, NFT_OBJECT_TUNNEL);
case CMD_OBJ_SECMARK:
return mnl_nft_obj_del(ctx, cmd, NFT_OBJECT_SECMARK);
case CMD_OBJ_FLOWTABLE:
@@ -1903,6 +1907,18 @@ static void obj_print_data(const struct obj *obj,
nft_print(octx, "%s", opts->nl);
}
break;
+ case NFT_OBJECT_TUNNEL:
+ nft_print(octx, " %s {%s", obj->handle.obj.name, opts->nl);
+
+ nft_print(octx, "%s%sid %u%s",
+ opts->tab, opts->tab, obj->tunnel.id, opts->nl);
+
+ if (obj->tunnel.dst) {
+ nft_print(octx, "%s%sip daddr ",
+ opts->tab, opts->tab);
+ expr_print(obj->tunnel.dst, octx);
+ }
+ break;
default:
nft_print(octx, " unknown {%s", opts->nl);
break;
@@ -1914,6 +1930,7 @@ static const char * const obj_type_name_array[] = {
[NFT_OBJECT_QUOTA] = "quota",
[NFT_OBJECT_CT_HELPER] = "ct helper",
[NFT_OBJECT_LIMIT] = "limit",
+ [NFT_OBJECT_TUNNEL] = "tunnel",
[NFT_OBJECT_CT_TIMEOUT] = "ct timeout",
[NFT_OBJECT_SECMARK] = "secmark",
[NFT_OBJECT_CT_EXPECT] = "ct expectation",
@@ -1931,6 +1948,7 @@ static uint32_t obj_type_cmd_array[NFT_OBJECT_MAX + 1] = {
[NFT_OBJECT_QUOTA] = CMD_OBJ_QUOTA,
[NFT_OBJECT_CT_HELPER] = CMD_OBJ_CT_HELPER,
[NFT_OBJECT_LIMIT] = CMD_OBJ_LIMIT,
+ [NFT_OBJECT_TUNNEL] = CMD_OBJ_TUNNEL,
[NFT_OBJECT_CT_TIMEOUT] = CMD_OBJ_CT_TIMEOUT,
[NFT_OBJECT_SECMARK] = CMD_OBJ_SECMARK,
[NFT_OBJECT_CT_EXPECT] = CMD_OBJ_CT_EXPECT,
@@ -2297,6 +2315,9 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_LIMIT:
case CMD_OBJ_LIMITS:
return do_list_obj(ctx, cmd, NFT_OBJECT_LIMIT);
+ case CMD_OBJ_TUNNEL:
+ case CMD_OBJ_TUNNELS:
+ return do_list_obj(ctx, cmd, NFT_OBJECT_TUNNEL);
case CMD_OBJ_SECMARK:
case CMD_OBJ_SECMARKS:
return do_list_obj(ctx, cmd, NFT_OBJECT_SECMARK);
diff --git a/src/scanner.l b/src/scanner.l
index 4ed5f9241381..f8575638a47b 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -326,6 +326,9 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"quotas" { return QUOTAS; }
"limits" { return LIMITS; }
+"tunnel" { return TUNNEL; }
+"tunnels" { return TUNNELS; }
+
"log" { return LOG; }
"prefix" { return PREFIX; }
"group" { return GROUP; }
@@ -577,7 +580,6 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"reqid" { return REQID; }
"spnum" { return SPNUM; }
"transport" { return TRANSPORT; }
-"tunnel" { return TUNNEL; }
"in" { return IN; }
"out" { return OUT; }
--
2.11.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH nft,v1 2/2] src: add tunnel expression support
2019-07-25 9:13 [PATCH nft,v1 1/2] src: add tunnel support Pablo Neira Ayuso
@ 2019-07-25 9:14 ` Pablo Neira Ayuso
2019-07-25 20:30 ` Jeremy Sowden
0 siblings, 1 reply; 3+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-25 9:14 UTC (permalink / raw)
To: netfilter-devel
This patch allows you to match on tunnel metadata.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/Makefile.am | 4 ++-
include/expression.h | 6 ++++
include/tunnel.h | 33 +++++++++++++++++++++
src/Makefile.am | 1 +
src/evaluate.c | 7 +++++
src/expression.c | 1 +
src/netlink_delinearize.c | 17 +++++++++++
src/netlink_linearize.c | 14 +++++++++
src/parser_bison.y | 33 +++++++++++++++++----
src/scanner.l | 2 ++
src/statement.c | 1 +
src/tunnel.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 188 insertions(+), 6 deletions(-)
create mode 100644 include/tunnel.h
create mode 100644 src/tunnel.c
diff --git a/include/Makefile.am b/include/Makefile.am
index 04a4a619a530..2224c5026836 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = linux \
+uSUBDIRS = linux \
nftables
noinst_HEADERS = cli.h \
@@ -31,8 +31,10 @@ noinst_HEADERS = cli.h \
parser.h \
proto.h \
socket.h \
+ tunnel.h \
rule.h \
rt.h \
+ tunnel.h \
utils.h \
xfrm.h \
xt.h
diff --git a/include/expression.h b/include/expression.h
index 717b67550381..9941149a687b 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -70,6 +70,7 @@ enum expr_types {
EXPR_RT,
EXPR_FIB,
EXPR_XFRM,
+ EXPR_TUNNEL,
};
enum ops {
@@ -196,6 +197,7 @@ enum expr_flags {
#include <hash.h>
#include <ct.h>
#include <socket.h>
+#include <tunnel.h>
#include <osf.h>
#include <xfrm.h>
@@ -311,6 +313,10 @@ struct expr {
enum nft_socket_keys key;
} socket;
struct {
+ /* EXPR_TUNNEL */
+ enum nft_tunnel_keys key;
+ } tunnel;
+ struct {
/* EXPR_RT */
enum nft_rt_keys key;
} rt;
diff --git a/include/tunnel.h b/include/tunnel.h
new file mode 100644
index 000000000000..90d3f8f75ad7
--- /dev/null
+++ b/include/tunnel.h
@@ -0,0 +1,33 @@
+#ifndef NFTABLES_TUNNEL_H
+#define NFTABLES_TUNNEL_H
+
+/**
+ * struct tunnel_template - template for tunnel expressions
+ *
+ * @token: parser token for the expression
+ * @dtype: data type of the expression
+ * @len: length of the expression
+ * @byteorder: byteorder
+ */
+struct tunnel_template {
+ const char *token;
+ const struct datatype *dtype;
+ enum byteorder byteorder;
+ unsigned int len;
+};
+
+extern const struct tunnel_template tunnel_templates[];
+
+#define TUNNEL_TEMPLATE(__token, __dtype, __len, __byteorder) { \
+ .token = (__token), \
+ .dtype = (__dtype), \
+ .len = (__len), \
+ .byteorder = (__byteorder), \
+}
+
+extern struct expr *tunnel_expr_alloc(const struct location *loc,
+ enum nft_tunnel_keys key);
+
+const struct expr_ops tunnel_expr_ops;
+
+#endif /* NFTABLES_TUNNEL_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index e2b531390cef..9b62c5325c8f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,6 +63,7 @@ libnftables_la_SOURCES = \
nfnl_osf.c \
tcpopt.c \
socket.c \
+ tunnel.c \
print.c \
libnftables.c \
libnftables.map
diff --git a/src/evaluate.c b/src/evaluate.c
index 0c2a8d0a9571..dca2bdfea917 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1828,6 +1828,11 @@ static int expr_evaluate_osf(struct eval_ctx *ctx, struct expr **expr)
return expr_evaluate_primary(ctx, expr);
}
+static int expr_evaluate_tunnel(struct eval_ctx *ctx, struct expr **exprp)
+{
+ return expr_evaluate_primary(ctx, exprp);
+}
+
static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp)
{
struct expr *new = expr_clone((*exprp)->sym->expr);
@@ -1884,6 +1889,8 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
return expr_evaluate_meta(ctx, expr);
case EXPR_SOCKET:
return expr_evaluate_socket(ctx, expr);
+ case EXPR_TUNNEL:
+ return expr_evaluate_tunnel(ctx, expr);
case EXPR_OSF:
return expr_evaluate_osf(ctx, expr);
case EXPR_FIB:
diff --git a/src/expression.c b/src/expression.c
index cb49e0b73f5a..c97b2c9dd5c9 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1204,6 +1204,7 @@ const struct expr_ops *expr_ops(const struct expr *e)
case EXPR_RT: return &rt_expr_ops;
case EXPR_FIB: return &fib_expr_ops;
case EXPR_XFRM: return &xfrm_expr_ops;
+ case EXPR_TUNNEL: return &tunnel_expr_ops;
}
BUG("Unknown expression type %d\n", e->etype);
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index fc2574b1dea9..25ce874b35d0 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -668,6 +668,21 @@ static void netlink_parse_osf(struct netlink_parse_ctx *ctx,
netlink_set_register(ctx, dreg, expr);
}
+static void netlink_parse_tunnel(struct netlink_parse_ctx *ctx,
+ const struct location *loc,
+ const struct nftnl_expr *nle)
+{
+ enum nft_registers dreg;
+ struct expr * expr;
+ uint32_t key;
+
+ key = nftnl_expr_get_u32(nle, NFTNL_EXPR_TUNNEL_KEY);
+ expr = tunnel_expr_alloc(loc, key);
+
+ dreg = netlink_parse_register(nle, NFTNL_EXPR_TUNNEL_DREG);
+ netlink_set_register(ctx, dreg, expr);
+}
+
static void netlink_parse_meta_stmt(struct netlink_parse_ctx *ctx,
const struct location *loc,
const struct nftnl_expr *nle)
@@ -1464,6 +1479,7 @@ static const struct {
{ .name = "exthdr", .parse = netlink_parse_exthdr },
{ .name = "meta", .parse = netlink_parse_meta },
{ .name = "socket", .parse = netlink_parse_socket },
+ { .name = "tunnel", .parse = netlink_parse_tunnel },
{ .name = "osf", .parse = netlink_parse_osf },
{ .name = "rt", .parse = netlink_parse_rt },
{ .name = "ct", .parse = netlink_parse_ct },
@@ -2158,6 +2174,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
case EXPR_NUMGEN:
case EXPR_FIB:
case EXPR_SOCKET:
+ case EXPR_TUNNEL:
case EXPR_OSF:
case EXPR_XFRM:
break;
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 498326d0087a..b337539a44cf 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -232,6 +232,18 @@ static void netlink_gen_osf(struct netlink_linearize_ctx *ctx,
nftnl_rule_add_expr(ctx->nlr, nle);
}
+static void netlink_gen_tunnel(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr,
+ enum nft_registers dreg)
+{
+ struct nftnl_expr *nle;
+
+ nle = alloc_nft_expr("tunnel");
+ netlink_put_register(nle, NFTNL_EXPR_TUNNEL_DREG, dreg);
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_TUNNEL_KEY, expr->tunnel.key);
+ nftnl_rule_add_expr(ctx->nlr, nle);
+}
+
static void netlink_gen_numgen(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers dreg)
@@ -735,6 +747,8 @@ static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
return netlink_gen_fib(ctx, expr, dreg);
case EXPR_SOCKET:
return netlink_gen_socket(ctx, expr, dreg);
+ case EXPR_TUNNEL:
+ return netlink_gen_tunnel(ctx, expr, dreg);
case EXPR_OSF:
return netlink_gen_osf(ctx, expr, dreg);
case EXPR_XFRM:
diff --git a/src/parser_bison.y b/src/parser_bison.y
index d3b64b641700..ba28224a3b96 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -225,6 +225,8 @@ int nft_lex(void *, void *, void *);
%token RULESET "ruleset"
%token TRACE "trace"
+%token PATH "path"
+
%token INET "inet"
%token NETDEV "netdev"
@@ -601,8 +603,8 @@ int nft_lex(void *, void *, void *);
%destructor { stmt_free($$); } counter_stmt counter_stmt_alloc stateful_stmt
%type <stmt> payload_stmt
%destructor { stmt_free($$); } payload_stmt
-%type <stmt> ct_stmt
-%destructor { stmt_free($$); } ct_stmt
+%type <stmt> ct_stmt tunnel_stmt
+%destructor { stmt_free($$); } ct_stmt tunnel_stmt
%type <stmt> meta_stmt
%destructor { stmt_free($$); } meta_stmt
%type <stmt> log_stmt log_stmt_alloc
@@ -746,9 +748,9 @@ int nft_lex(void *, void *, void *);
%destructor { expr_free($$); } mh_hdr_expr
%type <val> mh_hdr_field
-%type <expr> meta_expr
-%destructor { expr_free($$); } meta_expr
-%type <val> meta_key meta_key_qualified meta_key_unqualified numgen_type
+%type <expr> meta_expr tunnel_expr
+%destructor { expr_free($$); } meta_expr tunnel_expr
+%type <val> meta_key meta_key_qualified meta_key_unqualified numgen_type tunnel_key
%type <expr> socket_expr
%destructor { expr_free($$); } socket_expr
@@ -2310,6 +2312,7 @@ stmt : verdict_stmt
| tproxy_stmt
| queue_stmt
| ct_stmt
+ | tunnel_stmt
| masq_stmt
| redir_stmt
| dup_stmt
@@ -2788,6 +2791,7 @@ primary_stmt_expr : symbol_expr { $$ = $1; }
| integer_expr { $$ = $1; }
| boolean_expr { $$ = $1; }
| meta_expr { $$ = $1; }
+ | tunnel_expr { $$ = $1; }
| rt_expr { $$ = $1; }
| ct_expr { $$ = $1; }
| numgen_expr { $$ = $1; }
@@ -3243,6 +3247,7 @@ primary_expr : symbol_expr { $$ = $1; }
| exthdr_expr { $$ = $1; }
| exthdr_exists_expr { $$ = $1; }
| meta_expr { $$ = $1; }
+ | tunnel_expr { $$ = $1; }
| socket_expr { $$ = $1; }
| rt_expr { $$ = $1; }
| ct_expr { $$ = $1; }
@@ -4095,6 +4100,16 @@ meta_stmt : META meta_key SET stmt_expr
}
;
+tunnel_key : PATH { $$ = NFT_TUNNEL_PATH; }
+ | ID { $$ = NFT_TUNNEL_ID; }
+ ;
+
+tunnel_expr : TUNNEL tunnel_key
+ {
+ $$ = tunnel_expr_alloc(&@$, $2);
+ }
+ ;
+
socket_expr : SOCKET socket_key
{
$$ = socket_expr_alloc(&@$, $2);
@@ -4326,6 +4341,14 @@ ct_stmt : CT ct_key SET stmt_expr
}
;
+tunnel_stmt : TUNNEL NAME stmt_expr
+ {
+ $$ = objref_stmt_alloc(&@$);
+ $$->objref.type = NFT_OBJECT_TUNNEL;
+ $$->objref.expr = $3;
+ }
+ ;
+
payload_stmt : payload_expr SET stmt_expr
{
if ($1->etype == EXPR_EXTHDR)
diff --git a/src/scanner.l b/src/scanner.l
index f8575638a47b..7bbe5663dddd 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -329,6 +329,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"tunnel" { return TUNNEL; }
"tunnels" { return TUNNELS; }
+"path" { return PATH; }
+
"log" { return LOG; }
"prefix" { return PREFIX; }
"group" { return GROUP; }
diff --git a/src/statement.c b/src/statement.c
index a9e72de3edfd..ab893be664e3 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -207,6 +207,7 @@ static const char *objref_type[NFT_OBJECT_MAX + 1] = {
[NFT_OBJECT_QUOTA] = "quota",
[NFT_OBJECT_CT_HELPER] = "ct helper",
[NFT_OBJECT_LIMIT] = "limit",
+ [NFT_OBJECT_TUNNEL] = "tunnel",
[NFT_OBJECT_CT_TIMEOUT] = "ct timeout",
[NFT_OBJECT_SECMARK] = "secmark",
[NFT_OBJECT_CT_EXPECT] = "ct expectation",
diff --git a/src/tunnel.c b/src/tunnel.c
new file mode 100644
index 000000000000..de01622246ef
--- /dev/null
+++ b/src/tunnel.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <pwd.h>
+#include <grp.h>
+#include <arpa/inet.h>
+#include <linux/netfilter.h>
+#include <linux/pkt_sched.h>
+#include <linux/if_packet.h>
+
+#include <nftables.h>
+#include <expression.h>
+#include <datatype.h>
+#include <tunnel.h>
+#include <gmputil.h>
+#include <utils.h>
+#include <erec.h>
+
+const struct tunnel_template tunnel_templates[] = {
+ [NFT_TUNNEL_PATH] = META_TEMPLATE("path", &boolean_type,
+ BITS_PER_BYTE, BYTEORDER_HOST_ENDIAN),
+ [NFT_TUNNEL_ID] = META_TEMPLATE("id", &integer_type,
+ 4 * 8, BYTEORDER_HOST_ENDIAN),
+};
+
+static void tunnel_expr_print(const struct expr *expr, struct output_ctx *octx)
+{
+ nft_print(octx, "tunnel %s",
+ tunnel_templates[expr->tunnel.key].token);
+}
+
+static bool tunnel_expr_cmp(const struct expr *e1, const struct expr *e2)
+{
+ return e1->tunnel.key == e2->tunnel.key;
+}
+
+static void tunnel_expr_clone(struct expr *new, const struct expr *expr)
+{
+ new->tunnel.key = expr->tunnel.key;
+}
+
+const struct expr_ops tunnel_expr_ops = {
+ .type = EXPR_TUNNEL,
+ .name = "tunnel",
+ .print = tunnel_expr_print,
+ .cmp = tunnel_expr_cmp,
+ .clone = tunnel_expr_clone,
+};
+
+struct expr *tunnel_expr_alloc(const struct location *loc,
+ enum nft_tunnel_keys key)
+{
+ const struct tunnel_template *tmpl = &tunnel_templates[key];
+ struct expr *expr;
+
+ expr = expr_alloc(loc, EXPR_TUNNEL, tmpl->dtype, tmpl->byteorder,
+ tmpl->len);
+ expr->tunnel.key = key;
+
+ return expr;
+}
--
2.11.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH nft,v1 2/2] src: add tunnel expression support
2019-07-25 9:14 ` [PATCH nft,v1 2/2] src: add tunnel expression support Pablo Neira Ayuso
@ 2019-07-25 20:30 ` Jeremy Sowden
0 siblings, 0 replies; 3+ messages in thread
From: Jeremy Sowden @ 2019-07-25 20:30 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 13590 bytes --]
On 2019-07-25, at 11:14:00 +0200, Pablo Neira Ayuso wrote:
> This patch allows you to match on tunnel metadata.
>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> include/Makefile.am | 4 ++-
> include/expression.h | 6 ++++
> include/tunnel.h | 33 +++++++++++++++++++++
> src/Makefile.am | 1 +
> src/evaluate.c | 7 +++++
> src/expression.c | 1 +
> src/netlink_delinearize.c | 17 +++++++++++
> src/netlink_linearize.c | 14 +++++++++
> src/parser_bison.y | 33 +++++++++++++++++----
> src/scanner.l | 2 ++
> src/statement.c | 1 +
> src/tunnel.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
> 12 files changed, 188 insertions(+), 6 deletions(-)
> create mode 100644 include/tunnel.h
> create mode 100644 src/tunnel.c
>
> diff --git a/include/Makefile.am b/include/Makefile.am
> index 04a4a619a530..2224c5026836 100644
> --- a/include/Makefile.am
> +++ b/include/Makefile.am
> @@ -1,4 +1,4 @@
> -SUBDIRS = linux \
> +uSUBDIRS = linux \
Typo?
> nftables
>
> noinst_HEADERS = cli.h \
> @@ -31,8 +31,10 @@ noinst_HEADERS = cli.h \
> parser.h \
> proto.h \
> socket.h \
> + tunnel.h \
> rule.h \
> rt.h \
> + tunnel.h \
> utils.h \
> xfrm.h \
> xt.h
> diff --git a/include/expression.h b/include/expression.h
> index 717b67550381..9941149a687b 100644
> --- a/include/expression.h
> +++ b/include/expression.h
> @@ -70,6 +70,7 @@ enum expr_types {
> EXPR_RT,
> EXPR_FIB,
> EXPR_XFRM,
> + EXPR_TUNNEL,
> };
>
> enum ops {
> @@ -196,6 +197,7 @@ enum expr_flags {
> #include <hash.h>
> #include <ct.h>
> #include <socket.h>
> +#include <tunnel.h>
> #include <osf.h>
> #include <xfrm.h>
>
> @@ -311,6 +313,10 @@ struct expr {
> enum nft_socket_keys key;
> } socket;
> struct {
> + /* EXPR_TUNNEL */
> + enum nft_tunnel_keys key;
> + } tunnel;
> + struct {
> /* EXPR_RT */
> enum nft_rt_keys key;
> } rt;
> diff --git a/include/tunnel.h b/include/tunnel.h
> new file mode 100644
> index 000000000000..90d3f8f75ad7
> --- /dev/null
> +++ b/include/tunnel.h
> @@ -0,0 +1,33 @@
> +#ifndef NFTABLES_TUNNEL_H
> +#define NFTABLES_TUNNEL_H
> +
> +/**
> + * struct tunnel_template - template for tunnel expressions
> + *
> + * @token: parser token for the expression
> + * @dtype: data type of the expression
> + * @len: length of the expression
> + * @byteorder: byteorder
> + */
> +struct tunnel_template {
> + const char *token;
> + const struct datatype *dtype;
> + enum byteorder byteorder;
> + unsigned int len;
> +};
> +
> +extern const struct tunnel_template tunnel_templates[];
> +
> +#define TUNNEL_TEMPLATE(__token, __dtype, __len, __byteorder) { \
> + .token = (__token), \
> + .dtype = (__dtype), \
> + .len = (__len), \
> + .byteorder = (__byteorder), \
> +}
> +
> +extern struct expr *tunnel_expr_alloc(const struct location *loc,
> + enum nft_tunnel_keys key);
> +
> +const struct expr_ops tunnel_expr_ops;
> +
> +#endif /* NFTABLES_TUNNEL_H */
> diff --git a/src/Makefile.am b/src/Makefile.am
> index e2b531390cef..9b62c5325c8f 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -63,6 +63,7 @@ libnftables_la_SOURCES = \
> nfnl_osf.c \
> tcpopt.c \
> socket.c \
> + tunnel.c \
> print.c \
> libnftables.c \
> libnftables.map
> diff --git a/src/evaluate.c b/src/evaluate.c
> index 0c2a8d0a9571..dca2bdfea917 100644
> --- a/src/evaluate.c
> +++ b/src/evaluate.c
> @@ -1828,6 +1828,11 @@ static int expr_evaluate_osf(struct eval_ctx *ctx, struct expr **expr)
> return expr_evaluate_primary(ctx, expr);
> }
>
> +static int expr_evaluate_tunnel(struct eval_ctx *ctx, struct expr **exprp)
> +{
> + return expr_evaluate_primary(ctx, exprp);
> +}
> +
> static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp)
> {
> struct expr *new = expr_clone((*exprp)->sym->expr);
> @@ -1884,6 +1889,8 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
> return expr_evaluate_meta(ctx, expr);
> case EXPR_SOCKET:
> return expr_evaluate_socket(ctx, expr);
> + case EXPR_TUNNEL:
> + return expr_evaluate_tunnel(ctx, expr);
> case EXPR_OSF:
> return expr_evaluate_osf(ctx, expr);
> case EXPR_FIB:
> diff --git a/src/expression.c b/src/expression.c
> index cb49e0b73f5a..c97b2c9dd5c9 100644
> --- a/src/expression.c
> +++ b/src/expression.c
> @@ -1204,6 +1204,7 @@ const struct expr_ops *expr_ops(const struct expr *e)
> case EXPR_RT: return &rt_expr_ops;
> case EXPR_FIB: return &fib_expr_ops;
> case EXPR_XFRM: return &xfrm_expr_ops;
> + case EXPR_TUNNEL: return &tunnel_expr_ops;
> }
>
> BUG("Unknown expression type %d\n", e->etype);
> diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
> index fc2574b1dea9..25ce874b35d0 100644
> --- a/src/netlink_delinearize.c
> +++ b/src/netlink_delinearize.c
> @@ -668,6 +668,21 @@ static void netlink_parse_osf(struct netlink_parse_ctx *ctx,
> netlink_set_register(ctx, dreg, expr);
> }
>
> +static void netlink_parse_tunnel(struct netlink_parse_ctx *ctx,
> + const struct location *loc,
> + const struct nftnl_expr *nle)
> +{
> + enum nft_registers dreg;
> + struct expr * expr;
> + uint32_t key;
> +
> + key = nftnl_expr_get_u32(nle, NFTNL_EXPR_TUNNEL_KEY);
> + expr = tunnel_expr_alloc(loc, key);
> +
> + dreg = netlink_parse_register(nle, NFTNL_EXPR_TUNNEL_DREG);
> + netlink_set_register(ctx, dreg, expr);
> +}
> +
> static void netlink_parse_meta_stmt(struct netlink_parse_ctx *ctx,
> const struct location *loc,
> const struct nftnl_expr *nle)
> @@ -1464,6 +1479,7 @@ static const struct {
> { .name = "exthdr", .parse = netlink_parse_exthdr },
> { .name = "meta", .parse = netlink_parse_meta },
> { .name = "socket", .parse = netlink_parse_socket },
> + { .name = "tunnel", .parse = netlink_parse_tunnel },
> { .name = "osf", .parse = netlink_parse_osf },
> { .name = "rt", .parse = netlink_parse_rt },
> { .name = "ct", .parse = netlink_parse_ct },
> @@ -2158,6 +2174,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
> case EXPR_NUMGEN:
> case EXPR_FIB:
> case EXPR_SOCKET:
> + case EXPR_TUNNEL:
> case EXPR_OSF:
> case EXPR_XFRM:
> break;
> diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
> index 498326d0087a..b337539a44cf 100644
> --- a/src/netlink_linearize.c
> +++ b/src/netlink_linearize.c
> @@ -232,6 +232,18 @@ static void netlink_gen_osf(struct netlink_linearize_ctx *ctx,
> nftnl_rule_add_expr(ctx->nlr, nle);
> }
>
> +static void netlink_gen_tunnel(struct netlink_linearize_ctx *ctx,
> + const struct expr *expr,
> + enum nft_registers dreg)
> +{
> + struct nftnl_expr *nle;
> +
> + nle = alloc_nft_expr("tunnel");
> + netlink_put_register(nle, NFTNL_EXPR_TUNNEL_DREG, dreg);
> + nftnl_expr_set_u32(nle, NFTNL_EXPR_TUNNEL_KEY, expr->tunnel.key);
> + nftnl_rule_add_expr(ctx->nlr, nle);
> +}
> +
> static void netlink_gen_numgen(struct netlink_linearize_ctx *ctx,
> const struct expr *expr,
> enum nft_registers dreg)
> @@ -735,6 +747,8 @@ static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
> return netlink_gen_fib(ctx, expr, dreg);
> case EXPR_SOCKET:
> return netlink_gen_socket(ctx, expr, dreg);
> + case EXPR_TUNNEL:
> + return netlink_gen_tunnel(ctx, expr, dreg);
> case EXPR_OSF:
> return netlink_gen_osf(ctx, expr, dreg);
> case EXPR_XFRM:
> diff --git a/src/parser_bison.y b/src/parser_bison.y
> index d3b64b641700..ba28224a3b96 100644
> --- a/src/parser_bison.y
> +++ b/src/parser_bison.y
> @@ -225,6 +225,8 @@ int nft_lex(void *, void *, void *);
> %token RULESET "ruleset"
> %token TRACE "trace"
>
> +%token PATH "path"
> +
> %token INET "inet"
> %token NETDEV "netdev"
>
> @@ -601,8 +603,8 @@ int nft_lex(void *, void *, void *);
> %destructor { stmt_free($$); } counter_stmt counter_stmt_alloc stateful_stmt
> %type <stmt> payload_stmt
> %destructor { stmt_free($$); } payload_stmt
> -%type <stmt> ct_stmt
> -%destructor { stmt_free($$); } ct_stmt
> +%type <stmt> ct_stmt tunnel_stmt
> +%destructor { stmt_free($$); } ct_stmt tunnel_stmt
> %type <stmt> meta_stmt
> %destructor { stmt_free($$); } meta_stmt
> %type <stmt> log_stmt log_stmt_alloc
> @@ -746,9 +748,9 @@ int nft_lex(void *, void *, void *);
> %destructor { expr_free($$); } mh_hdr_expr
> %type <val> mh_hdr_field
>
> -%type <expr> meta_expr
> -%destructor { expr_free($$); } meta_expr
> -%type <val> meta_key meta_key_qualified meta_key_unqualified numgen_type
> +%type <expr> meta_expr tunnel_expr
> +%destructor { expr_free($$); } meta_expr tunnel_expr
> +%type <val> meta_key meta_key_qualified meta_key_unqualified numgen_type tunnel_key
>
> %type <expr> socket_expr
> %destructor { expr_free($$); } socket_expr
> @@ -2310,6 +2312,7 @@ stmt : verdict_stmt
> | tproxy_stmt
> | queue_stmt
> | ct_stmt
> + | tunnel_stmt
> | masq_stmt
> | redir_stmt
> | dup_stmt
> @@ -2788,6 +2791,7 @@ primary_stmt_expr : symbol_expr { $$ = $1; }
> | integer_expr { $$ = $1; }
> | boolean_expr { $$ = $1; }
> | meta_expr { $$ = $1; }
> + | tunnel_expr { $$ = $1; }
> | rt_expr { $$ = $1; }
> | ct_expr { $$ = $1; }
> | numgen_expr { $$ = $1; }
> @@ -3243,6 +3247,7 @@ primary_expr : symbol_expr { $$ = $1; }
> | exthdr_expr { $$ = $1; }
> | exthdr_exists_expr { $$ = $1; }
> | meta_expr { $$ = $1; }
> + | tunnel_expr { $$ = $1; }
> | socket_expr { $$ = $1; }
> | rt_expr { $$ = $1; }
> | ct_expr { $$ = $1; }
> @@ -4095,6 +4100,16 @@ meta_stmt : META meta_key SET stmt_expr
> }
> ;
>
> +tunnel_key : PATH { $$ = NFT_TUNNEL_PATH; }
> + | ID { $$ = NFT_TUNNEL_ID; }
> + ;
> +
> +tunnel_expr : TUNNEL tunnel_key
> + {
> + $$ = tunnel_expr_alloc(&@$, $2);
> + }
> + ;
> +
> socket_expr : SOCKET socket_key
> {
> $$ = socket_expr_alloc(&@$, $2);
> @@ -4326,6 +4341,14 @@ ct_stmt : CT ct_key SET stmt_expr
> }
> ;
>
> +tunnel_stmt : TUNNEL NAME stmt_expr
> + {
> + $$ = objref_stmt_alloc(&@$);
> + $$->objref.type = NFT_OBJECT_TUNNEL;
> + $$->objref.expr = $3;
> + }
> + ;
> +
> payload_stmt : payload_expr SET stmt_expr
> {
> if ($1->etype == EXPR_EXTHDR)
> diff --git a/src/scanner.l b/src/scanner.l
> index f8575638a47b..7bbe5663dddd 100644
> --- a/src/scanner.l
> +++ b/src/scanner.l
> @@ -329,6 +329,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
> "tunnel" { return TUNNEL; }
> "tunnels" { return TUNNELS; }
>
> +"path" { return PATH; }
> +
> "log" { return LOG; }
> "prefix" { return PREFIX; }
> "group" { return GROUP; }
> diff --git a/src/statement.c b/src/statement.c
> index a9e72de3edfd..ab893be664e3 100644
> --- a/src/statement.c
> +++ b/src/statement.c
> @@ -207,6 +207,7 @@ static const char *objref_type[NFT_OBJECT_MAX + 1] = {
> [NFT_OBJECT_QUOTA] = "quota",
> [NFT_OBJECT_CT_HELPER] = "ct helper",
> [NFT_OBJECT_LIMIT] = "limit",
> + [NFT_OBJECT_TUNNEL] = "tunnel",
> [NFT_OBJECT_CT_TIMEOUT] = "ct timeout",
> [NFT_OBJECT_SECMARK] = "secmark",
> [NFT_OBJECT_CT_EXPECT] = "ct expectation",
> diff --git a/src/tunnel.c b/src/tunnel.c
> new file mode 100644
> index 000000000000..de01622246ef
> --- /dev/null
> +++ b/src/tunnel.c
> @@ -0,0 +1,75 @@
> +/*
> + * Copyright (c) 2018 Pablo Neira Ayuso <pablo@netfilter.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <errno.h>
> +#include <limits.h>
> +#include <stddef.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <string.h>
> +#include <net/if.h>
> +#include <net/if_arp.h>
> +#include <pwd.h>
> +#include <grp.h>
> +#include <arpa/inet.h>
> +#include <linux/netfilter.h>
> +#include <linux/pkt_sched.h>
> +#include <linux/if_packet.h>
> +
> +#include <nftables.h>
> +#include <expression.h>
> +#include <datatype.h>
> +#include <tunnel.h>
> +#include <gmputil.h>
> +#include <utils.h>
> +#include <erec.h>
> +
> +const struct tunnel_template tunnel_templates[] = {
> + [NFT_TUNNEL_PATH] = META_TEMPLATE("path", &boolean_type,
> + BITS_PER_BYTE, BYTEORDER_HOST_ENDIAN),
> + [NFT_TUNNEL_ID] = META_TEMPLATE("id", &integer_type,
> + 4 * 8, BYTEORDER_HOST_ENDIAN),
> +};
> +
> +static void tunnel_expr_print(const struct expr *expr, struct output_ctx *octx)
> +{
> + nft_print(octx, "tunnel %s",
> + tunnel_templates[expr->tunnel.key].token);
> +}
> +
> +static bool tunnel_expr_cmp(const struct expr *e1, const struct expr *e2)
> +{
> + return e1->tunnel.key == e2->tunnel.key;
> +}
> +
> +static void tunnel_expr_clone(struct expr *new, const struct expr *expr)
> +{
> + new->tunnel.key = expr->tunnel.key;
> +}
> +
> +const struct expr_ops tunnel_expr_ops = {
> + .type = EXPR_TUNNEL,
> + .name = "tunnel",
> + .print = tunnel_expr_print,
> + .cmp = tunnel_expr_cmp,
> + .clone = tunnel_expr_clone,
> +};
> +
> +struct expr *tunnel_expr_alloc(const struct location *loc,
> + enum nft_tunnel_keys key)
> +{
> + const struct tunnel_template *tmpl = &tunnel_templates[key];
> + struct expr *expr;
> +
> + expr = expr_alloc(loc, EXPR_TUNNEL, tmpl->dtype, tmpl->byteorder,
> + tmpl->len);
> + expr->tunnel.key = key;
> +
> + return expr;
> +}
> --
> 2.11.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-07-25 20:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-25 9:13 [PATCH nft,v1 1/2] src: add tunnel support Pablo Neira Ayuso
2019-07-25 9:14 ` [PATCH nft,v1 2/2] src: add tunnel expression support Pablo Neira Ayuso
2019-07-25 20:30 ` Jeremy Sowden
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).