From a7278b36fcab9af469563bd7b9dadebe2ae25e48 Mon Sep 17 00:00:00 2001 From: Dana Rubin Date: Tue, 18 Aug 2015 12:45:55 +0300 Subject: net/vmxnet3: Refine l2 header validation Validation of l2 header length assumed minimal packet size as eth_header + 2 * vlan_header regardless of the actual protocol. This caused crash for valid non-IP packets shorter than 22 bytes, as 'tx_pkt->packet_type' hasn't been assigned for such packets, and 'vmxnet3_on_tx_done_update_stats()' expects it to be properly set. Refine header length validation in 'vmxnet_tx_pkt_parse_headers'. Check its return value during packet processing flow. As a side effect, in case IPv4 and IPv6 header validation failure, corrupt packets will be dropped. Signed-off-by: Dana Rubin Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 4 +--- hw/net/vmxnet_tx_pkt.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'hw/net') diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 04159c8..48ced71 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -729,9 +729,7 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx) } if (txd.eop) { - if (!s->skip_current_tx_pkt) { - vmxnet_tx_pkt_parse(s->tx_pkt); - + if (!s->skip_current_tx_pkt && vmxnet_tx_pkt_parse(s->tx_pkt)) { if (s->needs_vlan) { vmxnet_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci); } diff --git a/hw/net/vmxnet_tx_pkt.c b/hw/net/vmxnet_tx_pkt.c index f7344c4..eb88ddf 100644 --- a/hw/net/vmxnet_tx_pkt.c +++ b/hw/net/vmxnet_tx_pkt.c @@ -142,11 +142,24 @@ static bool vmxnet_tx_pkt_parse_headers(struct VmxnetTxPkt *pkt) bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base, ETH_MAX_L2_HDR_LEN); - if (bytes_read < ETH_MAX_L2_HDR_LEN) { + if (bytes_read < sizeof(struct eth_header)) { + l2_hdr->iov_len = 0; + return false; + } + + l2_hdr->iov_len = sizeof(struct eth_header); + switch (be16_to_cpu(PKT_GET_ETH_HDR(l2_hdr->iov_base)->h_proto)) { + case ETH_P_VLAN: + l2_hdr->iov_len += sizeof(struct vlan_header); + break; + case ETH_P_DVLAN: + l2_hdr->iov_len += 2 * sizeof(struct vlan_header); + break; + } + + if (bytes_read < l2_hdr->iov_len) { l2_hdr->iov_len = 0; return false; - } else { - l2_hdr->iov_len = eth_get_l2_hdr_length(l2_hdr->iov_base); } l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len); -- cgit v1.1 From c6048f849c7e3f009786df76206e895a69de032c Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Mon, 21 Sep 2015 17:09:02 +0300 Subject: vmxnet3: Support reading IMR registers on bar0 Instead of asserting, return the actual IMR register value. This is aligned with what's returned on ESXi. Signed-off-by: Shmulik Ladkani Tested-by: Dana Rubin Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'hw/net') diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 48ced71..057f0dc 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1163,9 +1163,13 @@ vmxnet3_io_bar0_write(void *opaque, hwaddr addr, static uint64_t vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size) { + VMXNET3State *s = opaque; + if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR, VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) { - g_assert_not_reached(); + int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR, + VMXNET3_REG_ALIGN); + return s->interrupt_states[l].is_masked; } VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size); -- cgit v1.1 From 8304402033e8dbe8e379017d51ed1dd8344f1dce Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 28 Sep 2015 13:37:26 +0800 Subject: e1000: use alias for default model Instead of duplicating the "e1000-82540em" device model as "e1000", make the latter an alias for the former. Cc: Markus Armbruster Signed-off-by: Jason Wang --- hw/net/e1000.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'hw/net') diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 09c9e9d..910de3a 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -1647,7 +1647,7 @@ static const TypeInfo e1000_base_info = { static const E1000Info e1000_devices[] = { { - .name = "e1000-82540em", + .name = "e1000", .device_id = E1000_DEV_ID_82540EM, .revision = 0x03, .phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT, @@ -1666,11 +1666,6 @@ static const E1000Info e1000_devices[] = { }, }; -static const TypeInfo e1000_default_info = { - .name = "e1000", - .parent = "e1000-82540em", -}; - static void e1000_register_types(void) { int i; @@ -1688,7 +1683,6 @@ static void e1000_register_types(void) type_register(&type_info); } - type_register_static(&e1000_default_info); } type_init(e1000_register_types) -- cgit v1.1 From d62241eb6da9bd2517f07b3219ba4208b90b4e0d Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Fri, 18 Sep 2015 08:55:04 +0300 Subject: vmxnet3: Add support for VMXNET3_CMD_GET_ADAPTIVE_RING_INFO command Some drivers (e.g. vmware-tools) issue the VMXNET3_CMD_GET_ADAPTIVE_RING_INFO command. Currently, due to lack of support, a bogus value (-1) is returned. Support this command, returning the "adaptive-ring disabled" flag. Signed-off-by: Shmulik Ladkani Signed-off-by: Jason Wang --- hw/net/vmxnet3.c | 9 +++++++++ hw/net/vmxnet3.h | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'hw/net') diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 057f0dc..3c5e10d 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1631,6 +1631,11 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd) VMW_CBPRN("Set: VMXNET3_CMD_GET_CONF_INTR - interrupt configuration"); break; + case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO: + VMW_CBPRN("Set: VMXNET3_CMD_GET_ADAPTIVE_RING_INFO - " + "adaptive ring info flags"); + break; + default: VMW_CBPRN("Received unknown command: %" PRIx64, cmd); break; @@ -1670,6 +1675,10 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s) ret = vmxnet3_get_interrupt_config(s); break; + case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO: + ret = VMXNET3_DISABLE_ADAPTIVE_RING; + break; + default: VMW_WRPRN("Received request for unknown command: %x", s->last_command); ret = -1; diff --git a/hw/net/vmxnet3.h b/hw/net/vmxnet3.h index f987d71..f7006af 100644 --- a/hw/net/vmxnet3.h +++ b/hw/net/vmxnet3.h @@ -198,9 +198,13 @@ enum { VMXNET3_CMD_GET_DID_LO, /* 0xF00D0005 */ VMXNET3_CMD_GET_DID_HI, /* 0xF00D0006 */ VMXNET3_CMD_GET_DEV_EXTRA_INFO, /* 0xF00D0007 */ - VMXNET3_CMD_GET_CONF_INTR /* 0xF00D0008 */ + VMXNET3_CMD_GET_CONF_INTR, /* 0xF00D0008 */ + VMXNET3_CMD_GET_ADAPTIVE_RING_INFO /* 0xF00D0009 */ }; +/* Adaptive Ring Info Flags */ +#define VMXNET3_DISABLE_ADAPTIVE_RING 1 + /* * Little Endian layout of bitfields - * Byte 0 : 7.....len.....0 -- cgit v1.1