-ip_csum_t
-ip_csum_and_memcpy (ip_csum_t sum, void *dst, void *src, uword n_bytes)
-{
- uword n_left;
- ip_csum_t sum0 = sum, sum1;
- n_left = n_bytes;
-
- if (n_left && (pointer_to_uword (dst) & sizeof (u8)))
- {
- u8 *d8, val;
-
- d8 = dst;
- val = ((u8 *) src)[0];
- d8[0] = val;
- dst += 1;
- src += 1;
- n_left -= 1;
- sum0 =
- ip_csum_with_carry (sum0, val << (8 * CLIB_ARCH_IS_LITTLE_ENDIAN));
- }
-
- while ((n_left >= sizeof (u16))
- && (pointer_to_uword (dst) & (sizeof (sum) - sizeof (u16))))
- {
- u16 *d16, *s16;
-
- d16 = dst;
- s16 = src;
-
- d16[0] = clib_mem_unaligned (&s16[0], u16);
-
- sum0 = ip_csum_with_carry (sum0, d16[0]);
- dst += sizeof (u16);
- src += sizeof (u16);
- n_left -= sizeof (u16);
- }
-
- sum1 = 0;
- while (n_left >= 2 * sizeof (sum))
- {
- ip_csum_t dst0, dst1;
- ip_csum_t *dst_even, *src_even;
-
- dst_even = dst;
- src_even = src;
- dst0 = clib_mem_unaligned (&src_even[0], ip_csum_t);
- dst1 = clib_mem_unaligned (&src_even[1], ip_csum_t);
-
- dst_even[0] = dst0;
- dst_even[1] = dst1;
-
- dst += 2 * sizeof (dst_even[0]);
- src += 2 * sizeof (dst_even[0]);
- n_left -= 2 * sizeof (dst_even[0]);
+/*
+ * Note: the tcp / udp checksum calculation is performance critical
+ * [e.g. when NIC h/w offload is not available],
+ * so it's worth producing architecture-dependent code.
+ *
+ * ip_incremental_checksum() is an always-inlined static
+ * function which uses the function pointer we set up in
+ * ip_checksum_init().
+ */