From patchwork Fri Mar 22 17:33:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1061466 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="VGLnCM0Z"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44QrYw1Tsyz9sR5 for ; Sat, 23 Mar 2019 04:41:40 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728630AbfCVRli (ORCPT ); Fri, 22 Mar 2019 13:41:38 -0400 Received: from mail-wr1-f51.google.com ([209.85.221.51]:35330 "EHLO mail-wr1-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727693AbfCVRli (ORCPT ); Fri, 22 Mar 2019 13:41:38 -0400 Received: by mail-wr1-f51.google.com with SMTP id w1so3289402wrp.2 for ; Fri, 22 Mar 2019 10:41:36 -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=lYtiSZGTZ9llKNYngHyXkIvCwnGajm/+IZEmM9+NrME=; b=VGLnCM0Z2DvxCp5gSnbztTClNwsFEqiHZsVyeqv+lETGLSBYDBqml62P8MpggFrFER x44u7jcqtsDnMgpja7D2hspFLcS/EyKFxZ8skX7nKdcEtv3a4yOOU6nCERhnxa5Rg5no 55QC75taYfaJIkbRlXEhS3JQEQHnYuaySXWMXX8FOH/6MJpoQrvBppl5Jl9u0YeoL2Fx W76weOKWbUAD5j7UjYG8Z1DFy2AbSEOvJAU0e+iYB6Pi6+W8wZooLGGxydgwszi8PkOx dcURf14Gb0pz8VT/dgiy8cWKJRSww176QNNVityhJc3BszwMssN0/LXWuwcicc67jTJ8 GNGw== 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=lYtiSZGTZ9llKNYngHyXkIvCwnGajm/+IZEmM9+NrME=; b=dg5I/b1rcedBeKm0F59yhxZgaTtw342mNipf8aPbRi5si4zFBW43p62wazACllvw+Y 1yh1ghVs3UPyrtGaPe6VEA1BzMb+74F7K5vUArYYbldJ3y+GFvSYl4790imNAqBYz6/7 cHwmzoj0U1xDPT39RF+aGBFQ5GQk5ClxNrfEbhZGUb4ra68zfZteqeUvXGyYtG+6q52q OdEZMkDedrobGLhNipZp5mWBZkmjVdnQNkojZQpgKnvKpF2/sw43fZLYtTFlYQh8aS+0 OKi9YhDiDYwMkYWM6Jxay9Ha0DepfvvYJT9u/pxzAX7YT+1M6saShpFq/+zxK/rAljGu bTAg== X-Gm-Message-State: APjAAAWDrGhM5ewCmglF3FSyn5hsxO2zjfM6jHy9/sX7DtY6Qfz+2VOC 7kkVQ7tSPlqTWY0ROGRI0P1DPZLa X-Google-Smtp-Source: APXvYqyQDXm2ipTgHPhcpUHWjuK2sUWOf/pSOsp/5SijhACyt4RvT4PanEpYorgQpWbTwRCjlBrP5Q== X-Received: by 2002:adf:e506:: with SMTP id j6mr327838wrm.41.1553276495010; Fri, 22 Mar 2019 10:41:35 -0700 (PDT) Received: from Husky.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id b16sm7477609wrq.41.2019.03.22.10.41.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 22 Mar 2019 10:41:34 -0700 (PDT) From: Yi-Hung Wei To: netdev@vger.kernel.org Cc: Yi-Hung Wei , Pablo Neira Ayuso Subject: [PATCH 1/2] netfilter: Export nf_ct_{set,destroy}_timeout() Date: Fri, 22 Mar 2019 10:33:28 -0700 Message-Id: <1553276009-39311-1-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch exports nf_ct_set_timeout() and nf_ct_destroy_timeout(). The two functions are derived from xt_ct_destroy_timeout() and xt_ct_set_timeout() in xt_CT.c, and moved to nf_conntrack_timeout.c without any functional change. It would be useful for other users (i.e. OVS) that utilizes the finer-grain conntrack timeout feature. CC: Pablo Neira Ayuso Signed-off-by: Yi-Hung Wei --- include/net/netfilter/nf_conntrack_timeout.h | 3 + net/netfilter/nf_conntrack_timeout.c | 97 ++++++++++++++++++++++++++++ net/netfilter/xt_CT.c | 93 ++------------------------ 3 files changed, 106 insertions(+), 87 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h index 3394d75e1c80..738f96348a7a 100644 --- a/include/net/netfilter/nf_conntrack_timeout.h +++ b/include/net/netfilter/nf_conntrack_timeout.h @@ -105,4 +105,7 @@ extern struct nf_ct_timeout *(*nf_ct_timeout_find_get_hook)(struct net *net, con extern void (*nf_ct_timeout_put_hook)(struct nf_ct_timeout *timeout); #endif +int nf_ct_set_timeout(struct net *net, struct nf_conn *ct, u8 l3num, u8 l4num, + const char *timeout_name); +void nf_ct_destroy_timeout(struct nf_conn *ct); #endif /* _NF_CONNTRACK_TIMEOUT_H */ diff --git a/net/netfilter/nf_conntrack_timeout.c b/net/netfilter/nf_conntrack_timeout.c index 91fbd183da2d..c2dee577548e 100644 --- a/net/netfilter/nf_conntrack_timeout.c +++ b/net/netfilter/nf_conntrack_timeout.c @@ -48,6 +48,103 @@ void nf_ct_untimeout(struct net *net, struct nf_ct_timeout *timeout) } EXPORT_SYMBOL_GPL(nf_ct_untimeout); +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT +static void __nf_ct_timeout_put(struct nf_ct_timeout *timeout) +{ + typeof(nf_ct_timeout_put_hook) timeout_put; + + timeout_put = rcu_dereference(nf_ct_timeout_put_hook); + if (timeout_put) + timeout_put(timeout); +} +#endif + +int nf_ct_set_timeout(struct net *net, struct nf_conn *ct, + u8 l3num, u8 l4num, const char *timeout_name) +{ +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + typeof(nf_ct_timeout_find_get_hook) timeout_find_get; + struct nf_ct_timeout *timeout; + struct nf_conn_timeout *timeout_ext; + const char *errmsg = NULL; + int ret = 0; + + rcu_read_lock(); + timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); + if (!timeout_find_get) { + ret = -ENOENT; + errmsg = "Timeout policy base is empty"; + goto out; + } + + timeout = timeout_find_get(net, timeout_name); + if (!timeout) { + ret = -ENOENT; + pr_info_ratelimited("No such timeout policy \"%s\"\n", + timeout_name); + goto out; + } + + if (timeout->l3num != l3num) { + ret = -EINVAL; + pr_info_ratelimited("Timeout policy `%s' can only be used by " + "L%d protocol number %d\n", + timeout_name, 3, timeout->l3num); + goto err_put_timeout; + } + /* Make sure the timeout policy matches any existing protocol tracker, + * otherwise default to generic. + */ + if (timeout->l4proto->l4proto != l4num) { + ret = -EINVAL; + pr_info_ratelimited("Timeout policy `%s' can only be used by " + "L%d protocol number %d\n", + timeout_name, 4, timeout->l4proto->l4proto); + goto err_put_timeout; + } + timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); + if (!timeout_ext) { + ret = -ENOMEM; + goto err_put_timeout; + } + + rcu_read_unlock(); + return ret; + +err_put_timeout: + __nf_ct_timeout_put(timeout); +out: + rcu_read_unlock(); + if (errmsg) + pr_info_ratelimited("%s\n", errmsg); + return ret; +#else + return -EOPNOTSUPP; +#endif +} +EXPORT_SYMBOL_GPL(nf_ct_set_timeout); + +void nf_ct_destroy_timeout(struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + struct nf_conn_timeout *timeout_ext; + typeof(nf_ct_timeout_put_hook) timeout_put; + + rcu_read_lock(); + timeout_put = rcu_dereference(nf_ct_timeout_put_hook); + + if (timeout_put) { + timeout_ext = nf_ct_timeout_find(ct); + if (timeout_ext) { + timeout_put(timeout_ext->timeout); + RCU_INIT_POINTER(timeout_ext->timeout, NULL); + } + } + rcu_read_unlock(); +#endif +} +EXPORT_SYMBOL_GPL(nf_ct_destroy_timeout); + static const struct nf_ct_ext_type timeout_extend = { .len = sizeof(struct nf_conn_timeout), .align = __alignof__(struct nf_conn_timeout), diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 0fa863f57575..d59cb4730fac 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -103,85 +103,24 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name, return 0; } -#ifdef CONFIG_NF_CONNTRACK_TIMEOUT -static void __xt_ct_tg_timeout_put(struct nf_ct_timeout *timeout) -{ - typeof(nf_ct_timeout_put_hook) timeout_put; - - timeout_put = rcu_dereference(nf_ct_timeout_put_hook); - if (timeout_put) - timeout_put(timeout); -} -#endif - static int xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, const char *timeout_name) { #ifdef CONFIG_NF_CONNTRACK_TIMEOUT - typeof(nf_ct_timeout_find_get_hook) timeout_find_get; const struct nf_conntrack_l4proto *l4proto; - struct nf_ct_timeout *timeout; - struct nf_conn_timeout *timeout_ext; - const char *errmsg = NULL; - int ret = 0; u8 proto; - rcu_read_lock(); - timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); - if (timeout_find_get == NULL) { - ret = -ENOENT; - errmsg = "Timeout policy base is empty"; - goto out; - } - proto = xt_ct_find_proto(par); if (!proto) { - ret = -EINVAL; - errmsg = "You must specify a L4 protocol and not use inversions on it"; - goto out; - } - - timeout = timeout_find_get(par->net, timeout_name); - if (timeout == NULL) { - ret = -ENOENT; - pr_info_ratelimited("No such timeout policy \"%s\"\n", - timeout_name); - goto out; - } - - if (timeout->l3num != par->family) { - ret = -EINVAL; - pr_info_ratelimited("Timeout policy `%s' can only be used by L%d protocol number %d\n", - timeout_name, 3, timeout->l3num); - goto err_put_timeout; + pr_info_ratelimited("You must specify a L4 protocol and not " + "use inversions on it"); + return -EINVAL; } - /* Make sure the timeout policy matches any existing protocol tracker, - * otherwise default to generic. - */ l4proto = nf_ct_l4proto_find(proto); - if (timeout->l4proto->l4proto != l4proto->l4proto) { - ret = -EINVAL; - pr_info_ratelimited("Timeout policy `%s' can only be used by L%d protocol number %d\n", - timeout_name, 4, timeout->l4proto->l4proto); - goto err_put_timeout; - } - timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); - if (!timeout_ext) { - ret = -ENOMEM; - goto err_put_timeout; - } + return nf_ct_set_timeout(par->net, ct, par->family, l4proto->l4proto, + timeout_name); - rcu_read_unlock(); - return ret; - -err_put_timeout: - __xt_ct_tg_timeout_put(timeout); -out: - rcu_read_unlock(); - if (errmsg) - pr_info_ratelimited("%s\n", errmsg); - return ret; #else return -EOPNOTSUPP; #endif @@ -328,26 +267,6 @@ static int xt_ct_tg_check_v2(const struct xt_tgchk_param *par) return xt_ct_tg_check(par, par->targinfo); } -static void xt_ct_destroy_timeout(struct nf_conn *ct) -{ -#ifdef CONFIG_NF_CONNTRACK_TIMEOUT - struct nf_conn_timeout *timeout_ext; - typeof(nf_ct_timeout_put_hook) timeout_put; - - rcu_read_lock(); - timeout_put = rcu_dereference(nf_ct_timeout_put_hook); - - if (timeout_put) { - timeout_ext = nf_ct_timeout_find(ct); - if (timeout_ext) { - timeout_put(timeout_ext->timeout); - RCU_INIT_POINTER(timeout_ext->timeout, NULL); - } - } - rcu_read_unlock(); -#endif -} - static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, struct xt_ct_target_info_v1 *info) { @@ -361,7 +280,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par, nf_ct_netns_put(par->net, par->family); - xt_ct_destroy_timeout(ct); + nf_ct_destroy_timeout(ct); nf_ct_put(info->ct); } } From patchwork Fri Mar 22 17:33:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 1061467 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HdyHvD2/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44QrZ16JQWz9sRW for ; Sat, 23 Mar 2019 04:41:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728865AbfCVRlo (ORCPT ); Fri, 22 Mar 2019 13:41:44 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:33464 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727693AbfCVRlo (ORCPT ); Fri, 22 Mar 2019 13:41:44 -0400 Received: by mail-wr1-f67.google.com with SMTP id q1so3292854wrp.0 for ; Fri, 22 Mar 2019 10:41:42 -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:in-reply-to:references; bh=WntBNEiaIPpBR/elfG8W4WRN81cCrUDW7hE9Ty2fCqY=; b=HdyHvD2/CmGbl+FnuFyyVZUXCAn0ZaqoCqgGJNk4YBWA/v1UC7uQzl6IgGOvrH2KOO kOvzPht+zKPyoV/+ja2BgRxnfL/vdFBp0MoI1NcE2SQ9sY0dRRpZX9XdWBUD6eklHweH 88EpRfLZGz0c2tSuOg9vux0LtN2WLeGlVdXs42XHIET3m82yxZR5k1vXDjvHN91rWPCH TPqIXYiAN7BMiGIhYMKDxXzh4IXfDGxJ4SwY9gF19uuZV+6mlLjG3flOIvkENMGI6iYl z1XoQJGVbXtilsq1BS5RCpXHIt6CWI2qYts+QxWSfOIbBuLu7ME2uZFZ1ai3aXygyWo8 +YEA== 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:in-reply-to :references; bh=WntBNEiaIPpBR/elfG8W4WRN81cCrUDW7hE9Ty2fCqY=; b=W3hDczN1mGT0YQjQQsumG0fCYs+rsiOOQ8MoNyLv7w/not3P2BOSUQOoYk72AFUKno HR83l6BMCqNVRBGk01l9Q/g4TSU32jRgI93TZjH5RlYjHbHorfKf2H+AFXI8qTk8sYN0 IYVt8ownAIQum2l5UVmniHTH+LqmWB+p0uxrduAjiYVqaWeSv1Hmrk4ugF2KXmdsQx/c Jz/sCxiIqqsddEAEM8NpJSGvvrnpjs+s94M+5v9GRia2FqlZXqBg5lTKxd66Ho7dMSXG jDPeH2lw+otpGnj1M+4D6vZfv7x/kJAV9tsX1Cib85FxE6AHSrSABx66ArlYO2w4r9tw cnEw== X-Gm-Message-State: APjAAAW9WGTplsKmIosU9KaRkl7lIJ8FGGWC5dhQcQCHGgQhjZKwfmbN nfVjiuZkrE96vv6J3k0IHmocS3kY X-Google-Smtp-Source: APXvYqxiCWUddGj0HUZjlDwir8rj01LVJbiacOH/MboFBUPBY7Z/uqUSpbFdhnz5NVW7itOOQCWyBA== X-Received: by 2002:a5d:6207:: with SMTP id y7mr7035704wru.60.1553276501895; Fri, 22 Mar 2019 10:41:41 -0700 (PDT) Received: from Husky.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id b16sm7477609wrq.41.2019.03.22.10.41.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 22 Mar 2019 10:41:41 -0700 (PDT) From: Yi-Hung Wei To: netdev@vger.kernel.org Cc: Yi-Hung Wei , Pravin Shelar Subject: [PATCH 2/2] openvswitch: Add timeout support to ct action Date: Fri, 22 Mar 2019 10:33:29 -0700 Message-Id: <1553276009-39311-2-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1553276009-39311-1-git-send-email-yihung.wei@gmail.com> References: <1553276009-39311-1-git-send-email-yihung.wei@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for fine-grain timeout support to conntrack action. The new OVS_CT_ATTR_TIMEOUT attribute of the conntrack action specifies a timeout to be associated with this connection. If no timeout is specified, it acts as is, that is the default timeout for the connection will be automatically applied. Example usage: $ nfct timeout add timeout_1 inet tcp syn_sent 100 established 200 $ ovs-ofctl add-flow br0 in_port=1,ip,tcp,action=ct(commit,timeout=timeout_1) CC: Pravin Shelar Signed-off-by: Yi-Hung Wei --- include/uapi/linux/openvswitch.h | 3 +++ net/openvswitch/conntrack.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index dbe0cbe4f1b7..00ec98836cf3 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -734,6 +734,7 @@ struct ovs_action_hash { * be received on NFNLGRP_CONNTRACK_NEW and NFNLGRP_CONNTRACK_DESTROY groups, * respectively. Remaining bits control the changes for which an event is * delivered on the NFNLGRP_CONNTRACK_UPDATE group. + * @OVS_CT_ATTR_TIMEOUT: Variable length string defining conntrack timeout. */ enum ovs_ct_attr { OVS_CT_ATTR_UNSPEC, @@ -746,6 +747,8 @@ enum ovs_ct_attr { OVS_CT_ATTR_NAT, /* Nested OVS_NAT_ATTR_* */ OVS_CT_ATTR_FORCE_COMMIT, /* No argument */ OVS_CT_ATTR_EVENTMASK, /* u32 mask of IPCT_* events. */ + OVS_CT_ATTR_TIMEOUT, /* Associate timeout with this connection for + * fine-grain timeout tuning. */ __OVS_CT_ATTR_MAX }; diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 1b6896896fff..ce2e148711de 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ struct ovs_conntrack_info { u32 eventmask; /* Mask of 1 << IPCT_*. */ struct md_mark mark; struct md_labels labels; + char timeout[CTNL_TIMEOUT_NAME_MAX]; #ifdef CONFIG_NF_NAT_NEEDED struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */ #endif @@ -1465,6 +1467,8 @@ static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = { #endif [OVS_CT_ATTR_EVENTMASK] = { .minlen = sizeof(u32), .maxlen = sizeof(u32) }, + [OVS_CT_ATTR_TIMEOUT] = { .minlen = 1, + .maxlen = CTNL_TIMEOUT_NAME_MAX }, }; static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, @@ -1550,6 +1554,15 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, info->have_eventmask = true; info->eventmask = nla_get_u32(a); break; +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + case OVS_CT_ATTR_TIMEOUT: + memcpy(info->timeout, nla_data(a), nla_len(a)); + if (!memchr(info->timeout, '\0', nla_len(a))) { + OVS_NLERR(log, "Invalid conntrack helper"); + return -EINVAL; + } + break; +#endif default: OVS_NLERR(log, "Unknown conntrack attr (%d)", @@ -1631,6 +1644,14 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr, OVS_NLERR(log, "Failed to allocate conntrack template"); return -ENOMEM; } + + if (ct_info.timeout[0]) { + if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto, + ct_info.timeout)) + pr_info_ratelimited("Failed to associated timeout " + "policy `%s'\n", ct_info.timeout); + } + if (helper) { err = ovs_ct_add_helper(&ct_info, helper, key, log); if (err) @@ -1751,6 +1772,10 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info, if (ct_info->have_eventmask && nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask)) return -EMSGSIZE; + if (ct_info->timeout[0]) { + if (nla_put_string(skb, OVS_CT_ATTR_TIMEOUT, ct_info->timeout)) + return -EMSGSIZE; + } #ifdef CONFIG_NF_NAT_NEEDED if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb)) @@ -1772,8 +1797,11 @@ static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info) { if (ct_info->helper) nf_conntrack_helper_put(ct_info->helper); - if (ct_info->ct) + if (ct_info->ct) { nf_ct_tmpl_free(ct_info->ct); + if (ct_info->timeout[0]) + nf_ct_destroy_timeout(ct_info->ct); + } } #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)