From patchwork Sun Aug 5 12:29:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harsha Sharma X-Patchwork-Id: 953522 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 (mailfrom) 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dUH6V81l"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41k0Z92xrwz9ryt for ; Sun, 5 Aug 2018 22:33:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726165AbeHEOiB (ORCPT ); Sun, 5 Aug 2018 10:38:01 -0400 Received: from mail-pf1-f195.google.com ([209.85.210.195]:45505 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726130AbeHEOiB (ORCPT ); Sun, 5 Aug 2018 10:38:01 -0400 Received: by mail-pf1-f195.google.com with SMTP id i26-v6so5475979pfo.12 for ; Sun, 05 Aug 2018 05:33: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=0USHharSrnSzOstxTSAn5EtqBCtmZT4T0TyI5X7GJY0=; b=dUH6V81lbrO4F+K0/SHuwIGCz0q/im/DQyyaRhJLCYnf3ll9AtNDEN4FroAn9q6PdE sAt2usWvyriiqG2LL/9wWMl2zQnOrzYNM1tTld4i+ubMio49nkcISQCVKMN45+hkPqGK iLfnLM84/Se5ERnz6fzuqrTLtHpv391hkfLDoBO02k0aC9WOi1sKNnbYICzrtjwiii0R pUTxiDOuybqqCWOroc8cpImQ/hj7riEUIs+FV6GuECR0L2NKjSIuUjGxjl2je+HXxkLh WNozXkJUshTH6AJKKTyNCI4sMOUzrkspWLAikCSVQBCqE7KpBoDMm+JNMNcw7Gdg00X7 X9pw== 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=0USHharSrnSzOstxTSAn5EtqBCtmZT4T0TyI5X7GJY0=; b=WpnDkUT4IwZNiY7gC+mccWQkEnBXRJFI34XBCuENgaHQwZ69ZOwRU4KVAmZ47AbaQG /vO0AMC7CNsSvLufJ4OAFFxt7EQMa50ZXbps9m21DeK6/Hr5yGBHV7yij1W91N6UDSAG LS+49tvygn4HBss6cwX9nL2slXAAp4dt8kp4VygqGG1cFFzyURCm0nTymXVzLz0/Yx5P GON5xrckqAZzMCs29KSKJH+G0mhO1N60uiDsgFVDLEbvVprBUw0nr4wmjoiz9w12gE+o EYbdU+YDTQLslWBwSmA3Objyh9i054b+4Bu0V/8DCRbVowgiYgwwSVmI91Y1xTJqlEOe FMRw== X-Gm-Message-State: AOUpUlEWzQJKG7Jk/jH+2bJ4J9ExwtQ0uRnxwbJf6yiZ+gylIQpaO93M r6gobDXiN9VEwGyBZrUMOio= X-Google-Smtp-Source: AAOMgpcc3rnEovL1F9JAEZsXBZwFA7Wi/xJd5DokglVn4i+AOvprskY2kw4UskUmUEHK9iZokV6EwQ== X-Received: by 2002:a65:52cc:: with SMTP id z12-v6mr10829829pgp.69.1533472414123; Sun, 05 Aug 2018 05:33:34 -0700 (PDT) Received: from XDDDDD.iitr.ernet.in ([103.37.201.44]) by smtp.gmail.com with ESMTPSA id s85-v6sm17920063pfa.116.2018.08.05.05.33.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 Aug 2018 05:33:33 -0700 (PDT) From: Harsha Sharma To: harshasharmaiitr@gmail.com, pablo@netfilter.org Cc: netfilter-devel@vger.kernel.org Subject: [PATCH nft v4 1/3] src: add ct timeout support Date: Sun, 5 Aug 2018 17:59:51 +0530 Message-Id: <20180805122951.19037-1-harshasharmaiitr@gmail.com> X-Mailer: git-send-email 2.14.1 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This patch adds support for adding, listing and deleting ct timeout objects which can be assigned via rule to assign connection tracking timeout policies via objref infrastructure. %nft add table filter %nft add chain filter output %nft add ct timeout filter test-tcp { protocol tcp \; policy = { established: 132, close: 13, close_wait: 17 } \; } %nft add rule filter output ct timeout set test-tcp %nft list ruleset table ip filter { ct timeout test-tcp { protocol tcp; policy = {established: 132, close_wait: 17, close: 13} } chain output { ct timeout set "test-tcp" } } %nft delete rule filter output handle %nft delete ct timeout filter test-tcp Signed-off-by: Harsha Sharma --- Changes in v4: - updated syntax and log message - fix parser_bison to parse input from files for ct timeout obj - output similar to output Changes in v3: - parse multiple timeout policies - return error for invalid timeout state name - change in log message Changes in v2: - Change in syntax for addition of ct timeout objects - remove tokens from scanner and parser_bison for timeout states - list only updated timeout values - change in log message accordingly - other minor changes include/linux/netfilter/nf_tables.h | 14 ++++- include/rule.h | 25 ++++++++ src/evaluate.c | 4 ++ src/netlink.c | 21 +++++++ src/parser_bison.y | 109 +++++++++++++++++++++++++++++++++- src/rule.c | 113 +++++++++++++++++++++++++++++++++++- src/statement.c | 4 ++ 7 files changed, 286 insertions(+), 4 deletions(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 63b9054..0948987 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -971,6 +971,7 @@ enum nft_osf_attributes { * @NFT_CT_DST_IP: conntrack layer 3 protocol destination (IPv4 address) * @NFT_CT_SRC_IP6: conntrack layer 3 protocol source (IPv6 address) * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address) + * @NFT_CT_TIMEOUT: connection tracking timeout policy assigned to conntrack */ enum nft_ct_keys { NFT_CT_STATE, @@ -996,6 +997,7 @@ enum nft_ct_keys { NFT_CT_DST_IP, NFT_CT_SRC_IP6, NFT_CT_DST_IP6, + NFT_CT_TIMEOUT, __NFT_CT_MAX }; #define NFT_CT_MAX (__NFT_CT_MAX - 1) @@ -1402,13 +1404,23 @@ enum nft_ct_helper_attributes { }; #define NFTA_CT_HELPER_MAX (__NFTA_CT_HELPER_MAX - 1) +enum nft_ct_timeout_attributes { + NFTA_CT_TIMEOUT_L3PROTO, + NFTA_CT_TIMEOUT_L4PROTO, + NFTA_CT_TIMEOUT_DATA, + __NFTA_CT_TIMEOUT_MAX, +}; +#define NFTA_CT_TIMEOUT_MAX (__NFTA_CT_TIMEOUT_MAX - 1) + #define NFT_OBJECT_UNSPEC 0 #define NFT_OBJECT_COUNTER 1 #define NFT_OBJECT_QUOTA 2 #define NFT_OBJECT_CT_HELPER 3 #define NFT_OBJECT_LIMIT 4 #define NFT_OBJECT_CONNLIMIT 5 -#define __NFT_OBJECT_MAX 6 +#define NFT_OBJECT_TUNNEL 6 +#define NFT_OBJECT_CT_TIMEOUT 7 +#define __NFT_OBJECT_MAX 8 #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) /** diff --git a/include/rule.h b/include/rule.h index 909ff36..2068887 100644 --- a/include/rule.h +++ b/include/rule.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include /** * struct handle_spec - handle ID @@ -308,6 +310,18 @@ struct ct_helper { uint8_t l4proto; }; +struct ct_timeout { + uint16_t l3proto; + uint8_t l4proto; + uint32_t *timeout; + struct timeout_state { + uint8_t timeout_index; + uint32_t timeout_value; + uint8_t l4; + struct list_head timeout_list; + } timeout_state; +}; + struct limit { uint64_t rate; uint64_t unit; @@ -336,6 +350,7 @@ struct obj { struct quota quota; struct ct_helper ct_helper; struct limit limit; + struct ct_timeout ct_timeout; }; }; @@ -462,6 +477,7 @@ enum cmd_obj { CMD_OBJ_LIMITS, CMD_OBJ_FLOWTABLE, CMD_OBJ_FLOWTABLES, + CMD_OBJ_CT_TIMEOUT, }; struct markup { @@ -617,4 +633,13 @@ enum udata_set_elem_flags { SET_ELEM_F_INTERVAL_OPEN = 0x1, }; +struct timeout_protocol { + uint32_t attr_max; + const char *const *state_to_name; + uint32_t *dflt_timeout; +}; + +extern struct timeout_protocol timeout_protocol[IPPROTO_MAX]; +extern void timeout_str2num(const char *timeout_state, struct timeout_state *ts); + #endif /* NFTABLES_RULE_H */ diff --git a/src/evaluate.c b/src/evaluate.c index 1fc861f..304990e 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -3224,6 +3224,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) case CMD_OBJ_COUNTER: case CMD_OBJ_QUOTA: case CMD_OBJ_CT_HELPER: + case CMD_OBJ_CT_TIMEOUT: case CMD_OBJ_LIMIT: return 0; default: @@ -3251,6 +3252,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd) case CMD_OBJ_COUNTER: case CMD_OBJ_QUOTA: case CMD_OBJ_CT_HELPER: + case CMD_OBJ_CT_TIMEOUT: case CMD_OBJ_LIMIT: return 0; default: @@ -3383,6 +3385,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_COUNTER); case CMD_OBJ_CT_HELPER: return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_CT_HELPER); + case CMD_OBJ_CT_TIMEOUT: + return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_CT_TIMEOUT); case CMD_OBJ_LIMIT: return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_LIMIT); case CMD_OBJ_COUNTERS: diff --git a/src/netlink.c b/src/netlink.c index 394af2f..967d9cc 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #define nft_mon_print(monh, ...) nft_print(monh->ctx->octx, __VA_ARGS__) @@ -334,6 +336,20 @@ alloc_nftnl_obj(const struct handle *h, struct obj *obj) nftnl_obj_set_u16(nlo, NFTNL_OBJ_CT_HELPER_L3PROTO, obj->ct_helper.l3proto); break; + case NFT_OBJECT_CT_TIMEOUT: + nftnl_obj_set_u8(nlo, NFTNL_OBJ_CT_TIMEOUT_L4PROTO, + obj->ct_timeout.l4proto); + if (obj->ct_timeout.l3proto) + nftnl_obj_set_u16(nlo, NFTNL_OBJ_CT_TIMEOUT_L3PROTO, + obj->ct_timeout.l3proto); + else + nftnl_obj_set_u16(nlo, NFTNL_OBJ_CT_TIMEOUT_L3PROTO, + NFPROTO_IPV4); + for (unsigned int i = 0; i < timeout_protocol[obj->ct_timeout.l4proto].attr_max; ++i) { + if (obj->ct_timeout.timeout[i]) + nftnl_timeout_policy_attr_set_u32(nlo, i, obj->ct_timeout.timeout[i]); + } + break; case NFT_OBJECT_LIMIT: nftnl_obj_set_u64(nlo, NFTNL_OBJ_LIMIT_RATE, obj->limit.rate); nftnl_obj_set_u64(nlo, NFTNL_OBJ_LIMIT_UNIT, obj->limit.unit); @@ -1437,6 +1453,11 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx, obj->ct_helper.l3proto = nftnl_obj_get_u16(nlo, NFTNL_OBJ_CT_HELPER_L3PROTO); obj->ct_helper.l4proto = nftnl_obj_get_u8(nlo, NFTNL_OBJ_CT_HELPER_L4PROTO); break; + case NFT_OBJECT_CT_TIMEOUT: + obj->ct_timeout.l3proto = nftnl_obj_get_u16(nlo, NFTNL_OBJ_CT_TIMEOUT_L3PROTO); + obj->ct_timeout.l4proto = nftnl_obj_get_u8(nlo, NFTNL_OBJ_CT_TIMEOUT_L4PROTO); + obj->ct_timeout.timeout = nftnl_obj_get_void(nlo, NFTNL_OBJ_CT_TIMEOUT_DATA); + break; case NFT_OBJECT_LIMIT: obj->limit.rate = nftnl_obj_get_u64(nlo, NFTNL_OBJ_LIMIT_RATE); diff --git a/src/parser_bison.y b/src/parser_bison.y index 9a75120..a2592ab 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -550,7 +550,7 @@ int nft_lex(void *, void *, void *); %type flowtable_block_alloc flowtable_block %destructor { flowtable_free($$); } flowtable_block_alloc -%type obj_block_alloc counter_block quota_block ct_helper_block limit_block +%type obj_block_alloc counter_block quota_block ct_helper_block ct_timeout_block limit_block %destructor { obj_free($$); } obj_block_alloc %type stmt_list @@ -753,6 +753,10 @@ int nft_lex(void *, void *, void *); %type ct_l4protoname ct_obj_type +%type timeout_states timeout_state +%destructor { xfree($$); } timeout_states timeout_state + + %% input : /* empty */ @@ -960,6 +964,10 @@ add_cmd : TABLE table_spec $$ = cmd_alloc_obj_ct(CMD_ADD, NFT_OBJECT_CT_HELPER, &$3, &@$, $4); } + | CT TIMEOUT obj_spec ct_obj_alloc '{' ct_timeout_block '}' stmt_separator + { + $$ = cmd_alloc_obj_ct(CMD_ADD, NFT_OBJECT_CT_TIMEOUT, &$3, &@$, $4); + } | LIMIT obj_spec limit_obj { $$ = cmd_alloc(CMD_ADD, CMD_OBJ_LIMIT, &$2, &@$, $3); @@ -1041,6 +1049,10 @@ create_cmd : TABLE table_spec { $$ = cmd_alloc_obj_ct(CMD_CREATE, NFT_OBJECT_CT_HELPER, &$3, &@$, $4); } + | CT TIMEOUT obj_spec ct_obj_alloc '{' ct_timeout_block '}' stmt_separator + { + $$ = cmd_alloc_obj_ct(CMD_CREATE, NFT_OBJECT_CT_TIMEOUT, &$3, &@$, $4); + } | LIMIT obj_spec limit_obj { $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_LIMIT, &$2, &@$, $3); @@ -1233,6 +1245,10 @@ list_cmd : TABLE table_spec { $$ = cmd_alloc(CMD_LIST, CMD_OBJ_CT_HELPERS, &$4, &@$, NULL); } + | CT TIMEOUT TABLE table_spec + { + $$ = cmd_alloc(CMD_LIST, CMD_OBJ_CT_TIMEOUT, &$4, &@$, NULL); + } ; reset_cmd : COUNTERS ruleset_spec @@ -1464,6 +1480,15 @@ table_block : /* empty */ { $$ = $-1; } list_add_tail(&$5->list, &$1->objs); $$ = $1; } + | table_block CT TIMEOUT obj_identifier obj_block_alloc '{' ct_timeout_block '}' stmt_separator + { + $5->location = @4; + $5->type = NFT_OBJECT_CT_TIMEOUT; + handle_merge(&$5->handle, &$4); + handle_free(&$4); + list_add_tail(&$5->list, &$1->objs); + $$ = $1; + } | table_block LIMIT obj_identifier obj_block_alloc '{' limit_block '}' stmt_separator @@ -1759,6 +1784,15 @@ ct_helper_block : /* empty */ { $$ = $-1; } } ; +ct_timeout_block : /*empty */ { $$ = $-1; } + | ct_timeout_block common_block + | ct_timeout_block stmt_separator + | ct_timeout_block ct_timeout_config + { + $$ = $1; + } + ; + limit_block : /* empty */ { $$ = $-1; } | limit_block common_block | limit_block stmt_separator @@ -3228,12 +3262,43 @@ quota_obj : quota_config ; ct_obj_type : HELPER { $$ = NFT_OBJECT_CT_HELPER; } + | TIMEOUT { $$ = NFT_OBJECT_CT_TIMEOUT; } ; ct_l4protoname : TCP { $$ = IPPROTO_TCP; } | UDP { $$ = IPPROTO_UDP; } ; +timeout_states : timeout_state + { + $$ = xmalloc(sizeof(*$$)); + init_list_head($$); + list_add_tail($1, $$); + } + | timeout_states COMMA timeout_state + { + list_add_tail($3, $1); + $$ = $1; + } + ; + +timeout_state : STRING COLON NUM + + { + struct timeout_state *ts; + + ts = xzalloc(sizeof(*ts)); + timeout_str2num($1, ts); + if (!ts) { + erec_queue(error(&@2, "invalid timeout state name '%s'\n", $1), state->msgs); + YYERROR; + } + ts->timeout_value = $3; + init_list_head(&ts->timeout_list); + $$ = &ts->timeout_list; + } + ; + ct_helper_config : TYPE QUOTED_STRING PROTOCOL ct_l4protoname stmt_separator { struct ct_helper *ct; @@ -3255,6 +3320,42 @@ ct_helper_config : TYPE QUOTED_STRING PROTOCOL ct_l4protoname stmt_separator } ; +ct_timeout_config : PROTOCOL ct_l4protoname SEMICOLON + { + struct ct_timeout *ct; + int l4proto = $2; + + ct = &$0->ct_timeout; + ct->l4proto = l4proto; + } + | POLICY '=' '{' timeout_states '}' stmt_separator + { + int l4proto = IPPROTO_TCP; + size_t timeout_array_size; + struct timeout_state *ts; + struct ct_timeout *ct; + uint32_t *timeout; + + ct = &$0->ct_timeout; + init_list_head(&ct->timeout_state.timeout_list); + timeout_array_size = sizeof(uint32_t) * (timeout_protocol[l4proto].attr_max); + timeout = xzalloc(timeout_array_size); + list_for_each_entry(ts, $4, timeout_list) { + if (ct->l4proto == ts->l4) { + timeout[ts->timeout_index] = ts->timeout_value; + } else { + erec_queue(error(&@2, "invalid timeout state name for given l4proto\n"), state->msgs); + YYERROR; + } + } + ct->timeout = timeout; + } + | L3PROTOCOL family_spec_explicit stmt_separator + { + $0->ct_timeout.l3proto = $2; + } + ; + ct_obj_alloc : { $$ = obj_alloc(&@$); @@ -3730,6 +3831,7 @@ ct_key : L3PROTOCOL { $$ = NFT_CT_L3PROTOCOL; } | PROTO_DST { $$ = NFT_CT_PROTO_DST; } | LABEL { $$ = NFT_CT_LABELS; } | EVENT { $$ = NFT_CT_EVENTMASK; } + | TIMEOUT { $$ = NFT_CT_TIMEOUT; } | ct_key_dir_optional ; @@ -3778,6 +3880,11 @@ ct_stmt : CT ct_key SET stmt_expr $$->objref.type = NFT_OBJECT_CT_HELPER; $$->objref.expr = $4; break; + case NFT_CT_TIMEOUT: + $$ = objref_stmt_alloc(&@$); + $$->objref.type = NFT_OBJECT_CT_TIMEOUT; + $$->objref.expr = $4; + break; default: $$ = ct_stmt_alloc(&@$, $2, -1, $4); break; diff --git a/src/rule.c b/src/rule.c index 7a7ac73..99b0dc4 100644 --- a/src/rule.c +++ b/src/rule.c @@ -29,6 +29,72 @@ #include #include +const char *const tcp_state_to_name[] = { + [NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT] = "syn_sent", + [NFTA_CT_TIMEOUT_ATTR_TCP_SYN_RECV] = "syn_recv", + [NFTA_CT_TIMEOUT_ATTR_TCP_ESTABLISHED] = "established", + [NFTA_CT_TIMEOUT_ATTR_TCP_FIN_WAIT] = "fin_wait", + [NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE_WAIT] = "close_wait", + [NFTA_CT_TIMEOUT_ATTR_TCP_LAST_ACK] = "last_ack", + [NFTA_CT_TIMEOUT_ATTR_TCP_TIME_WAIT] = "time_wait", + [NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE] = "close", + [NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT2] = "syn_sent2", + [NFTA_CT_TIMEOUT_ATTR_TCP_RETRANS] = "retrans", + [NFTA_CT_TIMEOUT_ATTR_TCP_UNACK] = "unack", +}; + +const char *const udp_state_to_name[] = { + [NFTA_CT_TIMEOUT_ATTR_UDP_UNREPLIED] = "unreplied", + [NFTA_CT_TIMEOUT_ATTR_UDP_REPLIED] = "replied", +}; + +uint32_t tcp_dflt_timeout[] = { + [NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT] = 120, + [NFTA_CT_TIMEOUT_ATTR_TCP_SYN_RECV] = 60, + [NFTA_CT_TIMEOUT_ATTR_TCP_ESTABLISHED] = 432000, + [NFTA_CT_TIMEOUT_ATTR_TCP_FIN_WAIT] = 120, + [NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE_WAIT] = 60, + [NFTA_CT_TIMEOUT_ATTR_TCP_LAST_ACK] = 30, + [NFTA_CT_TIMEOUT_ATTR_TCP_TIME_WAIT] = 120, + [NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE] = 10, + [NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT2] = 120, + [NFTA_CT_TIMEOUT_ATTR_TCP_RETRANS] = 300, + [NFTA_CT_TIMEOUT_ATTR_TCP_UNACK] = 300, + +}; + +uint32_t udp_dflt_timeout[] = { + [NFTA_CT_TIMEOUT_ATTR_UDP_UNREPLIED] = 30, + [NFTA_CT_TIMEOUT_ATTR_UDP_REPLIED] = 180, +}; + +struct timeout_protocol timeout_protocol[IPPROTO_MAX] = { + [IPPROTO_TCP] = { + .attr_max = NFTA_CT_TIMEOUT_ATTR_TCP_MAX, + .state_to_name = tcp_state_to_name, + .dflt_timeout = tcp_dflt_timeout, + }, + [IPPROTO_UDP] = { + .attr_max = NFTA_CT_TIMEOUT_ATTR_UDP_MAX, + .state_to_name = udp_state_to_name, + .dflt_timeout = udp_dflt_timeout, + }, +}; + +void timeout_str2num(const char *timeout_state, struct timeout_state *ts) +{ + unsigned int i, l4; + + for (l4 = 0; l4 < IPPROTO_MAX; l4++) { + for (i = 0; i < timeout_protocol[l4].attr_max; i++) { + if (!strcmp(timeout_protocol[l4].state_to_name[i], timeout_state)) { + ts->timeout_index = i; + ts->l4 = l4; + } + } + } +} + void handle_free(struct handle *h) { xfree(h->table.name); @@ -1093,6 +1159,7 @@ void cmd_free(struct cmd *cmd) case CMD_OBJ_COUNTER: case CMD_OBJ_QUOTA: case CMD_OBJ_CT_HELPER: + case CMD_OBJ_CT_TIMEOUT: case CMD_OBJ_LIMIT: obj_free(cmd->object); break; @@ -1187,6 +1254,7 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl) case CMD_OBJ_COUNTER: case CMD_OBJ_QUOTA: case CMD_OBJ_CT_HELPER: + case CMD_OBJ_CT_TIMEOUT: case CMD_OBJ_LIMIT: return netlink_add_obj(ctx, cmd, flags); case CMD_OBJ_FLOWTABLE: @@ -1272,6 +1340,9 @@ static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd) return netlink_delete_obj(ctx, cmd, NFT_OBJECT_QUOTA); case CMD_OBJ_CT_HELPER: return netlink_delete_obj(ctx, cmd, NFT_OBJECT_CT_HELPER); + case CMD_OBJ_CT_TIMEOUT: + return netlink_delete_obj(ctx, cmd, + NFT_OBJECT_CT_TIMEOUT); case CMD_OBJ_LIMIT: return netlink_delete_obj(ctx, cmd, NFT_OBJECT_LIMIT); case CMD_OBJ_FLOWTABLE: @@ -1417,9 +1488,28 @@ static void print_proto_name_proto(uint8_t l4, struct output_ctx *octx) const struct protoent *p = getprotobynumber(l4); if (p) - nft_print(octx, "%s\n", p->p_name); + nft_print(octx, "%s", p->p_name); else - nft_print(octx, "%d\n", l4); + nft_print(octx, "%d", l4); +} + +static void print_proto_timeout_policy(uint8_t l4, uint32_t *timeout, + struct output_ctx *octx) +{ + unsigned int i, b = 0; + + nft_print(octx, "\t\tpolicy = {"); + for (i = 0; i < timeout_protocol[l4].attr_max; i++) { + if (timeout[i] != timeout_protocol[l4].dflt_timeout[i]) { + if (b) + nft_print(octx, ", "); + nft_print(octx, "%s: %u", + timeout_protocol[l4].state_to_name[i], + timeout[i]); + b = 1; + } + } + nft_print(octx, "}"); } static void obj_print_data(const struct obj *obj, @@ -1466,9 +1556,21 @@ static void obj_print_data(const struct obj *obj, nft_print(octx, "\t\ttype \"%s\" protocol ", obj->ct_helper.name); print_proto_name_proto(obj->ct_helper.l4proto, octx); + nft_print(octx, "\n"); nft_print(octx, "\t\tl3proto %s", family2str(obj->ct_helper.l3proto)); break; + case NFT_OBJECT_CT_TIMEOUT: + nft_print(octx, "ct timeout %s {", obj->handle.obj.name); + if (octx->handle > 0) + nft_print(octx, " # handle %" PRIu64, obj->handle.handle.id); + nft_print(octx, "%s", opts->nl); + nft_print(octx, "\t\tprotocol "); + print_proto_name_proto(obj->ct_timeout.l4proto, octx); + nft_print(octx, ";%s", opts->nl); + print_proto_timeout_policy(obj->ct_timeout.l4proto, + obj->ct_timeout.timeout, octx); + break; case NFT_OBJECT_LIMIT: { bool inv = obj->limit.flags & NFT_LIMIT_F_INV; const char *data_unit; @@ -1515,6 +1617,7 @@ static const char * const obj_type_name_array[] = { [NFT_OBJECT_QUOTA] = "quota", [NFT_OBJECT_CT_HELPER] = "", [NFT_OBJECT_LIMIT] = "limit", + [NFT_OBJECT_CT_TIMEOUT] = "", }; const char *obj_type_name(enum stmt_types type) @@ -1529,6 +1632,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_CT_TIMEOUT] = CMD_OBJ_CT_TIMEOUT, }; uint32_t obj_type_to_cmd(uint32_t type) @@ -1877,6 +1981,8 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) case CMD_OBJ_CT_HELPER: case CMD_OBJ_CT_HELPERS: return do_list_obj(ctx, cmd, NFT_OBJECT_CT_HELPER); + case CMD_OBJ_CT_TIMEOUT: + return do_list_obj(ctx, cmd, NFT_OBJECT_CT_TIMEOUT); case CMD_OBJ_LIMIT: case CMD_OBJ_LIMITS: return do_list_obj(ctx, cmd, NFT_OBJECT_LIMIT); @@ -2094,6 +2200,9 @@ struct cmd *cmd_alloc_obj_ct(enum cmd_ops op, int type, const struct handle *h, case NFT_OBJECT_CT_HELPER: cmd_obj = CMD_OBJ_CT_HELPER; break; + case NFT_OBJECT_CT_TIMEOUT: + cmd_obj = CMD_OBJ_CT_TIMEOUT; + break; default: BUG("missing type mapping"); } diff --git a/src/statement.c b/src/statement.c index 3040476..25d75e9 100644 --- a/src/statement.c +++ b/src/statement.c @@ -203,6 +203,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_CT_TIMEOUT] = "ct timeout", }; const char *objref_type_name(uint32_t type) @@ -219,6 +220,9 @@ static void objref_stmt_print(const struct stmt *stmt, struct output_ctx *octx) case NFT_OBJECT_CT_HELPER: nft_print(octx, "ct helper set "); break; + case NFT_OBJECT_CT_TIMEOUT: + nft_print(octx, "ct timeout set "); + break; default: nft_print(octx, "%s name ", objref_type_name(stmt->objref.type)); From patchwork Sun Aug 5 12:34:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harsha Sharma X-Patchwork-Id: 953523 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 (mailfrom) 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hmL4kSxQ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41k0dM47JBz9ryt for ; Sun, 5 Aug 2018 22:36:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726150AbeHEOks (ORCPT ); Sun, 5 Aug 2018 10:40:48 -0400 Received: from mail-pf1-f180.google.com ([209.85.210.180]:41453 "EHLO mail-pf1-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726100AbeHEOks (ORCPT ); Sun, 5 Aug 2018 10:40:48 -0400 Received: by mail-pf1-f180.google.com with SMTP id y10-v6so5498239pfn.8 for ; Sun, 05 Aug 2018 05:36:22 -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=3t28Fd2xNIE5dkN7T0drxTKS4bPDpIBo0RE1rB7u/X4=; b=hmL4kSxQJpQw2x2KF3rdBPLdsnhqyoM7siss/5VeYQa+OeDqNNzeUAkA/UmLC7Hc6y hNJToo9nhvOZz0poQygaRmvyXwolGaOyz0FMv3m6GdWiedPYwgvo5hO0g35qBsZPdZx4 C5mol8Yz6GlAqBs5MSwwRZLIrgdT0lOoiqi6E6YQXEnxAXifyV6B1HqPIDtAYfOpSDCd aRqUiHGge3MWRLnmQW9cpWU8sNQ/EBaKRmGeesZY5Ky29Y4/jyT8rLFAm9Yd+vsqxt3C 85QOnMX1R36rS1nc10bYr7chUTZcQmDG81NxMUXKLC4TA+aTXA/RxdFopkNdGlzocowG syNw== 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=3t28Fd2xNIE5dkN7T0drxTKS4bPDpIBo0RE1rB7u/X4=; b=eXEQFOLf91cwoTbpgDbFgMKSIMoQZjh187NXIJhD78IiwbcIqzxsHrpHzzqkogfkzR m/jUj6FUYhJi2mMEsGmbXnETrvxTIkDuD4yB1ehTZ8BjeaIkto/u9uTW5bDxAdcijaGs wenOe9yGJRzyrCd64kCTFDrN6OhTE1Zq7dXX2Q/4k1YvixSlnXAYi3EbaIgRzmpgdij+ qTV1rTwDuWorE2gWzjTZ1hb7++EYAhPaaDd8T5HEcee4Rex7BzeG89vmBANApCHJfGVv YbRNr3hpDLvJza1Z94umgkFZp6ikGTLeFH9Di2CZ8znsB2Yv9+ofp9AYAwlxuPhQUSTs swjw== X-Gm-Message-State: AOUpUlFgwq2rqvDvhE/g2esHBZ50P9fQXyKc4n0ZFmBJFsVLgbtTr+da Iok9kMkzoH45WWx0Uz0blX8= X-Google-Smtp-Source: AAOMgpe7UZa1zEMCyJXfPbHhtPAUPWIBW5TGIXSpro8gC1n1EHTGiSoc3ZY5GNsXLJ8T9Wr/xiGnKA== X-Received: by 2002:a63:338e:: with SMTP id z136-v6mr10607370pgz.171.1533472580337; Sun, 05 Aug 2018 05:36:20 -0700 (PDT) Received: from XDDDDD.iitr.ernet.in ([103.37.201.44]) by smtp.gmail.com with ESMTPSA id r19-v6sm14051172pgo.68.2018.08.05.05.35.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 Aug 2018 05:36:19 -0700 (PDT) From: Harsha Sharma To: harshasharmaiitr@gmail.com, pablo@netfilter.org Cc: netfilter-devel@vger.kernel.org Subject: [PATCH nft v4 2/3] tests: py: add ct timeout tests Date: Sun, 5 Aug 2018 18:04:42 +0530 Message-Id: <20180805123442.19143-1-harshasharmaiitr@gmail.com> X-Mailer: git-send-email 2.14.1 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add test for adding ct timeout objects and assigning it via rule. Signed-off-by: Harsha Sharma --- Changes in v4: - update tests with syntax Changes in v3: - Add more tests for multiple timeout policies Changes in v2: - No change tests/py/ip/objects.t | 9 +++++++++ tests/py/ip/objects.t.payload | 4 ++++ tests/py/nft-test.py | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/tests/py/ip/objects.t b/tests/py/ip/objects.t index 5e8c763..4666809 100644 --- a/tests/py/ip/objects.t +++ b/tests/py/ip/objects.t @@ -32,3 +32,12 @@ ct helper set tcp dport map {21 : "cthelp1", 2121 : "cthelp1" };ok ip saddr 192.168.1.3 limit name "lim1";ok ip saddr 192.168.1.3 limit name "lim3";fail limit name tcp dport map {443 : "lim1", 80 : "lim2", 22 : "lim1"};ok + +# ct timeout +%cttime1 type ct timeout { protocol tcp; policy = { established:122 } ;};ok +%cttime2 type ct timeout { protocol udp; policy = { syn_sent:122 } ;};fail +%cttime3 type ct timeout { protocol tcp; policy = { established:132, close:16, close_wait:16 } ;};ok +%cttime4 type ct timeout { protocol udp; policy = { replied:14, unreplied:19 } ;};ok +%cttime5 type ct timeout {protocol tcp; policy = { estalbished:100 } ;};fail + +ct timeout set "cttime1";ok diff --git a/tests/py/ip/objects.t.payload b/tests/py/ip/objects.t.payload index 193d797..719b6c3 100644 --- a/tests/py/ip/objects.t.payload +++ b/tests/py/ip/objects.t.payload @@ -59,3 +59,7 @@ ip test-ip4 output [ cmp eq reg 1 0x00000006 ] [ payload load 2b @ transport header + 2 => reg 1 ] [ objref sreg 1 set __objmap%d ] + +# ct timeout set "cttime1" +ip test-ip4 output + [ objref type 7 name cttime1 ] diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py index e4367ad..5e9e2e3 100755 --- a/tests/py/nft-test.py +++ b/tests/py/nft-test.py @@ -1082,6 +1082,10 @@ def obj_process(obj_line, filename, lineno): obj_type = "ct helper" tokens[3] = "" + if obj_type == "ct" and tokens[3] == "timeout": + obj_type = "ct timeout" + tokens[3] = "" + if len(tokens) > 3: obj_spcf = " ".join(tokens[3:]) From patchwork Sun Aug 5 12:37:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harsha Sharma X-Patchwork-Id: 953524 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 (mailfrom) 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="XSGcqocG"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41k0fp2SLnz9ryt for ; Sun, 5 Aug 2018 22:37:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726159AbeHEOmD (ORCPT ); Sun, 5 Aug 2018 10:42:03 -0400 Received: from mail-pg1-f178.google.com ([209.85.215.178]:44630 "EHLO mail-pg1-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726100AbeHEOmC (ORCPT ); Sun, 5 Aug 2018 10:42:02 -0400 Received: by mail-pg1-f178.google.com with SMTP id r1-v6so4936083pgp.11 for ; Sun, 05 Aug 2018 05:37:35 -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=WpDIExxeNEkbclwECyn1wcW6xko8V8pfeBqdYQfIouw=; b=XSGcqocGl07ilPN8yanyQ15jdIiMh3t3mrZTK6+8JRVuDxlrRJV3vksAmJVcSjvcBF q+rU+jU7Z6GItJ8gzv4wLs9VINap1cxqBZbg8CUxzwa6GTXdlouCRUe5NbMmiD4r9dO3 8al12B+iRlovtZC1nHGd2E8xhrBlqbIDLHDkQ3cd2vmt992V51J4okFt3hAQMIGRRDAF QGxMaG5+OPHyQVLd3CEJ4uicL/4t3U9bpt8rNBTaz8cAuQNmDOTQPhIzACtQ8ffPBf/H /10vM3T3kxNPbeXi2P78R0hy2DFM/ziat0kzKGCjF+/YAP8FQFOEtbEANoW/3p8VLTf+ 4QHw== 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=WpDIExxeNEkbclwECyn1wcW6xko8V8pfeBqdYQfIouw=; b=T8ez91kMNIb6+1preAQbFTcB43iWMgejar40s9vZt9nlWH3TGEJLCzSw9CB7I6INAU Lzhw4EALiRXSiJS+Cf680qGXflaOt//UbXt5IYUpjmc7HiKGZnnPMgXLhvkK+yCJs3BG FfI+E/FZ4qBnOdPxYjzkxSRlmeqF850jF0sAATPk/sCHZjV08XzLXsvfY3yVaS4NJs/0 67mQRmGEQ1P9uFM8vDiGaBnsN2rhrLNp9G3Vg/88P62G0QQKuF/kbtj7EtFaBQ73+Fz8 /lD2dhSa4ziEeRI0xQM2GYCCMFOc8uhoE0cjA1xF4kHaHQOFgWJtO1sKzSZDjjXHbr3q PtiQ== X-Gm-Message-State: AOUpUlG6eStdoHfjbFYapHhTZ/2YFCroC7i46Eybi1wLCDqGzVmE9JbZ ajY+X8dmbyl3DwlZ4dcmu7pvPYBA X-Google-Smtp-Source: AAOMgpdX/DivIbenWEnFt8rhrAf+rOGQsMOUfPfvqXuOdYaI0uXYS5MwQeuXkVzyi6rIzQ/wt1R5kQ== X-Received: by 2002:a62:c90a:: with SMTP id k10-v6mr12580237pfg.180.1533472655346; Sun, 05 Aug 2018 05:37:35 -0700 (PDT) Received: from XDDDDD.iitr.ernet.in ([103.37.201.44]) by smtp.gmail.com with ESMTPSA id h7-v6sm19937647pfd.155.2018.08.05.05.37.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 Aug 2018 05:37:34 -0700 (PDT) From: Harsha Sharma To: harshasharmaiitr@gmail.com, pablo@netfilter.org Cc: netfilter-devel@vger.kernel.org Subject: [PATCH nft v4 3/3] tests: shell: add tests for ct timeout objects Date: Sun, 5 Aug 2018 18:07:17 +0530 Message-Id: <20180805123717.19312-1-harshasharmaiitr@gmail.com> X-Mailer: git-send-email 2.14.1 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add tests for listing ct timeout objects and input from file. Signed-off-by: Harsha Sharma --- Changes : - Added more tests tests/shell/testcases/listing/0013objects_0 | 6 ++++++ tests/shell/testcases/nft-f/0017ct_timeout_obj_0 | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100755 tests/shell/testcases/nft-f/0017ct_timeout_obj_0 diff --git a/tests/shell/testcases/listing/0013objects_0 b/tests/shell/testcases/listing/0013objects_0 index c5e0e32..1a26953 100755 --- a/tests/shell/testcases/listing/0013objects_0 +++ b/tests/shell/testcases/listing/0013objects_0 @@ -12,6 +12,11 @@ EXPECTED="table ip test { l3proto ip } + ct timeout cttime { + protocol udp; + policy = {unreplied: 15, replied: 12} + } + chain input { } }" @@ -22,6 +27,7 @@ $NFT add table test $NFT add chain test input $NFT add quota test https-quota 25 mbytes $NFT add ct helper test cthelp { type \"sip\" protocol tcp \; } +$NFT add ct timeout test cttime { protocol udp \; policy = {replied: 12, unreplied: 15 } \; } $NFT add table test-ip GET="$($NFT list table test)" diff --git a/tests/shell/testcases/nft-f/0017ct_timeout_obj_0 b/tests/shell/testcases/nft-f/0017ct_timeout_obj_0 new file mode 100755 index 0000000..d69f287 --- /dev/null +++ b/tests/shell/testcases/nft-f/0017ct_timeout_obj_0 @@ -0,0 +1,15 @@ +#!/bin/bash + +EXPECTED='table ip filter { + ct timeout cttime{ + protocol tcp; + policy = {established: 123, close: 12} + } + + chain c { + ct timeout set "cttime" + } +}' + +set -e +$NFT -f - <<< $EXPECTED