From a2dbe1356faff3cb613ae83b77c484a203be5f15 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 24 Jan 2017 10:42:49 +0100 Subject: [PATCH 1/5] net: Mark 'vlan' parameter as deprecated The 'vlan' parameter is a continuous source of confusion for the users, many people mix it up with the more common term VLAN (the link layer packet encapsulation), and even if they realize that the QEMU 'vlan' is rather some kind of network hub emulation, there is still a high risk that they configure their QEMU networking in a wrong way with this parameter (e.g. by hooking NICs together, so they get a 'loopback' between one and the other NIC). Thus at one point in time, we should finally get rid of the 'vlan' feature in QEMU. Let's do a first step in this direction by declaring the 'vlan' parameter as deprecated and informing the users to use the 'netdev' parameter instead. Signed-off-by: Thomas Huth Signed-off-by: Jason Wang --- net/net.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/net.c b/net/net.c index 939fe3193a..fb7af3a432 100644 --- a/net/net.c +++ b/net/net.c @@ -970,6 +970,7 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp) const Netdev *netdev; const char *name; NetClientState *peer = NULL; + static bool vlan_warned; if (is_netdev) { netdev = object; @@ -1050,6 +1051,11 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp) !opts->u.nic.data->has_netdev) { peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL); } + + if (net->has_vlan && !vlan_warned) { + error_report("'vlan' is deprecated. Please use 'netdev' instead."); + vlan_warned = true; + } } if (net_client_init_fun[netdev->type](netdev, name, peer, errp) < 0) { From e514fc7e1231c6d95011e448e6c626f2bb6f3cd8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 26 Jan 2017 11:10:10 +0100 Subject: [PATCH 2/5] net: e1000e: fix dead code in e1000e_write_packet_to_guest Because is_first is declared inside a loop, it is always true. The store is dead, and so is the "else" branch of "if (is_first)". is_last is okay though. Reported by Coverity. Signed-off-by: Paolo Bonzini Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/e1000e_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 2b11499829..c99e2fbd62 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -1507,6 +1507,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, const E1000E_RingInfo *rxi; size_t ps_hdr_len = 0; bool do_ps = e1000e_do_ps(core, pkt, &ps_hdr_len); + bool is_first = true; rxi = rxr->i; @@ -1514,7 +1515,6 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, hwaddr ba[MAX_PS_BUFFERS]; e1000e_ba_state bastate = { { 0 } }; bool is_last = false; - bool is_first = true; desc_size = total_size - desc_offset; From a935cc3132aea175502f76c06eba7a78521ef3ba Mon Sep 17 00:00:00 2001 From: Zhang Chen Date: Tue, 24 Jan 2017 16:53:46 +0800 Subject: [PATCH 3/5] colo-compare: sort TCP packet queue by sequence number Improve efficiency of TCP packet comparison. Signed-off-by: Zhang Chen Signed-off-by: Li Zhijian Signed-off-by: Jason Wang --- net/colo-compare.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/colo-compare.c b/net/colo-compare.c index 4962976c22..162fd6a570 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -101,6 +101,15 @@ static int compare_chr_send(CharBackend *out, const uint8_t *buf, uint32_t size); +static gint seq_sorter(Packet *a, Packet *b, gpointer data) +{ + struct tcphdr *atcp, *btcp; + + atcp = (struct tcphdr *)(a->transport_header); + btcp = (struct tcphdr *)(b->transport_header); + return ntohl(atcp->th_seq) - ntohl(btcp->th_seq); +} + /* * Return 0 on success, if return -1 means the pkt * is unsupported(arp and ipv6) and will be sent later @@ -137,6 +146,11 @@ static int packet_enqueue(CompareState *s, int mode) if (g_queue_get_length(&conn->primary_list) <= MAX_QUEUE_SIZE) { g_queue_push_tail(&conn->primary_list, pkt); + if (conn->ip_proto == IPPROTO_TCP) { + g_queue_sort(&conn->primary_list, + (GCompareDataFunc)seq_sorter, + NULL); + } } else { error_report("colo compare primary queue size too big," "drop packet"); @@ -145,6 +159,11 @@ static int packet_enqueue(CompareState *s, int mode) if (g_queue_get_length(&conn->secondary_list) <= MAX_QUEUE_SIZE) { g_queue_push_tail(&conn->secondary_list, pkt); + if (conn->ip_proto == IPPROTO_TCP) { + g_queue_sort(&conn->secondary_list, + (GCompareDataFunc)seq_sorter, + NULL); + } } else { error_report("colo compare secondary queue size too big," "drop packet"); From 81f17e0d435c3db3a3e67e0d32ebf9c98973211f Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Thu, 2 Feb 2017 16:16:24 +0530 Subject: [PATCH 4/5] net: imx: limit buffer descriptor count i.MX Fast Ethernet Controller uses buffer descriptors to manage data flow to/fro receive & transmit queues. While transmitting packets, it could continue to read buffer descriptors if a buffer descriptor has length of zero and has crafted values in bd.flags. Set an upper limit to number of buffer descriptors. Reported-by: Li Qiang Signed-off-by: Prasad J Pandit Signed-off-by: Jason Wang --- hw/net/imx_fec.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c index 50c75642c6..90e6ee35ba 100644 --- a/hw/net/imx_fec.c +++ b/hw/net/imx_fec.c @@ -55,6 +55,8 @@ } \ } while (0) +#define IMX_MAX_DESC 1024 + static const char *imx_default_reg_name(IMXFECState *s, uint32_t index) { static char tmp[20]; @@ -402,12 +404,12 @@ static void imx_eth_update(IMXFECState *s) static void imx_fec_do_tx(IMXFECState *s) { - int frame_size = 0; + int frame_size = 0, descnt = 0; uint8_t frame[ENET_MAX_FRAME_SIZE]; uint8_t *ptr = frame; uint32_t addr = s->tx_descriptor; - while (1) { + while (descnt++ < IMX_MAX_DESC) { IMXFECBufDesc bd; int len; @@ -453,12 +455,12 @@ static void imx_fec_do_tx(IMXFECState *s) static void imx_enet_do_tx(IMXFECState *s) { - int frame_size = 0; + int frame_size = 0, descnt = 0; uint8_t frame[ENET_MAX_FRAME_SIZE]; uint8_t *ptr = frame; uint32_t addr = s->tx_descriptor; - while (1) { + while (descnt++ < IMX_MAX_DESC) { IMXENETBufDesc bd; int len; From 4154c7e03fa55b4cf52509a83d50d6c09d743b77 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Thu, 9 Feb 2017 18:19:19 -0800 Subject: [PATCH 5/5] net: e1000e: fix an infinite loop issue This issue is like the issue in e1000 network card addressed in this commit: e1000: eliminate infinite loops on out-of-bounds transfer start. Signed-off-by: Li Qiang Reviewed-by: Dmitry Fleytman Signed-off-by: Jason Wang --- hw/net/e1000e_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index c99e2fbd62..28c5be1506 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -806,7 +806,8 @@ typedef struct E1000E_RingInfo_st { static inline bool e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r) { - return core->mac[r->dh] == core->mac[r->dt]; + return core->mac[r->dh] == core->mac[r->dt] || + core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN; } static inline uint64_t @@ -1522,6 +1523,10 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, desc_size = core->rx_desc_buf_size; } + if (e1000e_ring_empty(core, rxi)) { + return; + } + base = e1000e_ring_head_descr(core, rxi); pci_dma_read(d, base, &desc, core->rx_desc_len);