+ return error;
+}
+
+const struct netdev_tunnel_config *
+netdev_get_tunnel_config(const struct netdev *netdev)
+ OVS_EXCLUDED(netdev_mutex)
+{
+ if (netdev->netdev_class->get_tunnel_config) {
+ return netdev->netdev_class->get_tunnel_config(netdev);
+ } else {
+ return NULL;
+ }
+}
+
+static void
+netdev_unref(struct netdev *dev)
+ OVS_RELEASES(netdev_mutex)
+{
+ ovs_assert(dev->ref_cnt);
+ if (!--dev->ref_cnt) {
+ const struct netdev_class *class = dev->netdev_class;
+ struct netdev_registered_class *rc;
+ int old_ref_cnt;
+
+ dev->netdev_class->destruct(dev);
+
+ shash_delete(&netdev_shash, dev->node);
+ free(dev->name);
+ dev->netdev_class->dealloc(dev);
+ ovs_mutex_unlock(&netdev_mutex);
+
+ ovs_mutex_lock(&netdev_class_mutex);
+ rc = netdev_lookup_class(class->type);
+ atomic_sub(&rc->ref_cnt, 1, &old_ref_cnt);
+ ovs_assert(old_ref_cnt > 0);
+ ovs_mutex_unlock(&netdev_class_mutex);
+ } else {
+ ovs_mutex_unlock(&netdev_mutex);
+ }