* [PATCH v2 nft 0/3] nftables: tcp option set support @ 2017-08-22 13:51 Florian Westphal 2017-08-22 13:51 ` [PATCH nft 1/3] src: add tcp options " Florian Westphal ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Florian Westphal @ 2017-08-22 13:51 UTC (permalink / raw) To: netfilter-devel This version 2 of the patchset. The libnftnl patches have been pushed already, so only the nftables patches remain. The 'more compact syntax' patch has been dropped. 'rt mss' has been renamed 'rt mtu' (so we don't need a new token). Let me know if there are any problems. This version also adds small sections in documentation. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH nft 1/3] src: add tcp options set support 2017-08-22 13:51 [PATCH v2 nft 0/3] nftables: tcp option set support Florian Westphal @ 2017-08-22 13:51 ` Florian Westphal 2017-08-22 16:16 ` Pablo Neira Ayuso 2017-08-22 13:51 ` [PATCH nft 2/3] rt: add path mtu support Florian Westphal 2017-08-22 13:51 ` [PATCH nft 3/3] tests: add tcp option set support / tcp mss mangling test cases Florian Westphal 2 siblings, 1 reply; 7+ messages in thread From: Florian Westphal @ 2017-08-22 13:51 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal This adds support for tcp mss mangling: nft add rule filter input tcp option maxseg size 1200 Its also possible to change other tcp option fields, but maxseg is one of the more useful ones to change. Signed-off-by: Florian Westphal <fw@strlen.de> --- changes since v2: keep print part in exthdr.c doc/nft.xml | 16 ++++++++++++++++ include/statement.h | 11 +++++++++++ include/tcpopt.h | 1 + src/evaluate.c | 15 +++++++++++++++ src/exthdr.c | 25 +++++++++++++++++++++++++ src/netlink_delinearize.c | 21 +++++++++++++++++++-- src/netlink_linearize.c | 29 +++++++++++++++++++++++++++++ src/parser_bison.y | 5 ++++- 8 files changed, 120 insertions(+), 3 deletions(-) diff --git a/doc/nft.xml b/doc/nft.xml index d7aae3f03b8c..d3213d0281e1 100644 --- a/doc/nft.xml +++ b/doc/nft.xml @@ -4259,6 +4259,22 @@ ip forward ip dscp set 42 </para> </refsect2> <refsect2> + <title>Extension header statement</title> + <para> + The extension header statement alters packet content in variable-sized headers. + This can currently be used to alter the TCP Maximum segment size of packets, + similar to TCPMSS. + </para> + <para> + <example> + <title>change tcp mss</title> + <programlisting> +tcp option maxseg size set 1360 + </programlisting> + </example> + </para> + </refsect2> + <refsect2> <title>Log statement</title> <para> <cmdsynopsis> diff --git a/include/statement.h b/include/statement.h index 61b5027b97f1..6d8aaa8ba72b 100644 --- a/include/statement.h +++ b/include/statement.h @@ -24,6 +24,14 @@ struct counter_stmt { extern struct stmt *counter_stmt_alloc(const struct location *loc); +struct exthdr_stmt { + struct expr *expr; + struct expr *val; +}; + +extern struct stmt *exthdr_stmt_alloc(const struct location *loc, + struct expr *payload, struct expr *expr); + struct payload_stmt { struct expr *expr; struct expr *val; @@ -220,6 +228,7 @@ struct xt_stmt { * @STMT_QUOTA: quota statement * @STMT_NOTRACK: notrack statement * @STMT_OBJREF: stateful object reference statement + * @STMT_EXTHDR: extension header statement */ enum stmt_types { STMT_INVALID, @@ -244,6 +253,7 @@ enum stmt_types { STMT_QUOTA, STMT_NOTRACK, STMT_OBJREF, + STMT_EXTHDR, }; /** @@ -285,6 +295,7 @@ struct stmt { union { struct expr *expr; + struct exthdr_stmt exthdr; struct flow_stmt flow; struct counter_stmt counter; struct payload_stmt payload; diff --git a/include/tcpopt.h b/include/tcpopt.h index f96c04c6ee93..9be84817e6f2 100644 --- a/include/tcpopt.h +++ b/include/tcpopt.h @@ -3,6 +3,7 @@ #include <proto.h> #include <exthdr.h> +#include <statement.h> extern struct expr *tcpopt_expr_alloc(const struct location *loc, uint8_t type, uint8_t field); diff --git a/src/evaluate.c b/src/evaluate.c index f52a0843a0c0..3989d5e31f56 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1835,6 +1835,19 @@ static bool stmt_evaluate_payload_need_csum(const struct expr *payload) return desc && desc->checksum_key; } +static int stmt_evaluate_exthdr(struct eval_ctx *ctx, struct stmt *stmt) +{ + struct expr *exthdr; + + if (__expr_evaluate_exthdr(ctx, &stmt->exthdr.expr) < 0) + return -1; + + exthdr = stmt->exthdr.expr; + return stmt_evaluate_arg(ctx, stmt, exthdr->dtype, exthdr->len, + BYTEORDER_BIG_ENDIAN, + &stmt->exthdr.val); +} + static int stmt_evaluate_payload(struct eval_ctx *ctx, struct stmt *stmt) { struct expr *binop, *mask, *and, *payload_bytes; @@ -2700,6 +2713,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) return stmt_evaluate_verdict(ctx, stmt); case STMT_PAYLOAD: return stmt_evaluate_payload(ctx, stmt); + case STMT_EXTHDR: + return stmt_evaluate_exthdr(ctx, stmt); case STMT_FLOW: return stmt_evaluate_flow(ctx, stmt); case STMT_META: diff --git a/src/exthdr.c b/src/exthdr.c index a412025c9a48..4add3da24ad8 100644 --- a/src/exthdr.c +++ b/src/exthdr.c @@ -21,6 +21,7 @@ #include <utils.h> #include <headers.h> #include <expression.h> +#include <statement.h> static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx) { @@ -98,6 +99,30 @@ struct expr *exthdr_expr_alloc(const struct location *loc, return expr; } +static void exthdr_stmt_print(const struct stmt *stmt, struct output_ctx *octx) +{ + expr_print(stmt->exthdr.expr, octx); + printf(" set "); + expr_print(stmt->exthdr.val, octx); +} + +static const struct stmt_ops exthdr_stmt_ops = { + .type = STMT_EXTHDR, + .name = "exthdr", + .print = exthdr_stmt_print, +}; + +struct stmt *exthdr_stmt_alloc(const struct location *loc, + struct expr *expr, struct expr *val) +{ + struct stmt *stmt; + + stmt = stmt_alloc(loc, &exthdr_stmt_ops); + stmt->exthdr.expr = expr; + stmt->exthdr.val = val; + return stmt; +} + static const struct exthdr_desc *exthdr_protocols[IPPROTO_MAX] = { [IPPROTO_HOPOPTS] = &exthdr_hbh, [IPPROTO_ROUTING] = &exthdr_rt, diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 5317a830ac6d..51a61472a0f1 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -513,8 +513,25 @@ static void netlink_parse_exthdr(struct netlink_parse_ctx *ctx, expr = exthdr_expr_alloc(loc, NULL, 0); exthdr_init_raw(expr, type, offset, len, op, flags); - dreg = netlink_parse_register(nle, NFTNL_EXPR_EXTHDR_DREG); - netlink_set_register(ctx, dreg, expr); + if (nftnl_expr_is_set(nle, NFTNL_EXPR_EXTHDR_DREG)) { + dreg = netlink_parse_register(nle, NFTNL_EXPR_EXTHDR_DREG); + netlink_set_register(ctx, dreg, expr); + } else if (nftnl_expr_is_set(nle, NFTNL_EXPR_EXTHDR_SREG)) { + enum nft_registers sreg; + struct stmt *stmt; + struct expr *val; + + sreg = netlink_parse_register(nle, NFTNL_EXPR_EXTHDR_SREG); + val = netlink_get_register(ctx, loc, sreg); + if (val == NULL) + return netlink_error(ctx, loc, + "exthdr statement has no expression"); + + expr_set_type(val, expr->dtype, expr->byteorder); + + stmt = exthdr_stmt_alloc(loc, expr, val); + list_add_tail(&stmt->list, &ctx->rule->stmts); + } } static void netlink_parse_hash(struct netlink_parse_ctx *ctx, diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 3d684569cabf..c5a47dec7d10 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -816,6 +816,33 @@ static bool payload_needs_l4csum_update_pseudohdr(const struct expr *expr, return false; } +static void netlink_gen_exthdr_stmt(struct netlink_linearize_ctx *ctx, + const struct stmt *stmt) +{ + struct nftnl_expr *nle; + const struct expr *expr; + enum nft_registers sreg; + unsigned int offset; + + sreg = get_register(ctx, stmt->exthdr.val); + netlink_gen_expr(ctx, stmt->exthdr.val, sreg); + release_register(ctx, stmt->exthdr.val); + + expr = stmt->exthdr.expr; + + offset = expr->exthdr.tmpl->offset + expr->exthdr.offset; + + nle = alloc_nft_expr("exthdr"); + netlink_put_register(nle, NFTNL_EXPR_EXTHDR_SREG, sreg); + nftnl_expr_set_u8(nle, NFTNL_EXPR_EXTHDR_TYPE, + expr->exthdr.desc->type); + nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_OFFSET, offset / BITS_PER_BYTE); + nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_LEN, + div_round_up(expr->len, BITS_PER_BYTE)); + nftnl_expr_set_u8(nle, NFTNL_EXPR_EXTHDR_OP, expr->exthdr.op); + nftnl_rule_add_expr(ctx->nlr, nle); +} + static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx, const struct stmt *stmt) { @@ -1239,6 +1266,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, return netlink_gen_verdict_stmt(ctx, stmt); case STMT_FLOW: return netlink_gen_flow_stmt(ctx, stmt); + case STMT_EXTHDR: + return netlink_gen_exthdr_stmt(ctx, stmt); case STMT_PAYLOAD: return netlink_gen_payload_stmt(ctx, stmt); case STMT_META: diff --git a/src/parser_bison.y b/src/parser_bison.y index 783b72f5a343..7898ea3fe7bc 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3209,7 +3209,10 @@ ct_stmt : CT ct_key SET expr payload_stmt : payload_expr SET expr { - $$ = payload_stmt_alloc(&@$, $1, $3); + if ($1->ops->type == EXPR_EXTHDR) + $$ = exthdr_stmt_alloc(&@$, $1, $3); + else + $$ = payload_stmt_alloc(&@$, $1, $3); } ; -- 2.13.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH nft 1/3] src: add tcp options set support 2017-08-22 13:51 ` [PATCH nft 1/3] src: add tcp options " Florian Westphal @ 2017-08-22 16:16 ` Pablo Neira Ayuso 0 siblings, 0 replies; 7+ messages in thread From: Pablo Neira Ayuso @ 2017-08-22 16:16 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel On Tue, Aug 22, 2017 at 03:51:39PM +0200, Florian Westphal wrote: > This adds support for tcp mss mangling: > > nft add rule filter input tcp option maxseg size 1200 > > Its also possible to change other tcp option fields, but > maxseg is one of the more useful ones to change. > > Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH nft 2/3] rt: add path mtu support 2017-08-22 13:51 [PATCH v2 nft 0/3] nftables: tcp option set support Florian Westphal 2017-08-22 13:51 ` [PATCH nft 1/3] src: add tcp options " Florian Westphal @ 2017-08-22 13:51 ` Florian Westphal 2017-08-22 16:16 ` Pablo Neira Ayuso 2017-08-22 13:51 ` [PATCH nft 3/3] tests: add tcp option set support / tcp mss mangling test cases Florian Westphal 2 siblings, 1 reply; 7+ messages in thread From: Florian Westphal @ 2017-08-22 13:51 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal Only use case is to allow similar behaviour to iptables TCPMSS --clamp-mss-to-pmtu, by combining this with exthdr statement: tcp option maxseg size set rt mtu Signed-off-by: Florian Westphal <fw@strlen.de> --- v2: rename to 'rt mtu' instead of 'rt mss' to avoid adding a new MSS token to the scanner. doc/nft.xml | 7 +++++++ include/linux/netfilter/nf_tables.h | 1 + src/parser_bison.y | 1 + src/rt.c | 5 +++++ 4 files changed, 14 insertions(+) diff --git a/doc/nft.xml b/doc/nft.xml index d3213d0281e1..4e2730f698cb 100644 --- a/doc/nft.xml +++ b/doc/nft.xml @@ -2836,6 +2836,11 @@ filter prerouting meta mark set 0xdead fib daddr . mark type vmap { blackhole : <entry>Routing nexthop</entry> <entry>ipv4_addr/ipv6_addr</entry> </row> + <row> + <entry>mtu</entry> + <entry>TCP maximum segment size of route</entry> + <entry>integer (16 bit)</entry> + </row> </tbody> </tgroup> </table> @@ -4270,6 +4275,8 @@ ip forward ip dscp set 42 <title>change tcp mss</title> <programlisting> tcp option maxseg size set 1360 +# set a size based on route information: +tcp option maxseg size set rt mtu </programlisting> </example> </para> diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 40096de04e96..5441b190852f 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -813,6 +813,7 @@ enum nft_rt_keys { NFT_RT_CLASSID, NFT_RT_NEXTHOP4, NFT_RT_NEXTHOP6, + NFT_RT_TCPMSS, }; /** diff --git a/src/parser_bison.y b/src/parser_bison.y index 7898ea3fe7bc..18be53e88c77 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3094,6 +3094,7 @@ rt_expr : RT rt_key rt_key : CLASSID { $$ = NFT_RT_CLASSID; } | NEXTHOP { $$ = NFT_RT_NEXTHOP4; } + | MTU { $$ = NFT_RT_TCPMSS; } ; ct_expr : CT ct_key diff --git a/src/rt.c b/src/rt.c index cd2d5a4ed7b9..91be5a11c5a2 100644 --- a/src/rt.c +++ b/src/rt.c @@ -73,6 +73,11 @@ static const struct rt_template rt_templates[] = { 16 * BITS_PER_BYTE, BYTEORDER_BIG_ENDIAN, true), + [NFT_RT_TCPMSS] = RT_TEMPLATE("mtu", + &integer_type, + 2 * BITS_PER_BYTE, + BYTEORDER_HOST_ENDIAN, + false), }; static void rt_expr_print(const struct expr *expr, struct output_ctx *octx) -- 2.13.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH nft 2/3] rt: add path mtu support 2017-08-22 13:51 ` [PATCH nft 2/3] rt: add path mtu support Florian Westphal @ 2017-08-22 16:16 ` Pablo Neira Ayuso 0 siblings, 0 replies; 7+ messages in thread From: Pablo Neira Ayuso @ 2017-08-22 16:16 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel On Tue, Aug 22, 2017 at 03:51:40PM +0200, Florian Westphal wrote: > Only use case is to allow similar behaviour to iptables > TCPMSS --clamp-mss-to-pmtu, by combining this with exthdr statement: > > tcp option maxseg size set rt mtu > > Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH nft 3/3] tests: add tcp option set support / tcp mss mangling test cases 2017-08-22 13:51 [PATCH v2 nft 0/3] nftables: tcp option set support Florian Westphal 2017-08-22 13:51 ` [PATCH nft 1/3] src: add tcp options " Florian Westphal 2017-08-22 13:51 ` [PATCH nft 2/3] rt: add path mtu support Florian Westphal @ 2017-08-22 13:51 ` Florian Westphal 2017-08-22 16:16 ` Pablo Neira Ayuso 2 siblings, 1 reply; 7+ messages in thread From: Florian Westphal @ 2017-08-22 13:51 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal Signed-off-by: Florian Westphal <fw@strlen.de> --- v2: adjust for new syntax tests/py/inet/rt.t | 4 +++- tests/py/inet/rt.t.payload | 5 +++++ tests/py/inet/tcpopt.t | 2 ++ tests/py/inet/tcpopt.t.payload | 5 +++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/py/inet/rt.t b/tests/py/inet/rt.t index f2dcbdc41da9..9543738b786c 100644 --- a/tests/py/inet/rt.t +++ b/tests/py/inet/rt.t @@ -1,4 +1,4 @@ -:output;type filter hook input priority 0 +:output;type filter hook output priority 0 *inet;test-inet;output @@ -6,3 +6,5 @@ rt nexthop 192.168.0.1;fail rt nexthop fd00::1;fail meta nfproto ipv4 rt nexthop 192.168.0.1;ok meta nfproto ipv6 rt nexthop fd00::1;ok + +tcp option maxseg size set rt mtu;ok diff --git a/tests/py/inet/rt.t.payload b/tests/py/inet/rt.t.payload index d94973e03ffa..2f6265ed640a 100644 --- a/tests/py/inet/rt.t.payload +++ b/tests/py/inet/rt.t.payload @@ -12,3 +12,8 @@ inet test-inet output [ rt load nexthop6 => reg 1 ] [ cmp eq reg 1 0x000000fd 0x00000000 0x00000000 0x01000000 ] +# tcp option maxseg size set rt mtu +inet test-inet output + [ rt load tcpmss => reg 1 ] + [ exthdr write tcpopt reg 1 => 2b @ 2 + 2 ] + diff --git a/tests/py/inet/tcpopt.t b/tests/py/inet/tcpopt.t index a42ecd250a9c..b457691f7f27 100644 --- a/tests/py/inet/tcpopt.t +++ b/tests/py/inet/tcpopt.t @@ -38,3 +38,5 @@ tcp option sack window 1;fail tcp option window exists;ok tcp option window missing;ok + +tcp option maxseg size set 1360;ok diff --git a/tests/py/inet/tcpopt.t.payload b/tests/py/inet/tcpopt.t.payload index 10cf0c00f402..7e254ed3f605 100644 --- a/tests/py/inet/tcpopt.t.payload +++ b/tests/py/inet/tcpopt.t.payload @@ -193,3 +193,8 @@ inet test-inet input [ cmp eq reg 1 0x00000006 ] [ exthdr load tcpopt 1b @ 3 + 0 present => reg 1 ] [ cmp eq reg 1 0x00000000 ] + +# tcp option maxseg size set 1360 +inet test-inet input + [ immediate reg 1 0x00005005 ] + [ exthdr write tcpopt reg 1 => 2b @ 2 + 2 ] -- 2.13.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH nft 3/3] tests: add tcp option set support / tcp mss mangling test cases 2017-08-22 13:51 ` [PATCH nft 3/3] tests: add tcp option set support / tcp mss mangling test cases Florian Westphal @ 2017-08-22 16:16 ` Pablo Neira Ayuso 0 siblings, 0 replies; 7+ messages in thread From: Pablo Neira Ayuso @ 2017-08-22 16:16 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel On Tue, Aug 22, 2017 at 03:51:41PM +0200, Florian Westphal wrote: > Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-08-22 16:17 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-22 13:51 [PATCH v2 nft 0/3] nftables: tcp option set support Florian Westphal 2017-08-22 13:51 ` [PATCH nft 1/3] src: add tcp options " Florian Westphal 2017-08-22 16:16 ` Pablo Neira Ayuso 2017-08-22 13:51 ` [PATCH nft 2/3] rt: add path mtu support Florian Westphal 2017-08-22 16:16 ` Pablo Neira Ayuso 2017-08-22 13:51 ` [PATCH nft 3/3] tests: add tcp option set support / tcp mss mangling test cases Florian Westphal 2017-08-22 16:16 ` Pablo Neira Ayuso
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).