]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Implement uip_csum_tcp() to calculate TCP checksum
authorAsias He <asias.hejun@gmail.com>
Wed, 29 Jun 2011 08:47:24 +0000 (16:47 +0800)
committerPekka Enberg <penberg@kernel.org>
Thu, 30 Jun 2011 07:42:44 +0000 (10:42 +0300)
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/include/kvm/uip.h
tools/kvm/uip/csum.c

index 46cec2096d1a2d6d90cbd05d67c80a263dee8a51..37c87c697b2659fb079cd645392dd651bf529b67 100644 (file)
 /*
  * IP package maxium len == 64 KBytes
  * IP header == 20 Bytes
+ * TCP header == 20 Bytes
  * UDP header == 8 Bytes
  */
+#define UIP_MAX_TCP_PAYLOAD    (64*1024 - 20 - 20 - 1)
 #define UIP_MAX_UDP_PAYLOAD    (64*1024 - 20 -  8 - 1)
 
 struct uip_eth_addr {
@@ -269,6 +271,7 @@ int uip_tx_do_arp(struct uip_tx_arg *arg);
 
 u16 uip_csum_icmp(struct uip_icmp *icmp);
 u16 uip_csum_udp(struct uip_udp *udp);
+u16 uip_csum_tcp(struct uip_tcp *tcp);
 u16 uip_csum_ip(struct uip_ip *ip);
 
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
index a152a0f85372093e4d9d1c5dcb4b5aaa3b86ab09..7ca8badaaeeeb87802442a83e6934adfbce9ced1 100644 (file)
@@ -60,3 +60,33 @@ u16 uip_csum_udp(struct uip_udp *udp)
        }
 
 }
+
+u16 uip_csum_tcp(struct uip_tcp *tcp)
+{
+       struct uip_pseudo_hdr hdr;
+       struct uip_ip *ip;
+       u16 tcp_len;
+       u8 *pad;
+
+       ip        = &tcp->ip;
+       tcp_len   = ntohs(ip->len) - uip_ip_hdrlen(ip);
+
+       hdr.sip   = ip->sip;
+       hdr.dip   = ip->dip;
+       hdr.zero  = 0;
+       hdr.proto = ip->proto;
+       hdr.len   = htons(tcp_len);
+
+       if (tcp_len > UIP_MAX_TCP_PAYLOAD + 20)
+               pr_warning("tcp_len(%d) is too large", tcp_len);
+
+       if (tcp_len % 2) {
+               pad = (u8 *)&tcp->sport + tcp_len;
+               *pad = 0;
+               memcpy((u8 *)&tcp->sport + tcp_len + 1, &hdr, sizeof(hdr));
+               return uip_csum(0, (u8 *)&tcp->sport, tcp_len + 1 + sizeof(hdr));
+       } else {
+               memcpy((u8 *)&tcp->sport + tcp_len, &hdr, sizeof(hdr));
+               return uip_csum(0, (u8 *)&tcp->sport, tcp_len + sizeof(hdr));
+       }
+}