mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
vdpa: support set mac address from vdpa tool
Add new UAPI to support the mac address from vdpa tool Function vdpa_nl_cmd_dev_attr_set_doit() will get the new MAC address from the vdpa tool and then set it to the device. The usage is: vdpa dev set name vdpa_name mac **:**:**:**:**:** Here is example: root@L1# vdpa -jp dev config show vdpa0 { "config": { "vdpa0": { "mac": "82:4d:e9:5d:d7:e6", "link ": "up", "link_announce ": false, "mtu": 1500 } } } root@L1# vdpa dev set name vdpa0 mac 00:11:22:33:44:55 root@L1# vdpa -jp dev config show vdpa0 { "config": { "vdpa0": { "mac": "00:11:22:33:44:55", "link ": "up", "link_announce ": false, "mtu": 1500 } } } Signed-off-by: Cindy Lu <lulu@redhat.com> Message-Id: <20240731031653.1047692-2-lulu@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
parent
a8927f69e8
commit
2f87e9cf0c
@ -1361,6 +1361,80 @@ static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vdpa_dev_net_device_attr_set(struct vdpa_device *vdev,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct vdpa_dev_set_config set_config = {};
|
||||
struct vdpa_mgmt_dev *mdev = vdev->mdev;
|
||||
struct nlattr **nl_attrs = info->attrs;
|
||||
const u8 *macaddr;
|
||||
int err = -EOPNOTSUPP;
|
||||
|
||||
down_write(&vdev->cf_lock);
|
||||
if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
|
||||
set_config.mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR);
|
||||
macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
|
||||
|
||||
if (is_valid_ether_addr(macaddr)) {
|
||||
ether_addr_copy(set_config.net.mac, macaddr);
|
||||
if (mdev->ops->dev_set_attr) {
|
||||
err = mdev->ops->dev_set_attr(mdev, vdev,
|
||||
&set_config);
|
||||
} else {
|
||||
NL_SET_ERR_MSG_FMT_MOD(info->extack,
|
||||
"Operation not supported by the device.");
|
||||
}
|
||||
} else {
|
||||
NL_SET_ERR_MSG_FMT_MOD(info->extack,
|
||||
"Invalid MAC address");
|
||||
}
|
||||
}
|
||||
up_write(&vdev->cf_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vdpa_nl_cmd_dev_attr_set_doit(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct vdpa_device *vdev;
|
||||
struct device *dev;
|
||||
const char *name;
|
||||
u64 classes;
|
||||
int err = 0;
|
||||
|
||||
if (!info->attrs[VDPA_ATTR_DEV_NAME])
|
||||
return -EINVAL;
|
||||
|
||||
name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
|
||||
|
||||
down_write(&vdpa_dev_lock);
|
||||
dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match);
|
||||
if (!dev) {
|
||||
NL_SET_ERR_MSG_MOD(info->extack, "device not found");
|
||||
err = -ENODEV;
|
||||
goto dev_err;
|
||||
}
|
||||
vdev = container_of(dev, struct vdpa_device, dev);
|
||||
if (!vdev->mdev) {
|
||||
NL_SET_ERR_MSG_MOD(info->extack, "unmanaged vdpa device");
|
||||
err = -EINVAL;
|
||||
goto mdev_err;
|
||||
}
|
||||
classes = vdpa_mgmtdev_get_classes(vdev->mdev, NULL);
|
||||
if (classes & BIT_ULL(VIRTIO_ID_NET)) {
|
||||
err = vdpa_dev_net_device_attr_set(vdev, info);
|
||||
} else {
|
||||
NL_SET_ERR_MSG_FMT_MOD(info->extack, "%s device not supported",
|
||||
name);
|
||||
}
|
||||
|
||||
mdev_err:
|
||||
put_device(dev);
|
||||
dev_err:
|
||||
up_write(&vdpa_dev_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vdpa_dev_config_dump(struct device *dev, void *data)
|
||||
{
|
||||
struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
|
||||
@ -1497,6 +1571,11 @@ static const struct genl_ops vdpa_nl_ops[] = {
|
||||
.doit = vdpa_nl_cmd_dev_stats_get_doit,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
{
|
||||
.cmd = VDPA_CMD_DEV_ATTR_SET,
|
||||
.doit = vdpa_nl_cmd_dev_attr_set_doit,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct genl_family vdpa_nl_family __ro_after_init = {
|
||||
|
@ -582,11 +582,20 @@ void vdpa_set_status(struct vdpa_device *vdev, u8 status);
|
||||
* @dev: vdpa device to remove
|
||||
* Driver need to remove the specified device by calling
|
||||
* _vdpa_unregister_device().
|
||||
* @dev_set_attr: change a vdpa device's attr after it was create
|
||||
* @mdev: parent device to use for device
|
||||
* @dev: vdpa device structure
|
||||
* @config:Attributes to be set for the device.
|
||||
* The driver needs to check the mask of the structure and then set
|
||||
* the related information to the vdpa device. The driver must return 0
|
||||
* if set successfully.
|
||||
*/
|
||||
struct vdpa_mgmtdev_ops {
|
||||
int (*dev_add)(struct vdpa_mgmt_dev *mdev, const char *name,
|
||||
const struct vdpa_dev_set_config *config);
|
||||
void (*dev_del)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev);
|
||||
int (*dev_set_attr)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev,
|
||||
const struct vdpa_dev_set_config *config);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,7 @@ enum vdpa_command {
|
||||
VDPA_CMD_DEV_GET, /* can dump */
|
||||
VDPA_CMD_DEV_CONFIG_GET, /* can dump */
|
||||
VDPA_CMD_DEV_VSTATS_GET,
|
||||
VDPA_CMD_DEV_ATTR_SET,
|
||||
};
|
||||
|
||||
enum vdpa_attr {
|
||||
|
Loading…
Reference in New Issue
Block a user