net: spit out ip checksum routines into their own file
This commit is contained in:
5
build.mk
5
build.mk
@@ -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
|
||||
|
||||
|
||||
50
net/ip.cc
50
net/ip.cc
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
61
net/ip_checksum.cc
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user