datapath: Check for NULL upcall_portids.
[cascardo/ovs.git] / lib / netdev.c
index 45a4165..5bf2220 100644 (file)
@@ -151,6 +151,7 @@ netdev_run(void)
 {
     struct netdev_registered_class *rc;
 
+    netdev_initialize();
     ovs_mutex_lock(&netdev_class_mutex);
     HMAP_FOR_EACH (rc, hmap_node, &netdev_classes) {
         if (rc->class->run) {
@@ -386,15 +387,15 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
         error = 0;
     }
 
-    ovs_mutex_unlock(&netdev_mutex);
-    ovs_mutex_unlock(&netdev_class_mutex);
-
     if (!error) {
         netdev->ref_cnt++;
         *netdevp = netdev;
     } else {
         *netdevp = NULL;
     }
+    ovs_mutex_unlock(&netdev_mutex);
+    ovs_mutex_unlock(&netdev_class_mutex);
+
     return error;
 }
 
@@ -553,10 +554,7 @@ netdev_rxq_open(struct netdev *netdev, struct netdev_rxq **rxp, int id)
             rx->queue_id = id;
             error = netdev->netdev_class->rxq_construct(rx);
             if (!error) {
-                ovs_mutex_lock(&netdev_mutex);
-                netdev->ref_cnt++;
-                ovs_mutex_unlock(&netdev_mutex);
-
+                netdev_ref(netdev);
                 *rxp = rx;
                 return 0;
             }
@@ -1612,6 +1610,41 @@ netdev_get_devices(const struct netdev_class *netdev_class,
     ovs_mutex_unlock(&netdev_mutex);
 }
 
+/* Extracts pointers to all 'netdev-vports' into an array 'vports'
+ * and returns it.  Stores the size of the array into '*size'.
+ *
+ * The caller is responsible for freeing 'vports' and must close
+ * each 'netdev-vport' in the list. */
+struct netdev **
+netdev_get_vports(size_t *size)
+    OVS_EXCLUDED(netdev_mutex)
+{
+    struct netdev **vports;
+    struct shash_node *node;
+    size_t n = 0;
+
+    if (!size) {
+        return NULL;
+    }
+
+    /* Explicitly allocates big enough chunk of memory. */
+    vports = xmalloc(shash_count(&netdev_shash) * sizeof *vports);
+    ovs_mutex_lock(&netdev_mutex);
+    SHASH_FOR_EACH (node, &netdev_shash) {
+        struct netdev *dev = node->data;
+
+        if (netdev_vport_is_vport_class(dev->netdev_class)) {
+            dev->ref_cnt++;
+            vports[n] = dev;
+            n++;
+        }
+    }
+    ovs_mutex_unlock(&netdev_mutex);
+    *size = n;
+
+    return vports;
+}
+
 const char *
 netdev_get_type_from_name(const char *name)
 {