summaryrefslogtreecommitdiffstats
path: root/qemu/hw/net/vmxnet_tx_pkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/net/vmxnet_tx_pkt.c')
-rw-r--r--qemu/hw/net/vmxnet_tx_pkt.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/qemu/hw/net/vmxnet_tx_pkt.c b/qemu/hw/net/vmxnet_tx_pkt.c
index f7344c4cb..91e1e08fd 100644
--- a/qemu/hw/net/vmxnet_tx_pkt.c
+++ b/qemu/hw/net/vmxnet_tx_pkt.c
@@ -15,6 +15,7 @@
*
*/
+#include "qemu/osdep.h"
#include "hw/hw.h"
#include "vmxnet_tx_pkt.h"
#include "net/eth.h"
@@ -142,11 +143,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);