diff mbox

[ovs-dev,RFC,v5,7/8] dpif-netlink: Probe for out-of-tree datapath.

Message ID 20170216222533.11027-8-e@erig.me
State Superseded
Headers show

Commit Message

Eric Garver Feb. 16, 2017, 10:25 p.m. UTC
For out-of-tree datapath, only try genetlink/compat.
For in-tree kernel datapath, try rtnetlink then genetlink.

Signed-off-by: Eric Garver <e@erig.me>
---
 lib/dpif-netlink.c   | 16 +++++++++++++---
 lib/dpif-rtnetlink.c | 39 +++++++++++++++++++++++++++++++++++++++
 lib/dpif-rtnetlink.h |  7 +++++++
 3 files changed, 59 insertions(+), 3 deletions(-)

Comments

Joe Stringer March 14, 2017, 8:21 p.m. UTC | #1
On 16 February 2017 at 14:25, Eric Garver <e@erig.me> wrote:
> For out-of-tree datapath, only try genetlink/compat.
> For in-tree kernel datapath, try rtnetlink then genetlink.
>
> Signed-off-by: Eric Garver <e@erig.me>
> ---
>  lib/dpif-netlink.c   | 16 +++++++++++++---
>  lib/dpif-rtnetlink.c | 39 +++++++++++++++++++++++++++++++++++++++
>  lib/dpif-rtnetlink.h |  7 +++++++
>  3 files changed, 59 insertions(+), 3 deletions(-)
>
> diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
> index ae8204ffe6e1..991004491ec2 100644
> --- a/lib/dpif-netlink.c
> +++ b/lib/dpif-netlink.c
> @@ -211,6 +211,12 @@ static int ovs_packet_family;
>   * Initialized by dpif_netlink_init(). */
>  static unsigned int ovs_vport_mcgroup;
>
> +/* If true, tunnel devices are created using OVS compat/genetlink.
> + * If false, tunnel devices are created with rtnetlink and using light weight
> + * tunnels. If we fail to create the tunnel the rtnetlink+LWT, then we fallback
> + * to using the compat interface. */
> +static bool ovs_tunnels_out_of_tree = true;
> +
>  static int dpif_netlink_init(void);
>  static int open_dpif(const struct dpif_netlink_dp *, struct dpif **);
>  static uint32_t dpif_netlink_port_get_pid(const struct dpif *,
> @@ -979,11 +985,13 @@ dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev,
>                        odp_port_t *port_nop)
>  {
>      struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
> -    int error;
> +    int error = EOPNOTSUPP;
>
>      fat_rwlock_wrlock(&dpif->upcall_lock);
> -    error = dpif_rtnetlink_port_create_and_add(dpif, netdev, port_nop);
> -    if (error == EOPNOTSUPP) {
> +    if (!ovs_tunnels_out_of_tree) {
> +        error = dpif_rtnetlink_port_create_and_add(dpif, netdev, port_nop);
> +    }
> +    if (error) {
>          error = dpif_netlink_port_add_compat(dpif, netdev, port_nop);
>      }
>      fat_rwlock_unlock(&dpif->upcall_lock);
> @@ -2495,6 +2503,8 @@ dpif_netlink_init(void)
>                                             &ovs_vport_mcgroup);
>          }
>
> +        ovs_tunnels_out_of_tree = dpif_rtnetlink_probe_oot_tunnels();
> +
>          ovsthread_once_done(&once);
>      }
>
> diff --git a/lib/dpif-rtnetlink.c b/lib/dpif-rtnetlink.c
> index 60a5003b88ca..853de6b764e8 100644
> --- a/lib/dpif-rtnetlink.c
> +++ b/lib/dpif-rtnetlink.c
> @@ -474,3 +474,42 @@ dpif_rtnetlink_port_destroy(const char *name, const char *type)
>      }
>      return 0;
>  }
> +
> +/**
> + * This is to probe for whether the modules are out-of-tree (openvswitch) or
> + * in-tree (upstream kernel).

Minor style thing, "this is to" provides no additional information,
it's just language overhead:

/* Probe for whether the modules are out-of-tree (openvswitch) or
in-tree (upstream kernel). */

> + *
> + * We probe for "ovs_geneve" via rtnetlink. As long as this returns something
> + * other than EOPNOTSUPP we know that the module in use is the out-of-tree one.
> + * This will be used to determine what netlink interface to use when creating

...determine *which* netlink interface...

> + * ports; rtnetlink or compat/genetlink.
> + *
> + * See ovs_tunnels_out_of_tree
> + */
> +bool
> +dpif_rtnetlink_probe_oot_tunnels(void)
> +{
> +    struct netdev *netdev = NULL;
> +    bool out_of_tree = false;
> +    int error;
> +
> +    error = netdev_open("ovs-system-probe", "geneve", &netdev);
> +    if (!error) {
> +        error = dpif_rtnetlink_geneve_create_kind(netdev, "ovs_geneve");
> +        if (error != EOPNOTSUPP) {
> +            if (!error) {
> +                char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
> +                const char *dp_port;
> +
> +                dp_port = netdev_vport_get_dpif_port(netdev, namebuf,
> +                                                     sizeof namebuf);
> +                dpif_rtnetlink_geneve_destroy(dp_port);
> +            }
> +            out_of_tree = true;
> +        }
> +        netdev_close(netdev);
> +        error = 0;

I don't think this line is ever used?

> +    }
> +
> +    return out_of_tree;
> +}
> diff --git a/lib/dpif-rtnetlink.h b/lib/dpif-rtnetlink.h
> index 515820f02e66..5bb578c4ac65 100644
> --- a/lib/dpif-rtnetlink.h
> +++ b/lib/dpif-rtnetlink.h
> @@ -24,6 +24,8 @@
>  int dpif_rtnetlink_port_create(struct netdev *netdev);
>  int dpif_rtnetlink_port_destroy(const char *name, const char *type);
>
> +bool dpif_rtnetlink_probe_oot_tunnels(void);
> +
>  #ifndef __linux__
>  /* Dummy implementations for non Linux builds.
>   *
> @@ -41,6 +43,11 @@ static inline int dpif_rtnetlink_port_destroy(const char *name OVS_UNUSED,
>      return EOPNOTSUPP;
>  }
>
> +static inline bool dpif_rtnetlink_probe_oot_tunnels(void)
> +{
> +    return true;
> +}
> +
>  #endif
>
>  #endif /* DPIF_RTNETLINK_H */
> --
> 2.10.0
>
diff mbox

Patch

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index ae8204ffe6e1..991004491ec2 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -211,6 +211,12 @@  static int ovs_packet_family;
  * Initialized by dpif_netlink_init(). */
 static unsigned int ovs_vport_mcgroup;
 
+/* If true, tunnel devices are created using OVS compat/genetlink.
+ * If false, tunnel devices are created with rtnetlink and using light weight
+ * tunnels. If we fail to create the tunnel the rtnetlink+LWT, then we fallback
+ * to using the compat interface. */
+static bool ovs_tunnels_out_of_tree = true;
+
 static int dpif_netlink_init(void);
 static int open_dpif(const struct dpif_netlink_dp *, struct dpif **);
 static uint32_t dpif_netlink_port_get_pid(const struct dpif *,
@@ -979,11 +985,13 @@  dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev,
                       odp_port_t *port_nop)
 {
     struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
-    int error;
+    int error = EOPNOTSUPP;
 
     fat_rwlock_wrlock(&dpif->upcall_lock);
-    error = dpif_rtnetlink_port_create_and_add(dpif, netdev, port_nop);
-    if (error == EOPNOTSUPP) {
+    if (!ovs_tunnels_out_of_tree) {
+        error = dpif_rtnetlink_port_create_and_add(dpif, netdev, port_nop);
+    }
+    if (error) {
         error = dpif_netlink_port_add_compat(dpif, netdev, port_nop);
     }
     fat_rwlock_unlock(&dpif->upcall_lock);
@@ -2495,6 +2503,8 @@  dpif_netlink_init(void)
                                            &ovs_vport_mcgroup);
         }
 
+        ovs_tunnels_out_of_tree = dpif_rtnetlink_probe_oot_tunnels();
+
         ovsthread_once_done(&once);
     }
 
diff --git a/lib/dpif-rtnetlink.c b/lib/dpif-rtnetlink.c
index 60a5003b88ca..853de6b764e8 100644
--- a/lib/dpif-rtnetlink.c
+++ b/lib/dpif-rtnetlink.c
@@ -474,3 +474,42 @@  dpif_rtnetlink_port_destroy(const char *name, const char *type)
     }
     return 0;
 }
+
+/**
+ * This is to probe for whether the modules are out-of-tree (openvswitch) or
+ * in-tree (upstream kernel).
+ *
+ * We probe for "ovs_geneve" via rtnetlink. As long as this returns something
+ * other than EOPNOTSUPP we know that the module in use is the out-of-tree one.
+ * This will be used to determine what netlink interface to use when creating
+ * ports; rtnetlink or compat/genetlink.
+ *
+ * See ovs_tunnels_out_of_tree
+ */
+bool
+dpif_rtnetlink_probe_oot_tunnels(void)
+{
+    struct netdev *netdev = NULL;
+    bool out_of_tree = false;
+    int error;
+
+    error = netdev_open("ovs-system-probe", "geneve", &netdev);
+    if (!error) {
+        error = dpif_rtnetlink_geneve_create_kind(netdev, "ovs_geneve");
+        if (error != EOPNOTSUPP) {
+            if (!error) {
+                char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
+                const char *dp_port;
+
+                dp_port = netdev_vport_get_dpif_port(netdev, namebuf,
+                                                     sizeof namebuf);
+                dpif_rtnetlink_geneve_destroy(dp_port);
+            }
+            out_of_tree = true;
+        }
+        netdev_close(netdev);
+        error = 0;
+    }
+
+    return out_of_tree;
+}
diff --git a/lib/dpif-rtnetlink.h b/lib/dpif-rtnetlink.h
index 515820f02e66..5bb578c4ac65 100644
--- a/lib/dpif-rtnetlink.h
+++ b/lib/dpif-rtnetlink.h
@@ -24,6 +24,8 @@ 
 int dpif_rtnetlink_port_create(struct netdev *netdev);
 int dpif_rtnetlink_port_destroy(const char *name, const char *type);
 
+bool dpif_rtnetlink_probe_oot_tunnels(void);
+
 #ifndef __linux__
 /* Dummy implementations for non Linux builds.
  *
@@ -41,6 +43,11 @@  static inline int dpif_rtnetlink_port_destroy(const char *name OVS_UNUSED,
     return EOPNOTSUPP;
 }
 
+static inline bool dpif_rtnetlink_probe_oot_tunnels(void)
+{
+    return true;
+}
+
 #endif
 
 #endif /* DPIF_RTNETLINK_H */