Skip to content

Commit

Permalink
packet: Add IP pseudoheader checksum calculation.
Browse files Browse the repository at this point in the history
As OVS adds userspace support for being the endpoint in protocols
like tunnels, it will need to be able to calculate pseudoheaders
as part of the checksum calculation.

Signed-off-by: Jesse Gross <[email protected]>
Acked-by: Pravin B Shelar <[email protected]>
  • Loading branch information
jessegross committed Apr 7, 2015
1 parent e5a1cae commit 0292a0c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 1 deletion.
14 changes: 14 additions & 0 deletions lib/packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,3 +1043,17 @@ compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN],
dp_packet_set_frame(b, eth);
dp_packet_set_l3(b, arp);
}

uint32_t
packet_csum_pseudoheader(const struct ip_header *ip)
{
uint32_t partial = 0;

partial = csum_add32(partial, get_16aligned_be32(&ip->ip_src));
partial = csum_add32(partial, get_16aligned_be32(&ip->ip_dst));
partial = csum_add16(partial, htons(ip->ip_proto));
partial = csum_add16(partial, htons(ntohs(ip->ip_tot_len) -
IP_IHL(ip->ip_ihl_ver) * 4));

return partial;
}
1 change: 1 addition & 0 deletions lib/packets.h
Original file line number Diff line number Diff line change
Expand Up @@ -806,5 +806,6 @@ void packet_format_tcp_flags(struct ds *, uint16_t);
const char *packet_tcp_flag_to_string(uint32_t flag);
void compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN],
ovs_be32 ip_src, ovs_be32 ip_dst);
uint32_t packet_csum_pseudoheader(const struct ip_header *);

#endif /* packets.h */
2 changes: 1 addition & 1 deletion tests/library.at
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ AT_CHECK([ovstest test-flows flows pcap], [0], [checked 247 packets, 0 errors
AT_CLEANUP

AT_SETUP([test TCP/IP checksumming])
AT_CHECK([ovstest test-csum], [0], [....#....#....###................................#................................#
AT_CHECK([ovstest test-csum], [0], [....#....#....####................................#................................#
])
AT_CLEANUP

Expand Down
31 changes: 31 additions & 0 deletions tests/test-csum.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
#include <assert.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crc32c.h"
#include "ovstest.h"
#include "packets.h"
#include "random.h"
#include "unaligned.h"
#include "util.h"
Expand Down Expand Up @@ -175,6 +177,34 @@ test_crc32c(void)
mark('#');
}

/* Check the IP pseudoheader calculation. */
static void
test_pseudo(void)
{
/* Try an IP header similar to one that the tunnel code
* might generate. */
struct ip_header ip = {
.ip_ihl_ver = IP_IHL_VER(5, 4),
.ip_tos = 0,
.ip_tot_len = htons(134),
.ip_id = 0,
.ip_frag_off = htons(IP_DF),
.ip_ttl = 64,
.ip_proto = IPPROTO_UDP,
.ip_csum = htons(0x1265),
.ip_src = { .hi = htons(0x1400), .lo = htons(0x0002) },
.ip_dst = { .hi = htons(0x1400), .lo = htons(0x0001) }
};

assert(packet_csum_pseudoheader(&ip) == 0x8628);

/* And also test something totally different to check for
* corner cases. */
memset(&ip, 0xff, sizeof ip);
assert(packet_csum_pseudoheader(&ip) == 0x5c2fb);

mark('#');
}

static void
test_csum_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
Expand Down Expand Up @@ -239,6 +269,7 @@ test_csum_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)

test_rfc1624();
test_crc32c();
test_pseudo();

/* Test recalc_csum16(). */
for (i = 0; i < 32; i++) {
Expand Down

0 comments on commit 0292a0c

Please sign in to comment.