aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-03-06 15:13:23 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-03-06 15:13:23 +0000
commiteba44e9339fc13c36e24c8c59e2b73ea231b46a1 (patch)
tree738208c7e3504fc23aaf4ae80ab549943d5a47f9 /hw
parent56b51708e9e22809d2a78f38d0ac84bb3f3fca92 (diff)
parentf0aabd5c4ae11fde704d138e8f06c69e5c902a16 (diff)
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Mon 06 Mar 2017 04:15:17 GMT # gpg: using RSA key 0xEF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * remotes/jasowang/tags/net-pull-request: net/filter-mirror: Follow CODING_STYLE COLO-compare: Fix icmp and udp compare different packet always dump bug COLO-compare: Optimize compare_common and compare_tcp COLO-compare: Rename compare function and remove duplicate codes filter-rewriter: skip net_checksum_calculate() while offset = 0 net/colo: fix memory double free error vmxnet3: VMStatify rx/tx q_descr and int_state vmxnet3: Convert ring values to uint32_t's net/colo-compare: Fix memory free error colo-compare: Fix removing fds been watched incorrectly in finalization char: remove the right fd been watched in qemu_chr_fe_set_handlers() colo-compare: kick compare thread to exit after some cleanup in finalization colo-compare: use g_timeout_source_new() to process the stale packets NetRxPkt: Remove code duplication in net_rx_pkt_pull_data() NetRxPkt: Account buffer with ETH header in IOV length NetRxPkt: Do not try to pull more data than present NetRxPkt: Fix memory corruption on VLAN header stripping eth: Extend vlan stripping functions net: Remove useless local var pkt Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/net/net_rx_pkt.c41
-rw-r--r--hw/net/vmxnet3.c284
2 files changed, 117 insertions, 208 deletions
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
index 1019b50c18..cef1c2e0d1 100644
--- a/hw/net/net_rx_pkt.c
+++ b/hw/net/net_rx_pkt.c
@@ -23,13 +23,13 @@
struct NetRxPkt {
struct virtio_net_hdr virt_hdr;
- uint8_t ehdr_buf[sizeof(struct eth_header)];
+ uint8_t ehdr_buf[sizeof(struct eth_header) + sizeof(struct vlan_header)];
struct iovec *vec;
uint16_t vec_len_total;
uint16_t vec_len;
uint32_t tot_len;
uint16_t tci;
- bool vlan_stripped;
+ size_t ehdr_buf_len;
bool has_virt_hdr;
eth_pkt_types_e packet_type;
@@ -88,21 +88,21 @@ net_rx_pkt_pull_data(struct NetRxPkt *pkt,
const struct iovec *iov, int iovcnt,
size_t ploff)
{
- if (pkt->vlan_stripped) {
+ uint32_t pllen = iov_size(iov, iovcnt) - ploff;
+
+ if (pkt->ehdr_buf_len) {
net_rx_pkt_iovec_realloc(pkt, iovcnt + 1);
pkt->vec[0].iov_base = pkt->ehdr_buf;
- pkt->vec[0].iov_len = sizeof(pkt->ehdr_buf);
-
- pkt->tot_len =
- iov_size(iov, iovcnt) - ploff + sizeof(struct eth_header);
+ pkt->vec[0].iov_len = pkt->ehdr_buf_len;
+ pkt->tot_len = pllen + pkt->ehdr_buf_len;
pkt->vec_len = iov_copy(pkt->vec + 1, pkt->vec_len_total - 1,
- iov, iovcnt, ploff, pkt->tot_len);
+ iov, iovcnt, ploff, pllen) + 1;
} else {
net_rx_pkt_iovec_realloc(pkt, iovcnt);
- pkt->tot_len = iov_size(iov, iovcnt) - ploff;
+ pkt->tot_len = pllen;
pkt->vec_len = iov_copy(pkt->vec, pkt->vec_len_total,
iov, iovcnt, ploff, pkt->tot_len);
}
@@ -123,11 +123,12 @@ void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
uint16_t tci = 0;
uint16_t ploff = iovoff;
assert(pkt);
- pkt->vlan_stripped = false;
if (strip_vlan) {
- pkt->vlan_stripped = eth_strip_vlan(iov, iovcnt, iovoff, pkt->ehdr_buf,
- &ploff, &tci);
+ pkt->ehdr_buf_len = eth_strip_vlan(iov, iovcnt, iovoff, pkt->ehdr_buf,
+ &ploff, &tci);
+ } else {
+ pkt->ehdr_buf_len = 0;
}
pkt->tci = tci;
@@ -143,12 +144,13 @@ void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
uint16_t tci = 0;
uint16_t ploff = iovoff;
assert(pkt);
- pkt->vlan_stripped = false;
if (strip_vlan) {
- pkt->vlan_stripped = eth_strip_vlan_ex(iov, iovcnt, iovoff, vet,
- pkt->ehdr_buf,
- &ploff, &tci);
+ pkt->ehdr_buf_len = eth_strip_vlan_ex(iov, iovcnt, iovoff, vet,
+ pkt->ehdr_buf,
+ &ploff, &tci);
+ } else {
+ pkt->ehdr_buf_len = 0;
}
pkt->tci = tci;
@@ -159,11 +161,10 @@ void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
void net_rx_pkt_dump(struct NetRxPkt *pkt)
{
#ifdef NET_RX_PKT_DEBUG
- NetRxPkt *pkt = (NetRxPkt *)pkt;
assert(pkt);
- printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n",
- pkt->tot_len, pkt->vlan_stripped, pkt->tci);
+ printf("RX PKT: tot_len: %d, ehdr_buf_len: %lu, vlan_tag: %d\n",
+ pkt->tot_len, pkt->ehdr_buf_len, pkt->tci);
#endif
}
@@ -426,7 +427,7 @@ bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt)
{
assert(pkt);
- return pkt->vlan_stripped;
+ return pkt->ehdr_buf_len ? true : false;
}
bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt)
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index e13a798b3b..8b1fab24fd 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -141,17 +141,17 @@ typedef struct VMXNET3Class {
/* Cyclic ring abstraction */
typedef struct {
hwaddr pa;
- size_t size;
- size_t cell_size;
- size_t next;
+ uint32_t size;
+ uint32_t cell_size;
+ uint32_t next;
uint8_t gen;
} Vmxnet3Ring;
static inline void vmxnet3_ring_init(PCIDevice *d,
Vmxnet3Ring *ring,
hwaddr pa,
- size_t size,
- size_t cell_size,
+ uint32_t size,
+ uint32_t cell_size,
bool zero_region)
{
ring->pa = pa;
@@ -166,7 +166,7 @@ static inline void vmxnet3_ring_init(PCIDevice *d,
}
#define VMXNET3_RING_DUMP(macro, ring_name, ridx, r) \
- macro("%s#%d: base %" PRIx64 " size %zu cell_size %zu gen %d next %zu", \
+ macro("%s#%d: base %" PRIx64 " size %u cell_size %u gen %d next %u", \
(ring_name), (ridx), \
(r)->pa, (r)->size, (r)->cell_size, (r)->gen, (r)->next)
@@ -2403,155 +2403,87 @@ static const VMStateDescription vmxstate_vmxnet3_mcast_list = {
}
};
-static void vmxnet3_get_ring_from_file(QEMUFile *f, Vmxnet3Ring *r)
-{
- r->pa = qemu_get_be64(f);
- r->size = qemu_get_be32(f);
- r->cell_size = qemu_get_be32(f);
- r->next = qemu_get_be32(f);
- r->gen = qemu_get_byte(f);
-}
-
-static void vmxnet3_put_ring_to_file(QEMUFile *f, Vmxnet3Ring *r)
-{
- qemu_put_be64(f, r->pa);
- qemu_put_be32(f, r->size);
- qemu_put_be32(f, r->cell_size);
- qemu_put_be32(f, r->next);
- qemu_put_byte(f, r->gen);
-}
-
-static void vmxnet3_get_tx_stats_from_file(QEMUFile *f,
- struct UPT1_TxStats *tx_stat)
-{
- tx_stat->TSOPktsTxOK = qemu_get_be64(f);
- tx_stat->TSOBytesTxOK = qemu_get_be64(f);
- tx_stat->ucastPktsTxOK = qemu_get_be64(f);
- tx_stat->ucastBytesTxOK = qemu_get_be64(f);
- tx_stat->mcastPktsTxOK = qemu_get_be64(f);
- tx_stat->mcastBytesTxOK = qemu_get_be64(f);
- tx_stat->bcastPktsTxOK = qemu_get_be64(f);
- tx_stat->bcastBytesTxOK = qemu_get_be64(f);
- tx_stat->pktsTxError = qemu_get_be64(f);
- tx_stat->pktsTxDiscard = qemu_get_be64(f);
-}
-
-static void vmxnet3_put_tx_stats_to_file(QEMUFile *f,
- struct UPT1_TxStats *tx_stat)
-{
- qemu_put_be64(f, tx_stat->TSOPktsTxOK);
- qemu_put_be64(f, tx_stat->TSOBytesTxOK);
- qemu_put_be64(f, tx_stat->ucastPktsTxOK);
- qemu_put_be64(f, tx_stat->ucastBytesTxOK);
- qemu_put_be64(f, tx_stat->mcastPktsTxOK);
- qemu_put_be64(f, tx_stat->mcastBytesTxOK);
- qemu_put_be64(f, tx_stat->bcastPktsTxOK);
- qemu_put_be64(f, tx_stat->bcastBytesTxOK);
- qemu_put_be64(f, tx_stat->pktsTxError);
- qemu_put_be64(f, tx_stat->pktsTxDiscard);
-}
-
-static int vmxnet3_get_txq_descr(QEMUFile *f, void *pv, size_t size,
- VMStateField *field)
-{
- Vmxnet3TxqDescr *r = pv;
-
- vmxnet3_get_ring_from_file(f, &r->tx_ring);
- vmxnet3_get_ring_from_file(f, &r->comp_ring);
- r->intr_idx = qemu_get_byte(f);
- r->tx_stats_pa = qemu_get_be64(f);
-
- vmxnet3_get_tx_stats_from_file(f, &r->txq_stats);
-
- return 0;
-}
-
-static int vmxnet3_put_txq_descr(QEMUFile *f, void *pv, size_t size,
- VMStateField *field, QJSON *vmdesc)
-{
- Vmxnet3TxqDescr *r = pv;
-
- vmxnet3_put_ring_to_file(f, &r->tx_ring);
- vmxnet3_put_ring_to_file(f, &r->comp_ring);
- qemu_put_byte(f, r->intr_idx);
- qemu_put_be64(f, r->tx_stats_pa);
- vmxnet3_put_tx_stats_to_file(f, &r->txq_stats);
-
- return 0;
-}
-
-static const VMStateInfo txq_descr_info = {
- .name = "txq_descr",
- .get = vmxnet3_get_txq_descr,
- .put = vmxnet3_put_txq_descr
+static const VMStateDescription vmstate_vmxnet3_ring = {
+ .name = "vmxnet3-ring",
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(pa, Vmxnet3Ring),
+ VMSTATE_UINT32(size, Vmxnet3Ring),
+ VMSTATE_UINT32(cell_size, Vmxnet3Ring),
+ VMSTATE_UINT32(next, Vmxnet3Ring),
+ VMSTATE_UINT8(gen, Vmxnet3Ring),
+ VMSTATE_END_OF_LIST()
+ }
};
-static void vmxnet3_get_rx_stats_from_file(QEMUFile *f,
- struct UPT1_RxStats *rx_stat)
-{
- rx_stat->LROPktsRxOK = qemu_get_be64(f);
- rx_stat->LROBytesRxOK = qemu_get_be64(f);
- rx_stat->ucastPktsRxOK = qemu_get_be64(f);
- rx_stat->ucastBytesRxOK = qemu_get_be64(f);
- rx_stat->mcastPktsRxOK = qemu_get_be64(f);
- rx_stat->mcastBytesRxOK = qemu_get_be64(f);
- rx_stat->bcastPktsRxOK = qemu_get_be64(f);
- rx_stat->bcastBytesRxOK = qemu_get_be64(f);
- rx_stat->pktsRxOutOfBuf = qemu_get_be64(f);
- rx_stat->pktsRxError = qemu_get_be64(f);
-}
-
-static void vmxnet3_put_rx_stats_to_file(QEMUFile *f,
- struct UPT1_RxStats *rx_stat)
-{
- qemu_put_be64(f, rx_stat->LROPktsRxOK);
- qemu_put_be64(f, rx_stat->LROBytesRxOK);
- qemu_put_be64(f, rx_stat->ucastPktsRxOK);
- qemu_put_be64(f, rx_stat->ucastBytesRxOK);
- qemu_put_be64(f, rx_stat->mcastPktsRxOK);
- qemu_put_be64(f, rx_stat->mcastBytesRxOK);
- qemu_put_be64(f, rx_stat->bcastPktsRxOK);
- qemu_put_be64(f, rx_stat->bcastBytesRxOK);
- qemu_put_be64(f, rx_stat->pktsRxOutOfBuf);
- qemu_put_be64(f, rx_stat->pktsRxError);
-}
-
-static int vmxnet3_get_rxq_descr(QEMUFile *f, void *pv, size_t size,
- VMStateField *field)
-{
- Vmxnet3RxqDescr *r = pv;
- int i;
-
- for (i = 0; i < VMXNET3_RX_RINGS_PER_QUEUE; i++) {
- vmxnet3_get_ring_from_file(f, &r->rx_ring[i]);
+static const VMStateDescription vmstate_vmxnet3_tx_stats = {
+ .name = "vmxnet3-tx-stats",
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(TSOPktsTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(TSOBytesTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(ucastPktsTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(ucastBytesTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(mcastPktsTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(mcastBytesTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(bcastPktsTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(bcastBytesTxOK, struct UPT1_TxStats),
+ VMSTATE_UINT64(pktsTxError, struct UPT1_TxStats),
+ VMSTATE_UINT64(pktsTxDiscard, struct UPT1_TxStats),
+ VMSTATE_END_OF_LIST()
}
+};
- vmxnet3_get_ring_from_file(f, &r->comp_ring);
- r->intr_idx = qemu_get_byte(f);
- r->rx_stats_pa = qemu_get_be64(f);
-
- vmxnet3_get_rx_stats_from_file(f, &r->rxq_stats);
-
- return 0;
-}
-
-static int vmxnet3_put_rxq_descr(QEMUFile *f, void *pv, size_t size,
- VMStateField *field, QJSON *vmdesc)
-{
- Vmxnet3RxqDescr *r = pv;
- int i;
-
- for (i = 0; i < VMXNET3_RX_RINGS_PER_QUEUE; i++) {
- vmxnet3_put_ring_to_file(f, &r->rx_ring[i]);
+static const VMStateDescription vmstate_vmxnet3_txq_descr = {
+ .name = "vmxnet3-txq-descr",
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT(tx_ring, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_ring,
+ Vmxnet3Ring),
+ VMSTATE_STRUCT(comp_ring, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_ring,
+ Vmxnet3Ring),
+ VMSTATE_UINT8(intr_idx, Vmxnet3TxqDescr),
+ VMSTATE_UINT64(tx_stats_pa, Vmxnet3TxqDescr),
+ VMSTATE_STRUCT(txq_stats, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_tx_stats,
+ struct UPT1_TxStats),
+ VMSTATE_END_OF_LIST()
}
+};
- vmxnet3_put_ring_to_file(f, &r->comp_ring);
- qemu_put_byte(f, r->intr_idx);
- qemu_put_be64(f, r->rx_stats_pa);
- vmxnet3_put_rx_stats_to_file(f, &r->rxq_stats);
+static const VMStateDescription vmstate_vmxnet3_rx_stats = {
+ .name = "vmxnet3-rx-stats",
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(LROPktsRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(LROBytesRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(ucastPktsRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(ucastBytesRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(mcastPktsRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(mcastBytesRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(bcastPktsRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(bcastBytesRxOK, struct UPT1_RxStats),
+ VMSTATE_UINT64(pktsRxOutOfBuf, struct UPT1_RxStats),
+ VMSTATE_UINT64(pktsRxError, struct UPT1_RxStats),
+ VMSTATE_END_OF_LIST()
+ }
+};
- return 0;
-}
+static const VMStateDescription vmstate_vmxnet3_rxq_descr = {
+ .name = "vmxnet3-rxq-descr",
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT_ARRAY(rx_ring, Vmxnet3RxqDescr,
+ VMXNET3_RX_RINGS_PER_QUEUE, 0,
+ vmstate_vmxnet3_ring, Vmxnet3Ring),
+ VMSTATE_STRUCT(comp_ring, Vmxnet3RxqDescr, 0, vmstate_vmxnet3_ring,
+ Vmxnet3Ring),
+ VMSTATE_UINT8(intr_idx, Vmxnet3RxqDescr),
+ VMSTATE_UINT64(rx_stats_pa, Vmxnet3RxqDescr),
+ VMSTATE_STRUCT(rxq_stats, Vmxnet3RxqDescr, 0, vmstate_vmxnet3_rx_stats,
+ struct UPT1_RxStats),
+ VMSTATE_END_OF_LIST()
+ }
+};
static int vmxnet3_post_load(void *opaque, int version_id)
{
@@ -2577,40 +2509,15 @@ static int vmxnet3_post_load(void *opaque, int version_id)
return 0;
}
-static const VMStateInfo rxq_descr_info = {
- .name = "rxq_descr",
- .get = vmxnet3_get_rxq_descr,
- .put = vmxnet3_put_rxq_descr
-};
-
-static int vmxnet3_get_int_state(QEMUFile *f, void *pv, size_t size,
- VMStateField *field)
-{
- Vmxnet3IntState *r = pv;
-
- r->is_masked = qemu_get_byte(f);
- r->is_pending = qemu_get_byte(f);
- r->is_asserted = qemu_get_byte(f);
-
- return 0;
-}
-
-static int vmxnet3_put_int_state(QEMUFile *f, void *pv, size_t size,
- VMStateField *field, QJSON *vmdesc)
-{
- Vmxnet3IntState *r = pv;
-
- qemu_put_byte(f, r->is_masked);
- qemu_put_byte(f, r->is_pending);
- qemu_put_byte(f, r->is_asserted);
-
- return 0;
-}
-
-static const VMStateInfo int_state_info = {
- .name = "int_state",
- .get = vmxnet3_get_int_state,
- .put = vmxnet3_put_int_state
+static const VMStateDescription vmstate_vmxnet3_int_state = {
+ .name = "vmxnet3-int-state",
+ .version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_BOOL(is_masked, Vmxnet3IntState),
+ VMSTATE_BOOL(is_pending, Vmxnet3IntState),
+ VMSTATE_BOOL(is_asserted, Vmxnet3IntState),
+ VMSTATE_END_OF_LIST()
+ }
};
static bool vmxnet3_vmstate_need_pcie_device(void *opaque)
@@ -2667,14 +2574,15 @@ static const VMStateDescription vmstate_vmxnet3 = {
VMSTATE_UINT64(drv_shmem, VMXNET3State),
VMSTATE_UINT64(temp_shared_guest_driver_memory, VMXNET3State),
- VMSTATE_ARRAY(txq_descr, VMXNET3State,
- VMXNET3_DEVICE_MAX_TX_QUEUES, 0, txq_descr_info,
+ VMSTATE_STRUCT_ARRAY(txq_descr, VMXNET3State,
+ VMXNET3_DEVICE_MAX_TX_QUEUES, 0, vmstate_vmxnet3_txq_descr,
Vmxnet3TxqDescr),
- VMSTATE_ARRAY(rxq_descr, VMXNET3State,
- VMXNET3_DEVICE_MAX_RX_QUEUES, 0, rxq_descr_info,
+ VMSTATE_STRUCT_ARRAY(rxq_descr, VMXNET3State,
+ VMXNET3_DEVICE_MAX_RX_QUEUES, 0, vmstate_vmxnet3_rxq_descr,
Vmxnet3RxqDescr),
- VMSTATE_ARRAY(interrupt_states, VMXNET3State, VMXNET3_MAX_INTRS,
- 0, int_state_info, Vmxnet3IntState),
+ VMSTATE_STRUCT_ARRAY(interrupt_states, VMXNET3State,
+ VMXNET3_MAX_INTRS, 0, vmstate_vmxnet3_int_state,
+ Vmxnet3IntState),
VMSTATE_END_OF_LIST()
},