summaryrefslogtreecommitdiff
path: root/drivers/vdpa/vdpa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vdpa/vdpa.c')
-rw-r--r--drivers/vdpa/vdpa.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
index 8fcbdda8590c..7332a74a4b00 100644
--- a/drivers/vdpa/vdpa.c
+++ b/drivers/vdpa/vdpa.c
@@ -14,7 +14,6 @@
#include <uapi/linux/vdpa.h>
#include <net/genetlink.h>
#include <linux/mod_devicetable.h>
-#include <linux/virtio_net.h>
#include <linux/virtio_ids.h>
static LIST_HEAD(mdev_head);
@@ -480,9 +479,15 @@ out:
return msg->len;
}
+#define VDPA_DEV_NET_ATTRS_MASK ((1 << VDPA_ATTR_DEV_NET_CFG_MACADDR) | \
+ (1 << VDPA_ATTR_DEV_NET_CFG_MTU))
+
static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info)
{
+ struct vdpa_dev_set_config config = {};
+ struct nlattr **nl_attrs = info->attrs;
struct vdpa_mgmt_dev *mdev;
+ const u8 *macaddr;
const char *name;
int err = 0;
@@ -491,6 +496,26 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i
name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
+ if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
+ macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
+ memcpy(config.net.mac, macaddr, sizeof(config.net.mac));
+ config.mask |= (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR);
+ }
+ if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU]) {
+ config.net.mtu =
+ nla_get_u16(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU]);
+ config.mask |= (1 << VDPA_ATTR_DEV_NET_CFG_MTU);
+ }
+
+ /* Skip checking capability if user didn't prefer to configure any
+ * device networking attributes. It is likely that user might have used
+ * a device specific method to configure such attributes or using device
+ * default attributes.
+ */
+ if ((config.mask & VDPA_DEV_NET_ATTRS_MASK) &&
+ !netlink_capable(skb, CAP_NET_ADMIN))
+ return -EPERM;
+
mutex_lock(&vdpa_dev_mutex);
mdev = vdpa_mgmtdev_get_from_attr(info->attrs);
if (IS_ERR(mdev)) {
@@ -498,8 +523,14 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i
err = PTR_ERR(mdev);
goto err;
}
+ if ((config.mask & mdev->config_attr_mask) != config.mask) {
+ NL_SET_ERR_MSG_MOD(info->extack,
+ "All provided attributes are not supported");
+ err = -EOPNOTSUPP;
+ goto err;
+ }
- err = mdev->ops->dev_add(mdev, name);
+ err = mdev->ops->dev_add(mdev, name, &config);
err:
mutex_unlock(&vdpa_dev_mutex);
return err;
@@ -835,6 +866,9 @@ static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
[VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
[VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
[VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING },
+ [VDPA_ATTR_DEV_NET_CFG_MACADDR] = NLA_POLICY_ETH_ADDR,
+ /* virtio spec 1.1 section 5.1.4.1 for valid MTU range */
+ [VDPA_ATTR_DEV_NET_CFG_MTU] = NLA_POLICY_MIN(NLA_U16, 68),
};
static const struct genl_ops vdpa_nl_ops[] = {