Patchwork [v2] net/hyperv: fix the issue that large packets be dropped under bridge

login
register
mail settings
Submitter Wei Yongjun
Date Feb. 2, 2012, 6:17 a.m.
Message ID <CAPgLHd-Z5azR2_5O+GkdjBF45k8YY1te0huMo75pFULGHG+izg@mail.gmail.com>
Download mbox | patch
Permalink /patch/139086/
State Accepted
Delegated to: David Miller
Headers show

Comments

Wei Yongjun - Feb. 2, 2012, 6:17 a.m.
From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

The packets with size larger than 1452 will be dropped by bridge
which with two hyperv netdevice ports. This cause by hyperv netvsc
driver always copy the trailer padding to the data packet, and then
the skb received from netdevice may include wrong skb->len (20 bytes
larger than the real size normally). The captured packet may like
this:

  Ethernet II, Src: Microsof_00:00:07 (00:15:5d:00:00:07),
               Dst: HewlettP_00:00:4e (00:1f:29:00:00:4e)
    Destination: HewlettP_e6:00:4e (00:1f:29:00:00:4e)
    Source: Microsof_f6:6d:07 (00:15:5d:f6:6d:07)
    Type: IP (0x0800)
    Trailer: 1415161718191A1B1C1D1E1F20212223
    Frame check sequence: 0x24252627 [incorrect, should be 0x7c2e5a5e]

The following command help to reproduction it, and the ping ICMP
packets will be dropped by bridge.
  $ ping ip -s 1453

This patch fixed it by removing the trailer padding from the data
packet.

Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
v1 -> v2: change to error message
---
 drivers/net/hyperv/rndis_filter.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)
David Miller - Feb. 2, 2012, 7:22 p.m.
From: Wei Yongjun <weiyj.lk@gmail.com>
Date: Thu, 2 Feb 2012 14:17:23 +0800

> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> 
> The packets with size larger than 1452 will be dropped by bridge
> which with two hyperv netdevice ports. This cause by hyperv netvsc
> driver always copy the trailer padding to the data packet, and then
> the skb received from netdevice may include wrong skb->len (20 bytes
> larger than the real size normally). The captured packet may like
> this:
> 
>   Ethernet II, Src: Microsof_00:00:07 (00:15:5d:00:00:07),
>                Dst: HewlettP_00:00:4e (00:1f:29:00:00:4e)
>     Destination: HewlettP_e6:00:4e (00:1f:29:00:00:4e)
>     Source: Microsof_f6:6d:07 (00:15:5d:f6:6d:07)
>     Type: IP (0x0800)
>     Trailer: 1415161718191A1B1C1D1E1F20212223
>     Frame check sequence: 0x24252627 [incorrect, should be 0x7c2e5a5e]
> 
> The following command help to reproduction it, and the ping ICMP
> packets will be dropped by bridge.
>   $ ping ip -s 1453
> 
> This patch fixed it by removing the trailer padding from the data
> packet.
> 
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Applied.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index da181f9..dc2e384 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -321,6 +321,25 @@  static void rndis_filter_receive_data(struct rndis_device *dev,
 	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
 
 	pkt->total_data_buflen -= data_offset;
+
+	/*
+	 * Make sure we got a valid RNDIS message, now total_data_buflen
+	 * should be the data packet size plus the trailer padding size
+	 */
+	if (pkt->total_data_buflen < rndis_pkt->data_len) {
+		netdev_err(dev->net_dev->ndev, "rndis message buffer "
+			   "overflow detected (got %u, min %u)"
+			   "...dropping this message!\n",
+			   pkt->total_data_buflen, rndis_pkt->data_len);
+		return;
+	}
+
+	/*
+	 * Remove the rndis trailer padding from rndis packet message
+	 * rndis_pkt->data_len tell us the real data length, we only copy
+	 * the data packet to the stack, without the rndis trailer padding
+	 */
+	pkt->total_data_buflen = rndis_pkt->data_len;
 	pkt->data = (void *)((unsigned long)pkt->data + data_offset);
 
 	pkt->is_data_pkt = true;