10d09e41aSPaolo Bonzini /* 20d09e41aSPaolo Bonzini * Virtio Network Device 30d09e41aSPaolo Bonzini * 40d09e41aSPaolo Bonzini * Copyright IBM, Corp. 2007 50d09e41aSPaolo Bonzini * 60d09e41aSPaolo Bonzini * Authors: 70d09e41aSPaolo Bonzini * Anthony Liguori <aliguori@us.ibm.com> 80d09e41aSPaolo Bonzini * 90d09e41aSPaolo Bonzini * This work is licensed under the terms of the GNU GPL, version 2. See 100d09e41aSPaolo Bonzini * the COPYING file in the top-level directory. 110d09e41aSPaolo Bonzini * 120d09e41aSPaolo Bonzini */ 130d09e41aSPaolo Bonzini 142a6a4076SMarkus Armbruster #ifndef QEMU_VIRTIO_NET_H 152a6a4076SMarkus Armbruster #define QEMU_VIRTIO_NET_H 160d09e41aSPaolo Bonzini 17c9ad15d7SPhilippe Mathieu-Daudé #include "qemu/units.h" 18b93a5ba3SMichael S. Tsirkin #include "standard-headers/linux/virtio_net.h" 190d09e41aSPaolo Bonzini #include "hw/virtio/virtio.h" 209d8c6a25SDr. David Alan Gilbert #include "net/announce.h" 219711cd0dSJens Freimann #include "qemu/option_int.h" 22db1015e9SEduardo Habkost #include "qom/object.h" 230d09e41aSPaolo Bonzini 240145c393SAndrew Melnychenko #include "ebpf/ebpf_rss.h" 250145c393SAndrew Melnychenko 2617ec5a86SKONRAD Frederic #define TYPE_VIRTIO_NET "virtio-net-device" 278063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(VirtIONet, VIRTIO_NET) 2817ec5a86SKONRAD Frederic 290d09e41aSPaolo Bonzini #define TX_TIMER_INTERVAL 150000 /* 150 us */ 300d09e41aSPaolo Bonzini 310d09e41aSPaolo Bonzini /* Limit the number of packets that can be sent via a single flush 320d09e41aSPaolo Bonzini * of the TX queue. This gives us a guaranteed exit condition and 330d09e41aSPaolo Bonzini * ensures fairness in the io path. 256 conveniently matches the 340d09e41aSPaolo Bonzini * length of the TX queue and shows a good balance of performance 350d09e41aSPaolo Bonzini * and latency. */ 360d09e41aSPaolo Bonzini #define TX_BURST 256 370d09e41aSPaolo Bonzini 386758c01fSEugenio Pérez /* Maximum VIRTIO_NET_CTRL_MAC_TABLE_SET unicast + multicast entries. */ 396758c01fSEugenio Pérez #define MAC_TABLE_ENTRIES 64 406758c01fSEugenio Pérez 41e19751a3SHawkins Jiawei /* 42e19751a3SHawkins Jiawei * The maximum number of VLANs in the VLAN filter table 43e19751a3SHawkins Jiawei * added by VIRTIO_NET_CTRL_VLAN_ADD 44e19751a3SHawkins Jiawei */ 45e19751a3SHawkins Jiawei #define MAX_VLAN (1 << 12) /* Per 802.1Q definition */ 46e19751a3SHawkins Jiawei 470d09e41aSPaolo Bonzini typedef struct virtio_net_conf 480d09e41aSPaolo Bonzini { 490d09e41aSPaolo Bonzini uint32_t txtimer; 500d09e41aSPaolo Bonzini int32_t txburst; 510d09e41aSPaolo Bonzini char *tx; 521c0fbfa3SMichael S. Tsirkin uint16_t rx_queue_size; 539b02e161SWei Wang uint16_t tx_queue_size; 54a93e599dSMaxime Coquelin uint16_t mtu; 559473939eSJason Baron int32_t speed; 569473939eSJason Baron char *duplex_str; 579473939eSJason Baron uint8_t duplex; 589711cd0dSJens Freimann char *primary_id_str; 590d09e41aSPaolo Bonzini } virtio_net_conf; 600d09e41aSPaolo Bonzini 612974e916SYuri Benditovich /* Coalesced packets type & status */ 622974e916SYuri Benditovich typedef enum { 632974e916SYuri Benditovich RSC_COALESCE, /* Data been coalesced */ 642974e916SYuri Benditovich RSC_FINAL, /* Will terminate current connection */ 652974e916SYuri Benditovich RSC_NO_MATCH, /* No matched in the buffer pool */ 662974e916SYuri Benditovich RSC_BYPASS, /* Packet to be bypass, not tcp, tcp ctrl, etc */ 672974e916SYuri Benditovich RSC_CANDIDATE /* Data want to be coalesced */ 682974e916SYuri Benditovich } CoalesceStatus; 692974e916SYuri Benditovich 702974e916SYuri Benditovich typedef struct VirtioNetRscStat { 712974e916SYuri Benditovich uint32_t received; 722974e916SYuri Benditovich uint32_t coalesced; 732974e916SYuri Benditovich uint32_t over_size; 742974e916SYuri Benditovich uint32_t cache; 752974e916SYuri Benditovich uint32_t empty_cache; 762974e916SYuri Benditovich uint32_t no_match_cache; 772974e916SYuri Benditovich uint32_t win_update; 782974e916SYuri Benditovich uint32_t no_match; 792974e916SYuri Benditovich uint32_t tcp_syn; 802974e916SYuri Benditovich uint32_t tcp_ctrl_drain; 812974e916SYuri Benditovich uint32_t dup_ack; 822974e916SYuri Benditovich uint32_t dup_ack1; 832974e916SYuri Benditovich uint32_t dup_ack2; 842974e916SYuri Benditovich uint32_t pure_ack; 852974e916SYuri Benditovich uint32_t ack_out_of_win; 862974e916SYuri Benditovich uint32_t data_out_of_win; 872974e916SYuri Benditovich uint32_t data_out_of_order; 882974e916SYuri Benditovich uint32_t data_after_pure_ack; 892974e916SYuri Benditovich uint32_t bypass_not_tcp; 902974e916SYuri Benditovich uint32_t tcp_option; 912974e916SYuri Benditovich uint32_t tcp_all_opt; 922974e916SYuri Benditovich uint32_t ip_frag; 932974e916SYuri Benditovich uint32_t ip_ecn; 942974e916SYuri Benditovich uint32_t ip_hacked; 952974e916SYuri Benditovich uint32_t ip_option; 962974e916SYuri Benditovich uint32_t purge_failed; 972974e916SYuri Benditovich uint32_t drain_failed; 982974e916SYuri Benditovich uint32_t final_failed; 992974e916SYuri Benditovich int64_t timer; 1002974e916SYuri Benditovich } VirtioNetRscStat; 1012974e916SYuri Benditovich 1022974e916SYuri Benditovich /* Rsc unit general info used to checking if can coalescing */ 1032974e916SYuri Benditovich typedef struct VirtioNetRscUnit { 1042974e916SYuri Benditovich void *ip; /* ip header */ 105*5814c084SPeter Maydell void *ip_plen; /* pointer to unaligned uint16_t data len in ip header */ 1062974e916SYuri Benditovich struct tcp_header *tcp; /* tcp header */ 1072974e916SYuri Benditovich uint16_t tcp_hdrlen; /* tcp header len */ 1082974e916SYuri Benditovich uint16_t payload; /* pure payload without virtio/eth/ip/tcp */ 1092974e916SYuri Benditovich } VirtioNetRscUnit; 1102974e916SYuri Benditovich 111fbf7b20bSPhilippe Mathieu-Daudé /* Coalesced segment */ 1122974e916SYuri Benditovich typedef struct VirtioNetRscSeg { 1132974e916SYuri Benditovich QTAILQ_ENTRY(VirtioNetRscSeg) next; 1142974e916SYuri Benditovich void *buf; 1152974e916SYuri Benditovich size_t size; 1162974e916SYuri Benditovich uint16_t packets; 1172974e916SYuri Benditovich uint16_t dup_ack; 118a1a62cedSMichael Tokarev bool is_coalesced; /* need recall ipv4 header checksum, mark here */ 1192974e916SYuri Benditovich VirtioNetRscUnit unit; 1202974e916SYuri Benditovich NetClientState *nc; 1212974e916SYuri Benditovich } VirtioNetRscSeg; 1222974e916SYuri Benditovich 1232974e916SYuri Benditovich 1242974e916SYuri Benditovich /* Chain is divided by protocol(ipv4/v6) and NetClientInfo */ 1252974e916SYuri Benditovich typedef struct VirtioNetRscChain { 1262974e916SYuri Benditovich QTAILQ_ENTRY(VirtioNetRscChain) next; 1272974e916SYuri Benditovich VirtIONet *n; /* VirtIONet */ 1282974e916SYuri Benditovich uint16_t proto; 1292974e916SYuri Benditovich uint8_t gso_type; 1302974e916SYuri Benditovich uint16_t max_payload; 1312974e916SYuri Benditovich QEMUTimer *drain_timer; 1322974e916SYuri Benditovich QTAILQ_HEAD(, VirtioNetRscSeg) buffers; 1332974e916SYuri Benditovich VirtioNetRscStat stat; 1342974e916SYuri Benditovich } VirtioNetRscChain; 1352974e916SYuri Benditovich 1360d09e41aSPaolo Bonzini /* Maximum packet size we can receive from tap device: header + 64k */ 137c9ad15d7SPhilippe Mathieu-Daudé #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 * KiB)) 1380d09e41aSPaolo Bonzini 13959079029SYuri Benditovich #define VIRTIO_NET_RSS_MAX_KEY_SIZE 40 14059079029SYuri Benditovich #define VIRTIO_NET_RSS_MAX_TABLE_LEN 128 14159079029SYuri Benditovich 14259079029SYuri Benditovich typedef struct VirtioNetRssData { 14359079029SYuri Benditovich bool enabled; 1440145c393SAndrew Melnychenko bool enabled_software_rss; 145e22f0603SYuri Benditovich bool redirect; 146e22f0603SYuri Benditovich bool populate_hash; 14759079029SYuri Benditovich uint32_t hash_types; 14859079029SYuri Benditovich uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE]; 14959079029SYuri Benditovich uint16_t indirections_len; 15059079029SYuri Benditovich uint16_t *indirections_table; 15159079029SYuri Benditovich uint16_t default_queue; 15259079029SYuri Benditovich } VirtioNetRssData; 15359079029SYuri Benditovich 1540d09e41aSPaolo Bonzini typedef struct VirtIONetQueue { 1550d09e41aSPaolo Bonzini VirtQueue *rx_vq; 1560d09e41aSPaolo Bonzini VirtQueue *tx_vq; 1570d09e41aSPaolo Bonzini QEMUTimer *tx_timer; 1580d09e41aSPaolo Bonzini QEMUBH *tx_bh; 159982b78c5SDr. David Alan Gilbert uint32_t tx_waiting; 1600d09e41aSPaolo Bonzini struct { 16151b19ebeSPaolo Bonzini VirtQueueElement *elem; 1620d09e41aSPaolo Bonzini } async_tx; 1630d09e41aSPaolo Bonzini struct VirtIONet *n; 1640d09e41aSPaolo Bonzini } VirtIONetQueue; 1650d09e41aSPaolo Bonzini 166b0b36c02SPhilippe Mathieu-Daudé struct VirtIONet { 16717a0ca55SKONRAD Frederic VirtIODevice parent_obj; 1680d09e41aSPaolo Bonzini uint8_t mac[ETH_ALEN]; 1690d09e41aSPaolo Bonzini uint16_t status; 1700d09e41aSPaolo Bonzini VirtIONetQueue *vqs; 1710d09e41aSPaolo Bonzini VirtQueue *ctrl_vq; 1720d09e41aSPaolo Bonzini NICState *nic; 1732974e916SYuri Benditovich /* RSC Chains - temporary storage of coalesced data, 1742974e916SYuri Benditovich all these data are lost in case of migration */ 1752974e916SYuri Benditovich QTAILQ_HEAD(, VirtioNetRscChain) rsc_chains; 1760d09e41aSPaolo Bonzini uint32_t tx_timeout; 1770d09e41aSPaolo Bonzini int32_t tx_burst; 1780d09e41aSPaolo Bonzini uint32_t has_vnet_hdr; 1790d09e41aSPaolo Bonzini size_t host_hdr_len; 1800d09e41aSPaolo Bonzini size_t guest_hdr_len; 181127833eeSJason Baron uint64_t host_features; 1822974e916SYuri Benditovich uint32_t rsc_timeout; 1832974e916SYuri Benditovich uint8_t rsc4_enabled; 1842974e916SYuri Benditovich uint8_t rsc6_enabled; 1850d09e41aSPaolo Bonzini uint8_t has_ufo; 186982b78c5SDr. David Alan Gilbert uint32_t mergeable_rx_bufs; 1870d09e41aSPaolo Bonzini uint8_t promisc; 1880d09e41aSPaolo Bonzini uint8_t allmulti; 1890d09e41aSPaolo Bonzini uint8_t alluni; 1900d09e41aSPaolo Bonzini uint8_t nomulti; 1910d09e41aSPaolo Bonzini uint8_t nouni; 1920d09e41aSPaolo Bonzini uint8_t nobcast; 1930d09e41aSPaolo Bonzini uint8_t vhost_started; 1940d09e41aSPaolo Bonzini struct { 19571f7fe48SMichael S. Tsirkin uint32_t in_use; 19671f7fe48SMichael S. Tsirkin uint32_t first_multi; 1970d09e41aSPaolo Bonzini uint8_t multi_overflow; 1980d09e41aSPaolo Bonzini uint8_t uni_overflow; 1990d09e41aSPaolo Bonzini uint8_t *macs; 2000d09e41aSPaolo Bonzini } mac_table; 2010d09e41aSPaolo Bonzini uint32_t *vlans; 20217ec5a86SKONRAD Frederic virtio_net_conf net_conf; 20317ec5a86SKONRAD Frederic NICConf nic_conf; 2040d09e41aSPaolo Bonzini DeviceState *qdev; 2050d09e41aSPaolo Bonzini int multiqueue; 206441537f1SJason Wang uint16_t max_queue_pairs; 207441537f1SJason Wang uint16_t curr_queue_pairs; 20822288fe5SJason Wang uint16_t max_ncs; 2090d09e41aSPaolo Bonzini size_t config_size; 2108a253ec2SKONRAD Frederic char *netclient_name; 2118a253ec2SKONRAD Frederic char *netclient_type; 212644c9858SDmitry Fleytman uint64_t curr_guest_offloads; 2137788c3f2SMikhail Sennikovsky /* used on saved state restore phase to preserve the curr_guest_offloads */ 2147788c3f2SMikhail Sennikovsky uint64_t saved_guest_offloads; 2159d8c6a25SDr. David Alan Gilbert AnnounceTimer announce_timer; 2161bfa316cSGreg Kurz bool needs_vnet_hdr_swap; 21775ebec11SMaxime Coquelin bool mtu_bypass_backend; 218e2bde83eSJuan Quintela /* primary failover device is hidden*/ 219e2bde83eSJuan Quintela bool failover_primary_hidden; 2209711cd0dSJens Freimann bool failover; 2219711cd0dSJens Freimann DeviceListener primary_listener; 222f3558b1bSKevin Wolf QDict *primary_opts; 223f3558b1bSKevin Wolf bool primary_opts_from_json; 2243e775730SSteve Sistare NotifierWithReturn migration_state; 22559079029SYuri Benditovich VirtioNetRssData rss_data; 2264474e37aSYuri Benditovich struct NetRxPkt *rx_pkt; 2270145c393SAndrew Melnychenko struct EBPFRSSContext ebpf_rss; 2286b230b7dSAndrew Melnychenko uint32_t nr_ebpf_rss_fds; 2296b230b7dSAndrew Melnychenko char **ebpf_rss_fds; 230b0b36c02SPhilippe Mathieu-Daudé }; 2310d09e41aSPaolo Bonzini 232640b8a1cSEugenio Pérez size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev, 233640b8a1cSEugenio Pérez const struct iovec *in_sg, unsigned in_num, 234640b8a1cSEugenio Pérez const struct iovec *out_sg, 235640b8a1cSEugenio Pérez unsigned out_num); 2368a253ec2SKONRAD Frederic void virtio_net_set_netclient_name(VirtIONet *n, const char *name, 2378a253ec2SKONRAD Frederic const char *type); 2380b545b1eSHawkins Jiawei uint64_t virtio_net_supported_guest_offloads(const VirtIONet *n); 23917ec5a86SKONRAD Frederic 2400d09e41aSPaolo Bonzini #endif 241