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

Yifeng Sun pkusunyifeng at gmail.com
Thu Jul 26 21:29:18 UTC 2018


I tested and it fixed the loading issue on kernel 4.14. Thanks for the
patch.

Tested-by: Yifeng Sun <pkusunyifeng at gmail.com>

Reviewed-by: Yifeng Sun <pkusunyifeng at gmail.com>

On Thu, Jul 26, 2018 at 9:11 AM, Greg Rose <gvrose8192 at 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 at gmail.com>
> ---
>  datapath/linux/compat/ip6_gre.c | 39 ++++++++++++++++++++++++++++++
> +++------
>  datapath/vport.c                | 17 +++++++++++++++--
>  2 files changed, 48 insertions(+), 8 deletions(-)
>
> diff --git a/datapath/linux/compat/ip6_gre.c b/datapath/linux/compat/ip6_
> gre.c
> index 0c88547..f532f21 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,19 +2793,43 @@ 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;
> +               if (err == -EBUSY) {
> +                       goto ip6_gre_loaded;
> +               } else {
> +                       goto add_proto_failed;
> +               }
>         }
>
>         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;
> +       return err;
> +
> +ip6_gre_loaded:
> +       /* Since GRE only allows single receiver to be registerd,
> +        * we skip here so only gre transmit works, see:
> +        *
> +        * commit 9f57c67c379d88a10e8ad676426fee5ae7341b14
> +        * Author: Pravin B Shelar <pshelar at nicira.com>
> +        * Date:   Fri Aug 7 23:51:52 2015 -0700
> +        *     gre: Remove support for sharing GRE protocol hook
> +        *
> +        * 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;
>
> @@ -2817,7 +2842,9 @@ 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
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>


More information about the dev mailing list