[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