- if (dev->n_args) {
- for (i = 0; i < dev->n_args; i++) {
- free(dev->args[i].key);
- free(dev->args[i].value);
+ ovs_rwlock_rdlock(&netdev_class_rwlock);
+ ovs_mutex_lock(&netdev_mutex);
+ netdev = shash_find_data(&netdev_shash, name);
+ if (!netdev) {
+ struct netdev_registered_class *rc;
+
+ rc = netdev_lookup_class(type && type[0] ? type : "system");
+ if (rc) {
+ netdev = rc->class->alloc();
+ if (netdev) {
+ memset(netdev, 0, sizeof *netdev);
+ netdev->netdev_class = rc->class;
+ netdev->name = xstrdup(name);
+ netdev->node = shash_add(&netdev_shash, name, netdev);
+ list_init(&netdev->saved_flags_list);
+
+ error = rc->class->construct(netdev);
+ if (!error) {
+ int old_ref_cnt;
+
+ atomic_add(&rc->ref_cnt, 1, &old_ref_cnt);
+ seq_change(connectivity_seq_get());
+ } else {
+ free(netdev->name);
+ ovs_assert(list_is_empty(&netdev->saved_flags_list));
+ shash_delete(&netdev_shash, netdev->node);
+ rc->class->dealloc(netdev);
+ }
+ } else {
+ error = ENOMEM;
+ }
+ } else {
+ VLOG_WARN("could not create netdev %s of unknown type %s",
+ name, type);
+ error = EAFNOSUPPORT;