On Sat, Jul 7, 2018 at 7:03 PM, Harsha Sharma <harshasharmaiitr@xxxxxxxxx> wrote: > 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, established:132 \; } > %nft add rule filter output ct timeout set test-tcp > %nft list ruleset > > table ip filter { > ct timeout test-tcp { > protocol tcp > l3proto ip > established 132 > } > > chain output { > ct timeout set "test-tcp" > } > } > > %nft delete rule filter output handle <handle> > %nft delete ct timeout filter test-tcp > > Signed-off-by: Harsha Sharma <harshasharmaiitr@xxxxxxxxx> > --- > 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 | 13 ++++- > include/rule.h | 19 +++++++ > src/evaluate.c | 4 ++ > src/netlink.c | 21 ++++++++ > src/parser_bison.y | 60 ++++++++++++++++++++- > src/rule.c | 102 ++++++++++++++++++++++++++++++++++++ > src/statement.c | 4 ++ > 7 files changed, 221 insertions(+), 2 deletions(-) > > diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h > index 88e0ca1..8e7c757 100644 > --- a/include/linux/netfilter/nf_tables.h > +++ b/include/linux/netfilter/nf_tables.h > @@ -958,6 +958,7 @@ enum nft_socket_keys { > * @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, > @@ -983,6 +984,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) > @@ -1373,13 +1375,22 @@ 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_CT_TIMEOUT 6 > +#define __NFT_OBJECT_MAX 7 > #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) > > /** > diff --git a/include/rule.h b/include/rule.h > index 909ff36..f4afc9c 100644 > --- a/include/rule.h > +++ b/include/rule.h > @@ -4,6 +4,8 @@ > #include <stdint.h> > #include <nftables.h> > #include <list.h> > +#include <libnftnl/cttimeout.h> > +#include <netinet/in.h> > > /** > * struct handle_spec - handle ID > @@ -308,6 +310,12 @@ struct ct_helper { > uint8_t l4proto; > }; > > +struct ct_timeout { > + uint16_t l3proto; > + uint8_t l4proto; > + uint32_t *timeout; > +}; > + > struct limit { > uint64_t rate; > uint64_t unit; > @@ -336,6 +344,7 @@ struct obj { > struct quota quota; > struct ct_helper ct_helper; > struct limit limit; > + struct ct_timeout ct_timeout; > }; > }; > > @@ -462,6 +471,7 @@ enum cmd_obj { > CMD_OBJ_LIMITS, > CMD_OBJ_FLOWTABLE, > CMD_OBJ_FLOWTABLES, > + CMD_OBJ_CT_TIMEOUT, > }; > > struct markup { > @@ -617,4 +627,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 int timeout_str2num(const char *timeout_state, unsigned int l4); > + > #endif /* NFTABLES_RULE_H */ > diff --git a/src/evaluate.c b/src/evaluate.c > index c4ee3cc..69f3230 100644 > --- a/src/evaluate.c > +++ b/src/evaluate.c > @@ -3130,6 +3130,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: > @@ -3157,6 +3158,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: > @@ -3289,6 +3291,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 <libnftnl/udata.h> > #include <libnftnl/ruleset.h> > #include <libnftnl/common.h> > +#include <libnftnl/cttimeout.h> > #include <linux/netfilter/nfnetlink.h> > #include <linux/netfilter/nf_tables.h> > #include <linux/netfilter.h> > @@ -41,6 +42,7 @@ > #include <utils.h> > #include <erec.h> > #include <iface.h> > +#include <rule.h> > > #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 98bfeba..5540288 100644 > --- a/src/parser_bison.y > +++ b/src/parser_bison.y > @@ -12,6 +12,7 @@ > > #include <stddef.h> > #include <stdio.h> > +#include <stdlib.h> > #include <inttypes.h> > #include <syslog.h> > #include <netinet/ip.h> > @@ -154,6 +155,7 @@ int nft_lex(void *, void *, void *); > struct handle_spec handle_spec; > struct position_spec position_spec; > const struct exthdr_desc *exthdr_desc; > + struct ct_timeout *ct_timeout; > } > > %token TOKEN_EOF 0 "end of file" > @@ -546,7 +548,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 limit_block > +%type <obj> obj_block_alloc counter_block quota_block ct_helper_block ct_timeout_block limit_block > %destructor { obj_free($$); } obj_block_alloc > > %type <list> stmt_list > @@ -950,6 +952,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); > @@ -1031,6 +1037,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); > @@ -1223,6 +1233,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 > @@ -1454,6 +1468,15 @@ table_block : /* empty */ { $$ = $<table>-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 > @@ -1749,6 +1772,15 @@ ct_helper_block : /* empty */ { $$ = $<obj>-1; } > } > ; > > +ct_timeout_block : /*empty */ { $$ = $<obj>-1; } > + | ct_timeout_block common_block > + | ct_timeout_block stmt_separator > + | ct_timeout_block ct_timeout_config > + { > + $$ = $1; > + } > + ; > + > limit_block : /* empty */ { $$ = $<obj>-1; } > | limit_block common_block > | limit_block stmt_separator > @@ -3171,6 +3203,7 @@ quota_obj : quota_config > ; > > ct_obj_type : HELPER { $$ = NFT_OBJECT_CT_HELPER; } > + | TIMEOUT { $$ = NFT_OBJECT_CT_TIMEOUT; } > ; > > ct_l4protoname : TCP { $$ = IPPROTO_TCP; } > @@ -3198,6 +3231,25 @@ ct_helper_config : TYPE QUOTED_STRING PROTOCOL ct_l4protoname stmt_separator > } > ; > > +ct_timeout_config : PROTOCOL COLON ct_l4protoname COMMA STRING COLON NUM stmt_separator ct_timeout_config : PROTOCOL COLON ct_l4protoname COMMA timeout_states stmt_separator I want to parse multiple timeout policies like this : timeout_states : timeout_states timeout_state | timeout_state ; timeout_state : STRING COLON NUM { size_t timeout_array_size = sizeof(uint32_t) * (timeout_protocol[l4proto].attr_max); int type = timeout_str2num($1, l4proto); timeout = calloc(1, timeout_array_size); timeout[type] = $3; $$ = timeout; } ; So, I want to parse l4proto from ct_timeout_config to timeout_state. Any idea, on how can I do this ? Thanks. > + { > + struct ct_timeout *ct; > + size_t timeout_array_size; > + int l4proto = $3; > + int type = timeout_str2num($5, l4proto); > + > + ct = &$<obj>0->ct_timeout; > + ct->l4proto = l4proto; > + timeout_array_size = sizeof(uint32_t) * (timeout_protocol[l4proto].attr_max); > + ct->timeout = calloc(1, timeout_array_size); > + ct->timeout[type] = $7; > + } > + | L3PROTOCOL family_spec_explicit stmt_separator > + { > + $<obj>0->ct_timeout.l3proto = $2; > + } > + ; > + > ct_obj_alloc : > { > $$ = obj_alloc(&@$); > @@ -3672,6 +3724,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 > ; > > @@ -3720,6 +3773,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 188fc06..e3916cb 100644 > --- a/src/rule.c > +++ b/src/rule.c > @@ -29,6 +29,69 @@ > #include <linux/netfilter.h> > #include <linux/netfilter_arp.h> > > +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, > + }, > +}; > + > +int timeout_str2num(const char *timeout_state, unsigned int l4) > +{ > + unsigned int i; > + > + for (i = 0; i < timeout_protocol[l4].attr_max; i++) { > + if (!strcmp(timeout_protocol[l4].state_to_name[i], timeout_state)) > + return i; > + } > + return -1; > +} > + > void handle_free(struct handle *h) > { > xfree(h->table.name); > @@ -1089,6 +1152,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; > @@ -1183,6 +1247,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: > @@ -1268,6 +1333,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: > @@ -1418,6 +1486,21 @@ static void print_proto_name_proto(uint8_t l4, struct output_ctx *octx) > nft_print(octx, "%d\n", l4); > } > > +static void print_proto_timeout_policy(uint8_t l4, uint32_t *timeout, > + struct output_ctx *octx) > +{ > + unsigned int i; > + > + nft_print(octx, "\t\t"); > + for (i = 0; i < timeout_protocol[l4].attr_max; i++) { > + if (timeout[i] != timeout_protocol[l4].dflt_timeout[i]) { > + nft_print(octx, "%s %u ", > + timeout_protocol[l4].state_to_name[i], > + timeout[i]); > + } > + } > +} > + > static void obj_print_data(const struct obj *obj, > struct print_fmt_options *opts, > struct output_ctx *octx) > @@ -1465,6 +1548,19 @@ static void obj_print_data(const struct obj *obj, > 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, "\t\tl3proto %s", > + family2str(obj->ct_timeout.l3proto)); > + 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; > @@ -1511,6 +1607,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) > @@ -1525,6 +1622,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) > @@ -1875,6 +1973,7 @@ 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: > case CMD_OBJ_LIMIT: > case CMD_OBJ_LIMITS: > return do_list_obj(ctx, cmd, NFT_OBJECT_LIMIT); > @@ -2092,6 +2191,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 6f5e666..3f88729 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)); > -- > 2.14.1 > -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html