#include "monitor/qdev.h"
#include "hw/pci/pci.h"
#include "net_rx_pkt.h"
+#include "hw/virtio/vhost.h"
#define VIRTIO_NET_VM_VERSION 11
{
VirtIONet *n = VIRTIO_NET(vdev);
struct virtio_net_config netcfg;
+ NetClientState *nc = qemu_get_queue(n->nic);
+ int ret = 0;
+ memset(&netcfg, 0 , sizeof(struct virtio_net_config));
virtio_stw_p(vdev, &netcfg.status, n->status);
virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
virtio_stw_p(vdev, &netcfg.mtu, n->net_conf.mtu);
virtio_stl_p(vdev, &netcfg.supported_hash_types,
VIRTIO_NET_RSS_SUPPORTED_HASHES);
memcpy(config, &netcfg, n->config_size);
+
+ /*
+ * Is this VDPA? No peer means not VDPA: there's no way to
+ * disconnect/reconnect a VDPA peer.
+ */
+ if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
+ ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg,
+ n->config_size);
+ if (ret != -1) {
+ memcpy(config, &netcfg, n->config_size);
+ }
+ }
}
static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
{
VirtIONet *n = VIRTIO_NET(vdev);
struct virtio_net_config netcfg = {};
+ NetClientState *nc = qemu_get_queue(n->nic);
memcpy(&netcfg, config, n->config_size);
memcpy(n->mac, netcfg.mac, ETH_ALEN);
qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
}
+
+ /*
+ * Is this VDPA? No peer means not VDPA: there's no way to
+ * disconnect/reconnect a VDPA peer.
+ */
+ if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
+ vhost_net_set_config(get_vhost_net(nc->peer),
+ (uint8_t *)&netcfg, 0, n->config_size,
+ VHOST_SET_CONFIG_TYPE_MASTER);
+ }
}
static bool virtio_net_started(VirtIONet *n, uint8_t status)
tcp_flag = htons(tcp->th_offset_flags);
tcp_hdr = (tcp_flag & VIRTIO_NET_TCP_HDR_LENGTH) >> 10;
tcp_flag &= VIRTIO_NET_TCP_FLAG;
- tcp_flag = htons(tcp->th_offset_flags) & 0x3F;
if (tcp_flag & TH_SYN) {
chain->stat.tcp_syn++;
return RSC_BYPASS;
}
qdev_set_parent_bus(n->primary_dev, n->primary_bus);
n->primary_should_be_hidden = false;
- qemu_opt_set_bool(n->primary_device_opts,
- "partially_hotplugged", true, &err);
- if (err) {
- goto out;
+ if (!qemu_opt_set_bool(n->primary_device_opts,
+ "partially_hotplugged", true, errp)) {
+ return false;
}
hotplug_ctrl = qdev_get_hotplug_handler(n->primary_dev);
if (hotplug_ctrl) {
g_free(n->vlans);
if (n->failover) {
+ device_listener_unregister(&n->primary_listener);
g_free(n->primary_device_id);
g_free(n->standby_id);
qobject_unref(n->primary_device_dict);