]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/bridge/br_if.c
UBUNTU: Ubuntu-4.15.0-96.97
[mirror_ubuntu-bionic-kernel.git] / net / bridge / br_if.c
index 9ba4ed65c52ba83435b708db7d2643179336a8a5..263c5f1e4e46243ba986c609727005e7e8980b49 100644 (file)
@@ -26,6 +26,7 @@
 #include <net/sock.h>
 #include <linux/if_vlan.h>
 #include <net/switchdev.h>
+#include <net/net_namespace.h>
 
 #include "br_private.h"
 
@@ -199,11 +200,19 @@ static void release_nbp(struct kobject *kobj)
        kfree(p);
 }
 
+static void brport_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
+{
+       struct net_bridge_port *p = kobj_to_brport(kobj);
+
+       net_ns_get_ownership(dev_net(p->dev), uid, gid);
+}
+
 static struct kobj_type brport_ktype = {
 #ifdef CONFIG_SYSFS
        .sysfs_ops = &brport_sysfs_ops,
 #endif
        .release = release_nbp,
+       .get_ownership = brport_get_ownership,
 };
 
 static void destroy_nbp(struct net_bridge_port *p)
@@ -509,8 +518,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
                return -ELOOP;
        }
 
-       /* Device is already being bridged */
-       if (br_port_exists(dev))
+       /* Device has master upper dev */
+       if (netdev_master_upper_dev_get(dev))
                return -EBUSY;
 
        /* No bridging devices that dislike that (e.g. wireless) */
@@ -527,13 +536,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
        call_netdevice_notifiers(NETDEV_JOIN, dev);
 
        err = dev_set_allmulti(dev, 1);
-       if (err)
-               goto put_back;
+       if (err) {
+               kfree(p);       /* kobject not yet init'd, manually free */
+               goto err1;
+       }
 
        err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
                                   SYSFS_BRIDGE_PORT_ATTR);
        if (err)
-               goto err1;
+               goto err2;
 
        err = br_sysfs_addif(p);
        if (err)
@@ -616,12 +627,9 @@ err3:
        sysfs_remove_link(br->ifobj, p->dev->name);
 err2:
        kobject_put(&p->kobj);
-       p = NULL; /* kobject_put frees */
-err1:
        dev_set_allmulti(dev, -1);
-put_back:
+err1:
        dev_put(dev);
-       kfree(p);
        return err;
 }