[ovs-dev] [PATCH v2] Windows: Fix broken kernel userspace communication

Alin Gabriel Serdean aserdean at ovn.org
Fri Nov 16 13:32:58 UTC 2018


Patch: https://github.com/openvswitch/ovs/commit/69c51582ff786a68fc325c1c50624715482bc460
broke Windows userpace - kernel communication.

On windows we create netlink sockets when the handlers are initiated and
reuse them.
This patch remaps the usage of the netlink socket pool.

Fixes:
https://github.com/openvswitch/ovs-issues/issues/164

Signed-off-by: Alin Gabriel Serdean <aserdean at ovn.org>
Acked-by: Shashank Ram <rams at vmware.com>
Tested-by: Shashank Ram <rams at vmware.com>
Signed-off-by: Ben Pfaff <blp at ovn.org>
Co-authored-by: Ben Pfaff <blp at ovn.org>
---
v1 -> v2: Fold in nice incremental from Ben
RFC -> v1: Improve wording, change function name and add ifdef guard for them
---
 lib/dpif-netlink.c | 45 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 4ae132866..8d60e1d2e 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -246,6 +246,42 @@ static int dpif_netlink_port_query__(const struct dpif_netlink *dpif,
                                      odp_port_t port_no, const char *port_name,
                                      struct dpif_port *dpif_port);
 
+static int
+create_nl_sock(struct dpif_netlink *dpif OVS_UNUSED, struct nl_sock **socksp)
+    OVS_REQ_WRLOCK(dpif->upcall_lock)
+{
+#ifndef _WIN32
+    return nl_sock_create(NETLINK_GENERIC, socksp);
+#else
+    /* Pick netlink sockets to use in a round-robin fashion from each
+     * handler's pool of sockets. */
+    struct dpif_handler *handler = &dpif->handlers[0];
+    struct dpif_windows_vport_sock *sock_pool = handler->vport_sock_pool;
+    size_t index = handler->last_used_pool_idx;
+
+    /* A pool of sockets is allocated when the handler is initialized. */
+    if (sock_pool == NULL) {
+        *socksp = NULL;
+        return EINVAL;
+    }
+
+    ovs_assert(index < VPORT_SOCK_POOL_SIZE);
+    *socksp = sock_pool[index].nl_sock;
+    ovs_assert(*socksp);
+    index = (index == VPORT_SOCK_POOL_SIZE - 1) ? 0 : index + 1;
+    handler->last_used_pool_idx = index;
+    return 0;
+#endif
+}
+
+static void
+close_nl_sock(struct nl_sock *socksp)
+{
+#ifndef _WIN32
+    nl_sock_destroy(socksp);
+#endif
+}
+
 static struct dpif_netlink *
 dpif_netlink_cast(const struct dpif *dpif)
 {
@@ -716,7 +752,7 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, const char *name,
     int error = 0;
 
     if (dpif->handlers) {
-        error = nl_sock_create(NETLINK_GENERIC, &socksp);
+        error = create_nl_sock(dpif, &socksp);
         if (error) {
             return error;
         }
@@ -749,7 +785,7 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, const char *name,
                       dpif_name(&dpif->dpif), *port_nop);
         }
 
-        nl_sock_destroy(socksp);
+        close_nl_sock(socksp);
         goto exit;
     }
 
@@ -764,7 +800,7 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, const char *name,
         request.dp_ifindex = dpif->dp_ifindex;
         request.port_no = *port_nop;
         dpif_netlink_vport_transact(&request, NULL, NULL);
-        nl_sock_destroy(socksp);
+        close_nl_sock(socksp);
         goto exit;
     }
 
@@ -2249,8 +2285,9 @@ dpif_netlink_refresh_channels(struct dpif_netlink *dpif, uint32_t n_handlers)
         if (port_no >= dpif->uc_array_size
             || !vport_get_pid(dpif, port_no, &upcall_pid)) {
             struct nl_sock *socksp;
+            error = create_nl_sock(dpif, &socksp);
 
-            if (nl_sock_create(NETLINK_GENERIC, &socksp)) {
+            if (error) {
                 goto error;
             }
 
-- 
2.16.1.windows.1



More information about the dev mailing list