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 <[email protected]> --- 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(-) 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 <[email protected]> + * 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); -- 1.8.3.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
