|
@@ -1211,6 +1211,36 @@ nla_put_vfinfo_failure:
|
|
|
return -EMSGSIZE;
|
|
|
}
|
|
|
|
|
|
+static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
|
|
|
+ struct net_device *dev,
|
|
|
+ u32 ext_filter_mask)
|
|
|
+{
|
|
|
+ struct nlattr *vfinfo;
|
|
|
+ int i, num_vfs;
|
|
|
+
|
|
|
+ if (!dev->dev.parent || ((ext_filter_mask & RTEXT_FILTER_VF) == 0))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ num_vfs = dev_num_vf(dev->dev.parent);
|
|
|
+ if (nla_put_u32(skb, IFLA_NUM_VF, num_vfs))
|
|
|
+ return -EMSGSIZE;
|
|
|
+
|
|
|
+ if (!dev->netdev_ops->ndo_get_vf_config)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
|
|
|
+ if (!vfinfo)
|
|
|
+ return -EMSGSIZE;
|
|
|
+
|
|
|
+ for (i = 0; i < num_vfs; i++) {
|
|
|
+ if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
|
|
|
+ return -EMSGSIZE;
|
|
|
+ }
|
|
|
+
|
|
|
+ nla_nest_end(skb, vfinfo);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
|
|
|
{
|
|
|
struct rtnl_link_ifmap map;
|
|
@@ -1407,27 +1437,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
|
|
|
if (rtnl_fill_stats(skb, dev))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) &&
|
|
|
- nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)))
|
|
|
+ if (rtnl_fill_vf(skb, dev, ext_filter_mask))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
- if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent &&
|
|
|
- ext_filter_mask & RTEXT_FILTER_VF) {
|
|
|
- int i;
|
|
|
- struct nlattr *vfinfo;
|
|
|
- int num_vfs = dev_num_vf(dev->dev.parent);
|
|
|
-
|
|
|
- vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
|
|
|
- if (!vfinfo)
|
|
|
- goto nla_put_failure;
|
|
|
- for (i = 0; i < num_vfs; i++) {
|
|
|
- if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
|
|
|
- goto nla_put_failure;
|
|
|
- }
|
|
|
-
|
|
|
- nla_nest_end(skb, vfinfo);
|
|
|
- }
|
|
|
-
|
|
|
if (rtnl_port_fill(skb, dev, ext_filter_mask))
|
|
|
goto nla_put_failure;
|
|
|
|