36 tag = t->
is_slow_path ?
"NAT64-in2out-slowpath" :
"NAT64-in2out";
45 #define foreach_nat64_in2out_error \
46 _(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
47 _(NO_TRANSLATION, "no translation") \
53 #define _(sym,str) NAT64_IN2OUT_ERROR_##sym,
60 #define _(sym,string) string,
119 if (
nm->addr_pool[
i].addr.as_u32 ==
dst_addr->as_u32[3])
137 nat64_db_bib_entry_t *bibe;
138 nat64_db_st_entry_t *ste;
139 ip46_address_t old_saddr, old_daddr;
152 u32 ip_version_traffic_class_and_flow_label =
153 ip6->ip_version_traffic_class_and_flow_label;
154 u16 payload_length =
ip6->payload_length;
157 old_saddr.as_u64[0] =
ip6->src_address.as_u64[0];
158 old_saddr.as_u64[1] =
ip6->src_address.as_u64[1];
159 old_daddr.as_u64[0] =
ip6->dst_address.as_u64[0];
160 old_daddr.as_u64[1] =
ip6->dst_address.as_u64[1];
165 ip6_frag_hdr_t *hdr =
178 ip4->ip_version_and_header_length =
183 ip4->fragment_id = fragment_id;
184 ip4->flags_and_fragment_offset =
185 clib_host_to_net_u16 (frag_offset |
188 ip4->protocol = (
proto == IP_PROTOCOL_ICMP6) ? IP_PROTOCOL_ICMP :
proto;
215 &out_port,
ctx->thread_index))
220 &old_saddr.ip6, &out_addr,
sport,
221 out_port, fib_index,
proto, 0);
232 &old_daddr.ip6, &new_daddr,
dport);
240 ip4->src_address.as_u32 = bibe->out_addr.as_u32;
241 ip4->dst_address.as_u32 = ste->out_r_addr.as_u32;
251 if (
proto == IP_PROTOCOL_UDP)
283 nat64_db_bib_entry_t *bibe;
284 nat64_db_st_entry_t *ste;
285 ip46_address_t saddr, daddr;
294 saddr.as_u64[0] =
ip6->src_address.as_u64[0];
295 saddr.as_u64[1] =
ip6->src_address.as_u64[1];
296 daddr.as_u64[0] =
ip6->dst_address.as_u64[0];
297 daddr.as_u64[1] =
ip6->dst_address.as_u64[1];
299 if (
icmp->type == ICMP4_echo_request ||
icmp->type == ICMP4_echo_reply)
304 IP_PROTOCOL_ICMP, fib_index, 1);
318 IP_PROTOCOL_ICMP, fib_index, 1);
325 (fib_index, NAT_PROTOCOL_ICMP, &out_addr, &out_id,
331 &
ip6->src_address, &out_addr,
332 in_id, out_id, fib_index,
333 IP_PROTOCOL_ICMP, 0);
344 &
ip6->dst_address, &daddr.ip4, 0);
354 ip4->src_address.as_u32 = bibe->out_addr.as_u32;
355 ((
u16 *) (
icmp))[2] = bibe->out_port;
357 ip4->dst_address.as_u32 = ste->out_r_addr.as_u32;
364 ip4->src_address.as_u32 =
nm->addr_pool[0].addr.as_u32;
377 nat64_db_st_entry_t *ste;
378 nat64_db_bib_entry_t *bibe;
379 ip46_address_t saddr, daddr;
388 saddr.as_u64[0] =
ip6->src_address.as_u64[0];
389 saddr.as_u64[1] =
ip6->src_address.as_u64[1];
390 daddr.as_u64[0] =
ip6->dst_address.as_u64[0];
391 daddr.as_u64[1] =
ip6->dst_address.as_u64[1];
393 if (
proto == IP_PROTOCOL_ICMP6)
397 proto = IP_PROTOCOL_ICMP;
400 (
icmp->type == ICMP4_echo_request
401 ||
icmp->type == ICMP4_echo_reply))
414 ip4->dst_address.as_u32 = bibe->out_addr.as_u32;
415 ((
u16 *) (
icmp))[2] = bibe->out_port;
416 ip4->src_address.as_u32 = ste->out_r_addr.as_u32;
438 ip4->dst_address.as_u32 = bibe->out_addr.as_u32;
440 ip4->src_address.as_u32 = ste->out_r_addr.as_u32;
442 if (
proto == IP_PROTOCOL_TCP)
443 checksum = &tcp->checksum;
469 nat64_db_bib_entry_t *bibe;
470 ip46_address_t saddr, daddr;
480 && bibe->fib_index ==
ctx->fib_index)
483 saddr.ip4.as_u32 = bibe->out_addr.as_u32;
488 (db, &daddr, &saddr, 0, 0,
ctx->proto,
ctx->fib_index, 0))
491 ctx->out_addr.as_u32 = bibe->out_addr.as_u32;
501 u16 l4_offset,
u16 frag_hdr_offset,
519 ip6_frag_hdr_t *hdr =
533 nat64_db_bib_entry_t *bibe;
534 nat64_db_st_entry_t *ste;
535 ip46_address_t saddr, daddr,
addr;
544 saddr.as_u64[0] =
ip6->src_address.as_u64[0];
545 saddr.as_u64[1] =
ip6->src_address.as_u64[1];
546 daddr.as_u64[0] =
ip6->dst_address.as_u64[0];
547 daddr.as_u64[1] =
ip6->dst_address.as_u64[1];
568 .src_addr.as_u64[0] =
ip6->src_address.as_u64[0],
569 .src_addr.as_u64[1] =
ip6->src_address.as_u64[1],
570 .dst_addr.as_u64[0] =
ip6->dst_address.as_u64[0],
571 .dst_addr.as_u64[1] =
ip6->dst_address.as_u64[1],
572 .out_addr.as_u32 = 0,
573 .fib_index = fib_index,
574 .proto = l4_protocol,
580 if (!
ctx.out_addr.as_u32)
585 addr.ip4.as_u32 =
ctx.out_addr.as_u32;
587 ctx.out_addr.as_u32 = 0;
589 if (!
ctx.out_addr.as_u32)
593 addr.ip4.as_u32 =
nm->addr_pool[
i].addr.as_u32;
595 (db, &
addr, 0, l4_protocol, 0, 0))
600 if (!
ctx.out_addr.as_u32)
605 &
ip6->src_address, &
ctx.out_addr,
606 0, 0, fib_index, l4_protocol, 0);
617 &
ip6->dst_address, &daddr.ip4, 0);
627 ip4->src_address.as_u32 = bibe->out_addr.as_u32;
628 ip4->dst_address.as_u32 = ste->out_r_addr.as_u32;
630 ip4->ip_version_and_header_length =
634 sizeof (*
ip4) +
sizeof (*
ip6) - l4_offset);
635 ip4->fragment_id = fragment_id;
636 ip4->flags_and_fragment_offset =
637 clib_host_to_net_u16 (frag_offset |
639 ip4->ttl =
ip6->hop_limit;
640 ip4->protocol = l4_protocol;
652 nat64_db_bib_entry_t *bibe;
653 nat64_db_st_entry_t *ste;
654 ip46_address_t saddr, daddr;
661 u16 *checksum = NULL;
669 saddr.as_u64[0] =
ip6->src_address.as_u64[0];
670 saddr.as_u64[1] =
ip6->src_address.as_u64[1];
671 daddr.as_u64[0] =
ip6->dst_address.as_u64[0];
672 daddr.as_u64[1] =
ip6->dst_address.as_u64[1];
676 if (
proto == IP_PROTOCOL_UDP)
679 checksum = &tcp->checksum;
711 &out_addr,
sport, out_port, fib_index,
731 if (
proto == IP_PROTOCOL_TCP)
744 daddr.ip4.as_u32 = ste->out_r_addr.as_u32;
760 ip6->dst_address.as_u64[0] = bibe->in_addr.as_u64[0];
761 ip6->dst_address.as_u64[1] = bibe->in_addr.as_u64[1];
785 nat64_db_bib_entry_t *bibe;
786 nat64_db_st_entry_t *ste;
789 ip46_address_t saddr, daddr;
798 if (
icmp->type == ICMP6_echo_request ||
icmp->type == ICMP6_echo_reply)
805 if (
proto == IP_PROTOCOL_ICMP6)
812 saddr.as_u64[0] = inner_ip6->
src_address.as_u64[0];
813 saddr.as_u64[1] = inner_ip6->
src_address.as_u64[1];
814 daddr.as_u64[0] = inner_ip6->
dst_address.as_u64[0];
815 daddr.as_u64[1] = inner_ip6->
dst_address.as_u64[1];
823 if (
proto == IP_PROTOCOL_UDP)
826 checksum = &tcp->checksum;
850 saddr.ip4.as_u32 = ste->out_r_addr.as_u32;
851 daddr.ip4.as_u32 = bibe->out_addr.as_u32;
872 inner_ip6->
src_address.as_u64[0] = bibe->in_addr.as_u64[0];
873 inner_ip6->
src_address.as_u64[1] = bibe->in_addr.as_u64[1];
900 clib_net_to_host_u16 (
ip6->payload_length));
911 nat64_db_bib_entry_t *bibe;
912 nat64_db_st_entry_t *ste;
913 ip46_address_t saddr, daddr,
addr;
923 saddr.as_u64[0] =
ip6->src_address.as_u64[0];
924 saddr.as_u64[1] =
ip6->src_address.as_u64[1];
925 daddr.as_u64[0] =
ip6->dst_address.as_u64[0];
926 daddr.as_u64[1] =
ip6->dst_address.as_u64[1];
945 .src_addr.as_u64[0] =
ip6->src_address.as_u64[0],
946 .src_addr.as_u64[1] =
ip6->src_address.as_u64[1],
947 .dst_addr.as_u64[0] =
ip6->dst_address.as_u64[0],
948 .dst_addr.as_u64[1] =
ip6->dst_address.as_u64[1],
949 .out_addr.as_u32 = 0,
950 .fib_index = fib_index,
957 if (!
ctx.out_addr.as_u32)
962 addr.ip4.as_u32 =
ctx.out_addr.as_u32;
964 ctx.out_addr.as_u32 = 0;
966 if (!
ctx.out_addr.as_u32)
970 addr.ip4.as_u32 =
nm->addr_pool[
i].addr.as_u32;
976 if (!
ctx.out_addr.as_u32)
981 &
ctx.out_addr, 0, 0, fib_index,
proto,
1006 daddr.ip4.as_u32 = ste->out_r_addr.as_u32;
1022 ip6->dst_address.as_u64[0] = bibe->in_addr.as_u64[0];
1023 ip6->dst_address.as_u64[1] = bibe->in_addr.as_u64[1];
1053 u16 l4_offset0, frag_hdr_offset0;
1065 n_left_to_next -= 1;
1081 &frag_hdr_offset0)))
1084 b0->
error =
node->errors[NAT64_IN2OUT_ERROR_UNKNOWN];
1111 node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION];
1117 (
vm, b0, l4_protocol0, l4_offset0, frag_hdr_offset0,
1122 node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION];
1137 if (proto0 == NAT_PROTOCOL_ICMP)
1149 node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION];
1159 b0->
error =
node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION];
1163 else if (proto0 == NAT_PROTOCOL_TCP || proto0 == NAT_PROTOCOL_UDP)
1165 if (proto0 == NAT_PROTOCOL_TCP)
1180 node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION];
1186 (
vm, b0, l4_offset0, frag_hdr_offset0, &ctx0))
1189 b0->
error =
node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION];
1196 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
1214 n_left_to_next, bi0, next0);
1219 return frame->n_vectors;
1231 .name =
"nat64-in2out",
1232 .vector_size =
sizeof (
u32),
1257 .name =
"nat64-in2out-slowpath",
1258 .vector_size =
sizeof (
u32),
1285 #define foreach_nat64_in2out_handoff_error \
1286 _(CONGESTION_DROP, "congestion drop") \
1287 _(SAME_WORKER, "same worker") \
1288 _(DO_HANDOFF, "do handoff")
1292 #define _(sym,str) NAT64_IN2OUT_HANDOFF_ERROR_##sym,
1299 #define _(sym,string) string,
1333 u32 do_handoff = 0, same_worker = 0;
1340 ti = thread_indices;
1358 && (
b[0]->
flags & VLIB_BUFFER_IS_TRACED)))
1371 thread_indices,
frame->n_vectors, 1);
1375 NAT64_IN2OUT_HANDOFF_ERROR_CONGESTION_DROP,
1376 frame->n_vectors - n_enq);
1378 NAT64_IN2OUT_HANDOFF_ERROR_SAME_WORKER,
1381 NAT64_IN2OUT_HANDOFF_ERROR_DO_HANDOFF,
1384 return frame->n_vectors;
1389 .name =
"nat64-in2out-handoff",
1390 .vector_size =
sizeof (
u32),