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;
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));
265 memmove (
u8_ptr_add (ip6,
sizeof (*ip6) -
sizeof (*ip4)), ip4,
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));
279 sizeof (*ip6) - 2 *
sizeof (*ip4) +
280 sizeof (*inner_frag));
291 memmove (
u8_ptr_add (ip6,
sizeof (*ip6) -
sizeof (*ip4)), ip4,
295 icmp = (icmp46_header_t *)
u8_ptr_add (ip4,
sizeof (*ip4));
298 sizeof (*ip4) -
sizeof (*ip6));
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);
417 clib_host_to_net_u16 (clib_net_to_host_u16 (ip4->
length) -
423 clib_host_to_net_u32 ((6 << 28) + (ip4->
tos << 20));
428 if ((rv = fn (p, ip4, ip6, ctx)) != 0)
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));
static u8 icmp_to_icmp6_updater_pointer_table[]
u16 current_length
Nbytes between current data and the end of this buffer.
static ip_csum_t ip_csum_with_carry(ip_csum_t sum, ip_csum_t x)
struct _tcp_header tcp_header_t
static int ip4_is_fragment(const ip4_header_t *i)
#define u8_ptr_add(ptr, index)
int(* ip4_to_ip6_set_fn_t)(vlib_buffer_t *b, 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 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 u16 ip4_get_fragment_offset(const ip4_header_t *i)
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_is_first_fragment(const ip4_header_t *i)
VLIB buffer representation.
#define u16_net_add(u, val)
#define ip6_frag_hdr_offset_and_more(offset, more)
static ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
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)