19 #ifndef __included_ip4_to_ip6_h__
20 #define __included_ip4_to_ip6_h__
40 #define frag_id_4to6(id) (id)
53 if (
ip->ip_version_and_header_length != 0x45 ||
58 (
ip->protocol == IP_PROTOCOL_UDP)))
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)
70 else if (clib_net_to_host_u16 (
ip->length) >= 64)
74 (
ip->protocol == IP_PROTOCOL_UDP)))
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)
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;
229 ip6_frag_hdr_t *outer_frag= NULL;
231 u32 inner_frag_offset;
234 u16 *inner_L4_checksum = 0;
238 ip_len = clib_net_to_host_u16 (
ip4->length);
239 ASSERT (ip_len <= p->current_length);
241 icmp = (icmp46_header_t *) (
ip4 + 1);
262 -2 * (
sizeof (*
ip6) -
sizeof (*
ip4)) -
263 sizeof (*inner_frag));
269 icmp = (icmp46_header_t *) (
ip4 + 1);
273 sizeof (*
ip4) -
sizeof (*ip6) -
274 sizeof (*inner_frag));
276 (ip6_frag_hdr_t *)
u8_ptr_add (inner_ip6,
sizeof (*inner_ip6));
277 ip6->payload_length =
279 sizeof (*
ip6) - 2 *
sizeof (*
ip4) +
280 sizeof (*inner_frag));
298 sizeof (*
ip4) -
sizeof (*ip6));
299 ip6->payload_length =
306 inner_L4_checksum = &((
tcp_header_t *) (inner_ip4 + 1))->checksum;
314 inner_L4_checksum = &((
udp_header_t *) (inner_ip4 + 1))->checksum;
315 if (*inner_L4_checksum)
321 else if (inner_ip4->
protocol == IP_PROTOCOL_ICMP)
325 icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_ip4 + 1);
327 inner_icmp->type = (inner_icmp->type == ICMP4_echo_request) ?
328 ICMP6_echo_request : ICMP6_echo_reply;
329 inner_L4_checksum = &inner_icmp->checksum;
330 inner_ip4->
protocol = IP_PROTOCOL_ICMP6;
339 clib_host_to_net_u32 ((6 << 28) + (inner_ip4->
tos << 20));
345 if ((
rv = inner_fn (p, inner_ip4, inner_ip6, inner_ctx)) != 0)
350 inner_frag->next_hdr = inner_ip6->
protocol;
351 inner_frag->identification = inner_frag_id;
353 inner_frag->fragment_offset_and_more =
355 inner_ip6->
protocol = IP_PROTOCOL_IPV6_FRAGMENTATION;
357 clib_host_to_net_u16 (clib_net_to_host_u16
359 sizeof (*inner_frag));
362 csum = *inner_L4_checksum;
363 if (inner_ip6->
protocol == IP_PROTOCOL_ICMP6)
366 icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_ip4 + 1);
368 inner_icmp->checksum = 0;
372 clib_host_to_net_u16 (inner_ip6->
protocol));
406 sizeof (*outer_frag));
408 outer_frag = (ip6_frag_hdr_t *) (
ip6 + 1);
416 ip6->payload_length =
417 clib_host_to_net_u16 (clib_net_to_host_u16 (
ip4->length) -
422 ip6->ip_version_traffic_class_and_flow_label =
423 clib_host_to_net_u32 ((6 << 28) + (
ip4->tos << 20));
425 ip6->hop_limit =
ip4->ttl;
426 ip6->protocol = IP_PROTOCOL_ICMP6;
433 outer_frag->next_hdr =
ip6->protocol;
434 outer_frag->identification = outer_frag_id;
437 ip6->protocol = IP_PROTOCOL_IPV6_FRAGMENTATION;
439 sizeof (*outer_frag));
445 ip6->payload_length = clib_host_to_net_u16 (1280 -
sizeof (*
ip6));
459 clib_net_to_host_u16 (
ip6->payload_length));