19 #ifndef __included_ip4_to_ip6_h__ 20 #define __included_ip4_to_ip6_h__ 40 #define frag_id_4to6(id) (id) 63 else if (ip->
protocol == IP_PROTOCOL_ICMP)
65 icmp46_header_t *icmp = (
void *) (ip + 1);
66 if (icmp->type == ICMP4_echo_request || icmp->type == ICMP4_echo_reply)
68 return *((
u16 *) (icmp + 1));
70 else if (clib_net_to_host_u16 (ip->
length) >= 64)
79 else if (ip->
protocol == IP_PROTOCOL_ICMP)
81 icmp46_header_t *icmp = (
void *) (ip + 1);
82 if (icmp->type == ICMP4_echo_request ||
83 icmp->type == ICMP4_echo_reply)
85 return *((
u16 *) (icmp + 1));
107 case ICMP4_echo_reply:
108 icmp->type = ICMP6_echo_reply;
110 case ICMP4_echo_request:
111 icmp->type = ICMP6_echo_request;
113 case ICMP4_destination_unreachable:
118 case ICMP4_destination_unreachable_destination_unreachable_net:
119 case ICMP4_destination_unreachable_destination_unreachable_host:
120 icmp->type = ICMP6_destination_unreachable;
121 icmp->code = ICMP6_destination_unreachable_no_route_to_destination;
123 case ICMP4_destination_unreachable_protocol_unreachable:
124 icmp->type = ICMP6_parameter_problem;
125 icmp->code = ICMP6_parameter_problem_unrecognized_next_header;
127 case ICMP4_destination_unreachable_port_unreachable:
128 icmp->type = ICMP6_destination_unreachable;
129 icmp->code = ICMP6_destination_unreachable_port_unreachable;
131 case ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set:
133 ICMP6_packet_too_big;
136 u32 advertised_mtu = clib_net_to_host_u32 (*((
u32 *) (icmp + 1)));
138 advertised_mtu += 20;
140 advertised_mtu = 1000;
143 *((
u32 *) (icmp + 1)) = clib_host_to_net_u32 (advertised_mtu);
147 case ICMP4_destination_unreachable_source_route_failed:
148 case ICMP4_destination_unreachable_destination_network_unknown:
149 case ICMP4_destination_unreachable_destination_host_unknown:
150 case ICMP4_destination_unreachable_source_host_isolated:
151 case ICMP4_destination_unreachable_network_unreachable_for_type_of_service:
152 case ICMP4_destination_unreachable_host_unreachable_for_type_of_service:
154 ICMP6_destination_unreachable;
155 icmp->code = ICMP6_destination_unreachable_no_route_to_destination;
157 case ICMP4_destination_unreachable_network_administratively_prohibited:
158 case ICMP4_destination_unreachable_host_administratively_prohibited:
159 case ICMP4_destination_unreachable_communication_administratively_prohibited:
160 case ICMP4_destination_unreachable_precedence_cutoff_in_effect:
161 icmp->type = ICMP6_destination_unreachable;
163 ICMP6_destination_unreachable_destination_administratively_prohibited;
165 case ICMP4_destination_unreachable_host_precedence_violation:
171 case ICMP4_time_exceeded:
173 icmp->type = ICMP6_time_exceeded;
176 case ICMP4_parameter_problem:
181 case ICMP4_parameter_problem_pointer_indicates_error:
182 case ICMP4_parameter_problem_bad_length:
183 icmp->type = ICMP6_parameter_problem;
184 icmp->code = ICMP6_parameter_problem_erroneous_header_field;
191 *((
u32 *) (icmp + 1)) = clib_host_to_net_u32 (ptr);
226 icmp46_header_t *icmp;
228 ip6_frag_hdr_t *inner_frag;
230 u32 inner_frag_offset;
232 u16 *inner_L4_checksum = 0;
236 ip_len = clib_net_to_host_u16 (ip4->
length);
237 ASSERT (ip_len <= p->current_length);
239 icmp = (icmp46_header_t *) (ip4 + 1);
260 -2 * (
sizeof (*ip6) -
sizeof (*ip4)) -
261 sizeof (*inner_frag));
267 icmp = (icmp46_header_t *) (ip4 + 1);
271 sizeof (*ip4) -
sizeof (*ip6) -
272 sizeof (*inner_frag));
274 (ip6_frag_hdr_t *)
u8_ptr_add (inner_ip6,
sizeof (*inner_ip6));
277 sizeof (*ip6) - 2 *
sizeof (*ip4) +
278 sizeof (*inner_frag));
293 icmp = (icmp46_header_t *)
u8_ptr_add (ip4,
sizeof (*ip4));
296 sizeof (*ip4) -
sizeof (*ip6));
304 inner_L4_checksum = &((
tcp_header_t *) (inner_ip4 + 1))->checksum;
312 inner_L4_checksum = &((
udp_header_t *) (inner_ip4 + 1))->checksum;
313 if (*inner_L4_checksum)
319 else if (inner_ip4->
protocol == IP_PROTOCOL_ICMP)
323 icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_ip4 + 1);
325 inner_icmp->type = (inner_icmp->type == ICMP4_echo_request) ?
326 ICMP6_echo_request : ICMP6_echo_reply;
327 inner_L4_checksum = &inner_icmp->checksum;
328 inner_ip4->
protocol = IP_PROTOCOL_ICMP6;
337 clib_host_to_net_u32 ((6 << 28) + (inner_ip4->
tos << 20));
343 if ((rv = inner_fn (inner_ip4, inner_ip6, inner_ctx)) != 0)
348 inner_frag->next_hdr = inner_ip6->
protocol;
349 inner_frag->identification = inner_frag_id;
351 inner_frag->fragment_offset_and_more =
353 inner_ip6->
protocol = IP_PROTOCOL_IPV6_FRAGMENTATION;
355 clib_host_to_net_u16 (clib_net_to_host_u16
357 sizeof (*inner_frag));
360 csum = *inner_L4_checksum;
361 if (inner_ip6->
protocol == IP_PROTOCOL_ICMP6)
364 icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_ip4 + 1);
366 inner_icmp->checksum = 0;
370 clib_host_to_net_u16 (inner_ip6->
protocol));
403 clib_host_to_net_u16 (clib_net_to_host_u16 (ip4->
length) -
409 clib_host_to_net_u32 ((6 << 28) + (ip4->
tos << 20));
414 if ((rv = fn (ip4, ip6, ctx)) != 0)
420 ip6->
payload_length = clib_host_to_net_u16 (1280 -
sizeof (*ip6));
454 ip6_frag_hdr_t *frag;
458 frag = (ip6_frag_hdr_t *)
u8_ptr_add (ip4,
sizeof (*ip4) -
sizeof (*frag));
461 sizeof (*ip4) -
sizeof (*frag) -
471 frag->fragment_offset_and_more =
478 clib_host_to_net_u32 ((6 << 28) + (ip4->
tos << 20));
480 clib_host_to_net_u16 (clib_net_to_host_u16 (ip4->
length) -
481 sizeof (*ip4) +
sizeof (*frag));
483 ip6->
protocol = IP_PROTOCOL_IPV6_FRAGMENTATION;
485 if ((rv = fn (ip4, ip6, ctx)) != 0)
507 ip6_frag_hdr_t *frag;
514 if (ip4->
protocol == IP_PROTOCOL_UDP)
523 u16 udp_len = clib_host_to_net_u16 (ip4->
length) -
sizeof (*ip4);
535 checksum = &tcp->checksum;
547 sizeof (*ip4) -
sizeof (*ip6) -
550 (ip6_frag_hdr_t *)
u8_ptr_add (ip4,
sizeof (*ip4) -
sizeof (*frag));
556 ip6 = (
ip6_header_t *) (((
u8 *) ip4) +
sizeof (*ip4) -
sizeof (*ip6));
562 clib_host_to_net_u32 ((6 << 28) + (ip4->
tos << 20));
570 frag->identification = frag_id;
573 ip6->
protocol = IP_PROTOCOL_IPV6_FRAGMENTATION;
577 if ((rv = fn (ip4, ip6, ctx)) != 0)
605 ip6_frag_hdr_t *frag;
617 sizeof (*ip4) -
sizeof (*ip6) -
620 (ip6_frag_hdr_t *)
u8_ptr_add (ip4,
sizeof (*ip4) -
sizeof (*frag));
626 ip6 = (
ip6_header_t *) (((
u8 *) ip4) +
sizeof (*ip4) -
sizeof (*ip6));
632 clib_host_to_net_u32 ((6 << 28) + (ip4->
tos << 20));
640 frag->identification = frag_id;
643 ip6->
protocol = IP_PROTOCOL_IPV6_FRAGMENTATION;
647 if ((rv = fn (ip4, ip6, ctx)) != 0)
static u8 icmp_to_icmp6_updater_pointer_table[]
static ip_csum_t ip_csum_with_carry(ip_csum_t sum, ip_csum_t x)
struct _tcp_header tcp_header_t
#define u16_net_add(u, val)
ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
static int ip4_get_fragment_offset(ip4_header_t *i)
static void * ip4_next_header(ip4_header_t *i)
int(* ip4_to_ip6_set_fn_t)(ip4_header_t *ip4, ip6_header_t *ip6, void *ctx)
IPv4 to IPv6 set call back function type.
static u16 ip4_get_port(ip4_header_t *ip, u8 sender)
Get TCP/UDP port number or ICMP id from IPv4 packet.
static int ip4_is_fragment(ip4_header_t *i)
u16 current_length
Nbytes between current data and the end of this buffer.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static int icmp_to_icmp6_header(icmp46_header_t *icmp, ip4_header_t **inner_ip4)
Convert type and code value from ICMP4 to ICMP6.
#define IP4_HEADER_FLAG_MORE_FRAGMENTS
static int ip4_to_ip6_tcp_udp(vlib_buffer_t *p, ip4_to_ip6_set_fn_t fn, void *ctx)
Translate IPv4 UDP/TCP packet to IPv6.
#define clib_memcpy(a, b, c)
static int ip4_is_first_fragment(ip4_header_t *i)
#define u8_ptr_add(ptr, index)
static ip_csum_t ip_csum_sub_even(ip_csum_t c, ip_csum_t x)
static int icmp_to_icmp6(vlib_buffer_t *p, ip4_to_ip6_set_fn_t fn, void *ctx, ip4_to_ip6_set_fn_t inner_fn, void *inner_ctx)
Translate ICMP4 packet to ICMP6.
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
static int ip4_to_ip6_fragmented(vlib_buffer_t *p, ip4_to_ip6_set_fn_t fn, void *ctx)
Translate IPv4 fragmented packet to IPv6.
static int ip4_to_ip6(vlib_buffer_t *p, ip4_to_ip6_set_fn_t fn, void *ctx)
Translate IPv4 packet to IPv6 (IP header only).
#define ip6_frag_hdr_offset_and_more(offset, more)
static u16 ip_csum_fold(ip_csum_t c)
static ip_csum_t ip_csum_add_even(ip_csum_t c, ip_csum_t x)