Merge tag 'omap-for-v4.7/fixes-v2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / drivers / net / macvtap.c
index 9a35aa4623142795cbcf6311e4d05a8e13e5776c..bd6720962b1fc4325cf4ca848b73bb633bc4d98c 100644 (file)
@@ -129,7 +129,18 @@ static DEFINE_MUTEX(minor_lock);
 static DEFINE_IDR(minor_idr);
 
 #define GOODCOPY_LEN 128
-static struct class *macvtap_class;
+static const void *macvtap_net_namespace(struct device *d)
+{
+       struct net_device *dev = to_net_dev(d->parent);
+       return dev_net(dev);
+}
+
+static struct class macvtap_class = {
+       .name = "macvtap",
+       .owner = THIS_MODULE,
+       .ns_type = &net_ns_type_operations,
+       .namespace = macvtap_net_namespace,
+};
 static struct cdev macvtap_cdev;
 
 static const struct proto_ops macvtap_socket_ops;
@@ -1278,10 +1289,12 @@ static int macvtap_device_event(struct notifier_block *unused,
        struct device *classdev;
        dev_t devt;
        int err;
+       char tap_name[IFNAMSIZ];
 
        if (dev->rtnl_link_ops != &macvtap_link_ops)
                return NOTIFY_DONE;
 
+       snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);
        vlan = netdev_priv(dev);
 
        switch (event) {
@@ -1295,16 +1308,24 @@ static int macvtap_device_event(struct notifier_block *unused,
                        return notifier_from_errno(err);
 
                devt = MKDEV(MAJOR(macvtap_major), vlan->minor);
-               classdev = device_create(macvtap_class, &dev->dev, devt,
-                                        dev, "tap%d", dev->ifindex);
+               classdev = device_create(&macvtap_class, &dev->dev, devt,
+                                        dev, tap_name);
                if (IS_ERR(classdev)) {
                        macvtap_free_minor(vlan);
                        return notifier_from_errno(PTR_ERR(classdev));
                }
+               err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
+                                       tap_name);
+               if (err)
+                       return notifier_from_errno(err);
                break;
        case NETDEV_UNREGISTER:
+               /* vlan->minor == 0 if NETDEV_REGISTER above failed */
+               if (vlan->minor == 0)
+                       break;
+               sysfs_remove_link(&dev->dev.kobj, tap_name);
                devt = MKDEV(MAJOR(macvtap_major), vlan->minor);
-               device_destroy(macvtap_class, devt);
+               device_destroy(&macvtap_class, devt);
                macvtap_free_minor(vlan);
                break;
        }
@@ -1330,11 +1351,9 @@ static int macvtap_init(void)
        if (err)
                goto out2;
 
-       macvtap_class = class_create(THIS_MODULE, "macvtap");
-       if (IS_ERR(macvtap_class)) {
-               err = PTR_ERR(macvtap_class);
+       err = class_register(&macvtap_class);
+       if (err)
                goto out3;
-       }
 
        err = register_netdevice_notifier(&macvtap_notifier_block);
        if (err)
@@ -1349,7 +1368,7 @@ static int macvtap_init(void)
 out5:
        unregister_netdevice_notifier(&macvtap_notifier_block);
 out4:
-       class_unregister(macvtap_class);
+       class_unregister(&macvtap_class);
 out3:
        cdev_del(&macvtap_cdev);
 out2:
@@ -1363,7 +1382,7 @@ static void macvtap_exit(void)
 {
        rtnl_link_unregister(&macvtap_link_ops);
        unregister_netdevice_notifier(&macvtap_notifier_block);
-       class_unregister(macvtap_class);
+       class_unregister(&macvtap_class);
        cdev_del(&macvtap_cdev);
        unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS);
        idr_destroy(&minor_idr);