From: Dmitry Fleytman <dmi...@daynix.com> Signed-off-by: Dmitry Fleytman <dmi...@daynix.com> Signed-off-by: Yan Vugenfirer <y...@daynix.com> --- iov.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ iov.h | 6 ++++++ 2 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/iov.c b/iov.c index 0f96493..0ac15a1 100644 --- a/iov.c +++ b/iov.c @@ -16,6 +16,7 @@ */ #include "iov.h" +#include "net/checksum.h" size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, const void *buf, size_t iov_off, size_t size) @@ -65,6 +66,30 @@ size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, return buf_off; } +size_t iov_rebuild(struct iovec *dst, unsigned int dst_cnt, + const struct iovec *src, const unsigned int src_cnt, + size_t src_off) +{ + size_t curr_src_off = 0; + unsigned int i, j = 0; + + for (i = 0; i < src_cnt; i++) { + if (src_off < (curr_src_off + src[i].iov_len)) { + if (j == dst_cnt) { + return (size_t) -1; + } + + dst[j].iov_len = curr_src_off + src[i].iov_len - src_off; + dst[j].iov_base = src[i].iov_base + (src_off - curr_src_off); + + src_off += dst[j].iov_len; + j++; + } + curr_src_off += src[i].iov_len; + } + return j; +} + size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, size_t iov_off, size_t size) { @@ -130,3 +155,31 @@ void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, fprintf(fp, "\n"); } } + +uint32_t +iov_net_csum_add(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, size_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; +} diff --git a/iov.h b/iov.h index 94d2f78..b11cdd3 100644 --- a/iov.h +++ b/iov.h @@ -16,8 +16,14 @@ size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, const void *buf, size_t iov_off, size_t size); size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, void *buf, size_t iov_off, size_t size); +size_t iov_rebuild(struct iovec *dest, unsigned int dest_cnt, + const struct iovec *src, const unsigned int src_cnt, + size_t src_off); size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt); size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, size_t iov_off, size_t size); void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, FILE *fp, const char *prefix, size_t limit); +uint32_t +iov_net_csum_add(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, size_t size); -- 1.7.7.6