aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDmitry Fleytman <dmitry@daynix.com>2013-03-09 11:21:03 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2013-03-25 11:13:10 +0100
commit84026301694b98dd08272e613da3497b17023d5c (patch)
tree883a3e71e2680b2d9f96f1262de6198b265ba3c5 /net
parent5acf5ea4bc1535657692c509092caddec3d719ff (diff)
net: iovec checksum calculator
Signed-off-by: Dmitry Fleytman <dmitry@daynix.com> Signed-off-by: Yan Vugenfirer <yan@daynix.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/checksum.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/net/checksum.c b/net/checksum.c
index 4fa5563e7c..14c08550e0 100644
--- a/net/checksum.c
+++ b/net/checksum.c
@@ -15,6 +15,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu-common.h"
#include "net/checksum.h"
#define PROTO_TCP 6
@@ -84,3 +85,31 @@ void net_checksum_calculate(uint8_t *data, int length)
data[14+hlen+csum_offset] = csum >> 8;
data[14+hlen+csum_offset+1] = csum & 0xff;
}
+
+uint32_t
+net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt,
+ uint32_t iov_off, uint32_t size)
+{
+ size_t iovec_off, buf_off;
+ unsigned int i;
+ uint32_t res = 0;
+ uint32_t seq = 0;
+
+ iovec_off = 0;
+ buf_off = 0;
+ for (i = 0; i < iov_cnt && size; i++) {
+ if (iov_off < (iovec_off + iov[i].iov_len)) {
+ size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size);
+ void *chunk_buf = iov[i].iov_base + (iov_off - iovec_off);
+
+ res += net_checksum_add_cont(len, chunk_buf, seq);
+ seq += len;
+
+ buf_off += len;
+ iov_off += len;
+ size -= len;
+ }
+ iovec_off += iov[i].iov_len;
+ }
+ return res;
+}