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>
This commit is contained in:
parent
5acf5ea4bc
commit
8402630169
@ -38,4 +38,16 @@ net_raw_checksum(uint8_t *data, int length)
|
|||||||
return net_checksum_finish(net_checksum_add(length, data));
|
return net_checksum_finish(net_checksum_add(length, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* net_checksum_add_iov: scatter-gather vector checksumming
|
||||||
|
*
|
||||||
|
* @iov: input scatter-gather array
|
||||||
|
* @iov_cnt: number of array elements
|
||||||
|
* @iov_off: starting iov offset for checksumming
|
||||||
|
* @size: length of data to be checksummed
|
||||||
|
*/
|
||||||
|
uint32_t net_checksum_add_iov(const struct iovec *iov,
|
||||||
|
const unsigned int iov_cnt,
|
||||||
|
uint32_t iov_off, uint32_t size);
|
||||||
|
|
||||||
#endif /* QEMU_NET_CHECKSUM_H */
|
#endif /* QEMU_NET_CHECKSUM_H */
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
#include "net/checksum.h"
|
#include "net/checksum.h"
|
||||||
|
|
||||||
#define PROTO_TCP 6
|
#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] = csum >> 8;
|
||||||
data[14+hlen+csum_offset+1] = csum & 0xff;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user