Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-drm-fsl-dcu.git] / net / core / rtnetlink.c
index e4b9870e4706f7f4cf3e84b798f752c7e972f2fb..1a2af24e9e3d2b3754fa032e261a9480b4d0b7ac 100644 (file)
@@ -650,11 +650,12 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev)
        if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
 
                int num_vfs = dev_num_vf(dev->dev.parent);
-               size_t size = nlmsg_total_size(sizeof(struct nlattr));
-               size += nlmsg_total_size(num_vfs * sizeof(struct nlattr));
-               size += num_vfs * (sizeof(struct ifla_vf_mac) +
-                                 sizeof(struct ifla_vf_vlan) +
-                                 sizeof(struct ifla_vf_tx_rate));
+               size_t size = nla_total_size(sizeof(struct nlattr));
+               size += nla_total_size(num_vfs * sizeof(struct nlattr));
+               size += num_vfs *
+                       (nla_total_size(sizeof(struct ifla_vf_mac)) +
+                        nla_total_size(sizeof(struct ifla_vf_vlan)) +
+                        nla_total_size(sizeof(struct ifla_vf_tx_rate)));
                return size;
        } else
                return 0;
@@ -722,14 +723,13 @@ static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
 
        for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) {
                vf_port = nla_nest_start(skb, IFLA_VF_PORT);
-               if (!vf_port) {
-                       nla_nest_cancel(skb, vf_ports);
-                       return -EMSGSIZE;
-               }
+               if (!vf_port)
+                       goto nla_put_failure;
                NLA_PUT_U32(skb, IFLA_PORT_VF, vf);
                err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb);
+               if (err == -EMSGSIZE)
+                       goto nla_put_failure;
                if (err) {
-nla_put_failure:
                        nla_nest_cancel(skb, vf_port);
                        continue;
                }
@@ -739,6 +739,10 @@ nla_put_failure:
        nla_nest_end(skb, vf_ports);
 
        return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, vf_ports);
+       return -EMSGSIZE;
 }
 
 static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
@@ -753,7 +757,7 @@ static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
        err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb);
        if (err) {
                nla_nest_cancel(skb, port_self);
-               return err;
+               return (err == -EMSGSIZE) ? err : 0;
        }
 
        nla_nest_end(skb, port_self);
@@ -1199,8 +1203,10 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                struct nlattr *attr;
                int rem;
                nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
-                       if (nla_type(attr) != IFLA_VF_INFO)
+                       if (nla_type(attr) != IFLA_VF_INFO) {
+                               err = -EINVAL;
                                goto errout;
+                       }
                        err = do_setvfinfo(dev, attr);
                        if (err < 0)
                                goto errout;