From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38105) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2s8L-0000xU-2N for qemu-devel@nongnu.org; Tue, 17 May 2016 23:26:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b2s8G-00039j-RI for qemu-devel@nongnu.org; Tue, 17 May 2016 23:26:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40532) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2s8G-00039R-Lu for qemu-devel@nongnu.org; Tue, 17 May 2016 23:26:48 -0400 References: From: Jason Wang Message-ID: <573BE0F1.4010808@redhat.com> Date: Wed, 18 May 2016 11:26:41 +0800 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v3 2/5] net: handle optional VLAN header in checksum computation. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Jean-Christophe Dubois , qemu-devel@nongnu.org, peter.maydell@linaro.org On 2016=E5=B9=B405=E6=9C=8809=E6=97=A5 03:41, Jean-Christophe Dubois wrot= e: > Signed-off-by: Jean-Christophe Dubois > --- > > Changes since v1: > * Not present on v1 > =20 > Changes since v2: > * Not present on v2 > > net/checksum.c | 35 +++++++++++++++++++++++++++++++---- > 1 file changed, 31 insertions(+), 4 deletions(-) > > diff --git a/net/checksum.c b/net/checksum.c > index f62b18a..8acd997 100644 > --- a/net/checksum.c > +++ b/net/checksum.c > @@ -55,7 +55,7 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_= t proto, > =20 > void net_checksum_calculate(uint8_t *data, int length) > { > - int ip_len; > + int ip_hdr_len, ip_len; > struct ip_header *ip; > =20 > /* > @@ -64,12 +64,39 @@ void net_checksum_calculate(uint8_t *data, int leng= th) > * struct members (just in case). > */ > =20 > - /* Ensure data has complete L2 & L3 headers. */ > - if (length < (sizeof(struct eth_header) + sizeof(struct ip_header)= )) { > + /* Ensure we have at least an Eth header */ > + if (length < sizeof(struct eth_header)) { > return; > } > =20 > - ip =3D (struct ip_header *)(data + sizeof(struct eth_header)); > + /* Handle the optionnal VLAN headers */ > + switch (lduw_be_p(&PKT_GET_ETH_HDR(data)->h_proto)) { > + case ETH_P_VLAN: > + ip_hdr_len =3D sizeof(struct eth_header) + > + sizeof(struct vlan_header); Then "mac_hdr_len" seems much better than "ip_hdr_len". > + break; > + case ETH_P_DVLAN: > + if (lduw_be_p(&PKT_GET_VLAN_HDR(data)->h_proto) =3D=3D ETH_P_V= LAN) { > + ip_hdr_len =3D sizeof(struct eth_header) + > + 2 * sizeof(struct vlan_header); > + } else { > + ip_hdr_len =3D sizeof(struct eth_header) + > + sizeof(struct vlan_header); > + } > + break; > + default: > + ip_hdr_len =3D sizeof(struct eth_header); > + break; > + } > + > + length -=3D ip_hdr_len; > + > + /* Now check we have an IP header (with an optionnal VLAN header) = */ > + if (length < sizeof(struct ip_header)) { > + return; > + } > + > + ip =3D (struct ip_header *)(data + ip_hdr_len); > =20 > if (IP_HEADER_VERSION(ip) !=3D IP_HEADER_VERSION_4) { > return; /* not IPv4 */