[ovs-dev,v2,2/7] dpif-netlink: break up code that creates compat ports

Submitted by Eric Garver on March 16, 2017, 10:10 p.m.

Details

Message ID 20170316221021.11149-3-e@erig.me
State New
Headers show

Commit Message

Eric Garver March 16, 2017, 10:10 p.m.
This breaks up creating compat ports so we can reuse some of the code to
create ports with rtnetlink.

Co-authored-by: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
Signed-off-by: Eric Garver <e@erig.me>
---
 lib/dpif-netlink.c | 137 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 78 insertions(+), 59 deletions(-)

Patch hide | download patch | download mbox

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index bad575c9cf65..ee6a30ad5f10 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -784,10 +784,8 @@  get_vport_type(const struct dpif_netlink_vport *vport)
 }
 
 static enum ovs_vport_type
-netdev_to_ovs_vport_type(const struct netdev *netdev)
+netdev_to_ovs_vport_type(const char *type)
 {
-    const char *type = netdev_get_type(netdev);
-
     if (!strcmp(type, "tap") || !strcmp(type, "system")) {
         return OVS_VPORT_TYPE_NETDEV;
     } else if (!strcmp(type, "internal")) {
@@ -808,19 +806,14 @@  netdev_to_ovs_vport_type(const struct netdev *netdev)
 }
 
 static int
-dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev,
+dpif_netlink_port_add__(struct dpif_netlink *dpif, const char *name,
+                        enum ovs_vport_type type,
+                        struct ofpbuf *options,
                         odp_port_t *port_nop)
     OVS_REQ_WRLOCK(dpif->upcall_lock)
 {
-    const struct netdev_tunnel_config *tnl_cfg;
-    char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
-    const char *name = netdev_vport_get_dpif_port(netdev,
-                                                  namebuf, sizeof namebuf);
-    const char *type = netdev_get_type(netdev);
     struct dpif_netlink_vport request, reply;
     struct ofpbuf *buf;
-    uint64_t options_stub[64 / 8];
-    struct ofpbuf options;
     struct nl_sock **socksp = NULL;
     uint32_t *upcall_pids;
     int error = 0;
@@ -835,17 +828,80 @@  dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev,
     dpif_netlink_vport_init(&request);
     request.cmd = OVS_VPORT_CMD_NEW;
     request.dp_ifindex = dpif->dp_ifindex;
-    request.type = netdev_to_ovs_vport_type(netdev);
-    if (request.type == OVS_VPORT_TYPE_UNSPEC) {
+    request.type = type;
+    request.name = name;
+
+    request.port_no = *port_nop;
+    upcall_pids = vport_socksp_to_pids(socksp, dpif->n_handlers);
+    request.n_upcall_pids = socksp ? dpif->n_handlers : 1;
+    request.upcall_pids = upcall_pids;
+
+    if (options) {
+        request.options = options->data;
+        request.options_len = options->size;
+    }
+
+    error = dpif_netlink_vport_transact(&request, &reply, &buf);
+    if (!error) {
+        *port_nop = reply.port_no;
+    } else {
+        if (error == EBUSY && *port_nop != ODPP_NONE) {
+            VLOG_INFO("%s: requested port %"PRIu32" is in use",
+                      dpif_name(&dpif->dpif), *port_nop);
+        }
+
+        vport_del_socksp(dpif, socksp);
+        goto exit;
+    }
+
+    if (socksp) {
+        error = vport_add_channels(dpif, *port_nop, socksp);
+        if (error) {
+            VLOG_INFO("%s: could not add channel for port %s",
+                      dpif_name(&dpif->dpif), name);
+
+            /* Delete the port. */
+            dpif_netlink_vport_init(&request);
+            request.cmd = OVS_VPORT_CMD_DEL;
+            request.dp_ifindex = dpif->dp_ifindex;
+            request.port_no = *port_nop;
+            dpif_netlink_vport_transact(&request, NULL, NULL);
+            vport_del_socksp(dpif, socksp);
+            goto exit;
+        }
+    }
+    free(socksp);
+
+exit:
+    ofpbuf_delete(buf);
+    free(upcall_pids);
+
+    return error;
+}
+
+static int
+dpif_netlink_port_add_compat(struct dpif_netlink *dpif, struct netdev *netdev,
+                             odp_port_t *port_nop)
+    OVS_REQ_WRLOCK(dpif->upcall_lock)
+{
+    const struct netdev_tunnel_config *tnl_cfg;
+    char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
+    const char *name = netdev_vport_get_dpif_port(netdev,
+                                                  namebuf, sizeof namebuf);
+    const char *type = netdev_get_type(netdev);
+    uint64_t options_stub[64 / 8];
+    struct ofpbuf options;
+    enum ovs_vport_type ovs_type;
+
+    ovs_type = netdev_to_ovs_vport_type(netdev_get_type(netdev));
+    if (ovs_type == OVS_VPORT_TYPE_UNSPEC) {
         VLOG_WARN_RL(&error_rl, "%s: cannot create port `%s' because it has "
                      "unsupported type `%s'",
                      dpif_name(&dpif->dpif), name, type);
-        vport_del_socksp(dpif, socksp);
         return EINVAL;
     }
-    request.name = name;
 
-    if (request.type == OVS_VPORT_TYPE_NETDEV) {
+    if (ovs_type == OVS_VPORT_TYPE_NETDEV) {
 #ifdef _WIN32
         /* XXX : Map appropiate Windows handle */
 #else
@@ -854,10 +910,9 @@  dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev,
     }
 
 #ifdef _WIN32
-    if (request.type == OVS_VPORT_TYPE_INTERNAL) {
+    if (ovs_type == OVS_VPORT_TYPE_INTERNAL) {
         if (!create_wmi_port(name)){
             VLOG_ERR("Could not create wmi internal port with name:%s", name);
-            vport_del_socksp(dpif, socksp);
             return EINVAL;
         };
     }
@@ -882,52 +937,16 @@  dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev,
             }
             nl_msg_end_nested(&options, ext_ofs);
         }
-        request.options = options.data;
-        request.options_len = options.size;
-    }
-
-    request.port_no = *port_nop;
-    upcall_pids = vport_socksp_to_pids(socksp, dpif->n_handlers);
-    request.n_upcall_pids = socksp ? dpif->n_handlers : 1;
-    request.upcall_pids = upcall_pids;
-
-    error = dpif_netlink_vport_transact(&request, &reply, &buf);
-    if (!error) {
-        *port_nop = reply.port_no;
+        return dpif_netlink_port_add__(dpif, name, ovs_type, &options,
+                                       port_nop);
     } else {
-        if (error == EBUSY && *port_nop != ODPP_NONE) {
-            VLOG_INFO("%s: requested port %"PRIu32" is in use",
-                      dpif_name(&dpif->dpif), *port_nop);
-        }
-
-        vport_del_socksp(dpif, socksp);
-        goto exit;
+        return dpif_netlink_port_add__(dpif, name, ovs_type, NULL, port_nop);
     }
 
-    if (socksp) {
-        error = vport_add_channels(dpif, *port_nop, socksp);
-        if (error) {
-            VLOG_INFO("%s: could not add channel for port %s",
-                      dpif_name(&dpif->dpif), name);
+}
 
-            /* Delete the port. */
-            dpif_netlink_vport_init(&request);
-            request.cmd = OVS_VPORT_CMD_DEL;
-            request.dp_ifindex = dpif->dp_ifindex;
-            request.port_no = *port_nop;
-            dpif_netlink_vport_transact(&request, NULL, NULL);
-            vport_del_socksp(dpif, socksp);
-            goto exit;
-        }
-    }
-    free(socksp);
 
-exit:
-    ofpbuf_delete(buf);
-    free(upcall_pids);
 
-    return error;
-}
 
 static int
 dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev,
@@ -937,7 +956,7 @@  dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev,
     int error;
 
     fat_rwlock_wrlock(&dpif->upcall_lock);
-    error = dpif_netlink_port_add__(dpif, netdev, port_nop);
+    error = dpif_netlink_port_add_compat(dpif, netdev, port_nop);
     fat_rwlock_unlock(&dpif->upcall_lock);
 
     return error;