Merge branch 'vlan-rtnetlink-newlink-fixes'
Eric Dumazet says: ==================== vlan: rtnetlink newlink fixes First patch fixes a potential memory leak found by syzbot Second patch makes vlan_changelink() aware of errors and report them to user. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b57e1fff7d
|
@ -126,6 +126,7 @@ int vlan_check_real_dev(struct net_device *real_dev,
|
||||||
void vlan_setup(struct net_device *dev);
|
void vlan_setup(struct net_device *dev);
|
||||||
int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack);
|
int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack);
|
||||||
void unregister_vlan_dev(struct net_device *dev, struct list_head *head);
|
void unregister_vlan_dev(struct net_device *dev, struct list_head *head);
|
||||||
|
void vlan_dev_uninit(struct net_device *dev);
|
||||||
bool vlan_dev_inherit_address(struct net_device *dev,
|
bool vlan_dev_inherit_address(struct net_device *dev,
|
||||||
struct net_device *real_dev);
|
struct net_device *real_dev);
|
||||||
|
|
||||||
|
|
|
@ -586,7 +586,8 @@ static int vlan_dev_init(struct net_device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vlan_dev_uninit(struct net_device *dev)
|
/* Note: this function might be called multiple times for the same device. */
|
||||||
|
void vlan_dev_uninit(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct vlan_priority_tci_mapping *pm;
|
struct vlan_priority_tci_mapping *pm;
|
||||||
struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
|
struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
|
||||||
|
|
|
@ -108,11 +108,13 @@ static int vlan_changelink(struct net_device *dev, struct nlattr *tb[],
|
||||||
struct ifla_vlan_flags *flags;
|
struct ifla_vlan_flags *flags;
|
||||||
struct ifla_vlan_qos_mapping *m;
|
struct ifla_vlan_qos_mapping *m;
|
||||||
struct nlattr *attr;
|
struct nlattr *attr;
|
||||||
int rem;
|
int rem, err;
|
||||||
|
|
||||||
if (data[IFLA_VLAN_FLAGS]) {
|
if (data[IFLA_VLAN_FLAGS]) {
|
||||||
flags = nla_data(data[IFLA_VLAN_FLAGS]);
|
flags = nla_data(data[IFLA_VLAN_FLAGS]);
|
||||||
vlan_dev_change_flags(dev, flags->flags, flags->mask);
|
err = vlan_dev_change_flags(dev, flags->flags, flags->mask);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
if (data[IFLA_VLAN_INGRESS_QOS]) {
|
if (data[IFLA_VLAN_INGRESS_QOS]) {
|
||||||
nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) {
|
nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) {
|
||||||
|
@ -123,7 +125,9 @@ static int vlan_changelink(struct net_device *dev, struct nlattr *tb[],
|
||||||
if (data[IFLA_VLAN_EGRESS_QOS]) {
|
if (data[IFLA_VLAN_EGRESS_QOS]) {
|
||||||
nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) {
|
nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) {
|
||||||
m = nla_data(attr);
|
m = nla_data(attr);
|
||||||
vlan_dev_set_egress_priority(dev, m->from, m->to);
|
err = vlan_dev_set_egress_priority(dev, m->from, m->to);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -179,10 +183,11 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = vlan_changelink(dev, tb, data, extack);
|
err = vlan_changelink(dev, tb, data, extack);
|
||||||
if (err < 0)
|
if (!err)
|
||||||
|
err = register_vlan_dev(dev, extack);
|
||||||
|
if (err)
|
||||||
|
vlan_dev_uninit(dev);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return register_vlan_dev(dev, extack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t vlan_qos_map_size(unsigned int n)
|
static inline size_t vlan_qos_map_size(unsigned int n)
|
||||||
|
|
Loading…
Reference in New Issue