From patchwork Wed Aug 28 22:14:27 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: 1154910 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.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="YlyQ1Luk"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Jg9T1S6vz9sNC for ; Thu, 29 Aug 2019 08:18:05 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6C54E3B0D; Wed, 28 Aug 2019 22:15:33 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id B8D953A48 for ; Wed, 28 Aug 2019 22:15:11 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1FB57EC for ; Wed, 28 Aug 2019 22:15:11 +0000 (UTC) Received: by mail-pf1-f195.google.com with SMTP id g2so678787pfq.0 for ; Wed, 28 Aug 2019 15:15:11 -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=QayggdD7IdqlWCtQBRST+SYcwyi+qYLyFP+qscuUU/o=; b=YlyQ1Luks5tKhA4TaDwAIea/q7wT9XTweop8NGFpnCRONpakU+JbiPU6PqmYoukEUT zMiULC0n+5jIjpLezrqne1ERmqdgD2AGAWwLDhOBzExhZqfGzhOBsJW/YfYAKuSduq4c r4a1RIIiDkDrtjWVwuMSLJiSoCIo1/7AHNzaQhVo1HTB4GKMdr/7Go4N+hg4w0Vaqg+I vWLZ8w1JQbtxWzMQNq5WkF9TXdZgLNOHOnYu3CZBIDrES5PisEuRKmHo9Eq6ePTJT6Z0 XADGKOrmbwxwKWi+Q5Sikvj4JSGcmucJa+YClrL/79a/06VACv6e9SCyyZ7R60RrNTcC ogxg== 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=QayggdD7IdqlWCtQBRST+SYcwyi+qYLyFP+qscuUU/o=; b=ayV7q/UeTA/Dg9qDFS1m1UIWt7oCxegz7X+wTbU30obeI3cohnfKODKQmRM7bALK4l muog0qcUgyClehsags1fwp0E0l1FhFL0x/wzK5ouAc6IeIx+Js8vlQYvb4pzs0C4KMDe WTrzQL9IfBL9dJH1HCeEtvWAtQKwP3A9fxuTmd37ILk5dSxDcYYidAp7PgUHHokgDiwQ 2HtfuEncbJM9SiZnB+EtFqRi/iGCRfJwXiTZyzMx3F3mwnbrlRvXGx4FZMrz+UCYKzRq u2n1wTn8tCgfp68CBwdodKXtzVBubz91ulyg0LQ/48fUYK4768mwJL8fuGujGBL6XvbB /Bmg== X-Gm-Message-State: APjAAAWhC5FMoBrW/irzO4tdnuqy6XZ9Vqbo/Jv35yAqLBieDWmd7iMj xukP5fUV1W1n4i09iyHbImx/LfAp X-Google-Smtp-Source: APXvYqx5PIvCP+ZDGEBEp7wc0WLqAWGh3DQXMk4/so6OvQ0idUw3s/P4fGuy7bY60wS045x9Fm5Tqw== X-Received: by 2002:a63:6407:: with SMTP id y7mr5397968pgb.188.1567030510199; Wed, 28 Aug 2019 15:15:10 -0700 (PDT) Received: from vm-main.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id d128sm432493pfa.42.2019.08.28.15.15.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 28 Aug 2019 15:15:09 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org Date: Wed, 28 Aug 2019 15:14:27 -0700 Message-Id: <1567030469-120137-8-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1567030469-120137-1-git-send-email-yihung.wei@gmail.com> References: <1567030469-120137-1-git-send-email-yihung.wei@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v5 7/9] datapath: compat: Backport nf_conntrack_timeout support X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch brings in nf_ct_timeout_put() and nf_ct_set_timeout() when it is not available in the kernel. Three symbols are created in acinclude.m4. * HAVE_NF_CT_SET_TIMEOUT is used to determine if upstream net-next commit 717700d183d65 ("netfilter: Export nf_ct_{set,destroy}_timeout()") is availabe. If it is defined, the kernel should have all the nf_conntrack_timeout support that OVS needs. * HAVE_NF_CT_TIMEOUT is used to check if upstream net-next commit 6c1fd7dc489d9 ("netfilter: cttimeout: decouple timeout policy from nfnetlink_cttimeout object") is there. If it is not defined, we will use the old ctnl_timeout interface rather than the nf_ct_timeout interface that is introduced in this commit. * HAVE_NF_CT_TIMEOUT_FIND_GET_HOOK_NET is used to check if upstream commit 19576c9478682 ("netfilter: cttimeout: add netns support") is there, so that we pass different arguement based on whether the kernel has netns support. Signed-off-by: Yi-Hung Wei --- acinclude.m4 | 7 ++ datapath/linux/Modules.mk | 2 + .../include/net/netfilter/nf_conntrack_timeout.h | 34 +++++++ datapath/linux/compat/nf_conntrack_timeout.c | 102 +++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h create mode 100644 datapath/linux/compat/nf_conntrack_timeout.c diff --git a/acinclude.m4 b/acinclude.m4 index 116ffcf9096d..61fe4faa006a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -714,6 +714,13 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_seqadj.h], [nf_ct_seq_adjust]) OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_count.h], [nf_conncount_gc_list], [OVS_DEFINE([HAVE_UPSTREAM_NF_CONNCOUNT])]) + OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_timeout.h], [nf_ct_set_timeout]) + OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_timeout.h], [struct nf_ct_timeout], + [OVS_DEFINE([HAVE_NF_CT_TIMEOUT])]) + OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_timeout.h], + [\(*nf_ct_timeout_find_get_hook\)], [net], + [OVS_DEFINE([HAVE_NF_CT_TIMEOUT_FIND_GET_HOOK_NET])]) + OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32]) OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32_max]) diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk index cbb29f1c69d0..f93097b8e0e5 100644 --- a/datapath/linux/Modules.mk +++ b/datapath/linux/Modules.mk @@ -21,6 +21,7 @@ openvswitch_sources += \ linux/compat/nf_conntrack_core.c \ linux/compat/nf_conntrack_proto.c \ linux/compat/nf_conntrack_reasm.c \ + linux/compat/nf_conntrack_timeout.c \ linux/compat/reciprocal_div.c \ linux/compat/skbuff-openvswitch.c \ linux/compat/socket.c \ @@ -108,6 +109,7 @@ openvswitch_headers += \ linux/compat/include/net/netfilter/nf_conntrack_helper.h \ linux/compat/include/net/netfilter/nf_conntrack_labels.h \ linux/compat/include/net/netfilter/nf_conntrack_seqadj.h \ + linux/compat/include/net/netfilter/nf_conntrack_timeout.h \ linux/compat/include/net/netfilter/nf_conntrack_zones.h \ linux/compat/include/net/netfilter/nf_nat.h \ linux/compat/include/net/netfilter/ipv6/nf_defrag_ipv6.h \ diff --git a/datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h b/datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h new file mode 100644 index 000000000000..134e72b8363e --- /dev/null +++ b/datapath/linux/compat/include/net/netfilter/nf_conntrack_timeout.h @@ -0,0 +1,34 @@ +#ifndef _NF_CONNTRACK_TIMEOUT_WRAPPER_H +#define _NF_CONNTRACK_TIMEOUT_WRAPPER_H + +#include_next + +#ifndef HAVE_NF_CT_SET_TIMEOUT + +#ifndef HAVE_NF_CT_TIMEOUT +#define nf_ct_timeout ctnl_timeout +#endif + +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT +int rpl_nf_ct_set_timeout(struct net *net, struct nf_conn *ct, u8 l3num, u8 l4num, + const char *timeout_name); +void rpl_nf_ct_destroy_timeout(struct nf_conn *ct); +#else +static inline int rpl_nf_ct_set_timeout(struct net *net, struct nf_conn *ct, + u8 l3num, u8 l4num, + const char *timeout_name) +{ + return -EOPNOTSUPP; +} + +static inline void rpl_nf_ct_destroy_timeout(struct nf_conn *ct) +{ + return; +} +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ + +#define nf_ct_set_timeout rpl_nf_ct_set_timeout +#define nf_ct_destroy_timeout rpl_nf_ct_destroy_timeout + +#endif /* HAVE_NF_CT_SET_TIMEOUT */ +#endif /* _NF_CONNTRACK_TIMEOUT_WRAPPER_H */ diff --git a/datapath/linux/compat/nf_conntrack_timeout.c b/datapath/linux/compat/nf_conntrack_timeout.c new file mode 100644 index 000000000000..c02baff5771b --- /dev/null +++ b/datapath/linux/compat/nf_conntrack_timeout.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT +#ifndef HAVE_NF_CT_SET_TIMEOUT +static void rpl__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); +} + +int rpl_nf_ct_set_timeout(struct net *net, struct nf_conn *ct, + u8 l3num, u8 l4num, const char *timeout_name) +{ + 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; + } + +#ifdef HAVE_NF_CT_TIMEOUT_FIND_GET_HOOK_NET + timeout = timeout_find_get(net, timeout_name); +#else + timeout = timeout_find_get(timeout_name); +#endif + 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: + rpl__nf_ct_timeout_put(timeout); +out: + rcu_read_unlock(); + if (errmsg) + pr_info_ratelimited("%s\n", errmsg); + return ret; +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_set_timeout); + +void rpl_nf_ct_destroy_timeout(struct nf_conn *ct) +{ + 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(); +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_destroy_timeout); + +#endif /* HAVE_NF_CT_SET_TIMEOUT */ +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */