if (data[IFLA_VLAN_FLAGS]) {
flags = nla_data(data[IFLA_VLAN_FLAGS]);
if ((flags->flags & flags->mask) &
- ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP))
+ ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
+ VLAN_FLAG_LOOSE_BINDING))
return -EINVAL;
}
return 0;
}
-static int vlan_newlink(struct net_device *dev,
+static int vlan_get_tx_queues(struct net *net,
+ struct nlattr *tb[],
+ unsigned int *num_tx_queues,
+ unsigned int *real_num_tx_queues)
+{
+ struct net_device *real_dev;
+
+ if (!tb[IFLA_LINK])
+ return -EINVAL;
+
+ real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
+ if (!real_dev)
+ return -ENODEV;
+
+ *num_tx_queues = real_dev->num_tx_queues;
+ *real_num_tx_queues = real_dev->real_num_tx_queues;
+ return 0;
+}
+
+static int vlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
struct vlan_dev_info *vlan = vlan_dev_info(dev);
if (!tb[IFLA_LINK])
return -EINVAL;
- real_dev = __dev_get_by_index(dev_net(dev), nla_get_u32(tb[IFLA_LINK]));
+ real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
if (!real_dev)
return -ENODEV;
struct vlan_dev_info *vlan = vlan_dev_info(dev);
return nla_total_size(2) + /* IFLA_VLAN_ID */
+ sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */
vlan_qos_map_size(vlan->nr_ingress_mappings) +
vlan_qos_map_size(vlan->nr_egress_mappings);
}
.maxtype = IFLA_VLAN_MAX,
.policy = vlan_policy,
.priv_size = sizeof(struct vlan_dev_info),
+ .get_tx_queues = vlan_get_tx_queues,
.setup = vlan_setup,
.validate = vlan_validate,
.newlink = vlan_newlink,