diff options
author | Matus Fabian <matfabia@cisco.com> | 2017-06-15 02:28:50 -0700 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2017-06-19 11:08:47 +0000 |
commit | 029f3d2c1c6b04a6cfef17242cb36b304025fe23 (patch) | |
tree | 5036e25543b5d43deeb15fde31135a3531d864ce /src/vnet/ip/ip6_to_ip4.h | |
parent | acd4c63e3c6e70ea3f58527d9bace7c0e38df719 (diff) |
NAT64: Hairpinning (VPP-699)
Change-Id: I83a6c277fa211ac2c2ca2d603650c992886af0a7
Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src/vnet/ip/ip6_to_ip4.h')
-rw-r--r-- | src/vnet/ip/ip6_to_ip4.h | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/src/vnet/ip/ip6_to_ip4.h b/src/vnet/ip/ip6_to_ip4.h index 92f73ba165d..7a0d534959c 100644 --- a/src/vnet/ip/ip6_to_ip4.h +++ b/src/vnet/ip/ip6_to_ip4.h @@ -314,13 +314,9 @@ icmp6_to_icmp (vlib_buffer_t * p, ip6_to_ip4_set_fn_t fn, void *ctx, else if (inner_protocol == IP_PROTOCOL_ICMP6) { icmp46_header_t *inner_icmp = (icmp46_header_t *) inner_l4; - csum = inner_icmp->checksum; - csum = ip_csum_sub_even (csum, *((u16 *) inner_icmp)); //It cannot be of a different type as ip6_icmp_to_icmp6_in_place succeeded inner_icmp->type = (inner_icmp->type == ICMP6_echo_request) ? ICMP4_echo_request : ICMP4_echo_reply; - csum = ip_csum_add_even (csum, *((u16 *) inner_icmp)); - inner_icmp->checksum = ip_csum_fold (csum); inner_protocol = IP_PROTOCOL_ICMP; //Will be copied to ip6 later inner_L4_checksum = &inner_icmp->checksum; } @@ -334,6 +330,7 @@ icmp6_to_icmp (vlib_buffer_t * p, ip6_to_ip4_set_fn_t fn, void *ctx, csum = ip_csum_sub_even (csum, inner_ip6->src_address.as_u64[1]); csum = ip_csum_sub_even (csum, inner_ip6->dst_address.as_u64[0]); csum = ip_csum_sub_even (csum, inner_ip6->dst_address.as_u64[1]); + *inner_L4_checksum = ip_csum_fold (csum); if ((rv = inner_fn (inner_ip6, inner_ip4, inner_ctx)) != 0) return rv; @@ -353,19 +350,23 @@ icmp6_to_icmp (vlib_buffer_t * p, ip6_to_ip4_set_fn_t fn, void *ctx, if (inner_ip4->protocol == IP_PROTOCOL_ICMP) { - //Remove remainings of the pseudo-header in the csum - csum = - ip_csum_sub_even (csum, clib_host_to_net_u16 (IP_PROTOCOL_ICMP6)); + //Recompute ICMP checksum + icmp46_header_t *inner_icmp = (icmp46_header_t *) inner_l4; + inner_icmp->checksum = 0; csum = - ip_csum_sub_even (csum, inner_ip4->length - sizeof (*inner_ip4)); + ip_incremental_checksum (0, inner_icmp, + clib_net_to_host_u16 (inner_ip4->length) + - sizeof (*inner_ip4)); + inner_icmp->checksum = ~ip_csum_fold (csum); } else { //Update to new pseudo-header + csum = *inner_L4_checksum; csum = ip_csum_add_even (csum, inner_ip4->src_address.as_u32); csum = ip_csum_add_even (csum, inner_ip4->dst_address.as_u32); + *inner_L4_checksum = ip_csum_fold (csum); } - *inner_L4_checksum = ip_csum_fold (csum); //Move up icmp header ip4 = (ip4_header_t *) u8_ptr_add (inner_l4, -2 * sizeof (*ip4) - 8); @@ -512,6 +513,7 @@ ip6_to_ip4_tcp_udp (vlib_buffer_t * p, ip6_to_ip4_set_fn_t fn, void *ctx, csum = ip_csum_sub_even (csum, ip6->src_address.as_u64[1]); csum = ip_csum_sub_even (csum, ip6->dst_address.as_u64[0]); csum = ip_csum_sub_even (csum, ip6->dst_address.as_u64[1]); + *checksum = ip_csum_fold (csum); no_csum: ip4 = (ip4_header_t *) u8_ptr_add (ip6, l4_offset - sizeof (*ip4)); @@ -552,7 +554,7 @@ no_csum: } else { - csum = ip_csum_add_even (csum, ip4->dst_address.as_u32); + csum = ip_csum_add_even (*checksum, ip4->dst_address.as_u32); csum = ip_csum_add_even (csum, ip4->src_address.as_u32); *checksum = ip_csum_fold (csum); } |