From patchwork Wed Aug 1 22:46:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi-Hung Wei X-Patchwork-Id: 952457 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="EQJ07p7u"; 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 41gpSV6p1cz9s4c for ; Thu, 2 Aug 2018 08:51:06 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 133A4D88; Wed, 1 Aug 2018 22:50:35 +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 72174D6D for ; Wed, 1 Aug 2018 22:50:33 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id D2C556C5 for ; Wed, 1 Aug 2018 22:50:32 +0000 (UTC) Received: by mail-pl0-f67.google.com with SMTP id x6-v6so92824plv.10 for ; Wed, 01 Aug 2018 15:50:32 -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=lWHuCJIXD0FH0wHnqL7ztyciST3M6rGFO/A4c8Ns1Ag=; b=EQJ07p7uNGKgbD1hILhBya/6arhf7Q9zJio8KZ0OGIqIvo/BuH/C/3rwfemnimpCUe VJZBpQvM8lz+DNSnNUGmwCy7+cEPDzYuQcGQX3ymkXsj41iA3nUpj1aIK1JqDvZ9seBu CWQ6jWTOvZeJk60Nyk4DjC6n3mab2sWbvPgqRfx5qOyXJ/0UKnrXMEERnlsMy3NyKFFR RCrufLHgFcQyLqy2w3RkmMCGyLV6yF77Ji4J8/5NOTUAZ8/bSrno2DiqMCMckFvx0Tn0 +gfN6GJdvW1LUt9zaz0EoDDXFdFFl+V3o0gCy3xGQ8b95cvQevFk361ztoMw4f+34h1M Bv8g== 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=lWHuCJIXD0FH0wHnqL7ztyciST3M6rGFO/A4c8Ns1Ag=; b=LyWsv42FxJHHSlfGpdhbGqEm+N4aB/K20tZ3gs58UHCiqrd7v5L1tMddK9O9NWqBRj CznJgG9Zg4kYxtKYFrGqt/9CEnjz+LiI/Ejot+kf9vvhZh7yjUcSXw7+On8l+RZIJVvE fn882GXyqAi3GyRuv1DQqys8B542xRzNFg2+fZol+QpuvJDRtU0+Q690Bk3M37lfMmfk dpzClgGtxdzjJF0s/cuAgiH4kESGRyhr8/nxi2UII0U3waHnwOh0rv/iacMslxriRFxg LZOcFZRYOv1EXGpwhc9tQX5aI3wAZEB0Dm0cjWyVROVdkRwNtMGnDoZqx0fZ0e0i/3Pt CaQQ== X-Gm-Message-State: AOUpUlE4Jrl1zizwQWtuqTjqy+jEHZueW69CxpTO2QpBVduyMHf8XJk3 bdLDG7NBh9UoZJAZHjyrtoRwS/5t X-Google-Smtp-Source: AAOMgpdkMeo5Plh3O7/BWSFOosAdOwrwv3gpfbRNeZ/2c6Hug4mjbYLIrcEKAn8UY715yhQ0WvpZ7w== X-Received: by 2002:a17:902:7d8f:: with SMTP id a15-v6mr213473plm.332.1533163831931; Wed, 01 Aug 2018 15:50:31 -0700 (PDT) Received: from Husky.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id l85-v6sm196899pfk.34.2018.08.01.15.50.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 01 Aug 2018 15:50:30 -0700 (PDT) From: Yi-Hung Wei To: dev@openvswitch.org Date: Wed, 1 Aug 2018 15:46:10 -0700 Message-Id: <1533163580-27989-2-git-send-email-yihung.wei@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1533163580-27989-1-git-send-email-yihung.wei@gmail.com> References: <1533163580-27989-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 01/11] compat: Backport nf_ct_netns_{get,put}() 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 backports nf_ct_netns_get/put() in order to support a feature in the follow up patch. nf_ct_netns_{get,put} were first introduced in upstream net-next commit ecb2421b5ddf ("netfilter: add and use nf_ct_netns_get/put") in kernel v4.10, and then updated in commmit 7e35ec0e8044 ("netfilter: conntrack: move nf_ct_netns_{get,put}() to core") in kernel v4.15. We need to invoke nf_ct_netns_get/put() when the underlying nf_conntrack_l3proto supports net_ns_{get,put}(). Therefore, there are 3 cases that we need to consider. 1) Before nf_ct_{get,put}() is introduced. We just mock nf_ct_nets_{get,put}() and do nothing. 2) After 1) and before v4.15 Backports based on commit 7e35ec0e8044 . 3) Staring from v4.15 Use the upstream version. Signed-off-by: Yi-Hung Wei --- acinclude.m4 | 4 + datapath/linux/Modules.mk | 4 +- .../compat/include/net/netfilter/nf_conntrack.h | 8 ++ .../linux/compat/include/uapi/linux/netfilter.h | 14 +++ datapath/linux/compat/nf_conntrack_proto.c | 112 +++++++++++++++++++++ 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 datapath/linux/compat/include/uapi/linux/netfilter.h create mode 100644 datapath/linux/compat/nf_conntrack_proto.c diff --git a/acinclude.m4 b/acinclude.m4 index ad6b5b5e067e..731bc07be8fa 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -588,6 +588,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ [OVS_DEFINE([HAVE_NF_HOOKFN_ARG_PRIV])]) OVS_FIND_FIELD_IFELSE([$KSRC/include/linux/netfilter.h], [nf_hook_ops], [owner], [OVS_DEFINE([HAVE_NF_HOOKS_OPS_OWNER])]) + OVS_GREP_IFELSE([$KSRC/include/linux/netfilter.h], [NFPROTO_INET]) + OVS_FIND_FIELD_IFELSE([$KSRC/include/linux/netfilter_ipv6.h], [nf_ipv6_ops], [fragment.*sock], [OVS_DEFINE([HAVE_NF_IPV6_OPS_FRAGMENT])]) @@ -610,6 +612,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ [nf_ct_is_untracked]) OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_zones.h], [nf_ct_zone_init]) + OVS_FIND_FIELD_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_l3proto.h], + [net_ns_get]) OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_labels.h], [nf_connlabels_get]) OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_labels.h], diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk index 104c32fa16ea..04ea5b756b6c 100644 --- a/datapath/linux/Modules.mk +++ b/datapath/linux/Modules.mk @@ -18,6 +18,7 @@ openvswitch_sources += \ linux/compat/lisp.c \ linux/compat/netdevice.c \ linux/compat/nf_conntrack_core.c \ + linux/compat/nf_conntrack_proto.c \ linux/compat/nf_conntrack_reasm.c \ linux/compat/reciprocal_div.c \ linux/compat/skbuff-openvswitch.c \ @@ -107,5 +108,6 @@ openvswitch_headers += \ linux/compat/include/net/netfilter/nf_nat.h \ linux/compat/include/net/netfilter/ipv6/nf_defrag_ipv6.h \ linux/compat/include/net/sctp/checksum.h \ - linux/compat/include/net/erspan.h + linux/compat/include/net/erspan.h \ + linux/compat/include/uapi/linux/netfilter.h EXTRA_DIST += linux/compat/build-aux/export-check-whitelist diff --git a/datapath/linux/compat/include/net/netfilter/nf_conntrack.h b/datapath/linux/compat/include/net/netfilter/nf_conntrack.h index bb40b0f6da2a..50db914a39a1 100644 --- a/datapath/linux/compat/include/net/netfilter/nf_conntrack.h +++ b/datapath/linux/compat/include/net/netfilter/nf_conntrack.h @@ -22,4 +22,12 @@ nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info) skb->nfctinfo = info; } #endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) +int rpl_nf_ct_netns_get(struct net *net, u8 nfproto); +void rpl_nf_ct_netns_put(struct net *net, u8 nfproto); +#define nf_ct_netns_get rpl_nf_ct_netns_get +#define nf_ct_netns_put rpl_nf_ct_netns_put +#endif + #endif /* _NF_CONNTRACK_WRAPPER_H */ diff --git a/datapath/linux/compat/include/uapi/linux/netfilter.h b/datapath/linux/compat/include/uapi/linux/netfilter.h new file mode 100644 index 000000000000..56895b17b334 --- /dev/null +++ b/datapath/linux/compat/include/uapi/linux/netfilter.h @@ -0,0 +1,14 @@ +#ifndef _NETFILTER_WRAPPER_H +#define _NETFILTER_WRAPPER_H + +#include_next + +/* + * NFPROTO_INET was introduced in net-next commit 1d49144c0aaa + * ("netfilter: nf_tables: add "inet" table for IPv4/IPv6") in v3.14. + * Define this symbol to support back to v3.10 kernel. */ +#ifndef HAVE_NFPROTO_INET +#define NFPROTO_INET 1 +#endif + +#endif /* _NETFILTER_WRAPPER_H */ diff --git a/datapath/linux/compat/nf_conntrack_proto.c b/datapath/linux/compat/nf_conntrack_proto.c new file mode 100644 index 000000000000..e877d763892d --- /dev/null +++ b/datapath/linux/compat/nf_conntrack_proto.c @@ -0,0 +1,112 @@ +#include + +#include +#include + +/* + * Upstream net-next commmit 7e35ec0e8044 + * ("netfilter: conntrack: move nf_ct_netns_{get,put}() to core") + * is introduced in v4.15, and it supports NFPROTO_INET in + * nf_ct_netns_{get,put}() that OVS conntrack uses this feature. + * + * However, we only need this feature if the underlying nf_conntrack_l3proto + * supports net_ns_get/put. Thus, we just mock the functions if + * HAVE_NET_NS_SET is false. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) +#ifdef HAVE_NET_NS_SET +static int nf_ct_netns_do_get(struct net *net, u8 nfproto) +{ + const struct nf_conntrack_l3proto *l3proto; + int ret; + + might_sleep(); + + ret = nf_ct_l3proto_try_module_get(nfproto); + if (ret < 0) + return ret; + + /* we already have a reference, can't fail */ + rcu_read_lock(); + l3proto = __nf_ct_l3proto_find(nfproto); + rcu_read_unlock(); + + if (!l3proto->net_ns_get) + return 0; + + ret = l3proto->net_ns_get(net); + if (ret < 0) + nf_ct_l3proto_module_put(nfproto); + + return ret; +} + +int rpl_nf_ct_netns_get(struct net *net, u8 nfproto) +{ + int err; + + if (nfproto == NFPROTO_INET) { + err = nf_ct_netns_do_get(net, NFPROTO_IPV4); + if (err < 0) + goto err1; + err = nf_ct_netns_do_get(net, NFPROTO_IPV6); + if (err < 0) + goto err2; + } else { + err = nf_ct_netns_do_get(net, nfproto); + if (err < 0) + goto err1; + } + return 0; + +err2: + nf_ct_netns_put(net, NFPROTO_IPV4); +err1: + return err; +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_get); + +static void nf_ct_netns_do_put(struct net *net, u8 nfproto) +{ + const struct nf_conntrack_l3proto *l3proto; + + might_sleep(); + + /* same as nf_conntrack_netns_get(), reference assumed */ + rcu_read_lock(); + l3proto = __nf_ct_l3proto_find(nfproto); + rcu_read_unlock(); + + if (WARN_ON(!l3proto)) + return; + + if (l3proto->net_ns_put) + l3proto->net_ns_put(net); + + nf_ct_l3proto_module_put(nfproto); +} + +void rpl_nf_ct_netns_put(struct net *net, uint8_t nfproto) +{ + if (nfproto == NFPROTO_INET) { + nf_ct_netns_do_put(net, NFPROTO_IPV4); + nf_ct_netns_do_put(net, NFPROTO_IPV6); + } else + nf_ct_netns_do_put(net, nfproto); +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_put); + +#else /* !HAVE_NET_NS_SET */ +void rpl_nf_ct_netns_put(struct net *net, uint8_t nfproto) +{ +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_put); + +int rpl_nf_ct_netns_get(struct net *net, u8 nfproto) +{ + return 0; +} +EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_get); + +#endif /* HAVE_NET_NS_SET */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) */