X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=drivers%2Fnet%2Fmacvlan.c;h=13937f9c04ad276e22ee973ba7584c201947d8de;hb=266e83474c98e9f18d31f4837cfe05819a660d32;hp=18373b6ae37d78543cf925e2d86efab1578f3019;hpb=c756891a4e1c08c43780e17aca1d2b849ef31d1a;p=~andy%2Flinux diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 18373b6ae37..13937f9c04a 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -863,6 +863,18 @@ static int macvlan_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct macvlan_dev *vlan = netdev_priv(dev); + enum macvlan_mode mode; + bool set_mode = false; + + /* Validate mode, but don't set yet: setting flags may fail. */ + if (data && data[IFLA_MACVLAN_MODE]) { + set_mode = true; + mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); + /* Passthrough mode can't be set or cleared dynamically */ + if ((mode == MACVLAN_MODE_PASSTHRU) != + (vlan->mode == MACVLAN_MODE_PASSTHRU)) + return -EINVAL; + } if (data && data[IFLA_MACVLAN_FLAGS]) { __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); @@ -879,8 +891,8 @@ static int macvlan_changelink(struct net_device *dev, } vlan->flags = flags; } - if (data && data[IFLA_MACVLAN_MODE]) - vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); + if (set_mode) + vlan->mode = mode; return 0; }