Skip to content

Commit 2f87e9c

Browse files
lulu-github-namemstsirkin
authored andcommitted
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 <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Acked-by: Jason Wang <[email protected]>
1 parent a8927f6 commit 2f87e9c

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

drivers/vdpa/vdpa.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,80 @@ static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info
13611361
return err;
13621362
}
13631363

1364+
static int vdpa_dev_net_device_attr_set(struct vdpa_device *vdev,
1365+
struct genl_info *info)
1366+
{
1367+
struct vdpa_dev_set_config set_config = {};
1368+
struct vdpa_mgmt_dev *mdev = vdev->mdev;
1369+
struct nlattr **nl_attrs = info->attrs;
1370+
const u8 *macaddr;
1371+
int err = -EOPNOTSUPP;
1372+
1373+
down_write(&vdev->cf_lock);
1374+
if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
1375+
set_config.mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR);
1376+
macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
1377+
1378+
if (is_valid_ether_addr(macaddr)) {
1379+
ether_addr_copy(set_config.net.mac, macaddr);
1380+
if (mdev->ops->dev_set_attr) {
1381+
err = mdev->ops->dev_set_attr(mdev, vdev,
1382+
&set_config);
1383+
} else {
1384+
NL_SET_ERR_MSG_FMT_MOD(info->extack,
1385+
"Operation not supported by the device.");
1386+
}
1387+
} else {
1388+
NL_SET_ERR_MSG_FMT_MOD(info->extack,
1389+
"Invalid MAC address");
1390+
}
1391+
}
1392+
up_write(&vdev->cf_lock);
1393+
return err;
1394+
}
1395+
1396+
static int vdpa_nl_cmd_dev_attr_set_doit(struct sk_buff *skb,
1397+
struct genl_info *info)
1398+
{
1399+
struct vdpa_device *vdev;
1400+
struct device *dev;
1401+
const char *name;
1402+
u64 classes;
1403+
int err = 0;
1404+
1405+
if (!info->attrs[VDPA_ATTR_DEV_NAME])
1406+
return -EINVAL;
1407+
1408+
name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
1409+
1410+
down_write(&vdpa_dev_lock);
1411+
dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match);
1412+
if (!dev) {
1413+
NL_SET_ERR_MSG_MOD(info->extack, "device not found");
1414+
err = -ENODEV;
1415+
goto dev_err;
1416+
}
1417+
vdev = container_of(dev, struct vdpa_device, dev);
1418+
if (!vdev->mdev) {
1419+
NL_SET_ERR_MSG_MOD(info->extack, "unmanaged vdpa device");
1420+
err = -EINVAL;
1421+
goto mdev_err;
1422+
}
1423+
classes = vdpa_mgmtdev_get_classes(vdev->mdev, NULL);
1424+
if (classes & BIT_ULL(VIRTIO_ID_NET)) {
1425+
err = vdpa_dev_net_device_attr_set(vdev, info);
1426+
} else {
1427+
NL_SET_ERR_MSG_FMT_MOD(info->extack, "%s device not supported",
1428+
name);
1429+
}
1430+
1431+
mdev_err:
1432+
put_device(dev);
1433+
dev_err:
1434+
up_write(&vdpa_dev_lock);
1435+
return err;
1436+
}
1437+
13641438
static int vdpa_dev_config_dump(struct device *dev, void *data)
13651439
{
13661440
struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
@@ -1497,6 +1571,11 @@ static const struct genl_ops vdpa_nl_ops[] = {
14971571
.doit = vdpa_nl_cmd_dev_stats_get_doit,
14981572
.flags = GENL_ADMIN_PERM,
14991573
},
1574+
{
1575+
.cmd = VDPA_CMD_DEV_ATTR_SET,
1576+
.doit = vdpa_nl_cmd_dev_attr_set_doit,
1577+
.flags = GENL_ADMIN_PERM,
1578+
},
15001579
};
15011580

15021581
static struct genl_family vdpa_nl_family __ro_after_init = {

include/linux/vdpa.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,11 +582,20 @@ void vdpa_set_status(struct vdpa_device *vdev, u8 status);
582582
* @dev: vdpa device to remove
583583
* Driver need to remove the specified device by calling
584584
* _vdpa_unregister_device().
585+
* @dev_set_attr: change a vdpa device's attr after it was create
586+
* @mdev: parent device to use for device
587+
* @dev: vdpa device structure
588+
* @config:Attributes to be set for the device.
589+
* The driver needs to check the mask of the structure and then set
590+
* the related information to the vdpa device. The driver must return 0
591+
* if set successfully.
585592
*/
586593
struct vdpa_mgmtdev_ops {
587594
int (*dev_add)(struct vdpa_mgmt_dev *mdev, const char *name,
588595
const struct vdpa_dev_set_config *config);
589596
void (*dev_del)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev);
597+
int (*dev_set_attr)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev,
598+
const struct vdpa_dev_set_config *config);
590599
};
591600

592601
/**

include/uapi/linux/vdpa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ enum vdpa_command {
1919
VDPA_CMD_DEV_GET, /* can dump */
2020
VDPA_CMD_DEV_CONFIG_GET, /* can dump */
2121
VDPA_CMD_DEV_VSTATS_GET,
22+
VDPA_CMD_DEV_ATTR_SET,
2223
};
2324

2425
enum vdpa_attr {

0 commit comments

Comments
 (0)