Lines Matching +full:- +full:- +full:disable +full:- +full:vhost +full:- +full:vdpa
10 * the COPYING file in the top-level directory.
18 #include "qemu/main-loop.h"
24 #include "qemu/error-report.h"
28 #include "qemu/config-file.h"
30 #include "hw/virtio/virtio-net.h"
33 #include "hw/virtio/virtio-bus.h"
35 #include "qapi/qapi-events-net.h"
36 #include "hw/qdev-properties.h"
37 #include "qapi/qapi-types-migration.h"
38 #include "qapi/qapi-events-migration.h"
39 #include "hw/virtio/virtio-access.h"
41 #include "standard-headers/linux/ethtool.h"
49 #include "hw/virtio/vhost.h"
58 /* for now, only allow larger queue_pairs; with virtio-1, guest can downsize */
68 #define VIRTIO_NET_MAX_IP4_PAYLOAD (65535 - sizeof(struct ip_header))
119 return &n->vqs[nc->queue_index]; in virtio_net_get_subqueue()
129 if (!nc->peer) { in flush_or_purge_queued_packets()
133 qemu_flush_or_purge_queued_packets(nc->peer, true); in flush_or_purge_queued_packets()
134 assert(!virtio_net_get_subqueue(nc)->async_tx.elem); in flush_or_purge_queued_packets()
138 * - we could suppress RX interrupt if we were so inclined.
145 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_get_config()
150 virtio_stw_p(vdev, &netcfg.status, n->status); in virtio_net_get_config()
151 virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queue_pairs); in virtio_net_get_config()
152 virtio_stw_p(vdev, &netcfg.mtu, n->net_conf.mtu); in virtio_net_get_config()
153 memcpy(netcfg.mac, n->mac, ETH_ALEN); in virtio_net_get_config()
154 virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed); in virtio_net_get_config()
155 netcfg.duplex = n->net_conf.duplex; in virtio_net_get_config()
162 memcpy(config, &netcfg, n->config_size); in virtio_net_get_config()
165 * Is this VDPA? No peer means not VDPA: there's no way to in virtio_net_get_config()
166 * disconnect/reconnect a VDPA peer. in virtio_net_get_config()
168 if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { in virtio_net_get_config()
169 ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg, in virtio_net_get_config()
170 n->config_size); in virtio_net_get_config()
171 if (ret == -1) { in virtio_net_get_config()
179 * correctly elsewhere - just not reported by the device. in virtio_net_get_config()
183 memcpy(netcfg.mac, n->mac, ETH_ALEN); in virtio_net_get_config()
187 n->status & VIRTIO_NET_S_ANNOUNCE); in virtio_net_get_config()
188 memcpy(config, &netcfg, n->config_size); in virtio_net_get_config()
196 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_set_config()
198 memcpy(&netcfg, config, n->config_size); in virtio_net_set_config()
202 memcmp(netcfg.mac, n->mac, ETH_ALEN)) { in virtio_net_set_config()
203 memcpy(n->mac, netcfg.mac, ETH_ALEN); in virtio_net_set_config()
204 qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac); in virtio_net_set_config()
208 * Is this VDPA? No peer means not VDPA: there's no way to in virtio_net_set_config()
209 * disconnect/reconnect a VDPA peer. in virtio_net_set_config()
211 if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { in virtio_net_set_config()
212 vhost_net_set_config(get_vhost_net(nc->peer), in virtio_net_set_config()
213 (uint8_t *)&netcfg, 0, n->config_size, in virtio_net_set_config()
222 (n->status & VIRTIO_NET_S_LINK_UP) && vdev->vm_running; in virtio_net_started()
230 net->status |= VIRTIO_NET_S_ANNOUNCE; in virtio_net_announce_notify()
237 trace_virtio_net_announce_timer(n->announce_timer.round); in virtio_net_announce_timer()
239 n->announce_timer.round--; in virtio_net_announce_timer()
253 if (n->announce_timer.round) { in virtio_net_announce()
266 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_vhost_status()
267 int queue_pairs = n->multiqueue ? n->max_queue_pairs : 1; in virtio_net_vhost_status()
269 n->max_ncs - n->max_queue_pairs : 0; in virtio_net_vhost_status()
271 if (!get_vhost_net(nc->peer)) { in virtio_net_vhost_status()
275 if ((virtio_net_started(n, status) && !nc->peer->link_down) == in virtio_net_vhost_status()
276 !!n->vhost_started) { in virtio_net_vhost_status()
279 if (!n->vhost_started) { in virtio_net_vhost_status()
282 if (n->needs_vnet_hdr_swap) { in virtio_net_vhost_status()
290 * when vhost is running. in virtio_net_vhost_status()
293 NetClientState *qnc = qemu_get_subqueue(n->nic, i); in virtio_net_vhost_status()
296 qemu_net_queue_purge(qnc->peer->incoming_queue, qnc); in virtio_net_vhost_status()
297 qemu_net_queue_purge(qnc->incoming_queue, qnc->peer); in virtio_net_vhost_status()
300 if (virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MTU)) { in virtio_net_vhost_status()
301 r = vhost_net_set_mtu(get_vhost_net(nc->peer), n->net_conf.mtu); in virtio_net_vhost_status()
304 n->net_conf.mtu); in virtio_net_vhost_status()
310 n->vhost_started = 1; in virtio_net_vhost_status()
311 r = vhost_net_start(vdev, n->nic->ncs, queue_pairs, cvq); in virtio_net_vhost_status()
313 error_report("unable to start vhost net: %d: " in virtio_net_vhost_status()
314 "falling back on userspace virtio", -r); in virtio_net_vhost_status()
315 n->vhost_started = 0; in virtio_net_vhost_status()
318 vhost_net_stop(vdev, n->nic->ncs, queue_pairs, cvq); in virtio_net_vhost_status()
319 n->vhost_started = 0; in virtio_net_vhost_status()
342 while (--i >= 0) { in virtio_net_set_vnet_endian()
356 int queue_pairs = n->multiqueue ? n->max_queue_pairs : 1; in virtio_net_vnet_endian_status()
362 * virtio-net code. in virtio_net_vnet_endian_status()
364 n->needs_vnet_hdr_swap = n->has_vnet_hdr && in virtio_net_vnet_endian_status()
365 virtio_net_set_vnet_endian(vdev, n->nic->ncs, in virtio_net_vnet_endian_status()
367 } else if (virtio_net_started(n, vdev->status)) { in virtio_net_vnet_endian_status()
373 virtio_net_set_vnet_endian(vdev, n->nic->ncs, queue_pairs, false); in virtio_net_vnet_endian_status()
395 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_set_status()
396 NetClientState *ncs = qemu_get_subqueue(n->nic, i); in virtio_net_set_status()
398 q = &n->vqs[i]; in virtio_net_set_status()
400 if ((!n->multiqueue && i != 0) || i >= n->curr_queue_pairs) { in virtio_net_set_status()
406 virtio_net_started(n, queue_status) && !n->vhost_started; in virtio_net_set_status()
412 if (!q->tx_waiting) { in virtio_net_set_status()
417 if (q->tx_timer) { in virtio_net_set_status()
418 timer_mod(q->tx_timer, in virtio_net_set_status()
419 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); in virtio_net_set_status()
421 replay_bh_schedule_event(q->tx_bh); in virtio_net_set_status()
424 if (q->tx_timer) { in virtio_net_set_status()
425 timer_del(q->tx_timer); in virtio_net_set_status()
427 qemu_bh_cancel(q->tx_bh); in virtio_net_set_status()
429 if ((n->status & VIRTIO_NET_S_LINK_UP) == 0 && in virtio_net_set_status()
431 vdev->vm_running) { in virtio_net_set_status()
434 q->tx_waiting = 0; in virtio_net_set_status()
435 virtio_queue_set_notification(q->tx_vq, 1); in virtio_net_set_status()
436 virtio_net_drop_tx_queue_data(vdev, q->tx_vq); in virtio_net_set_status()
447 uint16_t old_status = n->status; in virtio_net_set_link_status()
449 if (nc->link_down) in virtio_net_set_link_status()
450 n->status &= ~VIRTIO_NET_S_LINK_UP; in virtio_net_set_link_status()
452 n->status |= VIRTIO_NET_S_LINK_UP; in virtio_net_set_link_status()
454 if (n->status != old_status) in virtio_net_set_link_status()
457 virtio_net_set_status(vdev, vdev->status); in virtio_net_set_link_status()
464 if (nc->rxfilter_notify_enabled) { in rxfilter_notify()
465 char *path = object_get_canonical_path(OBJECT(n->qdev)); in rxfilter_notify()
466 qapi_event_send_nic_rx_filter_changed(n->netclient_name, path); in rxfilter_notify()
469 /* disable event notification to avoid events flooding */ in rxfilter_notify()
470 nc->rxfilter_notify_enabled = 0; in rxfilter_notify()
481 for (j = 0; n->vlans[i] && j <= 0x1f; j++) { in get_vlan_table()
482 if (n->vlans[i] & (1U << j)) { in get_vlan_table()
500 info->name = g_strdup(nc->name); in virtio_net_query_rxfilter()
501 info->promiscuous = n->promisc; in virtio_net_query_rxfilter()
503 if (n->nouni) { in virtio_net_query_rxfilter()
504 info->unicast = RX_STATE_NONE; in virtio_net_query_rxfilter()
505 } else if (n->alluni) { in virtio_net_query_rxfilter()
506 info->unicast = RX_STATE_ALL; in virtio_net_query_rxfilter()
508 info->unicast = RX_STATE_NORMAL; in virtio_net_query_rxfilter()
511 if (n->nomulti) { in virtio_net_query_rxfilter()
512 info->multicast = RX_STATE_NONE; in virtio_net_query_rxfilter()
513 } else if (n->allmulti) { in virtio_net_query_rxfilter()
514 info->multicast = RX_STATE_ALL; in virtio_net_query_rxfilter()
516 info->multicast = RX_STATE_NORMAL; in virtio_net_query_rxfilter()
519 info->broadcast_allowed = n->nobcast; in virtio_net_query_rxfilter()
520 info->multicast_overflow = n->mac_table.multi_overflow; in virtio_net_query_rxfilter()
521 info->unicast_overflow = n->mac_table.uni_overflow; in virtio_net_query_rxfilter()
523 info->main_mac = qemu_mac_strdup_printf(n->mac); in virtio_net_query_rxfilter()
526 for (i = 0; i < n->mac_table.first_multi; i++) { in virtio_net_query_rxfilter()
528 qemu_mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN)); in virtio_net_query_rxfilter()
530 info->unicast_table = str_list; in virtio_net_query_rxfilter()
533 for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) { in virtio_net_query_rxfilter()
535 qemu_mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN)); in virtio_net_query_rxfilter()
537 info->multicast_table = str_list; in virtio_net_query_rxfilter()
538 info->vlan_table = get_vlan_table(n); in virtio_net_query_rxfilter()
541 info->vlan = RX_STATE_ALL; in virtio_net_query_rxfilter()
542 } else if (!info->vlan_table) { in virtio_net_query_rxfilter()
543 info->vlan = RX_STATE_NONE; in virtio_net_query_rxfilter()
545 info->vlan = RX_STATE_NORMAL; in virtio_net_query_rxfilter()
549 nc->rxfilter_notify_enabled = 1; in virtio_net_query_rxfilter()
560 if (queue_index >= n->max_queue_pairs * 2) { in virtio_net_queue_reset()
564 nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); in virtio_net_queue_reset()
566 if (!nc->peer) { in virtio_net_queue_reset()
570 if (get_vhost_net(nc->peer) && in virtio_net_queue_reset()
571 nc->peer->info->type == NET_CLIENT_DRIVER_TAP) { in virtio_net_queue_reset()
585 if (queue_index >= n->max_queue_pairs * 2) { in virtio_net_queue_enable()
589 nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); in virtio_net_queue_enable()
591 if (!nc->peer || !vdev->vhost_started) { in virtio_net_queue_enable()
595 if (get_vhost_net(nc->peer) && in virtio_net_queue_enable()
596 nc->peer->info->type == NET_CLIENT_DRIVER_TAP) { in virtio_net_queue_enable()
599 error_report("unable to restart vhost net virtqueue: %d, " in virtio_net_queue_enable()
607 NetClientState *nc = qemu_get_queue(n->nic); in peer_test_vnet_hdr()
608 if (!nc->peer) { in peer_test_vnet_hdr()
612 n->has_vnet_hdr = qemu_has_vnet_hdr(nc->peer); in peer_test_vnet_hdr()
617 return n->has_vnet_hdr; in peer_has_vnet_hdr()
625 n->has_ufo = qemu_has_ufo(qemu_get_queue(n->nic)->peer); in peer_has_ufo()
627 return n->has_ufo; in peer_has_ufo()
636 return qemu_has_uso(qemu_get_queue(n->nic)->peer); in peer_has_uso()
645 n->mergeable_rx_bufs = mergeable_rx_bufs; in virtio_net_set_mrg_rx_bufs()
648 n->guest_hdr_len = hash_report ? in virtio_net_set_mrg_rx_bufs()
651 n->rss_data.populate_hash = !!hash_report; in virtio_net_set_mrg_rx_bufs()
653 n->guest_hdr_len = n->mergeable_rx_bufs ? in virtio_net_set_mrg_rx_bufs()
656 n->rss_data.populate_hash = false; in virtio_net_set_mrg_rx_bufs()
659 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_set_mrg_rx_bufs()
660 nc = qemu_get_subqueue(n->nic, i); in virtio_net_set_mrg_rx_bufs()
663 qemu_has_vnet_hdr_len(nc->peer, n->guest_hdr_len)) { in virtio_net_set_mrg_rx_bufs()
664 qemu_set_vnet_hdr_len(nc->peer, n->guest_hdr_len); in virtio_net_set_mrg_rx_bufs()
665 n->host_hdr_len = n->guest_hdr_len; in virtio_net_set_mrg_rx_bufs()
672 NetClientState *peer = n->nic_conf.peers.ncs[0]; in virtio_net_max_tx_queue_size()
675 * Backends other than vhost-user or vhost-vdpa don't support max queue in virtio_net_max_tx_queue_size()
682 switch(peer->info->type) { in virtio_net_max_tx_queue_size()
693 NetClientState *nc = qemu_get_subqueue(n->nic, index); in peer_attach()
695 if (!nc->peer) { in peer_attach()
699 if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { in peer_attach()
700 vhost_set_vring_enable(nc->peer, 1); in peer_attach()
703 if (nc->peer->info->type != NET_CLIENT_DRIVER_TAP) { in peer_attach()
707 if (n->max_queue_pairs == 1) { in peer_attach()
711 return tap_enable(nc->peer); in peer_attach()
716 NetClientState *nc = qemu_get_subqueue(n->nic, index); in peer_detach()
718 if (!nc->peer) { in peer_detach()
722 if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { in peer_detach()
723 vhost_set_vring_enable(nc->peer, 0); in peer_detach()
726 if (nc->peer->info->type != NET_CLIENT_DRIVER_TAP) { in peer_detach()
730 return tap_disable(nc->peer); in peer_detach()
738 if (n->nic->peer_deleted) { in virtio_net_set_queue_pairs()
742 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_set_queue_pairs()
743 if (i < n->curr_queue_pairs) { in virtio_net_set_queue_pairs()
759 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_get_features()
761 /* Firstly sync all virtio-net possible supported features */ in virtio_net_get_features()
762 features |= n->host_features; in virtio_net_get_features()
795 if (!get_vhost_net(nc->peer)) { in virtio_net_get_features()
799 if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { in virtio_net_get_features()
802 features = vhost_net_get_features(get_vhost_net(nc->peer), features); in virtio_net_get_features()
803 vdev->backend_features = features; in virtio_net_get_features()
805 if (n->mtu_bypass_backend && in virtio_net_get_features()
806 (n->host_features & 1ULL << VIRTIO_NET_F_MTU)) { in virtio_net_get_features()
812 * enabled. This happens in the vDPA case. in virtio_net_get_features()
818 * helping guest to notify the new location with vDPA devices that does not in virtio_net_get_features()
821 if (!virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_CTRL_VQ)) { in virtio_net_get_features()
845 qemu_set_offload(qemu_get_queue(n->nic)->peer, in virtio_net_apply_guest_offloads()
846 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)), in virtio_net_apply_guest_offloads()
847 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)), in virtio_net_apply_guest_offloads()
848 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)), in virtio_net_apply_guest_offloads()
849 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)), in virtio_net_apply_guest_offloads()
850 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)), in virtio_net_apply_guest_offloads()
851 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO4)), in virtio_net_apply_guest_offloads()
852 !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO6))); in virtio_net_apply_guest_offloads()
872 return virtio_net_guest_offloads_by_features(vdev->guest_features); in virtio_net_supported_guest_offloads()
897 if (!g_strcmp0(pci_dev->failover_pair_id, fdev->n->netclient_name)) { in failover_set_primary()
898 fdev->dev = dev; in failover_set_primary()
906 * Find the primary device for this failover virtio-net
931 if (!n->primary_opts) { in failover_add_primary()
933 error_append_hint(errp, "Virtio-net failover will not work. Make " in failover_add_primary()
935 " failover_pair_id=%s\n", n->netclient_name); in failover_add_primary()
939 dev = qdev_device_add_from_qdict(n->primary_opts, in failover_add_primary()
940 n->primary_opts_from_json, in failover_add_primary()
943 qobject_unref(n->primary_opts); in failover_add_primary()
944 n->primary_opts = NULL; in failover_add_primary()
957 if (n->mtu_bypass_backend && in virtio_net_set_features()
958 !virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_MTU)) { in virtio_net_set_features()
974 n->rsc4_enabled = virtio_has_feature(features, VIRTIO_NET_F_RSC_EXT) && in virtio_net_set_features()
976 n->rsc6_enabled = virtio_has_feature(features, VIRTIO_NET_F_RSC_EXT) && in virtio_net_set_features()
978 n->rss_data.redirect = virtio_has_feature(features, VIRTIO_NET_F_RSS); in virtio_net_set_features()
980 if (n->has_vnet_hdr) { in virtio_net_set_features()
981 n->curr_guest_offloads = in virtio_net_set_features()
986 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_set_features()
987 NetClientState *nc = qemu_get_subqueue(n->nic, i); in virtio_net_set_features()
989 if (!get_vhost_net(nc->peer)) { in virtio_net_set_features()
992 vhost_net_ack_features(get_vhost_net(nc->peer), features); in virtio_net_set_features()
995 * keep acked_features in NetVhostUserState up-to-date so it in virtio_net_set_features()
998 vhost_net_save_acked_features(nc->peer); in virtio_net_set_features()
1002 memset(n->vlans, 0xff, MAX_VLAN >> 3); in virtio_net_set_features()
1006 qapi_event_send_failover_negotiated(n->netclient_name); in virtio_net_set_features()
1007 qatomic_set(&n->failover_primary_hidden, false); in virtio_net_set_features()
1024 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_handle_rx_mode()
1032 n->promisc = on; in virtio_net_handle_rx_mode()
1034 n->allmulti = on; in virtio_net_handle_rx_mode()
1036 n->alluni = on; in virtio_net_handle_rx_mode()
1038 n->nomulti = on; in virtio_net_handle_rx_mode()
1040 n->nouni = on; in virtio_net_handle_rx_mode()
1042 n->nobcast = on; in virtio_net_handle_rx_mode()
1073 if (!n->has_vnet_hdr) { in virtio_net_handle_offloads()
1077 n->rsc4_enabled = virtio_has_feature(offloads, VIRTIO_NET_F_RSC_EXT) && in virtio_net_handle_offloads()
1079 n->rsc6_enabled = virtio_has_feature(offloads, VIRTIO_NET_F_RSC_EXT) && in virtio_net_handle_offloads()
1088 n->curr_guest_offloads = offloads; in virtio_net_handle_offloads()
1103 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_handle_mac()
1106 if (iov_size(iov, iov_cnt) != sizeof(n->mac)) { in virtio_net_handle_mac()
1109 s = iov_to_buf(iov, iov_cnt, 0, &n->mac, sizeof(n->mac)); in virtio_net_handle_mac()
1110 assert(s == sizeof(n->mac)); in virtio_net_handle_mac()
1111 qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac); in virtio_net_handle_mac()
1167 if (mac_data.entries <= MAC_TABLE_ENTRIES - in_use) { in virtio_net_handle_mac()
1178 n->mac_table.in_use = in_use; in virtio_net_handle_mac()
1179 n->mac_table.first_multi = first_multi; in virtio_net_handle_mac()
1180 n->mac_table.uni_overflow = uni_overflow; in virtio_net_handle_mac()
1181 n->mac_table.multi_overflow = multi_overflow; in virtio_net_handle_mac()
1182 memcpy(n->mac_table.macs, macs, MAC_TABLE_ENTRIES * ETH_ALEN); in virtio_net_handle_mac()
1199 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_handle_vlan_table()
1211 n->vlans[vid >> 5] |= (1U << (vid & 0x1f)); in virtio_net_handle_vlan_table()
1213 n->vlans[vid >> 5] &= ~(1U << (vid & 0x1f)); in virtio_net_handle_vlan_table()
1225 trace_virtio_net_handle_announce(n->announce_timer.round); in virtio_net_handle_announce()
1227 n->status & VIRTIO_NET_S_ANNOUNCE) { in virtio_net_handle_announce()
1228 n->status &= ~VIRTIO_NET_S_ANNOUNCE; in virtio_net_handle_announce()
1229 if (n->announce_timer.round) { in virtio_net_handle_announce()
1230 qemu_announce_timer_step(&n->announce_timer); in virtio_net_handle_announce()
1241 if (nc == NULL || nc->info->set_steering_ebpf == NULL) { in virtio_net_attach_ebpf_to_backend()
1246 return nc->info->set_steering_ebpf(nc, prog_fd); in virtio_net_attach_ebpf_to_backend()
1252 config->redirect = data->redirect; in rss_data_to_rss_config()
1253 config->populate_hash = data->populate_hash; in rss_data_to_rss_config()
1254 config->hash_types = data->hash_types; in rss_data_to_rss_config()
1255 config->indirections_len = data->indirections_len; in rss_data_to_rss_config()
1256 config->default_queue = data->default_queue; in rss_data_to_rss_config()
1263 if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { in virtio_net_attach_ebpf_rss()
1267 rss_data_to_rss_config(&n->rss_data, &config); in virtio_net_attach_ebpf_rss()
1269 if (!ebpf_rss_set_all(&n->ebpf_rss, &config, in virtio_net_attach_ebpf_rss()
1270 n->rss_data.indirections_table, n->rss_data.key, in virtio_net_attach_ebpf_rss()
1275 if (!virtio_net_attach_ebpf_to_backend(n->nic, n->ebpf_rss.program_fd)) { in virtio_net_attach_ebpf_rss()
1284 virtio_net_attach_ebpf_to_backend(n->nic, -1); in virtio_net_detach_ebpf_rss()
1289 if (n->rss_data.enabled) { in virtio_net_commit_rss_config()
1290 n->rss_data.enabled_software_rss = n->rss_data.populate_hash; in virtio_net_commit_rss_config()
1291 if (n->rss_data.populate_hash) { in virtio_net_commit_rss_config()
1294 if (get_vhost_net(qemu_get_queue(n->nic)->peer)) { in virtio_net_commit_rss_config()
1295 warn_report("Can't load eBPF RSS for vhost"); in virtio_net_commit_rss_config()
1297 warn_report("Can't load eBPF RSS - fallback to software RSS"); in virtio_net_commit_rss_config()
1298 n->rss_data.enabled_software_rss = true; in virtio_net_commit_rss_config()
1303 n->rss_data.hash_types, in virtio_net_commit_rss_config()
1304 n->rss_data.indirections_len, in virtio_net_commit_rss_config()
1305 sizeof(n->rss_data.key)); in virtio_net_commit_rss_config()
1314 if (!n->rss_data.enabled) { in virtio_net_disable_rss()
1318 n->rss_data.enabled = false; in virtio_net_disable_rss()
1324 int fds[EBPF_RSS_MAX_FDS] = { [0 ... EBPF_RSS_MAX_FDS - 1] = -1}; in virtio_net_load_ebpf_fds()
1328 if (n->nr_ebpf_rss_fds != EBPF_RSS_MAX_FDS) { in virtio_net_load_ebpf_fds()
1330 EBPF_RSS_MAX_FDS, n->nr_ebpf_rss_fds); in virtio_net_load_ebpf_fds()
1334 for (i = 0; i < n->nr_ebpf_rss_fds; i++) { in virtio_net_load_ebpf_fds()
1335 fds[i] = monitor_fd_param(monitor_cur(), n->ebpf_rss_fds[i], errp); in virtio_net_load_ebpf_fds()
1342 ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3], errp); in virtio_net_load_ebpf_fds()
1346 for (i = 0; i < n->nr_ebpf_rss_fds && fds[i] != -1; i++) { in virtio_net_load_ebpf_fds()
1356 if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) { in virtio_net_load_ebpf()
1360 trace_virtio_net_rss_load(n, n->nr_ebpf_rss_fds, n->ebpf_rss_fds); in virtio_net_load_ebpf()
1369 if (n->ebpf_rss_fds) { in virtio_net_load_ebpf()
1373 ebpf_rss_load(&n->ebpf_rss, &error_warn); in virtio_net_load_ebpf()
1379 virtio_net_attach_ebpf_to_backend(n->nic, -1); in virtio_net_unload_ebpf()
1380 ebpf_rss_unload(&n->ebpf_rss); in virtio_net_unload_ebpf()
1414 n->rss_data.hash_types = virtio_ldl_p(vdev, &cfg.hash_types); in virtio_net_handle_rss()
1415 n->rss_data.indirections_len = in virtio_net_handle_rss()
1418 n->rss_data.indirections_len = 0; in virtio_net_handle_rss()
1420 if (n->rss_data.indirections_len >= VIRTIO_NET_RSS_MAX_TABLE_LEN) { in virtio_net_handle_rss()
1422 err_value = n->rss_data.indirections_len; in virtio_net_handle_rss()
1425 n->rss_data.indirections_len++; in virtio_net_handle_rss()
1426 if (!is_power_of_2(n->rss_data.indirections_len)) { in virtio_net_handle_rss()
1428 err_value = n->rss_data.indirections_len; in virtio_net_handle_rss()
1431 n->rss_data.default_queue = do_rss ? in virtio_net_handle_rss()
1433 if (n->rss_data.default_queue >= n->max_queue_pairs) { in virtio_net_handle_rss()
1435 err_value = n->rss_data.default_queue; in virtio_net_handle_rss()
1439 size_get = sizeof(uint16_t) * n->rss_data.indirections_len; in virtio_net_handle_rss()
1440 g_free(n->rss_data.indirections_table); in virtio_net_handle_rss()
1441 n->rss_data.indirections_table = g_malloc(size_get); in virtio_net_handle_rss()
1442 if (!n->rss_data.indirections_table) { in virtio_net_handle_rss()
1444 err_value = n->rss_data.indirections_len; in virtio_net_handle_rss()
1448 n->rss_data.indirections_table, size_get); in virtio_net_handle_rss()
1454 for (i = 0; i < n->rss_data.indirections_len; ++i) { in virtio_net_handle_rss()
1455 uint16_t val = n->rss_data.indirections_table[i]; in virtio_net_handle_rss()
1456 n->rss_data.indirections_table[i] = virtio_lduw_p(vdev, &val); in virtio_net_handle_rss()
1466 queue_pairs = do_rss ? virtio_lduw_p(vdev, &temp.us) : n->curr_queue_pairs; in virtio_net_handle_rss()
1467 if (queue_pairs == 0 || queue_pairs > n->max_queue_pairs) { in virtio_net_handle_rss()
1477 if (!temp.b && n->rss_data.hash_types) { in virtio_net_handle_rss()
1482 if (!temp.b && !n->rss_data.hash_types) { in virtio_net_handle_rss()
1488 s = iov_to_buf(iov, iov_cnt, offset, n->rss_data.key, size_get); in virtio_net_handle_rss()
1494 n->rss_data.enabled = true; in virtio_net_handle_rss()
1508 NetClientState *nc = qemu_get_queue(n->nic); in virtio_net_handle_mq()
1535 queue_pairs > n->max_queue_pairs || in virtio_net_handle_mq()
1536 !n->multiqueue) { in virtio_net_handle_mq()
1540 n->curr_queue_pairs = queue_pairs; in virtio_net_handle_mq()
1541 if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { in virtio_net_handle_mq()
1543 * Avoid updating the backend for a vdpa device: We're only interested in virtio_net_handle_mq()
1550 virtio_net_set_status(vdev, vdev->status); in virtio_net_handle_mq()
1569 virtio_error(vdev, "virtio-net ctrl missing headers"); in virtio_net_handle_ctrl_iov()
1610 written = virtio_net_handle_ctrl_iov(vdev, elem->in_sg, elem->in_num, in virtio_net_handle_ctrl()
1611 elem->out_sg, elem->out_num); in virtio_net_handle_ctrl()
1631 qemu_flush_queued_packets(qemu_get_subqueue(n->nic, queue_index)); in virtio_net_handle_rx()
1640 if (!vdev->vm_running) { in virtio_net_can_receive()
1644 if (nc->queue_index >= n->curr_queue_pairs) { in virtio_net_can_receive()
1648 if (!virtio_queue_ready(q->rx_vq) || in virtio_net_can_receive()
1649 !(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { in virtio_net_can_receive()
1660 VirtIONet *n = q->n; in virtio_net_has_buffers()
1662 while (virtio_queue_empty(q->rx_vq) || n->mergeable_rx_bufs) { in virtio_net_has_buffers()
1663 opaque = virtqueue_get_avail_bytes(q->rx_vq, &in_bytes, NULL, in virtio_net_has_buffers()
1665 /* Buffer is enough, disable notifiaction */ in virtio_net_has_buffers()
1670 if (virtio_queue_enable_notification_and_check(q->rx_vq, opaque)) { in virtio_net_has_buffers()
1678 virtio_queue_set_notification(q->rx_vq, 0); in virtio_net_has_buffers()
1685 virtio_tswap16s(vdev, &hdr->hdr_len); in virtio_net_hdr_swap()
1686 virtio_tswap16s(vdev, &hdr->gso_size); in virtio_net_hdr_swap()
1687 virtio_tswap16s(vdev, &hdr->csum_start); in virtio_net_hdr_swap()
1688 virtio_tswap16s(vdev, &hdr->csum_offset); in virtio_net_hdr_swap()
1701 * N.B. if we introduce a zero-copy API, this operation is no longer free so
1702 * we should provide a mechanism to disable it to avoid polluting the host
1711 if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */ in work_around_broken_dhclient()
1717 hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM; in work_around_broken_dhclient()
1724 if (n->has_vnet_hdr) { in receive_header()
1727 work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, in receive_header()
1728 size - n->host_hdr_len); in receive_header()
1730 if (n->needs_vnet_hdr_swap) { in receive_header()
1750 if (n->promisc) in receive_filter()
1753 ptr += n->host_hdr_len; in receive_filter()
1757 if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f)))) in receive_filter()
1763 return !n->nobcast; in receive_filter()
1764 } else if (n->nomulti) { in receive_filter()
1766 } else if (n->allmulti || n->mac_table.multi_overflow) { in receive_filter()
1770 for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) { in receive_filter()
1771 if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN)) { in receive_filter()
1776 if (n->nouni) { in receive_filter()
1778 } else if (n->alluni || n->mac_table.uni_overflow) { in receive_filter()
1780 } else if (!memcmp(ptr, n->mac, ETH_ALEN)) { in receive_filter()
1784 for (i = 0; i < n->mac_table.first_multi; i++) { in receive_filter()
1785 if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN)) { in receive_filter()
1859 unsigned int index = nc->queue_index, new_index = index; in virtio_net_process_rss()
1860 struct NetRxPkt *pkt = n->rx_pkt; in virtio_net_process_rss()
1881 net_rx_pkt_set_protocols(pkt, &iov, 1, n->host_hdr_len); in virtio_net_process_rss()
1884 n->rss_data.hash_types); in virtio_net_process_rss()
1886 if (n->rss_data.populate_hash) { in virtio_net_process_rss()
1887 hdr->hash_value = VIRTIO_NET_HASH_REPORT_NONE; in virtio_net_process_rss()
1888 hdr->hash_report = 0; in virtio_net_process_rss()
1890 return n->rss_data.redirect ? n->rss_data.default_queue : -1; in virtio_net_process_rss()
1893 hash = net_rx_pkt_calc_rss_hash(pkt, net_hash_type, n->rss_data.key); in virtio_net_process_rss()
1895 if (n->rss_data.populate_hash) { in virtio_net_process_rss()
1896 hdr->hash_value = hash; in virtio_net_process_rss()
1897 hdr->hash_report = reports[net_hash_type]; in virtio_net_process_rss()
1900 if (n->rss_data.redirect) { in virtio_net_process_rss()
1901 new_index = hash & (n->rss_data.indirections_len - 1); in virtio_net_process_rss()
1902 new_index = n->rss_data.indirections_table[new_index]; in virtio_net_process_rss()
1905 return (index == new_index) ? -1 : new_index; in virtio_net_process_rss()
1924 if (n->rss_data.enabled && n->rss_data.enabled_software_rss) { in virtio_net_receive_rcu()
1927 nc = qemu_get_subqueue(n->nic, index % n->curr_queue_pairs); in virtio_net_receive_rcu()
1932 return -1; in virtio_net_receive_rcu()
1938 if (!virtio_net_has_buffers(q, size + n->guest_hdr_len - n->host_hdr_len)) { in virtio_net_receive_rcu()
1955 virtio_error(vdev, "virtio-net unexpected long buffer chain"); in virtio_net_receive_rcu()
1960 elem = virtqueue_pop(q->rx_vq, sizeof(VirtQueueElement)); in virtio_net_receive_rcu()
1963 virtio_error(vdev, "virtio-net unexpected empty queue: " in virtio_net_receive_rcu()
1967 i, n->mergeable_rx_bufs, offset, size, in virtio_net_receive_rcu()
1968 n->guest_hdr_len, n->host_hdr_len, in virtio_net_receive_rcu()
1969 vdev->guest_features); in virtio_net_receive_rcu()
1971 err = -1; in virtio_net_receive_rcu()
1975 if (elem->in_num < 1) { in virtio_net_receive_rcu()
1977 "virtio-net receive queue contains no in buffers"); in virtio_net_receive_rcu()
1978 virtqueue_detach_element(q->rx_vq, elem, 0); in virtio_net_receive_rcu()
1980 err = -1; in virtio_net_receive_rcu()
1984 sg = elem->in_sg; in virtio_net_receive_rcu()
1987 if (n->mergeable_rx_bufs) { in virtio_net_receive_rcu()
1989 sg, elem->in_num, in virtio_net_receive_rcu()
1996 receive_header(n, sg, elem->in_num, buf, size); in virtio_net_receive_rcu()
1997 if (n->rss_data.populate_hash) { in virtio_net_receive_rcu()
1999 iov_from_buf(sg, elem->in_num, offset, in virtio_net_receive_rcu()
2004 offset = n->host_hdr_len; in virtio_net_receive_rcu()
2005 total += n->guest_hdr_len; in virtio_net_receive_rcu()
2006 guest_offset = n->guest_hdr_len; in virtio_net_receive_rcu()
2012 len = iov_from_buf(sg, elem->in_num, guest_offset, in virtio_net_receive_rcu()
2013 buf + offset, size - offset); in virtio_net_receive_rcu()
2019 if (!n->mergeable_rx_bufs && offset < size) { in virtio_net_receive_rcu()
2020 virtqueue_unpop(q->rx_vq, elem, total); in virtio_net_receive_rcu()
2041 virtqueue_fill(q->rx_vq, elems[j], lens[j], j); in virtio_net_receive_rcu()
2045 virtqueue_flush(q->rx_vq, i); in virtio_net_receive_rcu()
2046 virtio_notify(vdev, q->rx_vq); in virtio_net_receive_rcu()
2052 virtqueue_detach_element(q->rx_vq, elems[j], lens[j]); in virtio_net_receive_rcu()
2069 * is a potentially unaligned network-byte-order 16 bit unsigned integer
2070 * pointed to by unit->ip_len.
2074 return lduw_be_p(unit->ip_plen); in read_unit_ip_len()
2079 stw_be_p(unit->ip_plen, l); in write_unit_ip_len()
2089 ip = (struct ip_header *)(buf + chain->n->guest_hdr_len in virtio_net_rsc_extract_unit4()
2091 unit->ip = (void *)ip; in virtio_net_rsc_extract_unit4()
2092 ip_hdrlen = (ip->ip_ver_len & 0xF) << 2; in virtio_net_rsc_extract_unit4()
2093 unit->ip_plen = &ip->ip_len; in virtio_net_rsc_extract_unit4()
2094 unit->tcp = (struct tcp_header *)(((uint8_t *)unit->ip) + ip_hdrlen); in virtio_net_rsc_extract_unit4()
2095 unit->tcp_hdrlen = (htons(unit->tcp->th_offset_flags) & 0xF000) >> 10; in virtio_net_rsc_extract_unit4()
2096 unit->payload = read_unit_ip_len(unit) - ip_hdrlen - unit->tcp_hdrlen; in virtio_net_rsc_extract_unit4()
2105 ip6 = (struct ip6_header *)(buf + chain->n->guest_hdr_len in virtio_net_rsc_extract_unit6()
2107 unit->ip = ip6; in virtio_net_rsc_extract_unit6()
2108 unit->ip_plen = &(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen); in virtio_net_rsc_extract_unit6()
2109 unit->tcp = (struct tcp_header *)(((uint8_t *)unit->ip) in virtio_net_rsc_extract_unit6()
2111 unit->tcp_hdrlen = (htons(unit->tcp->th_offset_flags) & 0xF000) >> 10; in virtio_net_rsc_extract_unit6()
2115 unit->payload = read_unit_ip_len(unit) - unit->tcp_hdrlen; in virtio_net_rsc_extract_unit6()
2124 h = (struct virtio_net_hdr_v1 *)seg->buf; in virtio_net_rsc_drain_seg()
2125 h->flags = 0; in virtio_net_rsc_drain_seg()
2126 h->gso_type = VIRTIO_NET_HDR_GSO_NONE; in virtio_net_rsc_drain_seg()
2128 if (seg->is_coalesced) { in virtio_net_rsc_drain_seg()
2129 h->rsc.segments = seg->packets; in virtio_net_rsc_drain_seg()
2130 h->rsc.dup_acks = seg->dup_ack; in virtio_net_rsc_drain_seg()
2131 h->flags = VIRTIO_NET_HDR_F_RSC_INFO; in virtio_net_rsc_drain_seg()
2132 if (chain->proto == ETH_P_IP) { in virtio_net_rsc_drain_seg()
2133 h->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; in virtio_net_rsc_drain_seg()
2135 h->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; in virtio_net_rsc_drain_seg()
2139 ret = virtio_net_do_receive(seg->nc, seg->buf, seg->size); in virtio_net_rsc_drain_seg()
2140 QTAILQ_REMOVE(&chain->buffers, seg, next); in virtio_net_rsc_drain_seg()
2141 g_free(seg->buf); in virtio_net_rsc_drain_seg()
2152 QTAILQ_FOREACH_SAFE(seg, &chain->buffers, next, rn) { in virtio_net_rsc_purge()
2154 chain->stat.purge_failed++; in virtio_net_rsc_purge()
2159 chain->stat.timer++; in virtio_net_rsc_purge()
2160 if (!QTAILQ_EMPTY(&chain->buffers)) { in virtio_net_rsc_purge()
2161 timer_mod(chain->drain_timer, in virtio_net_rsc_purge()
2162 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + chain->n->rsc_timeout); in virtio_net_rsc_purge()
2171 QTAILQ_FOREACH_SAFE(chain, &n->rsc_chains, next, rn_chain) { in virtio_net_rsc_cleanup()
2172 QTAILQ_FOREACH_SAFE(seg, &chain->buffers, next, rn_seg) { in virtio_net_rsc_cleanup()
2173 QTAILQ_REMOVE(&chain->buffers, seg, next); in virtio_net_rsc_cleanup()
2174 g_free(seg->buf); in virtio_net_rsc_cleanup()
2178 timer_free(chain->drain_timer); in virtio_net_rsc_cleanup()
2179 QTAILQ_REMOVE(&n->rsc_chains, chain, next); in virtio_net_rsc_cleanup()
2191 hdr_len = chain->n->guest_hdr_len; in virtio_net_rsc_cache_buf()
2193 seg->buf = g_malloc(hdr_len + sizeof(struct eth_header) in virtio_net_rsc_cache_buf()
2195 memcpy(seg->buf, buf, size); in virtio_net_rsc_cache_buf()
2196 seg->size = size; in virtio_net_rsc_cache_buf()
2197 seg->packets = 1; in virtio_net_rsc_cache_buf()
2198 seg->dup_ack = 0; in virtio_net_rsc_cache_buf()
2199 seg->is_coalesced = 0; in virtio_net_rsc_cache_buf()
2200 seg->nc = nc; in virtio_net_rsc_cache_buf()
2202 QTAILQ_INSERT_TAIL(&chain->buffers, seg, next); in virtio_net_rsc_cache_buf()
2203 chain->stat.cache++; in virtio_net_rsc_cache_buf()
2205 switch (chain->proto) { in virtio_net_rsc_cache_buf()
2207 virtio_net_rsc_extract_unit4(chain, seg->buf, &seg->unit); in virtio_net_rsc_cache_buf()
2210 virtio_net_rsc_extract_unit6(chain, seg->buf, &seg->unit); in virtio_net_rsc_cache_buf()
2226 nack = htonl(n_tcp->th_ack); in virtio_net_rsc_handle_ack()
2227 nwin = htons(n_tcp->th_win); in virtio_net_rsc_handle_ack()
2228 oack = htonl(o_tcp->th_ack); in virtio_net_rsc_handle_ack()
2229 owin = htons(o_tcp->th_win); in virtio_net_rsc_handle_ack()
2231 if ((nack - oack) >= VIRTIO_NET_MAX_TCP_PAYLOAD) { in virtio_net_rsc_handle_ack()
2232 chain->stat.ack_out_of_win++; in virtio_net_rsc_handle_ack()
2238 chain->stat.dup_ack++; in virtio_net_rsc_handle_ack()
2242 o_tcp->th_win = n_tcp->th_win; in virtio_net_rsc_handle_ack()
2243 chain->stat.win_update++; in virtio_net_rsc_handle_ack()
2248 chain->stat.pure_ack++; in virtio_net_rsc_handle_ack()
2263 o_unit = &seg->unit; in virtio_net_rsc_coalesce_data()
2265 nseq = htonl(n_unit->tcp->th_seq); in virtio_net_rsc_coalesce_data()
2266 oseq = htonl(o_unit->tcp->th_seq); in virtio_net_rsc_coalesce_data()
2269 if ((nseq - oseq) > VIRTIO_NET_MAX_TCP_PAYLOAD) { in virtio_net_rsc_coalesce_data()
2270 chain->stat.data_out_of_win++; in virtio_net_rsc_coalesce_data()
2274 data = ((uint8_t *)n_unit->tcp) + n_unit->tcp_hdrlen; in virtio_net_rsc_coalesce_data()
2276 if ((o_unit->payload == 0) && n_unit->payload) { in virtio_net_rsc_coalesce_data()
2278 chain->stat.data_after_pure_ack++; in virtio_net_rsc_coalesce_data()
2282 n_unit->tcp, o_unit->tcp); in virtio_net_rsc_coalesce_data()
2284 } else if ((nseq - oseq) != o_unit->payload) { in virtio_net_rsc_coalesce_data()
2286 chain->stat.data_out_of_order++; in virtio_net_rsc_coalesce_data()
2290 if ((o_ip_len + n_unit->payload) > chain->max_payload) { in virtio_net_rsc_coalesce_data()
2291 chain->stat.over_size++; in virtio_net_rsc_coalesce_data()
2297 o_unit->payload += n_unit->payload; /* update new data len */ in virtio_net_rsc_coalesce_data()
2300 write_unit_ip_len(o_unit, o_ip_len + n_unit->payload); in virtio_net_rsc_coalesce_data()
2305 o_unit->tcp->th_offset_flags = n_unit->tcp->th_offset_flags; in virtio_net_rsc_coalesce_data()
2307 o_unit->tcp->th_ack = n_unit->tcp->th_ack; in virtio_net_rsc_coalesce_data()
2308 o_unit->tcp->th_win = n_unit->tcp->th_win; in virtio_net_rsc_coalesce_data()
2310 memmove(seg->buf + seg->size, data, n_unit->payload); in virtio_net_rsc_coalesce_data()
2311 seg->size += n_unit->payload; in virtio_net_rsc_coalesce_data()
2312 seg->packets++; in virtio_net_rsc_coalesce_data()
2313 chain->stat.coalesced++; in virtio_net_rsc_coalesce_data()
2325 ip1 = (struct ip_header *)(unit->ip); in virtio_net_rsc_coalesce4()
2326 ip2 = (struct ip_header *)(seg->unit.ip); in virtio_net_rsc_coalesce4()
2327 if ((ip1->ip_src ^ ip2->ip_src) || (ip1->ip_dst ^ ip2->ip_dst) in virtio_net_rsc_coalesce4()
2328 || (unit->tcp->th_sport ^ seg->unit.tcp->th_sport) in virtio_net_rsc_coalesce4()
2329 || (unit->tcp->th_dport ^ seg->unit.tcp->th_dport)) { in virtio_net_rsc_coalesce4()
2330 chain->stat.no_match++; in virtio_net_rsc_coalesce4()
2344 ip1 = (struct ip6_header *)(unit->ip); in virtio_net_rsc_coalesce6()
2345 ip2 = (struct ip6_header *)(seg->unit.ip); in virtio_net_rsc_coalesce6()
2346 if (memcmp(&ip1->ip6_src, &ip2->ip6_src, sizeof(struct in6_address)) in virtio_net_rsc_coalesce6()
2347 || memcmp(&ip1->ip6_dst, &ip2->ip6_dst, sizeof(struct in6_address)) in virtio_net_rsc_coalesce6()
2348 || (unit->tcp->th_sport ^ seg->unit.tcp->th_sport) in virtio_net_rsc_coalesce6()
2349 || (unit->tcp->th_dport ^ seg->unit.tcp->th_dport)) { in virtio_net_rsc_coalesce6()
2350 chain->stat.no_match++; in virtio_net_rsc_coalesce6()
2365 tcp_flag = htons(tcp->th_offset_flags); in virtio_net_rsc_tcp_ctrl_check()
2369 chain->stat.tcp_syn++; in virtio_net_rsc_tcp_ctrl_check()
2374 chain->stat.tcp_ctrl_drain++; in virtio_net_rsc_tcp_ctrl_check()
2379 chain->stat.tcp_all_opt++; in virtio_net_rsc_tcp_ctrl_check()
2394 if (QTAILQ_EMPTY(&chain->buffers)) { in virtio_net_rsc_do_coalesce()
2395 chain->stat.empty_cache++; in virtio_net_rsc_do_coalesce()
2397 timer_mod(chain->drain_timer, in virtio_net_rsc_do_coalesce()
2398 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + chain->n->rsc_timeout); in virtio_net_rsc_do_coalesce()
2402 QTAILQ_FOREACH_SAFE(seg, &chain->buffers, next, nseg) { in virtio_net_rsc_do_coalesce()
2403 if (chain->proto == ETH_P_IP) { in virtio_net_rsc_do_coalesce()
2412 chain->stat.final_failed++; in virtio_net_rsc_do_coalesce()
2422 seg->is_coalesced = 1; in virtio_net_rsc_do_coalesce()
2427 chain->stat.no_match_cache++; in virtio_net_rsc_do_coalesce()
2443 QTAILQ_FOREACH_SAFE(seg, &chain->buffers, next, nseg) { in virtio_net_rsc_drain_flow()
2444 ppair2 = *(uint32_t *)(seg->buf + tcp_port); in virtio_net_rsc_drain_flow()
2445 if (memcmp(buf + ip_start, seg->buf + ip_start, ip_size) in virtio_net_rsc_drain_flow()
2450 chain->stat.drain_failed++; in virtio_net_rsc_drain_flow()
2466 if (((ip->ip_ver_len & 0xF0) >> 4) != IP_HEADER_VERSION_4) { in virtio_net_rsc_sanity_check4()
2467 chain->stat.ip_option++; in virtio_net_rsc_sanity_check4()
2472 if ((ip->ip_ver_len & 0xF) != VIRTIO_NET_IP4_HEADER_LENGTH) { in virtio_net_rsc_sanity_check4()
2473 chain->stat.ip_option++; in virtio_net_rsc_sanity_check4()
2477 if (ip->ip_p != IPPROTO_TCP) { in virtio_net_rsc_sanity_check4()
2478 chain->stat.bypass_not_tcp++; in virtio_net_rsc_sanity_check4()
2483 if (!(htons(ip->ip_off) & IP_DF)) { in virtio_net_rsc_sanity_check4()
2484 chain->stat.ip_frag++; in virtio_net_rsc_sanity_check4()
2489 if (IPTOS_ECN(ip->ip_tos)) { in virtio_net_rsc_sanity_check4()
2490 chain->stat.ip_ecn++; in virtio_net_rsc_sanity_check4()
2494 ip_len = htons(ip->ip_len); in virtio_net_rsc_sanity_check4()
2496 || ip_len > (size - chain->n->guest_hdr_len - in virtio_net_rsc_sanity_check4()
2498 chain->stat.ip_hacked++; in virtio_net_rsc_sanity_check4()
2513 hdr_len = ((VirtIONet *)(chain->n))->guest_hdr_len; in virtio_net_rsc_receive4()
2517 chain->stat.bypass_not_tcp++; in virtio_net_rsc_receive4()
2546 if (((ip6->ip6_ctlun.ip6_un1.ip6_un1_flow & 0xF0) >> 4) in virtio_net_rsc_sanity_check6()
2552 if (ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) { in virtio_net_rsc_sanity_check6()
2553 chain->stat.bypass_not_tcp++; in virtio_net_rsc_sanity_check6()
2557 ip_len = htons(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen); in virtio_net_rsc_sanity_check6()
2559 ip_len > (size - chain->n->guest_hdr_len - sizeof(struct eth_header) in virtio_net_rsc_sanity_check6()
2560 - sizeof(struct ip6_header))) { in virtio_net_rsc_sanity_check6()
2561 chain->stat.ip_hacked++; in virtio_net_rsc_sanity_check6()
2566 if (IP6_ECN(ip6->ip6_ctlun.ip6_un3.ip6_un3_ecn)) { in virtio_net_rsc_sanity_check6()
2567 chain->stat.ip_ecn++; in virtio_net_rsc_sanity_check6()
2583 hdr_len = ((VirtIONet *)(chain->n))->guest_hdr_len; in virtio_net_rsc_receive6()
2620 QTAILQ_FOREACH(chain, &n->rsc_chains, next) { in virtio_net_rsc_lookup_chain()
2621 if (chain->proto == proto) { in virtio_net_rsc_lookup_chain()
2627 chain->n = n; in virtio_net_rsc_lookup_chain()
2628 chain->proto = proto; in virtio_net_rsc_lookup_chain()
2630 chain->max_payload = VIRTIO_NET_MAX_IP4_PAYLOAD; in virtio_net_rsc_lookup_chain()
2631 chain->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; in virtio_net_rsc_lookup_chain()
2633 chain->max_payload = VIRTIO_NET_MAX_IP6_PAYLOAD; in virtio_net_rsc_lookup_chain()
2634 chain->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; in virtio_net_rsc_lookup_chain()
2636 chain->drain_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, in virtio_net_rsc_lookup_chain()
2638 memset(&chain->stat, 0, sizeof(chain->stat)); in virtio_net_rsc_lookup_chain()
2640 QTAILQ_INIT(&chain->buffers); in virtio_net_rsc_lookup_chain()
2641 QTAILQ_INSERT_TAIL(&n->rsc_chains, chain, next); in virtio_net_rsc_lookup_chain()
2656 if (size < (n->host_hdr_len + sizeof(struct eth_header))) { in virtio_net_rsc_receive()
2660 eth = (struct eth_header *)(buf + n->guest_hdr_len); in virtio_net_rsc_receive()
2661 proto = htons(eth->h_proto); in virtio_net_rsc_receive()
2665 chain->stat.received++; in virtio_net_rsc_receive()
2666 if (proto == (uint16_t)ETH_P_IP && n->rsc4_enabled) { in virtio_net_rsc_receive()
2668 } else if (proto == (uint16_t)ETH_P_IPV6 && n->rsc6_enabled) { in virtio_net_rsc_receive()
2679 if ((n->rsc4_enabled || n->rsc6_enabled)) { in virtio_net_receive()
2695 virtqueue_push(q->tx_vq, q->async_tx.elem, 0); in virtio_net_tx_complete()
2696 virtio_notify(vdev, q->tx_vq); in virtio_net_tx_complete()
2698 g_free(q->async_tx.elem); in virtio_net_tx_complete()
2699 q->async_tx.elem = NULL; in virtio_net_tx_complete()
2701 virtio_queue_set_notification(q->tx_vq, 1); in virtio_net_tx_complete()
2703 if (ret >= n->tx_burst) { in virtio_net_tx_complete()
2707 * remainining part, so re-schedule in virtio_net_tx_complete()
2709 virtio_queue_set_notification(q->tx_vq, 0); in virtio_net_tx_complete()
2710 if (q->tx_bh) { in virtio_net_tx_complete()
2711 replay_bh_schedule_event(q->tx_bh); in virtio_net_tx_complete()
2713 timer_mod(q->tx_timer, in virtio_net_tx_complete()
2714 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); in virtio_net_tx_complete()
2716 q->tx_waiting = 1; in virtio_net_tx_complete()
2723 VirtIONet *n = q->n; in virtio_net_flush_tx()
2727 int queue_index = vq2q(virtio_get_queue_index(q->tx_vq)); in virtio_net_flush_tx()
2728 if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { in virtio_net_flush_tx()
2732 if (q->async_tx.elem) { in virtio_net_flush_tx()
2733 virtio_queue_set_notification(q->tx_vq, 0); in virtio_net_flush_tx()
2743 elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement)); in virtio_net_flush_tx()
2748 out_num = elem->out_num; in virtio_net_flush_tx()
2749 out_sg = elem->out_sg; in virtio_net_flush_tx()
2751 virtio_error(vdev, "virtio-net header not in first element"); in virtio_net_flush_tx()
2755 if (n->needs_vnet_hdr_swap) { in virtio_net_flush_tx()
2758 virtio_error(vdev, "virtio-net header incorrect"); in virtio_net_flush_tx()
2764 out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, out_sg, out_num, in virtio_net_flush_tx()
2765 sizeof(vhdr), -1); in virtio_net_flush_tx()
2777 assert(n->host_hdr_len <= n->guest_hdr_len); in virtio_net_flush_tx()
2778 if (n->host_hdr_len != n->guest_hdr_len) { in virtio_net_flush_tx()
2779 if (iov_size(out_sg, out_num) < n->guest_hdr_len) { in virtio_net_flush_tx()
2780 virtio_error(vdev, "virtio-net header is invalid"); in virtio_net_flush_tx()
2785 0, n->host_hdr_len); in virtio_net_flush_tx()
2786 sg_num += iov_copy(sg + sg_num, ARRAY_SIZE(sg) - sg_num, in virtio_net_flush_tx()
2788 n->guest_hdr_len, -1); in virtio_net_flush_tx()
2793 virtio_error(vdev, "virtio-net nothing to send"); in virtio_net_flush_tx()
2798 ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index), in virtio_net_flush_tx()
2801 virtio_queue_set_notification(q->tx_vq, 0); in virtio_net_flush_tx()
2802 q->async_tx.elem = elem; in virtio_net_flush_tx()
2803 return -EBUSY; in virtio_net_flush_tx()
2807 virtqueue_push(q->tx_vq, elem, 0); in virtio_net_flush_tx()
2808 virtio_notify(vdev, q->tx_vq); in virtio_net_flush_tx()
2811 if (++num_packets >= n->tx_burst) { in virtio_net_flush_tx()
2818 virtqueue_detach_element(q->tx_vq, elem, 0); in virtio_net_flush_tx()
2820 return -EINVAL; in virtio_net_flush_tx()
2828 VirtIONetQueue *q = &n->vqs[vq2q(virtio_get_queue_index(vq))]; in virtio_net_handle_tx_timer()
2830 if (unlikely((n->status & VIRTIO_NET_S_LINK_UP) == 0)) { in virtio_net_handle_tx_timer()
2836 if (!vdev->vm_running) { in virtio_net_handle_tx_timer()
2837 q->tx_waiting = 1; in virtio_net_handle_tx_timer()
2841 if (q->tx_waiting) { in virtio_net_handle_tx_timer()
2843 timer_del(q->tx_timer); in virtio_net_handle_tx_timer()
2846 /* re-arm timer to flush it (and more) on next tick */ in virtio_net_handle_tx_timer()
2847 timer_mod(q->tx_timer, in virtio_net_handle_tx_timer()
2848 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); in virtio_net_handle_tx_timer()
2849 q->tx_waiting = 1; in virtio_net_handle_tx_timer()
2857 VirtIONetQueue *q = &n->vqs[vq2q(virtio_get_queue_index(vq))]; in virtio_net_handle_tx_bh()
2859 if (unlikely(n->vhost_started)) { in virtio_net_handle_tx_bh()
2863 if (unlikely((n->status & VIRTIO_NET_S_LINK_UP) == 0)) { in virtio_net_handle_tx_bh()
2868 if (unlikely(q->tx_waiting)) { in virtio_net_handle_tx_bh()
2871 q->tx_waiting = 1; in virtio_net_handle_tx_bh()
2873 if (!vdev->vm_running) { in virtio_net_handle_tx_bh()
2877 replay_bh_schedule_event(q->tx_bh); in virtio_net_handle_tx_bh()
2883 VirtIONet *n = q->n; in virtio_net_tx_timer()
2888 if (!vdev->vm_running) { in virtio_net_tx_timer()
2890 assert(q->tx_waiting); in virtio_net_tx_timer()
2894 q->tx_waiting = 0; in virtio_net_tx_timer()
2897 if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { in virtio_net_tx_timer()
2902 if (ret == -EBUSY || ret == -EINVAL) { in virtio_net_tx_timer()
2909 if (ret >= n->tx_burst) { in virtio_net_tx_timer()
2910 q->tx_waiting = 1; in virtio_net_tx_timer()
2911 timer_mod(q->tx_timer, in virtio_net_tx_timer()
2912 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); in virtio_net_tx_timer()
2916 * If less than a full burst, re-enable notification and flush in virtio_net_tx_timer()
2920 virtio_queue_set_notification(q->tx_vq, 1); in virtio_net_tx_timer()
2923 virtio_queue_set_notification(q->tx_vq, 0); in virtio_net_tx_timer()
2924 q->tx_waiting = 1; in virtio_net_tx_timer()
2925 timer_mod(q->tx_timer, in virtio_net_tx_timer()
2926 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); in virtio_net_tx_timer()
2933 VirtIONet *n = q->n; in virtio_net_tx_bh()
2938 if (!vdev->vm_running) { in virtio_net_tx_bh()
2940 assert(q->tx_waiting); in virtio_net_tx_bh()
2944 q->tx_waiting = 0; in virtio_net_tx_bh()
2947 if (unlikely(!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))) { in virtio_net_tx_bh()
2952 if (ret == -EBUSY || ret == -EINVAL) { in virtio_net_tx_bh()
2953 return; /* Notification re-enable handled by tx_complete or device in virtio_net_tx_bh()
2959 if (ret >= n->tx_burst) { in virtio_net_tx_bh()
2960 replay_bh_schedule_event(q->tx_bh); in virtio_net_tx_bh()
2961 q->tx_waiting = 1; in virtio_net_tx_bh()
2965 /* If less than a full burst, re-enable notification and flush in virtio_net_tx_bh()
2968 virtio_queue_set_notification(q->tx_vq, 1); in virtio_net_tx_bh()
2970 if (ret == -EINVAL) { in virtio_net_tx_bh()
2973 virtio_queue_set_notification(q->tx_vq, 0); in virtio_net_tx_bh()
2974 replay_bh_schedule_event(q->tx_bh); in virtio_net_tx_bh()
2975 q->tx_waiting = 1; in virtio_net_tx_bh()
2983 n->vqs[index].rx_vq = virtio_add_queue(vdev, n->net_conf.rx_queue_size, in virtio_net_add_queue()
2986 if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) { in virtio_net_add_queue()
2987 n->vqs[index].tx_vq = in virtio_net_add_queue()
2988 virtio_add_queue(vdev, n->net_conf.tx_queue_size, in virtio_net_add_queue()
2990 n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, in virtio_net_add_queue()
2992 &n->vqs[index]); in virtio_net_add_queue()
2994 n->vqs[index].tx_vq = in virtio_net_add_queue()
2995 virtio_add_queue(vdev, n->net_conf.tx_queue_size, in virtio_net_add_queue()
2997 n->vqs[index].tx_bh = qemu_bh_new_guarded(virtio_net_tx_bh, &n->vqs[index], in virtio_net_add_queue()
2998 &DEVICE(vdev)->mem_reentrancy_guard); in virtio_net_add_queue()
3001 n->vqs[index].tx_waiting = 0; in virtio_net_add_queue()
3002 n->vqs[index].n = n; in virtio_net_add_queue()
3008 VirtIONetQueue *q = &n->vqs[index]; in virtio_net_del_queue()
3009 NetClientState *nc = qemu_get_subqueue(n->nic, index); in virtio_net_del_queue()
3014 if (q->tx_timer) { in virtio_net_del_queue()
3015 timer_free(q->tx_timer); in virtio_net_del_queue()
3016 q->tx_timer = NULL; in virtio_net_del_queue()
3018 qemu_bh_delete(q->tx_bh); in virtio_net_del_queue()
3019 q->tx_bh = NULL; in virtio_net_del_queue()
3021 q->tx_waiting = 0; in virtio_net_del_queue()
3044 virtio_del_queue(vdev, old_num_queues - 1); in virtio_net_change_num_queue_pairs()
3046 for (i = new_num_queues - 1; i < old_num_queues - 1; i += 2) { in virtio_net_change_num_queue_pairs()
3051 for (i = old_num_queues - 1; i < new_num_queues - 1; i += 2) { in virtio_net_change_num_queue_pairs()
3057 n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); in virtio_net_change_num_queue_pairs()
3062 int max = multiqueue ? n->max_queue_pairs : 1; in virtio_net_set_multiqueue()
3064 n->multiqueue = multiqueue; in virtio_net_set_multiqueue()
3073 virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_RSS) || in virtio_net_pre_load_queues()
3074 virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MQ)); in virtio_net_pre_load_queues()
3086 virtio_net_set_mrg_rx_bufs(n, n->mergeable_rx_bufs, in virtio_net_post_load_device()
3093 if (n->mac_table.in_use > MAC_TABLE_ENTRIES) { in virtio_net_post_load_device()
3094 n->mac_table.in_use = 0; in virtio_net_post_load_device()
3098 n->curr_guest_offloads = virtio_net_supported_guest_offloads(n); in virtio_net_post_load_device()
3107 n->saved_guest_offloads = n->curr_guest_offloads; in virtio_net_post_load_device()
3112 for (i = 0; i < n->mac_table.in_use; i++) { in virtio_net_post_load_device()
3113 if (n->mac_table.macs[i * ETH_ALEN] & 1) { in virtio_net_post_load_device()
3117 n->mac_table.first_multi = i; in virtio_net_post_load_device()
3120 * to link status bit in n->status */ in virtio_net_post_load_device()
3121 link_down = (n->status & VIRTIO_NET_S_LINK_UP) == 0; in virtio_net_post_load_device()
3122 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_post_load_device()
3123 qemu_get_subqueue(n->nic, i)->link_down = link_down; in virtio_net_post_load_device()
3128 qemu_announce_timer_reset(&n->announce_timer, migrate_announce_params(), in virtio_net_post_load_device()
3131 if (n->announce_timer.round) { in virtio_net_post_load_device()
3132 timer_mod(n->announce_timer.tm, in virtio_net_post_load_device()
3133 qemu_clock_get_ms(n->announce_timer.type)); in virtio_net_post_load_device()
3135 qemu_announce_timer_del(&n->announce_timer, false); in virtio_net_post_load_device()
3151 n->curr_guest_offloads = n->saved_guest_offloads; in virtio_net_post_load_virtio()
3161 .name = "virtio-net-queue-tx_waiting",
3170 return VIRTIO_NET(opaque)->max_queue_pairs > 1; in max_queue_pairs_gt_1()
3181 return VIRTIO_NET(opaque)->mac_table.in_use <= MAC_TABLE_ENTRIES; in mac_table_fits()
3210 tmp->vqs_1 = tmp->parent->vqs + 1; in virtio_net_tx_waiting_pre_save()
3211 tmp->curr_queue_pairs_1 = tmp->parent->curr_queue_pairs - 1; in virtio_net_tx_waiting_pre_save()
3212 if (tmp->parent->curr_queue_pairs == 0) { in virtio_net_tx_waiting_pre_save()
3213 tmp->curr_queue_pairs_1 = 0; in virtio_net_tx_waiting_pre_save()
3226 if (tmp->parent->curr_queue_pairs > tmp->parent->max_queue_pairs) { in virtio_net_tx_waiting_pre_load()
3227 error_report("virtio-net: curr_queue_pairs %x > max_queue_pairs %x", in virtio_net_tx_waiting_pre_load()
3228 tmp->parent->curr_queue_pairs, tmp->parent->max_queue_pairs); in virtio_net_tx_waiting_pre_load()
3230 return -EINVAL; in virtio_net_tx_waiting_pre_load()
3237 .name = "virtio-net-tx_waiting",
3256 if (tmp->has_ufo && !peer_has_ufo(tmp->parent)) { in virtio_net_ufo_post_load()
3257 error_report("virtio-net: saved image requires TUN_F_UFO support"); in virtio_net_ufo_post_load()
3258 return -EINVAL; in virtio_net_ufo_post_load()
3268 tmp->has_ufo = tmp->parent->has_ufo; in virtio_net_ufo_pre_save()
3274 .name = "virtio-net-ufo",
3290 if (tmp->has_vnet_hdr && !peer_has_vnet_hdr(tmp->parent)) { in virtio_net_vnet_post_load()
3291 error_report("virtio-net: saved image requires vnet_hdr=on"); in virtio_net_vnet_post_load()
3292 return -EINVAL; in virtio_net_vnet_post_load()
3302 tmp->has_vnet_hdr = tmp->parent->has_vnet_hdr; in virtio_net_vnet_pre_save()
3308 .name = "virtio-net-vnet",
3319 return VIRTIO_NET(opaque)->rss_data.enabled; in virtio_net_rss_needed()
3323 .name = "virtio-net-device/rss",
3349 if (!n->nic) { in virtio_net_get_vhost()
3353 nc = qemu_get_queue(n->nic); in virtio_net_get_vhost()
3358 net = get_vhost_net(nc->peer); in virtio_net_get_vhost()
3363 return &net->dev; in virtio_net_get_vhost()
3379 "Error getting vhost back-end of %s device %s: ", in vhost_user_net_save_state()
3380 vdev->name, vdev->parent_obj.canonical_path); in vhost_user_net_save_state()
3381 return -1; in vhost_user_net_save_state()
3387 "Error saving back-end state of %s device %s: ", in vhost_user_net_save_state()
3388 vdev->name, vdev->parent_obj.canonical_path); in vhost_user_net_save_state()
3407 "Error getting vhost back-end of %s device %s: ", in vhost_user_net_load_state()
3408 vdev->name, vdev->parent_obj.canonical_path); in vhost_user_net_load_state()
3409 return -1; in vhost_user_net_load_state()
3415 "Error loading back-end state of %s device %s: ", in vhost_user_net_load_state()
3416 vdev->name, vdev->parent_obj.canonical_path); in vhost_user_net_load_state()
3438 .name = "virtio-net-device/backend",
3445 .name = "virtio-net vhost-user backend state",
3455 .name = "virtio-net-device",
3471 * - can happen if source has a larger MAC table.; post-load
3525 assert(n->vhost_started); in virtio_net_guest_notifier_pending()
3526 if (!n->multiqueue && idx == 2) { in virtio_net_guest_notifier_pending()
3536 nc = qemu_get_subqueue(n->nic, n->max_queue_pairs); in virtio_net_guest_notifier_pending()
3538 nc = qemu_get_subqueue(n->nic, vq2q(idx)); in virtio_net_guest_notifier_pending()
3541 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 in virtio_net_guest_notifier_pending()
3547 return vhost_net_config_pending(get_vhost_net(nc->peer)); in virtio_net_guest_notifier_pending()
3549 return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); in virtio_net_guest_notifier_pending()
3557 assert(n->vhost_started); in virtio_net_guest_notifier_mask()
3558 if (!n->multiqueue && idx == 2) { in virtio_net_guest_notifier_mask()
3568 nc = qemu_get_subqueue(n->nic, n->max_queue_pairs); in virtio_net_guest_notifier_mask()
3570 nc = qemu_get_subqueue(n->nic, vq2q(idx)); in virtio_net_guest_notifier_mask()
3573 *Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 in virtio_net_guest_notifier_mask()
3579 vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask); in virtio_net_guest_notifier_mask()
3582 vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask); in virtio_net_guest_notifier_mask()
3589 n->config_size = virtio_get_config_size(&cfg_size_params, host_features); in virtio_net_set_config_size()
3600 g_free(n->netclient_name); in virtio_net_set_netclient_name()
3601 g_free(n->netclient_type); in virtio_net_set_netclient_name()
3602 n->netclient_name = g_strdup(name); in virtio_net_set_netclient_name()
3603 n->netclient_type = g_strdup(type); in virtio_net_set_netclient_name()
3615 pci_dev->partially_hotplugged = true; in failover_unplug_primary()
3635 if (!pdev->partially_hotplugged) { in failover_replug_primary()
3638 primary_bus = dev->parent_bus; in failover_replug_primary()
3644 qatomic_set(&n->failover_primary_hidden, false); in failover_replug_primary()
3653 pdev->partially_hotplugged = false; in failover_replug_primary()
3670 should_be_hidden = qatomic_read(&n->failover_primary_hidden); in virtio_net_handle_migration_primary()
3672 if (e->type == MIG_EVENT_PRECOPY_SETUP && !should_be_hidden) { in virtio_net_handle_migration_primary()
3675 qapi_event_send_unplug_primary(dev->id); in virtio_net_handle_migration_primary()
3676 qatomic_set(&n->failover_primary_hidden, true); in virtio_net_handle_migration_primary()
3680 } else if (e->type == MIG_EVENT_PRECOPY_FAILED) { in virtio_net_handle_migration_primary()
3720 if (g_strcmp0(standby_id, n->netclient_name) != 0) { in failover_hide_primary_device()
3726 * Check there is only one primary for a virtio-net device but in failover_hide_primary_device()
3730 if (n->primary_opts) { in failover_hide_primary_device()
3733 old = qdict_get_str(n->primary_opts, "id"); in failover_hide_primary_device()
3737 "'%s': '%s' and '%s'", n->netclient_name, old, new); in failover_hide_primary_device()
3741 n->primary_opts = qdict_clone_shallow(device_opts); in failover_hide_primary_device()
3742 n->primary_opts_from_json = from_json; in failover_hide_primary_device()
3746 return qatomic_read(&n->failover_primary_hidden); in failover_hide_primary_device()
3756 if (n->net_conf.mtu) { in virtio_net_device_realize()
3757 n->host_features |= (1ULL << VIRTIO_NET_F_MTU); in virtio_net_device_realize()
3760 if (n->net_conf.duplex_str) { in virtio_net_device_realize()
3761 if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) { in virtio_net_device_realize()
3762 n->net_conf.duplex = DUPLEX_HALF; in virtio_net_device_realize()
3763 } else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) { in virtio_net_device_realize()
3764 n->net_conf.duplex = DUPLEX_FULL; in virtio_net_device_realize()
3769 n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX); in virtio_net_device_realize()
3771 n->net_conf.duplex = DUPLEX_UNKNOWN; in virtio_net_device_realize()
3774 if (n->net_conf.speed < SPEED_UNKNOWN) { in virtio_net_device_realize()
3778 if (n->net_conf.speed >= 0) { in virtio_net_device_realize()
3779 n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX); in virtio_net_device_realize()
3782 if (n->failover) { in virtio_net_device_realize()
3783 n->primary_listener.hide_device = failover_hide_primary_device; in virtio_net_device_realize()
3784 qatomic_set(&n->failover_primary_hidden, true); in virtio_net_device_realize()
3785 device_listener_register(&n->primary_listener); in virtio_net_device_realize()
3786 migration_add_notifier(&n->migration_state, in virtio_net_device_realize()
3788 n->host_features |= (1ULL << VIRTIO_NET_F_STANDBY); in virtio_net_device_realize()
3791 virtio_net_set_config_size(n, n->host_features); in virtio_net_device_realize()
3792 virtio_init(vdev, VIRTIO_ID_NET, n->config_size); in virtio_net_device_realize()
3799 if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE || in virtio_net_device_realize()
3800 n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE || in virtio_net_device_realize()
3801 !is_power_of_2(n->net_conf.rx_queue_size)) { in virtio_net_device_realize()
3804 n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE, in virtio_net_device_realize()
3810 if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE || in virtio_net_device_realize()
3811 n->net_conf.tx_queue_size > virtio_net_max_tx_queue_size(n) || in virtio_net_device_realize()
3812 !is_power_of_2(n->net_conf.tx_queue_size)) { in virtio_net_device_realize()
3815 n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE, in virtio_net_device_realize()
3821 n->max_ncs = MAX(n->nic_conf.peers.queues, 1); in virtio_net_device_realize()
3827 if (n->nic_conf.peers.queues) { in virtio_net_device_realize()
3828 for (i = 0; i < n->max_ncs; i++) { in virtio_net_device_realize()
3829 if (n->nic_conf.peers.ncs[i]->is_datapath) { in virtio_net_device_realize()
3830 ++n->max_queue_pairs; in virtio_net_device_realize()
3834 n->max_queue_pairs = MAX(n->max_queue_pairs, 1); in virtio_net_device_realize()
3836 if (n->max_queue_pairs * 2 + 1 > VIRTIO_QUEUE_MAX) { in virtio_net_device_realize()
3839 n->max_queue_pairs, (VIRTIO_QUEUE_MAX - 1) / 2); in virtio_net_device_realize()
3843 n->vqs = g_new0(VirtIONetQueue, n->max_queue_pairs); in virtio_net_device_realize()
3844 n->curr_queue_pairs = 1; in virtio_net_device_realize()
3845 n->tx_timeout = n->net_conf.txtimer; in virtio_net_device_realize()
3847 if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer") in virtio_net_device_realize()
3848 && strcmp(n->net_conf.tx, "bh")) { in virtio_net_device_realize()
3849 warn_report("virtio-net: " in virtio_net_device_realize()
3851 n->net_conf.tx); in virtio_net_device_realize()
3855 n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n), in virtio_net_device_realize()
3856 n->net_conf.tx_queue_size); in virtio_net_device_realize()
3860 n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); in virtio_net_device_realize()
3861 qemu_macaddr_default_if_unset(&n->nic_conf.macaddr); in virtio_net_device_realize()
3862 memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac)); in virtio_net_device_realize()
3863 n->status = VIRTIO_NET_S_LINK_UP; in virtio_net_device_realize()
3864 qemu_announce_timer_reset(&n->announce_timer, migrate_announce_params(), in virtio_net_device_realize()
3867 n->announce_timer.round = 0; in virtio_net_device_realize()
3869 if (n->netclient_type) { in virtio_net_device_realize()
3873 n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, in virtio_net_device_realize()
3874 n->netclient_type, n->netclient_name, in virtio_net_device_realize()
3875 &dev->mem_reentrancy_guard, n); in virtio_net_device_realize()
3877 n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf, in virtio_net_device_realize()
3878 object_get_typename(OBJECT(dev)), dev->id, in virtio_net_device_realize()
3879 &dev->mem_reentrancy_guard, n); in virtio_net_device_realize()
3882 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_device_realize()
3883 n->nic->ncs[i].do_not_pad = true; in virtio_net_device_realize()
3888 n->host_hdr_len = sizeof(struct virtio_net_hdr); in virtio_net_device_realize()
3890 n->host_hdr_len = 0; in virtio_net_device_realize()
3893 qemu_format_nic_info_str(qemu_get_queue(n->nic), n->nic_conf.macaddr.a); in virtio_net_device_realize()
3895 n->vqs[0].tx_waiting = 0; in virtio_net_device_realize()
3896 n->tx_burst = n->net_conf.txburst; in virtio_net_device_realize()
3898 n->promisc = 1; /* for compatibility */ in virtio_net_device_realize()
3900 n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN); in virtio_net_device_realize()
3902 n->vlans = g_malloc0(MAX_VLAN >> 3); in virtio_net_device_realize()
3904 nc = qemu_get_queue(n->nic); in virtio_net_device_realize()
3905 nc->rxfilter_notify_enabled = 1; in virtio_net_device_realize()
3907 if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { in virtio_net_device_realize()
3909 memcpy(&netcfg.mac, &n->nic_conf.macaddr, ETH_ALEN); in virtio_net_device_realize()
3910 vhost_net_set_config(get_vhost_net(nc->peer), in virtio_net_device_realize()
3913 QTAILQ_INIT(&n->rsc_chains); in virtio_net_device_realize()
3914 n->qdev = dev; in virtio_net_device_realize()
3916 net_rx_pkt_init(&n->rx_pkt); in virtio_net_device_realize()
3918 if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) { in virtio_net_device_realize()
3929 if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) { in virtio_net_device_unrealize()
3933 /* This will stop vhost backend if appropriate. */ in virtio_net_device_unrealize()
3936 g_free(n->netclient_name); in virtio_net_device_unrealize()
3937 n->netclient_name = NULL; in virtio_net_device_unrealize()
3938 g_free(n->netclient_type); in virtio_net_device_unrealize()
3939 n->netclient_type = NULL; in virtio_net_device_unrealize()
3941 g_free(n->mac_table.macs); in virtio_net_device_unrealize()
3942 g_free(n->vlans); in virtio_net_device_unrealize()
3944 if (n->failover) { in virtio_net_device_unrealize()
3945 qobject_unref(n->primary_opts); in virtio_net_device_unrealize()
3946 device_listener_unregister(&n->primary_listener); in virtio_net_device_unrealize()
3947 migration_remove_notifier(&n->migration_state); in virtio_net_device_unrealize()
3949 assert(n->primary_opts == NULL); in virtio_net_device_unrealize()
3952 max_queue_pairs = n->multiqueue ? n->max_queue_pairs : 1; in virtio_net_device_unrealize()
3958 qemu_announce_timer_del(&n->announce_timer, false); in virtio_net_device_unrealize()
3959 g_free(n->vqs); in virtio_net_device_unrealize()
3960 qemu_del_nic(n->nic); in virtio_net_device_unrealize()
3962 g_free(n->rss_data.indirections_table); in virtio_net_device_unrealize()
3963 net_rx_pkt_uninit(n->rx_pkt); in virtio_net_device_unrealize()
3973 n->promisc = 1; in virtio_net_reset()
3974 n->allmulti = 0; in virtio_net_reset()
3975 n->alluni = 0; in virtio_net_reset()
3976 n->nomulti = 0; in virtio_net_reset()
3977 n->nouni = 0; in virtio_net_reset()
3978 n->nobcast = 0; in virtio_net_reset()
3980 n->curr_queue_pairs = 1; in virtio_net_reset()
3981 timer_del(n->announce_timer.tm); in virtio_net_reset()
3982 n->announce_timer.round = 0; in virtio_net_reset()
3983 n->status &= ~VIRTIO_NET_S_ANNOUNCE; in virtio_net_reset()
3986 n->mac_table.in_use = 0; in virtio_net_reset()
3987 n->mac_table.first_multi = 0; in virtio_net_reset()
3988 n->mac_table.multi_overflow = 0; in virtio_net_reset()
3989 n->mac_table.uni_overflow = 0; in virtio_net_reset()
3990 memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN); in virtio_net_reset()
3991 memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac)); in virtio_net_reset()
3992 qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac); in virtio_net_reset()
3993 memset(n->vlans, 0, MAX_VLAN >> 3); in virtio_net_reset()
3996 for (i = 0; i < n->max_queue_pairs; i++) { in virtio_net_reset()
3997 flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i)); in virtio_net_reset()
4011 n->config_size = sizeof(struct virtio_net_config); in virtio_net_instance_init()
4012 device_add_bootindex_property(obj, &n->nic_conf.bootindex, in virtio_net_instance_init()
4013 "bootindex", "/ethernet-phy@0", in virtio_net_instance_init()
4016 ebpf_rss_init(&n->ebpf_rss); in virtio_net_instance_init()
4025 assert(!n->vhost_started); in virtio_net_pre_save()
4041 return primary ? primary->pending_deleted_event : false; in primary_unplug_pending()
4049 return vdc->primary_unplug_pending(dev); in dev_unplug_pending()
4053 .name = "virtio-net",
4109 DEFINE_PROP_ARRAY("ebpf-rss-fds", VirtIONet, nr_ebpf_rss_fds,
4116 DEFINE_PROP_UINT32("x-txtimer", VirtIONet, net_conf.txtimer,
4118 DEFINE_PROP_INT32("x-txburst", VirtIONet, net_conf.txburst, TX_BURST),
4125 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
4144 dc->vmsd = &vmstate_virtio_net; in virtio_net_class_init()
4145 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); in virtio_net_class_init()
4146 vdc->realize = virtio_net_device_realize; in virtio_net_class_init()
4147 vdc->unrealize = virtio_net_device_unrealize; in virtio_net_class_init()
4148 vdc->get_config = virtio_net_get_config; in virtio_net_class_init()
4149 vdc->set_config = virtio_net_set_config; in virtio_net_class_init()
4150 vdc->get_features = virtio_net_get_features; in virtio_net_class_init()
4151 vdc->set_features = virtio_net_set_features; in virtio_net_class_init()
4152 vdc->bad_features = virtio_net_bad_features; in virtio_net_class_init()
4153 vdc->reset = virtio_net_reset; in virtio_net_class_init()
4154 vdc->queue_reset = virtio_net_queue_reset; in virtio_net_class_init()
4155 vdc->queue_enable = virtio_net_queue_enable; in virtio_net_class_init()
4156 vdc->set_status = virtio_net_set_status; in virtio_net_class_init()
4157 vdc->guest_notifier_mask = virtio_net_guest_notifier_mask; in virtio_net_class_init()
4158 vdc->guest_notifier_pending = virtio_net_guest_notifier_pending; in virtio_net_class_init()
4159 vdc->legacy_features |= (0x1 << VIRTIO_NET_F_GSO); in virtio_net_class_init()
4160 vdc->pre_load_queues = virtio_net_pre_load_queues; in virtio_net_class_init()
4161 vdc->post_load = virtio_net_post_load_virtio; in virtio_net_class_init()
4162 vdc->vmsd = &vmstate_virtio_net_device; in virtio_net_class_init()
4163 vdc->primary_unplug_pending = primary_unplug_pending; in virtio_net_class_init()
4164 vdc->get_vhost = virtio_net_get_vhost; in virtio_net_class_init()
4165 vdc->toggle_device_iotlb = vhost_toggle_device_iotlb; in virtio_net_class_init()