@@ -1702,44 +1702,41 @@ static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr)
1702
1702
* cache.
1703
1703
*/
1704
1704
static void work_around_broken_dhclient (struct virtio_net_hdr * hdr ,
1705
- size_t * hdr_len , const uint8_t * buf ,
1706
- size_t buf_size , size_t * buf_offset )
1705
+ uint8_t * buf , size_t size )
1707
1706
{
1708
1707
size_t csum_size = ETH_HLEN + sizeof (struct ip_header ) +
1709
1708
sizeof (struct udp_header );
1710
1709
1711
- buf += * buf_offset ;
1712
- buf_size -= * buf_offset ;
1713
-
1714
1710
if ((hdr -> flags & VIRTIO_NET_HDR_F_NEEDS_CSUM ) && /* missing csum */
1715
- (buf_size >= csum_size && buf_size < 1500 ) && /* normal sized MTU */
1711
+ (size >= csum_size && size < 1500 ) && /* normal sized MTU */
1716
1712
(buf [12 ] == 0x08 && buf [13 ] == 0x00 ) && /* ethertype == IPv4 */
1717
1713
(buf [23 ] == 17 ) && /* ip.protocol == UDP */
1718
1714
(buf [34 ] == 0 && buf [35 ] == 67 )) { /* udp.srcport == bootps */
1719
- memcpy ((uint8_t * )hdr + * hdr_len , buf , csum_size );
1720
- net_checksum_calculate ((uint8_t * )hdr + * hdr_len , csum_size , CSUM_UDP );
1715
+ net_checksum_calculate (buf , size , CSUM_UDP );
1721
1716
hdr -> flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM ;
1722
- * hdr_len += csum_size ;
1723
- * buf_offset += csum_size ;
1724
1717
}
1725
1718
}
1726
1719
1727
- static size_t receive_header (VirtIONet * n , struct virtio_net_hdr * hdr ,
1728
- const void * buf , size_t buf_size ,
1729
- size_t * buf_offset )
1720
+ static void receive_header (VirtIONet * n , const struct iovec * iov , int iov_cnt ,
1721
+ const void * buf , size_t size )
1730
1722
{
1731
- size_t hdr_len = n -> guest_hdr_len ;
1732
-
1733
- memcpy (hdr , buf , sizeof (struct virtio_net_hdr ));
1734
-
1735
- * buf_offset = n -> host_hdr_len ;
1736
- work_around_broken_dhclient (hdr , & hdr_len , buf , buf_size , buf_offset );
1723
+ if (n -> has_vnet_hdr ) {
1724
+ /* FIXME this cast is evil */
1725
+ void * wbuf = (void * )buf ;
1726
+ work_around_broken_dhclient (wbuf , wbuf + n -> host_hdr_len ,
1727
+ size - n -> host_hdr_len );
1737
1728
1738
- if (n -> needs_vnet_hdr_swap ) {
1739
- virtio_net_hdr_swap (VIRTIO_DEVICE (n ), hdr );
1729
+ if (n -> needs_vnet_hdr_swap ) {
1730
+ virtio_net_hdr_swap (VIRTIO_DEVICE (n ), wbuf );
1731
+ }
1732
+ iov_from_buf (iov , iov_cnt , 0 , buf , sizeof (struct virtio_net_hdr ));
1733
+ } else {
1734
+ struct virtio_net_hdr hdr = {
1735
+ .flags = 0 ,
1736
+ .gso_type = VIRTIO_NET_HDR_GSO_NONE
1737
+ };
1738
+ iov_from_buf (iov , iov_cnt , 0 , & hdr , sizeof hdr );
1740
1739
}
1741
-
1742
- return hdr_len ;
1743
1740
}
1744
1741
1745
1742
static int receive_filter (VirtIONet * n , const uint8_t * buf , int size )
@@ -1907,13 +1904,6 @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
1907
1904
return (index == new_index ) ? -1 : new_index ;
1908
1905
}
1909
1906
1910
- typedef struct Header {
1911
- struct virtio_net_hdr_v1_hash virtio_net ;
1912
- struct eth_header eth ;
1913
- struct ip_header ip ;
1914
- struct udp_header udp ;
1915
- } Header ;
1916
-
1917
1907
static ssize_t virtio_net_receive_rcu (NetClientState * nc , const uint8_t * buf ,
1918
1908
size_t size )
1919
1909
{
@@ -1923,15 +1913,15 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
1923
1913
VirtQueueElement * elems [VIRTQUEUE_MAX_SIZE ];
1924
1914
size_t lens [VIRTQUEUE_MAX_SIZE ];
1925
1915
struct iovec mhdr_sg [VIRTQUEUE_MAX_SIZE ];
1926
- Header hdr ;
1916
+ struct virtio_net_hdr_v1_hash extra_hdr ;
1927
1917
unsigned mhdr_cnt = 0 ;
1928
1918
size_t offset , i , guest_offset , j ;
1929
1919
ssize_t err ;
1930
1920
1931
- memset (& hdr . virtio_net , 0 , sizeof (hdr . virtio_net ));
1921
+ memset (& extra_hdr , 0 , sizeof (extra_hdr ));
1932
1922
1933
1923
if (n -> rss_data .enabled && n -> rss_data .enabled_software_rss ) {
1934
- int index = virtio_net_process_rss (nc , buf , size , & hdr . virtio_net );
1924
+ int index = virtio_net_process_rss (nc , buf , size , & extra_hdr );
1935
1925
if (index >= 0 ) {
1936
1926
nc = qemu_get_subqueue (n -> nic , index % n -> curr_queue_pairs );
1937
1927
}
@@ -1996,20 +1986,23 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
1996
1986
if (n -> mergeable_rx_bufs ) {
1997
1987
mhdr_cnt = iov_copy (mhdr_sg , ARRAY_SIZE (mhdr_sg ),
1998
1988
sg , elem -> in_num ,
1999
- offsetof(typeof (hdr ),
2000
- virtio_net .hdr .num_buffers ),
2001
- sizeof (hdr .virtio_net .hdr .num_buffers ));
1989
+ offsetof(typeof (extra_hdr ), hdr .num_buffers ),
1990
+ sizeof (extra_hdr .hdr .num_buffers ));
2002
1991
} else {
2003
- hdr . virtio_net .hdr .num_buffers = cpu_to_le16 (1 );
1992
+ extra_hdr .hdr .num_buffers = cpu_to_le16 (1 );
2004
1993
}
2005
1994
2006
- guest_offset = n -> has_vnet_hdr ?
2007
- receive_header (n , (struct virtio_net_hdr * )& hdr ,
2008
- buf , size , & offset ) :
2009
- n -> guest_hdr_len ;
2010
-
2011
- iov_from_buf (sg , elem -> in_num , 0 , & hdr , guest_offset );
2012
- total += guest_offset ;
1995
+ receive_header (n , sg , elem -> in_num , buf , size );
1996
+ if (n -> rss_data .populate_hash ) {
1997
+ offset = offsetof(typeof (extra_hdr ), hash_value );
1998
+ iov_from_buf (sg , elem -> in_num , offset ,
1999
+ (char * )& extra_hdr + offset ,
2000
+ sizeof (extra_hdr .hash_value ) +
2001
+ sizeof (extra_hdr .hash_report ));
2002
+ }
2003
+ offset = n -> host_hdr_len ;
2004
+ total += n -> guest_hdr_len ;
2005
+ guest_offset = n -> guest_hdr_len ;
2013
2006
} else {
2014
2007
guest_offset = 0 ;
2015
2008
}
@@ -2035,11 +2028,11 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
2035
2028
}
2036
2029
2037
2030
if (mhdr_cnt ) {
2038
- virtio_stw_p (vdev , & hdr . virtio_net .hdr .num_buffers , i );
2031
+ virtio_stw_p (vdev , & extra_hdr .hdr .num_buffers , i );
2039
2032
iov_from_buf (mhdr_sg , mhdr_cnt ,
2040
2033
0 ,
2041
- & hdr . virtio_net .hdr .num_buffers ,
2042
- sizeof hdr . virtio_net .hdr .num_buffers );
2034
+ & extra_hdr .hdr .num_buffers ,
2035
+ sizeof extra_hdr .hdr .num_buffers );
2043
2036
}
2044
2037
2045
2038
for (j = 0 ; j < i ; j ++ ) {
0 commit comments