Parav Pandit
2021-Dec-02 04:22 UTC
[iproute2-next 0/4] vdpa tool to query and set config layout
This series implements querying and setting of the mac address and mtu device config fields of the vdpa device of type net. An example of query and set as below. $ vdpa dev add name bar mgmtdev vdpasim_net mac 00:11:22:33:44:55 mtu 9000 $ vdpa dev config show bar: mac 00:11:22:33:44:55 link up link_announce false mtu 9000 $ vdpa dev config show -jp { "config": { "bar": { "mac": "00:11:22:33:44:55", "link ": "up", "link_announce ": false, "mtu": 1500, } } } patch summary: patch-1 updates the kernel headers patch-2 implements the query command patch-3 implements setting the mac address of vdpa dev config space patch-4 implements setting the mtu of vdpa dev config space Parav Pandit (4): vdpa: Update kernel headers vdpa: Enable user to query vdpa device config layout vdpa: Enable user to set mac address of vdpa device vdpa: Enable user to set mtu of the vdpa device include/uapi/linux/virtio_net.h | 81 +++++++++++++ vdpa/include/uapi/linux/vdpa.h | 7 ++ vdpa/vdpa.c | 198 ++++++++++++++++++++++++++++++-- 3 files changed, 277 insertions(+), 9 deletions(-) create mode 100644 include/uapi/linux/virtio_net.h -- 2.26.2
Update kernel headers to commit: ad69dd0bf26b ("vdpa: Introduce query of device config layout") Signed-off-by: Parav Pandit <parav at nvidia.com> --- include/uapi/linux/virtio_net.h | 81 +++++++++++++++++++++++++++++++++ vdpa/include/uapi/linux/vdpa.h | 7 +++ 2 files changed, 88 insertions(+) create mode 100644 include/uapi/linux/virtio_net.h diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h new file mode 100644 index 00000000..d52965cf --- /dev/null +++ b/include/uapi/linux/virtio_net.h @@ -0,0 +1,81 @@ +#ifndef _LINUX_VIRTIO_NET_H +#define _LINUX_VIRTIO_NET_H +/* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ + +/* The feature bitmap for virtio net */ +#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ +#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ +#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */ +#define VIRTIO_NET_F_MTU 3 /* Initial MTU advice */ +#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ +#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ +#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ +#define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ +#define VIRTIO_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ +#define VIRTIO_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ +#define VIRTIO_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ +#define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */ +#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ +#define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ +#define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ +#define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ +#define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ +#define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ +#define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */ +#define VIRTIO_NET_F_GUEST_ANNOUNCE 21 /* Guest can announce device on the + * network */ +#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow + * Steering */ +#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ + +#define VIRTIO_NET_F_HASH_REPORT 57 /* Supports hash report */ +#define VIRTIO_NET_F_RSS 60 /* Supports RSS RX steering */ +#define VIRTIO_NET_F_RSC_EXT 61 /* extended coalescing info */ +#define VIRTIO_NET_F_STANDBY 62 /* Act as standby for another device + * with the same MAC. + */ +#define VIRTIO_NET_F_SPEED_DUPLEX 63 /* Device set linkspeed and duplex */ + +#ifndef VIRTIO_NET_NO_LEGACY +#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ +#endif /* VIRTIO_NET_NO_LEGACY */ + +#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ +#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */ + +/* supported/enabled hash types */ +#define VIRTIO_NET_RSS_HASH_TYPE_IPv4 (1 << 0) +#define VIRTIO_NET_RSS_HASH_TYPE_TCPv4 (1 << 1) +#define VIRTIO_NET_RSS_HASH_TYPE_UDPv4 (1 << 2) +#define VIRTIO_NET_RSS_HASH_TYPE_IPv6 (1 << 3) +#define VIRTIO_NET_RSS_HASH_TYPE_TCPv6 (1 << 4) +#define VIRTIO_NET_RSS_HASH_TYPE_UDPv6 (1 << 5) +#define VIRTIO_NET_RSS_HASH_TYPE_IP_EX (1 << 6) +#define VIRTIO_NET_RSS_HASH_TYPE_TCP_EX (1 << 7) +#define VIRTIO_NET_RSS_HASH_TYPE_UDP_EX (1 << 8) + +#endif /* _LINUX_VIRTIO_NET_H */ diff --git a/vdpa/include/uapi/linux/vdpa.h b/vdpa/include/uapi/linux/vdpa.h index 37ae26b6..b7eab069 100644 --- a/vdpa/include/uapi/linux/vdpa.h +++ b/vdpa/include/uapi/linux/vdpa.h @@ -17,6 +17,7 @@ enum vdpa_command { VDPA_CMD_DEV_NEW, VDPA_CMD_DEV_DEL, VDPA_CMD_DEV_GET, /* can dump */ + VDPA_CMD_DEV_CONFIG_GET, /* can dump */ }; enum vdpa_attr { @@ -32,6 +33,12 @@ enum vdpa_attr { VDPA_ATTR_DEV_VENDOR_ID, /* u32 */ VDPA_ATTR_DEV_MAX_VQS, /* u32 */ VDPA_ATTR_DEV_MAX_VQ_SIZE, /* u16 */ + VDPA_ATTR_DEV_MIN_VQ_SIZE, /* u16 */ + + VDPA_ATTR_DEV_NET_CFG_MACADDR, /* binary */ + VDPA_ATTR_DEV_NET_STATUS, /* u8 */ + VDPA_ATTR_DEV_NET_CFG_MAX_VQP, /* u16 */ + VDPA_ATTR_DEV_NET_CFG_MTU, /* u16 */ /* new attributes must be added above here */ VDPA_ATTR_MAX, -- 2.26.2
Parav Pandit
2021-Dec-02 04:22 UTC
[iproute2-next 2/4] vdpa: Enable user to query vdpa device config layout
Query the device configuration layout whenever kernel supports it. An example of configuration layout of vdpa device of type network: $ vdpa dev add name bar mgmtdev vdpasim_net $ vdpa dev config show bar: mac 00:35:09:19:48:05 link up link_announce false mtu 1500 $ vdpa dev config show -jp { "config": { "bar": { "mac": "00:35:09:19:48:05", "link ": "up", "link_announce ": false, "mtu": 1500, } } } Signed-off-by: Parav Pandit <parav at nvidia.com> --- vdpa/vdpa.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/vdpa/vdpa.c b/vdpa/vdpa.c index 7fdb36b9..ba704254 100644 --- a/vdpa/vdpa.c +++ b/vdpa/vdpa.c @@ -6,9 +6,11 @@ #include <linux/genetlink.h> #include <linux/vdpa.h> #include <linux/virtio_ids.h> +#include <linux/virtio_net.h> #include <linux/netlink.h> #include <libmnl/libmnl.h> #include "mnl_utils.h" +#include <rt_names.h> #include "version.h" #include "json_print.h" @@ -413,6 +415,7 @@ static void cmd_dev_help(void) fprintf(stderr, "Usage: vdpa dev show [ DEV ]\n"); fprintf(stderr, " vdpa dev add name NAME mgmtdev MANAGEMENTDEV\n"); fprintf(stderr, " vdpa dev del DEV\n"); + fprintf(stderr, "Usage: vdpa dev config COMMAND [ OPTIONS ]\n"); } static const char *device_type_name(uint32_t type) @@ -520,6 +523,111 @@ static int cmd_dev_del(struct vdpa *vdpa, int argc, char **argv) return mnlu_gen_socket_sndrcv(&vdpa->nlg, nlh, NULL, NULL); } +static void pr_out_dev_net_config(struct nlattr **tb) +{ + SPRINT_BUF(macaddr); + uint16_t val_u16; + + if (tb[VDPA_ATTR_DEV_NET_CFG_MACADDR]) { + const unsigned char *data; + uint16_t len; + + len = mnl_attr_get_payload_len(tb[VDPA_ATTR_DEV_NET_CFG_MACADDR]); + data = mnl_attr_get_payload(tb[VDPA_ATTR_DEV_NET_CFG_MACADDR]); + + print_string(PRINT_ANY, "mac", "mac %s ", + ll_addr_n2a(data, len, 0, macaddr, sizeof(macaddr))); + } + if (tb[VDPA_ATTR_DEV_NET_STATUS]) { + val_u16 = mnl_attr_get_u16(tb[VDPA_ATTR_DEV_NET_STATUS]); + print_string(PRINT_ANY, "link ", "link %s ", + (val_u16 & VIRTIO_NET_S_LINK_UP) ? "up" : "down"); + print_bool(PRINT_ANY, "link_announce ", "link_announce %s ", + (val_u16 & VIRTIO_NET_S_ANNOUNCE) ? true : false); + } + if (tb[VDPA_ATTR_DEV_NET_CFG_MAX_VQP]) { + val_u16 = mnl_attr_get_u16(tb[VDPA_ATTR_DEV_NET_CFG_MAX_VQP]); + print_uint(PRINT_ANY, "max_vq_pairs", "max_vq_pairs %d ", + val_u16); + } + if (tb[VDPA_ATTR_DEV_NET_CFG_MTU]) { + val_u16 = mnl_attr_get_u16(tb[VDPA_ATTR_DEV_NET_CFG_MTU]); + print_uint(PRINT_ANY, "mtu", "mtu %d ", val_u16); + } +} + +static void pr_out_dev_config(struct vdpa *vdpa, struct nlattr **tb) +{ + uint32_t device_id = mnl_attr_get_u32(tb[VDPA_ATTR_DEV_ID]); + + pr_out_vdev_handle_start(vdpa, tb); + switch (device_id) { + case VIRTIO_ID_NET: + pr_out_dev_net_config(tb); + break; + default: + break; + } + pr_out_vdev_handle_end(vdpa); +} + +static int cmd_dev_config_show_cb(const struct nlmsghdr *nlh, void *data) +{ + struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); + struct nlattr *tb[VDPA_ATTR_MAX + 1] = {}; + struct vdpa *vdpa = data; + + mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); + if (!tb[VDPA_ATTR_DEV_NAME] || !tb[VDPA_ATTR_DEV_ID]) + return MNL_CB_ERROR; + pr_out_dev_config(vdpa, tb); + return MNL_CB_OK; +} + +static int cmd_dev_config_show(struct vdpa *vdpa, int argc, char **argv) +{ + uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; + struct nlmsghdr *nlh; + int err; + + if (argc <= 0) + flags |= NLM_F_DUMP; + + nlh = mnlu_gen_socket_cmd_prepare(&vdpa->nlg, VDPA_CMD_DEV_CONFIG_GET, + flags); + if (argc > 0) { + err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, + VDPA_OPT_VDEV_HANDLE); + if (err) + return err; + } + + pr_out_section_start(vdpa, "config"); + err = mnlu_gen_socket_sndrcv(&vdpa->nlg, nlh, cmd_dev_config_show_cb, vdpa); + pr_out_section_end(vdpa); + return err; +} + +static void cmd_dev_config_help(void) +{ + fprintf(stderr, "Usage: vdpa dev config show [ DEV ]\n"); +} + +static int cmd_dev_config(struct vdpa *vdpa, int argc, char **argv) +{ + if (!argc) + return cmd_dev_config_show(vdpa, argc - 1, argv + 1); + + if (matches(*argv, "help") == 0) { + cmd_dev_config_help(); + return 0; + } else if (matches(*argv, "show") == 0) { + return cmd_dev_config_show(vdpa, argc - 1, argv + 1); + } + fprintf(stderr, "Command \"%s\" not found\n", *argv); + return -ENOENT; +} + static int cmd_dev(struct vdpa *vdpa, int argc, char **argv) { if (!argc) @@ -535,6 +643,8 @@ static int cmd_dev(struct vdpa *vdpa, int argc, char **argv) return cmd_dev_add(vdpa, argc - 1, argv + 1); } else if (matches(*argv, "del") == 0) { return cmd_dev_del(vdpa, argc - 1, argv + 1); + } else if (matches(*argv, "config") == 0) { + return cmd_dev_config(vdpa, argc - 1, argv + 1); } fprintf(stderr, "Command \"%s\" not found\n", *argv); return -ENOENT; -- 2.26.2
Parav Pandit
2021-Dec-02 04:22 UTC
[iproute2-next 3/4] vdpa: Enable user to set mac address of vdpa device
vdpa: Enable user to set mtu of the vdpa device Implement mtu setting for vdpa device. $ vdpa mgmtdev show vdpasim_net: supported_classes net Add the device with specified mac address: $ vdpa dev add name bar mgmtdev vdpasim_net mac 00:11:22:33:44:55 View the config after setting: $ vdpa dev config show bar: mac 00:11:22:33:44:55 link up link_announce false mtu 1500 Signed-off-by: Parav Pandit <parav at nvidia.com> --- vdpa/vdpa.c | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/vdpa/vdpa.c b/vdpa/vdpa.c index ba704254..9d20bdb4 100644 --- a/vdpa/vdpa.c +++ b/vdpa/vdpa.c @@ -4,6 +4,7 @@ #include <getopt.h> #include <errno.h> #include <linux/genetlink.h> +#include <linux/if_ether.h> #include <linux/vdpa.h> #include <linux/virtio_ids.h> #include <linux/virtio_net.h> @@ -20,6 +21,7 @@ #define VDPA_OPT_VDEV_MGMTDEV_HANDLE BIT(1) #define VDPA_OPT_VDEV_NAME BIT(2) #define VDPA_OPT_VDEV_HANDLE BIT(3) +#define VDPA_OPT_VDEV_MAC BIT(4) struct vdpa_opts { uint64_t present; /* flags of present items */ @@ -27,6 +29,7 @@ struct vdpa_opts { char *mdev_name; const char *vdev_name; unsigned int device_id; + char mac[ETH_ALEN]; }; struct vdpa { @@ -136,6 +139,21 @@ static int vdpa_argv_str(struct vdpa *vdpa, int argc, char **argv, return 0; } +static int vdpa_argv_mac(struct vdpa *vdpa, int argc, char **argv, char *mac) +{ + int alen; + + if (argc <= 0 || *argv == NULL) { + fprintf(stderr, "String parameter expected\n"); + return -EINVAL; + } + + alen = ll_addr_a2n(mac, ETH_ALEN, *argv); + if (alen < 0) + return -EINVAL; + return 0; +} + struct vdpa_args_metadata { uint64_t o_flag; const char *err_msg; @@ -183,13 +201,16 @@ static void vdpa_opts_put(struct nlmsghdr *nlh, struct vdpa *vdpa) if ((opts->present & VDPA_OPT_VDEV_NAME) || (opts->present & VDPA_OPT_VDEV_HANDLE)) mnl_attr_put_strz(nlh, VDPA_ATTR_DEV_NAME, opts->vdev_name); + if (opts->present & VDPA_OPT_VDEV_MAC) + mnl_attr_put(nlh, VDPA_ATTR_DEV_NET_CFG_MACADDR, + sizeof(opts->mac), opts->mac); } static int vdpa_argv_parse(struct vdpa *vdpa, int argc, char **argv, - uint64_t o_required) + uint64_t o_required, uint64_t o_optional) { + uint64_t o_all = o_required | o_optional; struct vdpa_opts *opts = &vdpa->opts; - uint64_t o_all = o_required; uint64_t o_found = 0; int err; @@ -233,6 +254,15 @@ static int vdpa_argv_parse(struct vdpa *vdpa, int argc, char **argv, NEXT_ARG_FWD(); o_found |= VDPA_OPT_VDEV_MGMTDEV_HANDLE; + } else if ((matches(*argv, "mac") == 0) && + (o_all & VDPA_OPT_VDEV_MAC)) { + NEXT_ARG_FWD(); + err = vdpa_argv_mac(vdpa, argc, argv, opts->mac); + if (err) + return err; + + NEXT_ARG_FWD(); + o_found |= VDPA_OPT_VDEV_MAC; } else { fprintf(stderr, "Unknown option \"%s\"\n", *argv); return -EINVAL; @@ -246,11 +276,11 @@ static int vdpa_argv_parse(struct vdpa *vdpa, int argc, char **argv, static int vdpa_argv_parse_put(struct nlmsghdr *nlh, struct vdpa *vdpa, int argc, char **argv, - uint64_t o_required) + uint64_t o_required, uint64_t o_optional) { int err; - err = vdpa_argv_parse(vdpa, argc, argv, o_required); + err = vdpa_argv_parse(vdpa, argc, argv, o_required, o_optional); if (err) return err; vdpa_opts_put(nlh, vdpa); @@ -386,7 +416,7 @@ static int cmd_mgmtdev_show(struct vdpa *vdpa, int argc, char **argv) flags); if (argc > 0) { err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, - VDPA_OPT_MGMTDEV_HANDLE); + VDPA_OPT_MGMTDEV_HANDLE, 0); if (err) return err; } @@ -413,7 +443,7 @@ static int cmd_mgmtdev(struct vdpa *vdpa, int argc, char **argv) static void cmd_dev_help(void) { fprintf(stderr, "Usage: vdpa dev show [ DEV ]\n"); - fprintf(stderr, " vdpa dev add name NAME mgmtdev MANAGEMENTDEV\n"); + fprintf(stderr, " vdpa dev add name NAME mgmtdev MANAGEMENTDEV [ mac MACADDR ]\n"); fprintf(stderr, " vdpa dev del DEV\n"); fprintf(stderr, "Usage: vdpa dev config COMMAND [ OPTIONS ]\n"); } @@ -483,7 +513,7 @@ static int cmd_dev_show(struct vdpa *vdpa, int argc, char **argv) nlh = mnlu_gen_socket_cmd_prepare(&vdpa->nlg, VDPA_CMD_DEV_GET, flags); if (argc > 0) { err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, - VDPA_OPT_VDEV_HANDLE); + VDPA_OPT_VDEV_HANDLE, 0); if (err) return err; } @@ -502,7 +532,8 @@ static int cmd_dev_add(struct vdpa *vdpa, int argc, char **argv) nlh = mnlu_gen_socket_cmd_prepare(&vdpa->nlg, VDPA_CMD_DEV_NEW, NLM_F_REQUEST | NLM_F_ACK); err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, - VDPA_OPT_VDEV_MGMTDEV_HANDLE | VDPA_OPT_VDEV_NAME); + VDPA_OPT_VDEV_MGMTDEV_HANDLE | VDPA_OPT_VDEV_NAME, + VDPA_OPT_VDEV_MAC); if (err) return err; @@ -516,7 +547,8 @@ static int cmd_dev_del(struct vdpa *vdpa, int argc, char **argv) nlh = mnlu_gen_socket_cmd_prepare(&vdpa->nlg, VDPA_CMD_DEV_DEL, NLM_F_REQUEST | NLM_F_ACK); - err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, VDPA_OPT_VDEV_HANDLE); + err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, VDPA_OPT_VDEV_HANDLE, + 0); if (err) return err; @@ -597,7 +629,7 @@ static int cmd_dev_config_show(struct vdpa *vdpa, int argc, char **argv) flags); if (argc > 0) { err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, - VDPA_OPT_VDEV_HANDLE); + VDPA_OPT_VDEV_HANDLE, 0); if (err) return err; } -- 2.26.2
Parav Pandit
2021-Dec-02 04:22 UTC
[iproute2-next 4/4] vdpa: Enable user to set mtu of the vdpa device
Implement mtu setting for vdpa device. $ vdpa mgmtdev show vdpasim_net: supported_classes net Add the device with mac address and mtu: $ vdpa dev add name bar mgmtdev vdpasim_net mac 00:11:22:33:44:55 mtu 9000 In above command only mac address or only mtu can also be set. View the config after setting: $ vdpa dev config show bar: mac 00:11:22:33:44:55 link up link_announce false mtu 9000 Signed-off-by: Parav Pandit <parav at nvidia.com> --- vdpa/vdpa.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/vdpa/vdpa.c b/vdpa/vdpa.c index 9d20bdb4..7da2ea7a 100644 --- a/vdpa/vdpa.c +++ b/vdpa/vdpa.c @@ -22,6 +22,7 @@ #define VDPA_OPT_VDEV_NAME BIT(2) #define VDPA_OPT_VDEV_HANDLE BIT(3) #define VDPA_OPT_VDEV_MAC BIT(4) +#define VDPA_OPT_VDEV_MTU BIT(5) struct vdpa_opts { uint64_t present; /* flags of present items */ @@ -30,6 +31,7 @@ struct vdpa_opts { const char *vdev_name; unsigned int device_id; char mac[ETH_ALEN]; + uint16_t mtu; }; struct vdpa { @@ -154,6 +156,31 @@ static int vdpa_argv_mac(struct vdpa *vdpa, int argc, char **argv, char *mac) return 0; } +static int strtouint16_t(const char *str, uint16_t *p_val) +{ + char *endptr; + unsigned long int val; + + val = strtoul(str, &endptr, 10); + if (endptr == str || *endptr != '\0') + return -EINVAL; + if (val > USHRT_MAX) + return -ERANGE; + *p_val = val; + return 0; +} + +static int vdpa_argv_u16(struct vdpa *vdpa, int argc, char **argv, + uint16_t *result) +{ + if (argc <= 0 || *argv == NULL) { + fprintf(stderr, "number expected\n"); + return -EINVAL; + } + + return strtouint16_t(*argv, result); +} + struct vdpa_args_metadata { uint64_t o_flag; const char *err_msg; @@ -204,6 +231,8 @@ static void vdpa_opts_put(struct nlmsghdr *nlh, struct vdpa *vdpa) if (opts->present & VDPA_OPT_VDEV_MAC) mnl_attr_put(nlh, VDPA_ATTR_DEV_NET_CFG_MACADDR, sizeof(opts->mac), opts->mac); + if (opts->present & VDPA_OPT_VDEV_MTU) + mnl_attr_put_u16(nlh, VDPA_ATTR_DEV_NET_CFG_MTU, opts->mtu); } static int vdpa_argv_parse(struct vdpa *vdpa, int argc, char **argv, @@ -263,6 +292,15 @@ static int vdpa_argv_parse(struct vdpa *vdpa, int argc, char **argv, NEXT_ARG_FWD(); o_found |= VDPA_OPT_VDEV_MAC; + } else if ((matches(*argv, "mtu") == 0) && + (o_all & VDPA_OPT_VDEV_MTU)) { + NEXT_ARG_FWD(); + err = vdpa_argv_u16(vdpa, argc, argv, &opts->mtu); + if (err) + return err; + + NEXT_ARG_FWD(); + o_found |= VDPA_OPT_VDEV_MTU; } else { fprintf(stderr, "Unknown option \"%s\"\n", *argv); return -EINVAL; @@ -443,7 +481,7 @@ static int cmd_mgmtdev(struct vdpa *vdpa, int argc, char **argv) static void cmd_dev_help(void) { fprintf(stderr, "Usage: vdpa dev show [ DEV ]\n"); - fprintf(stderr, " vdpa dev add name NAME mgmtdev MANAGEMENTDEV [ mac MACADDR ]\n"); + fprintf(stderr, " vdpa dev add name NAME mgmtdev MANAGEMENTDEV [ mac MACADDR ] [ mtu MTU ]\n"); fprintf(stderr, " vdpa dev del DEV\n"); fprintf(stderr, "Usage: vdpa dev config COMMAND [ OPTIONS ]\n"); } @@ -533,7 +571,7 @@ static int cmd_dev_add(struct vdpa *vdpa, int argc, char **argv) NLM_F_REQUEST | NLM_F_ACK); err = vdpa_argv_parse_put(nlh, vdpa, argc, argv, VDPA_OPT_VDEV_MGMTDEV_HANDLE | VDPA_OPT_VDEV_NAME, - VDPA_OPT_VDEV_MAC); + VDPA_OPT_VDEV_MAC | VDPA_OPT_VDEV_MTU); if (err) return err; -- 2.26.2
David Ahern
2021-Dec-03 16:56 UTC
[iproute2-next 0/4] vdpa tool to query and set config layout
On 12/1/21 9:22 PM, Parav Pandit wrote:> This series implements querying and setting of the mac address and mtu > device config fields of the vdpa device of type net. > > An example of query and set as below. > > $ vdpa dev add name bar mgmtdev vdpasim_net mac 00:11:22:33:44:55 mtu 9000 > > $ vdpa dev config show > bar: mac 00:11:22:33:44:55 link up link_announce false mtu 9000 > > $ vdpa dev config show -jp > { > "config": { > "bar": { > "mac": "00:11:22:33:44:55", > "link ": "up", > "link_announce ": false, > "mtu": 1500, > } > } > } > > patch summary: > patch-1 updates the kernel headers > patch-2 implements the query command > patch-3 implements setting the mac address of vdpa dev config space > patch-4 implements setting the mtu of vdpa dev config space > > > Parav Pandit (4): > vdpa: Update kernel headers > vdpa: Enable user to query vdpa device config layout > vdpa: Enable user to set mac address of vdpa device > vdpa: Enable user to set mtu of the vdpa device > > include/uapi/linux/virtio_net.h | 81 +++++++++++++ > vdpa/include/uapi/linux/vdpa.h | 7 ++ > vdpa/vdpa.c | 198 ++++++++++++++++++++++++++++++-- > 3 files changed, 277 insertions(+), 9 deletions(-) > create mode 100644 include/uapi/linux/virtio_net.h >please update man page(s)