diff mbox series

[ovs-dev,V2] compat: Allow IPv6 GRE/ERSPAN Tx when ip6_gre is loaded

Message ID 1532715608-15895-1-git-send-email-gvrose8192@gmail.com
State Accepted
Headers show
Series [ovs-dev,V2] compat: Allow IPv6 GRE/ERSPAN Tx when ip6_gre is loaded | expand

Commit Message

Gregory Rose July 27, 2018, 6:20 p.m. UTC
When for some reason the built-in kernel ip6_gre module is loaded that
would prevent the openvswitch kernel driver from loading.  Even when
the built-in kernel ip6_gre module is loaded we can still perform
port mirroring via Tx.  Adjust the error handling and detect when
the ip6_gre kernel module is loaded and in that case still enable
IPv6 GRE/ERSPAN Tx.

Signed-off-by: Greg Rose <gvrose8192@gmail.com>

---

V2 - Fix up a couple of issues William found
---
 datapath/linux/compat/ip6_gre.c | 41 +++++++++++++++++++++++++++++++----------
 datapath/vport.c                | 17 +++++++++++++++--
 2 files changed, 46 insertions(+), 12 deletions(-)

Comments

William Tu July 27, 2018, 6:43 p.m. UTC | #1
On Fri, Jul 27, 2018 at 11:20 AM, Greg Rose <gvrose8192@gmail.com> wrote:

> When for some reason the built-in kernel ip6_gre module is loaded that
> would prevent the openvswitch kernel driver from loading.  Even when
> the built-in kernel ip6_gre module is loaded we can still perform
> port mirroring via Tx.  Adjust the error handling and detect when
> the ip6_gre kernel module is loaded and in that case still enable
> IPv6 GRE/ERSPAN Tx.
>
> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>
> ---
>

LGTM, Thanks.
Acked-by: William Tu <u9012063@gmail.com>
Ben Pfaff July 27, 2018, 7:31 p.m. UTC | #2
On Fri, Jul 27, 2018 at 11:20:08AM -0700, Greg Rose wrote:
> When for some reason the built-in kernel ip6_gre module is loaded that
> would prevent the openvswitch kernel driver from loading.  Even when
> the built-in kernel ip6_gre module is loaded we can still perform
> port mirroring via Tx.  Adjust the error handling and detect when
> the ip6_gre kernel module is loaded and in that case still enable
> IPv6 GRE/ERSPAN Tx.
> 
> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
> 
> ---
> 
> V2 - Fix up a couple of issues William found

Thanks.  I applied this to master and branch-2.10.  If it should be
backported further, please let me know how far.
Gregory Rose July 27, 2018, 8:39 p.m. UTC | #3
On 7/27/2018 12:31 PM, Ben Pfaff wrote:
> On Fri, Jul 27, 2018 at 11:20:08AM -0700, Greg Rose wrote:
>> When for some reason the built-in kernel ip6_gre module is loaded that
>> would prevent the openvswitch kernel driver from loading.  Even when
>> the built-in kernel ip6_gre module is loaded we can still perform
>> port mirroring via Tx.  Adjust the error handling and detect when
>> the ip6_gre kernel module is loaded and in that case still enable
>> IPv6 GRE/ERSPAN Tx.
>>
>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>>
>> ---
>>
>> V2 - Fix up a couple of issues William found
> Thanks.  I applied this to master and branch-2.10.  If it should be
> backported further, please let me know how far.

Thanks Ben, I think master and 2.10 is fine.

- Greg
diff mbox series

Patch

diff --git a/datapath/linux/compat/ip6_gre.c b/datapath/linux/compat/ip6_gre.c
index 0c88547..54a76ab 100644
--- a/datapath/linux/compat/ip6_gre.c
+++ b/datapath/linux/compat/ip6_gre.c
@@ -65,6 +65,7 @@ 
 #define IP6_GRE_HASH_SIZE (1 << IP6_GRE_HASH_SIZE_SHIFT)
 
 static unsigned int ip6gre_net_id __read_mostly;
+static bool ip6_gre_loaded = false;
 struct ip6gre_net {
 	struct ip6_tnl __rcu *tunnels[4][IP6_GRE_HASH_SIZE];
 
@@ -2792,32 +2793,52 @@  int rpl_ip6gre_init(void)
 	int err;
 
 	err = register_pernet_device(&ip6gre_net_ops);
-	if (err < 0)
-		return err;
+	if (err < 0) {
+		if (err == -EEXIST)
+			goto ip6_gre_loaded;
+		else
+			goto out;
+	}
 
 	err = inet6_add_protocol(&ip6gre_protocol, IPPROTO_GRE);
 	if (err < 0) {
 		pr_info("%s: can't add protocol\n", __func__);
-		goto add_proto_failed;
+		unregister_pernet_device(&ip6gre_net_ops);
+		goto ip6_gre_loaded;
 	}
 
 	pr_info("GRE over IPv6 tunneling driver\n");
 	ovs_vport_ops_register(&ovs_ip6gre_vport_ops);
 	ovs_vport_ops_register(&ovs_erspan6_vport_ops);
-	return 0;
-out:
 	return err;
 
-add_proto_failed:
-	unregister_pernet_device(&ip6gre_net_ops);
-	goto out;
+ip6_gre_loaded:
+	/* Since IPv6 GRE only allows single receiver to be registerd,
+	 * we skip here so only transmit works, see:
+	 *
+	 * commit f9242b6b28d61295f2bf7e8adfb1060b382e5381
+	 * Author: David S. Miller <davem@davemloft.net>
+	 * Date:   Tue Jun 19 18:56:21 2012 -0700
+	 *
+	 *     inet: Sanitize inet{,6} protocol demux.
+	 *
+	 * OVS GRE receive part is disabled.
+	 */
+	pr_info("GRE TX only over IPv6 tunneling driver\n");
+	ip6_gre_loaded = true;
+	ovs_vport_ops_register(&ovs_ip6gre_vport_ops);
+	ovs_vport_ops_register(&ovs_erspan6_vport_ops);
+out:
+	return err;
 }
 
 void rpl_ip6gre_fini(void)
 {
 	ovs_vport_ops_unregister(&ovs_erspan6_vport_ops);
 	ovs_vport_ops_unregister(&ovs_ip6gre_vport_ops);
-	inet6_del_protocol(&ip6gre_protocol, IPPROTO_GRE);
-	unregister_pernet_device(&ip6gre_net_ops);
+	if (!ip6_gre_loaded) {
+		inet6_del_protocol(&ip6gre_protocol, IPPROTO_GRE);
+		unregister_pernet_device(&ip6gre_net_ops);
+	}
 }
 #endif /* USE_UPSTREAM_TUNNEL */
diff --git a/datapath/vport.c b/datapath/vport.c
index 28ddb86..e1b321f 100644
--- a/datapath/vport.c
+++ b/datapath/vport.c
@@ -43,6 +43,7 @@ 
 
 static LIST_HEAD(vport_ops_list);
 static bool compat_gre_loaded = false;
+static bool compat_ip6_tunnel_loaded = false;
 
 /* Protected by RCU read lock for reading, ovs_mutex for writing. */
 static struct hlist_head *dev_table;
@@ -81,11 +82,22 @@  int ovs_vport_init(void)
 		compat_gre_loaded = true;
 	}
 	err = ip6gre_init();
-	if (err)
+	if (err && err != -EEXIST) {
 		goto err_ip6gre;
+	} else {
+		if (err == -EEXIST) {
+			pr_warn("IPv6 GRE/ERSPAN Rx mode is not supported\n");
+			goto skip_ip6_tunnel_init;
+		}
+	}
+
 	err = ip6_tunnel_init();
 	if (err)
 		goto err_ip6_tunnel;
+	else
+		compat_ip6_tunnel_loaded = true;
+
+skip_ip6_tunnel_init:
 	err = geneve_init_module();
 	if (err)
 		goto err_geneve;
@@ -131,7 +143,8 @@  void ovs_vport_exit(void)
 	ovs_stt_cleanup_module();
 	vxlan_cleanup_module();
 	geneve_cleanup_module();
-	ip6_tunnel_cleanup();
+	if (compat_ip6_tunnel_loaded)
+		ip6_tunnel_cleanup();
 	ip6gre_fini();
 	lisp_cleanup_module();
 	kfree(dev_table);