net: spit out ip checksum routines into their own file

This commit is contained in:
Avi Kivity
2014-09-16 10:24:28 +03:00
parent 812ac77d2f
commit 5e2f1f0bc6
5 changed files with 72 additions and 52 deletions

View File

@@ -45,6 +45,7 @@ clean:
rm seastar $(tests) *.o
libnet = net/virtio.o net/net.o net/ip.o net/ethernet.o net/arp.o net/stack.o net/packet.o
libnet += net/ip_checksum.o
apps/seastar/seastar: apps/seastar/main.o core/reactor.o
$(link)
@@ -56,12 +57,16 @@ apps/httpd/httpd: apps/httpd/httpd.o core/reactor.o $(libnet)
tests/fileiotest: tests/fileiotest.o core/reactor.o
tests/virtiotest: tests/virtiotest.o net/virtio.o core/reactor.o net/net.o net/ip.o net/ethernet.o net/arp.o net/packet.o
tests/virtiotest: net/ip_checksum.o
tests/l3_test: tests/l3_test.o net/virtio.o core/reactor.o net/net.o net/ip.o net/ethernet.o net/arp.o net/packet.o
tests/l3_test: net/ip_checksum.o
tests/ip_test: tests/ip_test.o net/virtio.o core/reactor.o net/net.o net/ip.o net/arp.o net/ethernet.o net/packet.o
tests/ip_test: net/ip_checksum.o
tests/tcp_test: tests/tcp_test.o net/virtio.o core/reactor.o net/net.o net/ip.o net/arp.o net/ethernet.o net/packet.o
tests/tcp_test: net/ip_checksum.o
tests/timertest: tests/timertest.o core/reactor.o

View File

@@ -17,35 +17,6 @@ std::ostream& operator<<(std::ostream& os, ipv4_address a) {
(ip >> 0) & 0xff);
}
uint16_t ip_checksum(const void* data, size_t len) {
uint64_t csum = 0;
auto p64 = reinterpret_cast<const packed<uint64_t>*>(data);
while (len >= 8) {
auto old = csum;
csum += ntohq(*p64++);
csum += (csum < old);
len -= 8;
}
auto p16 = reinterpret_cast<const packed<uint16_t>*>(p64);
while (len >= 2) {
auto old = csum;
csum += ntohs(*p16++);
csum += (csum < old);
len -= 2;
}
auto p8 = reinterpret_cast<const uint8_t*>(p16);
if (len) {
auto old = csum;
csum += *p8++ << 8;
csum += (csum < old);
len -= 1;
}
csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48);
csum = (csum & 0xffff) + (csum >> 16);
csum = (csum & 0xffff) + (csum >> 16);
return htons(~csum);
}
ipv4::ipv4(interface* netif)
: _netif(netif)
, _global_arp(netif)
@@ -128,25 +99,4 @@ void ipv4::set_host_address(ipv4_address ip) {
_arp.set_self_addr(ip);
}
void checksummer::sum(const char* data, size_t len) {
auto orig_len = len;
if (odd) {
partial += uint8_t(*data++);
--len;
}
partial += ip_checksum(data, len);
odd ^= orig_len & 1;
}
void checksummer::sum(const packet& p) {
for (auto&& f : p.fragments) {
sum(f.base, f.size);
}
}
uint16_t checksummer::get() const {
auto tmp = (partial & 0xffff) + (partial >> 16);
return tmp + (tmp >> 16);
}
}

View File

@@ -18,8 +18,6 @@
namespace net {
uint16_t ip_checksum(const void* data, size_t len);
class ipv4;
template <uint8_t ProtoNum>
class ipv4_l4;

61
net/ip_checksum.cc Normal file
View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2014 Cloudius Systems, Ltd.
*/
#include "ip_checksum.hh"
#include "net.hh"
#include <arpa/inet.h>
namespace net {
uint16_t ip_checksum(const void* data, size_t len) {
uint64_t csum = 0;
auto p64 = reinterpret_cast<const packed<uint64_t>*>(data);
while (len >= 8) {
auto old = csum;
csum += ntohq(*p64++);
csum += (csum < old);
len -= 8;
}
auto p16 = reinterpret_cast<const packed<uint16_t>*>(p64);
while (len >= 2) {
auto old = csum;
csum += ntohs(*p16++);
csum += (csum < old);
len -= 2;
}
auto p8 = reinterpret_cast<const uint8_t*>(p16);
if (len) {
auto old = csum;
csum += *p8++ << 8;
csum += (csum < old);
len -= 1;
}
csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48);
csum = (csum & 0xffff) + (csum >> 16);
csum = (csum & 0xffff) + (csum >> 16);
return htons(~csum);
}
void checksummer::sum(const char* data, size_t len) {
auto orig_len = len;
if (odd) {
partial += uint8_t(*data++);
--len;
}
partial += ip_checksum(data, len);
odd ^= orig_len & 1;
}
void checksummer::sum(const packet& p) {
for (auto&& f : p.fragments) {
sum(f.base, f.size);
}
}
uint16_t checksummer::get() const {
auto tmp = (partial & 0xffff) + (partial >> 16);
return tmp + (tmp >> 16);
}
}

View File

@@ -5,8 +5,14 @@
#ifndef IP_CHECKSUM_HH_
#define IP_CHECKSUM_HH_
#include "packet.hh"
#include <cstdint>
#include <cstddef>
namespace net {
uint16_t ip_checksum(const void* data, size_t len);
struct checksummer {
uint32_t partial = 0;
bool odd = false;