aboutsummaryrefslogtreecommitdiff
path: root/hw/net/virtio-net.c
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki@daynix.com>2023-02-23 19:50:49 +0900
committerJason Wang <jasowang@redhat.com>2023-03-10 15:35:38 +0800
commit65f474bbae9a33b08707084efb95701e187f79e3 (patch)
tree2f52c41e376d2c32cfdcb6cccd0618229e3b043d /hw/net/virtio-net.c
parent5fb7d149953f469381a11e486d66dc56af2c0f21 (diff)
downloadqemu-65f474bbae9a33b08707084efb95701e187f79e3.zip
qemu-65f474bbae9a33b08707084efb95701e187f79e3.tar.gz
qemu-65f474bbae9a33b08707084efb95701e187f79e3.tar.bz2
net/eth: Introduce EthL4HdrProto
igb, a new network device emulation, will need SCTP checksum offloading. Currently eth_get_protocols() has a bool parameter for each protocol currently it supports, but there will be a bit too many parameters if we add yet another protocol. Introduce an enum type, EthL4HdrProto to represent all L4 protocols eth_get_protocols() support with one parameter. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net/virtio-net.c')
-rw-r--r--hw/net/virtio-net.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index a14d3aa..53e1c32 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1748,37 +1748,59 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
static uint8_t virtio_net_get_hash_type(bool hasip4,
bool hasip6,
- bool hasudp,
- bool hastcp,
+ EthL4HdrProto l4hdr_proto,
uint32_t types)
{
if (hasip4) {
- if (hastcp && (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4)) {
- return NetPktRssIpV4Tcp;
- }
- if (hasudp && (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4)) {
- return NetPktRssIpV4Udp;
+ switch (l4hdr_proto) {
+ case ETH_L4_HDR_PROTO_TCP:
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4) {
+ return NetPktRssIpV4Tcp;
+ }
+ break;
+
+ case ETH_L4_HDR_PROTO_UDP:
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4) {
+ return NetPktRssIpV4Udp;
+ }
+ break;
+
+ default:
+ break;
}
+
if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv4) {
return NetPktRssIpV4;
}
} else if (hasip6) {
- uint32_t mask = VIRTIO_NET_RSS_HASH_TYPE_TCP_EX |
- VIRTIO_NET_RSS_HASH_TYPE_TCPv6;
+ switch (l4hdr_proto) {
+ case ETH_L4_HDR_PROTO_TCP:
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_TCP_EX) {
+ return NetPktRssIpV6TcpEx;
+ }
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv6) {
+ return NetPktRssIpV6Tcp;
+ }
+ break;
- if (hastcp && (types & mask)) {
- return (types & VIRTIO_NET_RSS_HASH_TYPE_TCP_EX) ?
- NetPktRssIpV6TcpEx : NetPktRssIpV6Tcp;
+ case ETH_L4_HDR_PROTO_UDP:
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_UDP_EX) {
+ return NetPktRssIpV6UdpEx;
+ }
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv6) {
+ return NetPktRssIpV6Udp;
+ }
+ break;
+
+ default:
+ break;
}
- mask = VIRTIO_NET_RSS_HASH_TYPE_UDP_EX | VIRTIO_NET_RSS_HASH_TYPE_UDPv6;
- if (hasudp && (types & mask)) {
- return (types & VIRTIO_NET_RSS_HASH_TYPE_UDP_EX) ?
- NetPktRssIpV6UdpEx : NetPktRssIpV6Udp;
+
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_IP_EX) {
+ return NetPktRssIpV6Ex;
}
- mask = VIRTIO_NET_RSS_HASH_TYPE_IP_EX | VIRTIO_NET_RSS_HASH_TYPE_IPv6;
- if (types & mask) {
- return (types & VIRTIO_NET_RSS_HASH_TYPE_IP_EX) ?
- NetPktRssIpV6Ex : NetPktRssIpV6;
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv6) {
+ return NetPktRssIpV6;
}
}
return 0xff;
@@ -1800,7 +1822,8 @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
struct NetRxPkt *pkt = n->rx_pkt;
uint8_t net_hash_type;
uint32_t hash;
- bool hasip4, hasip6, hasudp, hastcp;
+ bool hasip4, hasip6;
+ EthL4HdrProto l4hdr_proto;
static const uint8_t reports[NetPktRssIpV6UdpEx + 1] = {
VIRTIO_NET_HASH_REPORT_IPv4,
VIRTIO_NET_HASH_REPORT_TCPv4,
@@ -1815,8 +1838,8 @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
net_rx_pkt_set_protocols(pkt, buf + n->host_hdr_len,
size - n->host_hdr_len);
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
- net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, hasudp, hastcp,
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
+ net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, l4hdr_proto,
n->rss_data.hash_types);
if (net_hash_type > NetPktRssIpV6UdpEx) {
if (n->rss_data.populate_hash) {