[ovs-dev] [PATCH 09/12] datapath: compat: Backport nf_conntrack_timeout support

William Tu u9012063 at gmail.com
Fri Jul 26 20:35:57 UTC 2019


On Thu, Jul 25, 2019 at 04:24:11PM -0700, Yi-Hung Wei wrote:
> 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 <yihung.wei at gmail.com>
> ---
Looks good to me.

Acked-by: William Tu <u9012063 at gmail.com>

>  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 9e1569b07c73..396b5f412094 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -707,6 +707,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 <net/netfilter/nf_conntrack_timeout.h>
> +
> +#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 <net/netfilter/nf_conntrack.h>
> +#include <net/netfilter/nf_conntrack_core.h>
> +#include <net/netfilter/nf_conntrack_extend.h>
> +#include <net/netfilter/nf_conntrack_timeout.h>
> +
> +#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 */
> -- 
> 2.7.4
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev


More information about the dev mailing list