18 #include <vpp/app/version.h> 46 #define skip_if_disabled() \ 49 snat_main_t *sm = &snat_main; \ 50 if (PREDICT_FALSE (!sm->enabled)) \ 55 #define fail_if_enabled() \ 58 snat_main_t *sm = &snat_main; \ 59 if (PREDICT_FALSE (sm->enabled)) \ 61 nat_log_err ("plugin enabled"); \ 67 #define fail_if_disabled() \ 70 snat_main_t *sm = &snat_main; \ 71 if (PREDICT_FALSE (!sm->enabled)) \ 73 nat_log_err ("plugin disabled"); \ 81 .arc_name =
"ip4-unicast",
82 .node_name =
"nat-pre-in2out",
84 "ip4-sv-reassembly-feature"),
87 .arc_name =
"ip4-unicast",
88 .node_name =
"nat-pre-out2in",
90 "ip4-dhcp-client-detect",
91 "ip4-sv-reassembly-feature"),
94 .arc_name =
"ip4-unicast",
95 .node_name =
"nat44-in2out-worker-handoff",
99 .arc_name =
"ip4-unicast",
100 .node_name =
"nat44-out2in-worker-handoff",
102 "ip4-dhcp-client-detect"),
105 .arc_name =
"ip4-unicast",
106 .node_name =
"nat44-in2out",
107 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
110 .arc_name =
"ip4-unicast",
111 .node_name =
"nat44-out2in",
112 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature",
113 "ip4-dhcp-client-detect"),
116 .arc_name =
"ip4-unicast",
117 .node_name =
"nat44-ed-in2out",
118 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
121 .arc_name =
"ip4-unicast",
122 .node_name =
"nat44-ed-out2in",
123 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature",
124 "ip4-dhcp-client-detect"),
127 .arc_name =
"ip4-unicast",
128 .node_name =
"nat44-ed-classify",
129 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
132 .arc_name =
"ip4-unicast",
133 .node_name =
"nat44-handoff-classify",
134 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
137 .arc_name =
"ip4-unicast",
138 .node_name =
"nat44-in2out-fast",
139 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
142 .arc_name =
"ip4-unicast",
143 .node_name =
"nat44-out2in-fast",
144 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature",
145 "ip4-dhcp-client-detect"),
150 .arc_name =
"ip4-output",
151 .node_name =
"nat44-in2out-output",
152 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
156 .arc_name =
"ip4-output",
157 .node_name =
"nat44-in2out-output-worker-handoff",
158 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
162 .arc_name =
"ip4-output",
163 .node_name =
"nat-pre-in2out-output",
164 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
168 .arc_name =
"ip4-output",
169 .node_name =
"nat44-ed-in2out-output",
170 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
175 .version = VPP_BUILD_VER,
176 .description =
"Network Address Translation (NAT)",
202 s =
format (s,
"%U static-mapping-index %llu",
218 split_ed_kv (v, &l_addr, &r_addr, &proto, &fib_index, &l_port, &r_port);
220 "local %U:%d remote %U:%d proto %U fib %d thread-index %u " 249 s->nat_proto, s->out2in.port);
253 0, s->in2out.fib_index, &s->in2out.addr, s->in2out.port,
254 &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr,
255 s->out2in.port, &s->ext_host_addr, s->ext_host_port, s->nat_proto,
265 s->in2out.addr.as_u32,
266 s->out2in.addr.as_u32,
270 s->in2out.fib_index);
278 &s->ext_host_nat_addr,
279 s->ext_host_nat_port, s->nat_proto);
286 &s->out2in.
addr, s->out2in.port,
299 .ip4.as_u32 = addr->
as_u32,
333 return VNET_API_ERROR_VALUE_EXIST;
350 #define _(N, i, n, s) \ 351 clib_memset(ap->busy_##n##_port_refcounts, 0, sizeof(ap->busy_##n##_port_refcounts));\ 352 ap->busy_##n##_ports = 0; \ 353 ap->busy_##n##_ports_per_thread = 0;\ 354 vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); 403 int addr_only,
u8 *tag,
int twice_nat,
404 int out2in_only,
int identity_nat,
445 u32 fib_index,
int addr_only,
449 u32 *indexes_to_free = NULL;
451 if (s->in2out.fib_index != fib_index ||
452 s->in2out.addr.as_u32 != l_addr.
as_u32)
458 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) ||
459 s->out2in.port != e_port ||
460 s->in2out.port != l_port ||
461 s->nat_proto != protocol)
503 if (sw_if_index != ~0)
533 return VNET_API_ERROR_VALUE_EXIST;
536 sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto, addr_only,
537 tag, twice_nat, out2in_only, identity_nat, pool_addr, exact);
540 if (first_int_addr == 0)
555 return VNET_API_ERROR_NO_SUCH_ENTRY;
571 init_nat_k (&kv, e_addr, addr_only ? 0 : e_port, 0, addr_only ? 0 : proto);
585 if (local->
vrf_id == vrf_id)
586 return VNET_API_ERROR_VALUE_EXIST;
599 return VNET_API_ERROR_VALUE_EXIST;
602 if (twice_nat && addr_only)
603 return VNET_API_ERROR_UNSUPPORTED;
618 if (!(out2in_only || identity_nat))
620 init_nat_k (&kv, l_addr, addr_only ? 0 : l_port, fib_index,
621 addr_only ? 0 : proto);
622 if (!clib_bihash_search_8_8
624 return VNET_API_ERROR_VALUE_EXIST;
639 #define _(N, j, n, s) \ 640 case NAT_PROTOCOL_##N: \ 641 if (a->busy_##n##_port_refcounts[e_port]) \ 642 return VNET_API_ERROR_INVALID_VALUE; \ 643 ++a->busy_##n##_port_refcounts[e_port]; \ 646 a->busy_##n##_ports++; \ 647 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \ 653 return VNET_API_ERROR_INVALID_VALUE_2;
661 if (sw_if_index != ~0)
678 return VNET_API_ERROR_NO_SUCH_ENTRY;
745 if (sw_if_index != ~0)
748 return VNET_API_ERROR_NO_SUCH_ENTRY;
758 if (local->
vrf_id == vrf_id)
762 return VNET_API_ERROR_NO_SUCH_ENTRY;
781 #define _(N, j, n, s) \ 782 case NAT_PROTOCOL_##N: \ 783 --a->busy_##n##_port_refcounts[e_port]; \ 786 a->busy_##n##_ports--; \ 787 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \ 793 return VNET_API_ERROR_INVALID_VALUE_2;
815 addr_only, e_addr, e_port);
860 u8 * tag,
u32 affinity)
881 return VNET_API_ERROR_VALUE_EXIST;
884 return VNET_API_ERROR_INVALID_VALUE;
898 #define _(N, j, n, s) \ 899 case NAT_PROTOCOL_##N: \ 900 if (a->busy_##n##_port_refcounts[e_port]) \ 901 return VNET_API_ERROR_INVALID_VALUE; \ 902 ++a->busy_##n##_port_refcounts[e_port]; \ 905 a->busy_##n##_ports++; \ 906 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \ 912 return VNET_API_ERROR_INVALID_VALUE_2;
919 return VNET_API_ERROR_NO_SUCH_ENTRY;
944 nat_elog_err (sm,
"static_mapping_by_external key add failed");
945 return VNET_API_ERROR_UNSPECIFIED;
948 for (i = 0; i <
vec_len (locals); i++)
957 locals[i].fib_index, m->
proto, 0,
988 return VNET_API_ERROR_NO_SUCH_ENTRY;
991 return VNET_API_ERROR_INVALID_VALUE;
1003 #define _(N, j, n, s) \ 1004 case NAT_PROTOCOL_##N: \ 1005 --a->busy_##n##_port_refcounts[e_port]; \ 1006 if (e_port > 1024) \ 1008 a->busy_##n##_ports--; \ 1009 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \ 1015 return VNET_API_ERROR_INVALID_VALUE_2;
1025 nat_elog_err (sm,
"static_mapping_by_external key del failed");
1026 return VNET_API_ERROR_UNSPECIFIED;
1040 nat_elog_err (sm,
"static_mapping_by_local key del failed");
1041 return VNET_API_ERROR_UNSPECIFIED;
1063 if ((s->in2out.addr.as_u32 != local->
addr.
as_u32) ||
1064 s->in2out.port != local->
port)
1104 return VNET_API_ERROR_NO_SUCH_ENTRY;
1107 return VNET_API_ERROR_INVALID_VALUE;
1112 (local->
vrf_id == vrf_id))
1114 match_local = local;
1122 return VNET_API_ERROR_VALUE_EXIST;
1127 local->
port = l_port;
1139 nat_elog_err (sm,
"static_mapping_by_local key add failed");
1145 return VNET_API_ERROR_NO_SUCH_ENTRY;
1148 return VNET_API_ERROR_UNSPECIFIED;
1157 nat_elog_err (sm,
"static_mapping_by_local key del failed");
1177 if ((s->in2out.addr.as_u32 != match_local->
addr.
as_u32) ||
1178 s->in2out.port != match_local->
port)
1207 for (i = 1; i <
vec_len (locals); i++)
1228 snat_session_t *ses;
1229 u32 *ses_to_be_removed = 0, *ses_index;
1238 for (i = 0; i <
vec_len (addresses); i++)
1249 return VNET_API_ERROR_NO_SUCH_ENTRY;
1276 return VNET_API_ERROR_UNSPECIFIED;
1284 if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
1289 if (ses->out2in.addr.as_u32 == addr.
as_u32)
1306 #define _(N, i, n, s) \ 1307 vec_free (a->busy_##n##_ports_per_thread); 1342 per_vrf_sessions_t *per_vrf_sessions;
1350 if ((per_vrf_sessions->rx_fib_index == fib_index) ||
1351 (per_vrf_sessions->tx_fib_index == fib_index))
1353 per_vrf_sessions->expired = 1;
1401 const char *feature_name, *del_feature_name;
1411 return VNET_API_ERROR_UNSUPPORTED;
1418 nat_log_err (
"error interface already configured");
1419 return VNET_API_ERROR_VALUE_EXIST;
1424 feature_name = is_inside ?
"nat44-in2out-fast" :
"nat44-out2in-fast";
1429 is_inside ?
"nat44-in2out-worker-handoff" :
1430 "nat44-out2in-worker-handoff";
1432 feature_name = is_inside ?
"nat-pre-in2out" :
"nat-pre-out2in";
1451 if (outside_fib->
fib_index == fib_index)
1488 del_feature_name =
"nat44-handoff-classify";
1489 feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1490 "nat44-out2in-worker-handoff";
1494 del_feature_name =
"nat44-ed-classify";
1496 !is_inside ?
"nat-pre-in2out" :
"nat-pre-out2in";
1503 sw_if_index, 0, 0, 0);
1505 sw_if_index, 1, 0, 0);
1513 sw_if_index, 0, 0, 0);
1525 del_feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1526 "nat44-out2in-worker-handoff";
1527 feature_name =
"nat44-handoff-classify";
1532 !is_inside ?
"nat-pre-in2out" :
"nat-pre-out2in";
1534 feature_name =
"nat44-ed-classify";
1541 sw_if_index, 0, 0, 0);
1543 sw_if_index, 1, 0, 0);
1553 nat_log_err (
"error interface couldn't be found");
1554 return VNET_API_ERROR_NO_SUCH_ENTRY;
1596 u8 is_inside,
int is_del)
1609 return VNET_API_ERROR_UNSUPPORTED;
1615 return VNET_API_ERROR_UNSUPPORTED;
1622 nat_log_err (
"error interface already configured");
1623 return VNET_API_ERROR_VALUE_EXIST;
1633 if (outside_fib->
fib_index == fib_index)
1679 "nat44-out2in-worker-handoff",
1680 sw_if_index, !is_del, 0, 0);
1682 "nat44-in2out-output-worker-handoff",
1683 sw_if_index, !is_del, 0, 0);
1697 sw_if_index, !is_del, 0, 0);
1699 sw_if_index, !is_del, 0, 0);
1718 return VNET_API_ERROR_VALUE_EXIST;
1726 nat_log_err (
"error interface couldn't be found");
1727 return VNET_API_ERROR_NO_SUCH_ENTRY;
1765 return VNET_API_ERROR_FEATURE_DISABLED;
1768 return VNET_API_ERROR_INVALID_WORKER;
1804 if (!sm->
enabled || (new_fib_index == old_fib_index)
1835 if (outside_fib->
fib_index == old_fib_index)
1846 if (outside_fib->
fib_index == new_fib_index)
1873 u32 if_address_index,
u32 is_delete);
1881 u32 if_address_index,
u32 is_delete);
1887 l_addr.
as_u8[0] = 1;
1888 l_addr.
as_u8[1] = 1;
1889 l_addr.
as_u8[2] = 1;
1890 l_addr.
as_u8[3] = 1;
1892 r_addr.
as_u8[0] = 2;
1893 r_addr.
as_u8[1] = 2;
1894 r_addr.
as_u8[2] = 2;
1895 r_addr.
as_u8[3] = 2;
1899 u32 fib_index = 9000001;
1901 u32 session_index = 3000000221;
1903 init_ed_kv (&kv, l_addr, l_port, r_addr, r_port, fib_index, proto,
1904 thread_index, session_index);
1913 split_ed_kv (&kv, &l_addr2, &r_addr2, &proto2, &fib_index2, &l_port2,
1917 ASSERT (l_port == l_port2);
1918 ASSERT (r_port == r_port2);
1919 ASSERT (proto == proto2);
1920 ASSERT (fib_index == fib_index2);
1928 split_nat_key (key, &l_addr2, &l_port2, &fib_index2, &proto3);
1930 ASSERT (l_port == l_port2);
1931 ASSERT (proto == proto3);
1932 ASSERT (fib_index == fib_index2);
1944 if (fib_index != ~0)
1967 #define nat_validate_simple_counter(c, i) \ 1970 vlib_validate_simple_counter (&c, i); \ 1971 vlib_zero_simple_counter (&c, i); \ 1975 #define nat_init_simple_counter(c, n, sn) \ 1979 c.stat_segment_name = sn; \ 1980 nat_validate_simple_counter (c, 0); \ 1988 nat_validate_simple_counter (sm->counters.fastpath.in2out.x, sw_if_index); \ 1989 nat_validate_simple_counter (sm->counters.fastpath.out2in.x, sw_if_index); \ 1990 nat_validate_simple_counter (sm->counters.slowpath.in2out.x, sw_if_index); \ 1991 nat_validate_simple_counter (sm->counters.slowpath.out2in.x, sw_if_index); 2005 u32 i, num_threads = 0;
2006 uword *p, *bitmap = 0;
2029 "/nat44-ed/total-sessions");
2034 nat_init_simple_counter (sm->counters.fastpath.in2out.x, #x, \ 2035 "/nat44-ed/in2out/fastpath/" #x); \ 2036 nat_init_simple_counter (sm->counters.fastpath.out2in.x, #x, \ 2037 "/nat44-ed/out2in/fastpath/" #x); \ 2038 nat_init_simple_counter (sm->counters.slowpath.in2out.x, #x, \ 2039 "/nat44-ed/in2out/slowpath/" #x); \ 2040 nat_init_simple_counter (sm->counters.slowpath.out2in.x, #x, \ 2041 "/nat44-ed/out2in/slowpath/" #x); 2045 "/nat44-ed/hairpinning");
2113 nat_log_err (
"unsupported combination of configuration");
2169 #define _(N, i, n, s) \ 2170 vec_free (ap->busy_##n##_ports_per_thread); 2198 nat_log_err (
"error occurred while removing interface %u",
2215 nat_log_err (
"error occurred while removing interface %u",
2252 u32 *ses_to_be_removed = 0, *ses_index;
2287 u16 port_host_byte_order = clib_net_to_host_u16 (port);
2289 for (address_index = 0; address_index <
vec_len (addresses);
2292 if (addresses[address_index].addr.
as_u32 == addr->
as_u32)
2296 ASSERT (address_index < vec_len (addresses));
2298 a = addresses + address_index;
2302 #define _(N, i, n, s) \ 2303 case NAT_PROTOCOL_##N: \ 2304 ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \ 2305 --a->busy_##n##_port_refcounts[port_host_byte_order]; \ 2306 a->busy_##n##_ports--; \ 2307 a->busy_##n##_ports_per_thread[thread_index]--; \ 2324 u16 port_host_byte_order = clib_net_to_host_u16 (port);
2326 for (address_index = 0; address_index <
vec_len (addresses);
2329 if (addresses[address_index].addr.
as_u32 != addr.
as_u32)
2332 a = addresses + address_index;
2335 #define _(N, j, n, s) \ 2336 case NAT_PROTOCOL_##N: \ 2337 if (a->busy_##n##_port_refcounts[port_host_byte_order]) \ 2338 return VNET_API_ERROR_INSTANCE_IN_USE; \ 2339 ++a->busy_##n##_port_refcounts[port_host_byte_order]; \ 2340 a->busy_##n##_ports_per_thread[thread_index]++; \ 2341 a->busy_##n##_ports++; \ 2350 return VNET_API_ERROR_NO_SUCH_ENTRY;
2358 u32 *mapping_fib_index,
u8 by_external,
2364 clib_bihash_8_8_t *mapping_hash;
2373 init_nat_k (&kv, match_addr, match_port, match_fib_index,
2375 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2378 init_nat_k (&kv, match_addr, 0, match_fib_index, 0);
2379 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2386 init_nat_k (&kv, match_addr, match_port, 0, match_protocol);
2387 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2391 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2405 vm, ext_host_addr[0], match_addr,
2406 match_protocol, match_port, &backend_index))
2409 *mapping_addr = local->
addr;
2410 *mapping_port = local->
port;
2446 mid = ((hi -
lo) >> 1) +
lo;
2448 (rand > local->
prefix) ? (lo = mid + 1) : (hi = mid);
2451 if (!(local->
prefix >= rand))
2453 *mapping_addr = local->
addr;
2454 *mapping_port = local->
port;
2459 match_protocol, match_port,
2504 u32 rx_fib_index,
u8 is_output)
2512 u32 fib_index = rx_fib_index;
2557 if (!clib_bihash_search_16_8 (&sm->
flow_hash, &kv16, &value16))
2569 if (!clib_bihash_search_16_8 (&sm->
flow_hash, &kv16, &value16))
2582 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
2597 next_worker_index, rx_fib_index,
2602 return next_worker_index;
2607 u32 rx_fib_index,
u8 is_output)
2623 u16 lookup_sport, lookup_dport;
2626 b, ip, &lookup_saddr, &lookup_sport, &lookup_daddr, &lookup_dport,
2629 init_ed_k (&kv16, lookup_saddr, lookup_sport, lookup_daddr,
2630 lookup_dport, rx_fib_index, lookup_protocol);
2632 !clib_bihash_search_16_8 (&sm->
flow_hash, &kv16, &value16)))
2636 sm,
"HANDOFF OUT2IN (session)", next_worker_index,
2639 return next_worker_index;
2649 !clib_bihash_search_16_8 (&sm->
flow_hash, &kv16, &value16)))
2655 next_worker_index, rx_fib_index,
2658 return next_worker_index;
2665 if (!clib_bihash_search_8_8
2669 next_worker_index = m->
workers[0];
2687 icmp46_header_t *
icmp = (icmp46_header_t *) udp;
2690 (
vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
2700 case NAT_PROTOCOL_ICMP:
2701 icmp = (icmp46_header_t *) l4_header;
2705 case NAT_PROTOCOL_UDP:
2706 case NAT_PROTOCOL_TCP:
2720 if (!clib_bihash_search_8_8
2726 next_worker_index = m->
workers[0];
2744 next_worker_index +=
2752 return next_worker_index;
2759 u32 max_limit = 0,
len = 0;
2763 if (max_limit < sm->max_translations_per_fib[
len])
2776 if (len <= fib_index)
2809 u32 translation_buckets)
2842 clib_bihash_init_16_8 (
2853 u32 static_mapping_buckets = 1024;
2854 u32 static_mapping_memory_size = 64 << 20;
2859 "static_mapping_by_local", static_mapping_buckets,
2860 static_mapping_memory_size);
2865 "static_mapping_by_external", static_mapping_buckets,
2866 static_mapping_memory_size);
2935 u32 if_address_index,
u32 is_delete)
3003 u32 if_address_index,
u32 is_delete)
3036 for (j = 0; j <
vec_len (addresses); j++)
3037 if (addresses[j].
addr.as_u32 == address->
as_u32)
3082 u32 *indices_to_delete = 0;
3084 u32 *auto_add_sw_if_indices =
3091 for (i = 0; i <
vec_len (auto_add_sw_if_indices); i++)
3093 if (auto_add_sw_if_indices[i] == sw_if_index)
3108 if (vec_len (indices_to_delete))
3110 for (j = vec_len (indices_to_delete) - 1; j >= 0; j--)
3121 return VNET_API_ERROR_VALUE_EXIST;
3128 return VNET_API_ERROR_NO_SUCH_ENTRY;
3162 init_ed_k (&kv, *addr, port, *eh_addr, eh_port, fib_index, proto);
3163 if (clib_bihash_search_16_8 (&sm->
flow_hash, &kv, &value))
3165 return VNET_API_ERROR_NO_SUCH_ENTRY;
3169 return VNET_API_ERROR_UNSPECIFIED;
3184 .name =
"nat-default",
3185 .vector_size =
sizeof (
u32),
3279 int is_icmp_inner_ip4)
3284 if ((NAT_PROTOCOL_TCP == proto || NAT_PROTOCOL_UDP == proto) &&
3287 if (!is_icmp_inner_ip4)
3302 if (NAT_PROTOCOL_TCP == proto)
3310 else if (proto == NAT_PROTOCOL_UDP && udp->
checksum)
3320 if (!is_icmp_inner_ip4)
3344 if (IP_PROTOCOL_ICMP != ip->
protocol)
3350 if ((!
vnet_buffer (b)->ip.reass.is_non_first_fragment))
3352 if (icmp->checksum == 0)
3353 icmp->checksum = 0xffff;
3383 switch (inner_proto)
3385 case NAT_PROTOCOL_UDP:
3386 case NAT_PROTOCOL_TCP:
3392 case NAT_PROTOCOL_ICMP:
3405 ip_csum_t inner_sum = inner_icmp->checksum;
3415 clib_warning (
"unexpected NAT protocol value `%d'", inner_proto);
3426 int is_output_feature)
3435 if (NAT_PROTOCOL_ICMP == proto)
3448 s =
format (s,
"saddr %U sport %u daddr %U dport %u proto %U fib_idx %u",
3464 s =
format (s,
"success");
3467 s =
format (s,
"translation-failed");
3470 s =
format (s,
"flow-mismatch");
3493 s =
format (s,
"rewrite: ");
3502 s =
format (s,
"rewrite: ");
3511 s =
format (s,
"rewrite: ");
3520 s =
format (s,
"rewrite: ");
3529 s =
format (s,
"rewrite: ");
ip4_address_t external_addr
u32 nat44_ed_get_in2out_worker_index(vlib_buffer_t *b, ip4_header_t *ip, u32 rx_fib_index, u8 is_output)
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static void mss_clamping(u16 mss_clamping, tcp_header_t *tcp, ip_csum_t *sum)
fib_protocol_t fp_proto
protocol type
#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY
nat_outside_fib_t * outside_fibs
u32 * max_translations_per_fib
u32 max_cfg_sessions_gauge
static void nat44_ed_worker_db_free(snat_main_per_thread_data_t *tsm)
#define nat_init_simple_counter(c, n, sn)
int ip4_sv_reass_output_enable_disable_with_refcnt(u32 sw_if_index, int is_enable)
ip4_table_bind_function_t * function
#define pool_foreach_index(i, v)
static int is_snat_address_used_in_static_mapping(snat_main_t *sm, ip4_address_t addr)
#define nat_validate_simple_counter(c, i)
#define nat_elog_info(_pm, nat_elog_str)
static void reinit_ed_flow_hash()
#define snat_is_unk_proto_session(s)
Check if SNAT session for unknown protocol.
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
u32 nat_affinity_get_per_service_list_head_index(void)
Get new affinity per service list head index.
vnet_hw_if_output_node_runtime_t * r
void nat_ipfix_logging_init(vlib_main_t *vm)
Initialize NAT plugin IPFIX logging.
int snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
Add external address to NAT44 pool.
void test_key_calc_split()
u32 fq_in2out_output_index
#define pool_foreach(VAR, POOL)
Iterate through pool.
#define pool_alloc(P, N)
Allocate N more free elements to pool (unspecified alignment).
static void nat44_ed_worker_db_init(snat_main_per_thread_data_t *tsm, u32 translations, u32 translation_buckets)
void nat44_ed_sessions_clear()
int nat44_ed_set_frame_queue_nelts(u32 frame_queue_nelts)
void nat_affinity_enable()
NAT affinity enable.
vl_api_ip_proto_t protocol
int nat_affinity_find_and_lock(vlib_main_t *vm, ip4_address_t client_addr, ip4_address_t service_addr, u8 proto, u16 service_port, u8 *backend_index)
Find service backend index for client-IP and take a reference counting lock.
int nat_affinity_create_and_lock(ip4_address_t client_addr, ip4_address_t service_addr, u8 proto, u16 service_port, u8 backend_index, u32 sticky_time, u32 affinity_per_service_list_head_index)
Create affinity record and take reference counting lock.
int nat44_del_ed_session(snat_main_t *sm, ip4_address_t *addr, u16 port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 vrf_id, int is_in)
Delete NAT44 endpoint-dependent session.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
void nat44_addresses_free(snat_address_t **addresses)
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
per_vrf_sessions_t * per_vrf_sessions_vec
#define clib_bitmap_foreach(i, ai)
Macro to iterate across set bits in a bitmap.
u32 vlib_frame_queue_main_init(u32 node_index, u32 frame_queue_nelts)
#define is_twice_nat_session(s)
Check if NAT session is twice NAT.
add paths without path extensions
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
void nat44_ed_forwarding_enable_disable(u8 is_enable)
NAT plugin client-IP based session affinity for load-balancing.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
ip_lookup_main_t lookup_main
static_always_inline void nat_validate_interface_counters(snat_main_t *sm, u32 sw_if_index)
static u32 nat_value_get_thread_index(clib_bihash_kv_8_8_t *value)
#define VLIB_NODE_FN(node)
static_always_inline int nat_6t_flow_icmp_translate(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, nat_6t_flow_t *f)
VNET_IP_TABLE_ADD_DEL_FUNCTION(nat_ip_table_add_del)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
struct _tcp_header tcp_header_t
u32 max_translations_per_thread
#define NAT_INTERFACE_FLAG_IS_OUTSIDE
vlib_simple_counter_main_t hairpinning
static void split_nat_key(u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto)
static_always_inline void nat_reset_timeouts(nat_timeouts_t *timeouts)
nat44_lb_addr_port_t * locals
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
static u64 calc_nat_key(ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
static_always_inline void per_vrf_sessions_unregister_session(snat_session_t *s, u32 thread_index)
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
#define NAT_STATIC_MAPPING_FLAG_EXACT_ADDRESS
u32 in2out_output_node_index
vlib_node_registration_t nat_default_node
(constructor) VLIB_REGISTER_NODE (nat_default_node)
#define static_always_inline
void nat_affinity_flush_service(u32 affinity_per_service_list_head_index)
Flush all service affinity data.
static uword ip4_header_checksum_is_valid(ip4_header_t *i)
void snat_free_outside_address_and_port(snat_address_t *addresses, u32 thread_index, ip4_address_t *addr, u16 port, nat_protocol_t protocol)
Free outside address and port pair.
#define VLIB_INIT_FUNCTION(x)
static nat_protocol_t ip_proto_to_nat_proto(u8 ip_proto)
Common NAT inline functions.
#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY
#define nat_elog_notice_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
static clib_error_t * nat_init(vlib_main_t *vm)
description fragment has unexpected format
static void snat_update_outside_fib(ip4_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
void nat_ed_static_mapping_del_sessions(snat_main_t *sm, snat_main_per_thread_data_t *tsm, ip4_address_t l_addr, u16 l_port, u8 protocol, u32 fib_index, int addr_only, ip4_address_t e_addr, u16 e_port)
u8 * format_static_mapping_kvp(u8 *s, va_list *args)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Aggregate type for a prefix.
#define nat_elog_warn(_pm, nat_elog_str)
void nat_affinity_unlock(ip4_address_t client_addr, ip4_address_t service_addr, u8 proto, u16 service_port)
Release a reference counting lock for affinity.
static void init_nat_kv(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto, u32 thread_index, u32 session_index)
vnet_main_t * vnet_get_main(void)
static u32 nat_value_get_session_index(clib_bihash_kv_8_8_t *value)
#define is_addr_only_static_mapping(sm)
Check if NAT static mapping is address only (1:1NAT).
static void * ip4_next_header(ip4_header_t *i)
int ip4_sv_reass_enable_disable_with_refcnt(u32 sw_if_index, int is_enable)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
clib_error_t * nat_affinity_init(vlib_main_t *vm)
Initialize NAT client-IP based affinity.
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
static void nat44_ed_db_init(u32 translations, u32 translation_buckets)
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
vl_api_fib_path_type_t type
twice_nat_type_t twice_nat
u32 * auto_add_sw_if_indices_twice_nat
static void nat_ip4_add_del_addr_only_sm_cb(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete)
int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
Delete external address from NAT44 pool.
int nat44_set_session_limit(u32 session_limit, u32 vrf_id)
Set NAT44 session limit (session limit, vrf id)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vl_api_interface_index_t sw_if_index
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
void nat44_set_node_indexes(snat_main_t *sm, vlib_main_t *vm)
#define FIB_SOURCE_PRIORITY_HI
Some priority values that plugins might use when they are not to concerned where in the list they'll ...
static uword clib_bitmap_last_set(uword *ai)
Return the higest numbered set bit in a bitmap.
#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT
IPv4 shallow virtual reassembly.
u32 get_thread_idx_by_port(u16 e_port)
#define NAT_FLOW_OP_SPORT_REWRITE
snat_static_mapping_t * static_mappings
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
#define is_fwd_bypass_session(s)
Check if NAT session is forwarding bypass.
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
int nat44_update_session_limit(u32 session_limit, u32 vrf_id)
Update NAT44 session limit flushing all data (session limit, vrf id)
#define vec_del1(v, i)
Delete the element at index I.
clib_bihash_8_8_t static_mapping_by_external
u8 * format_nat_6t_flow(u8 *s, va_list *args)
#define fail_if_enabled()
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
#define nat_elog_err(_pm, nat_elog_str)
#define is_affinity_sessions(s)
Check if NAT session has affinity record.
#define NAT_FQ_NELTS_DEFAULT
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
VNET_FEATURE_INIT(nat_pre_in2out, static)
static_always_inline int nat_get_icmp_session_lookup_values(vlib_buffer_t *b, ip4_header_t *ip0, ip4_address_t *lookup_saddr, u16 *lookup_sport, ip4_address_t *lookup_daddr, u16 *lookup_dport, u8 *lookup_protocol)
u8 * format_nat_6t(u8 *s, va_list *args)
u8 * format_ed_session_kvp(u8 *s, va_list *args)
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
snat_interface_t * output_feature_interfaces
#define is_identity_static_mapping(sm)
Check if NAT static mapping is identity NAT.
clib_error_t * nat44_api_hookup(vlib_main_t *vm)
#define pool_free(p)
Free a pool.
void snat_add_del_addr_to_fib(ip4_address_t *addr, u8 p_len, u32 sw_if_index, int is_add)
Add/del NAT address to FIB.
int nat44_lb_static_mapping_add_del_local(ip4_address_t e_addr, u16 e_port, ip4_address_t l_addr, u16 l_port, nat_protocol_t proto, u32 vrf_id, u8 probability, u8 is_add)
#define VLIB_REGISTER_NODE(x,...)
#define is_out2in_only_static_mapping(sm)
Check if NAT static mapping match only out2in direction.
static_always_inline uword vlib_get_thread_index(void)
sll srl srl sll sra u16x4 i
int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port, u32 vrf_id, int addr_only, u32 sw_if_index, nat_protocol_t proto, int is_add, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag, u8 identity_nat, ip4_address_t pool_addr, int exact)
Add/delete NAT44 static mapping.
u8 static_mapping_connection_tracking
#define vec_free(V)
Free vector's memory (no header).
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
#define NAT_FLOW_OP_TXFIB_REWRITE
ip4_add_del_interface_address_function_t * function
static void init_ed_k(clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port, ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
#define clib_warning(format, args...)
int nat44_plugin_disable()
Disable NAT44 plugin.
static void init_ed_kv(clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port, ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto, u32 thread_index, u32 session_index)
struct snat_main_s::@736 counters
static void nat44_ed_db_free()
u32 fib_node_index_t
A typedef of a node index.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static u32 ip4_fib_index_from_table_id(u32 table_id)
8 octet key, 8 octet key value pair
static_always_inline void nat_6t_flow_ip4_translate(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, nat_6t_flow_t *f, nat_protocol_t proto, int is_icmp_inner_ip4)
#define NAT_STATIC_MAPPING_FLAG_LB
#define nat_interface_is_outside(i)
Check if NAT interface is outside.
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
u32 * auto_add_sw_if_indices
#define NAT_FLOW_OP_SADDR_REWRITE
int nat_set_outside_address_and_port(snat_address_t *addresses, u32 thread_index, ip4_address_t addr, u16 port, nat_protocol_t protocol)
void nat_syslog_nat44_sdel(u32 ssubix, u32 sfibix, ip4_address_t *isaddr, u16 isport, ip4_address_t *idaddr, u16 idport, ip4_address_t *xsaddr, u16 xsport, ip4_address_t *xdaddr, u16 xdport, nat_protocol_t proto, u8 is_twicenat)
#define NAT_FLOW_OP_DADDR_REWRITE
u32 nat44_get_max_session_limit()
int nat44_add_del_lb_static_mapping(ip4_address_t e_addr, u16 e_port, nat_protocol_t proto, nat44_lb_addr_port_t *locals, u8 is_add, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag, u32 affinity)
Add/delete static mapping with load-balancing (multiple backends)
static ip_csum_t ip_csum_sub_even(ip_csum_t c, ip_csum_t x)
vlib_log_class_t log_class
#define foreach_nat_counter
static void snat_ip4_add_del_interface_address_cb(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete)
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
nat_translation_error_e nat_6t_flow_buf_translate(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, nat_6t_flow_t *f, nat_protocol_t proto, int is_output_feature)
int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del, u8 twice_nat)
Add/delete NAT44 pool address from specific interface.
#define clib_bitmap_free(v)
Free a bitmap.
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
#define is_lb_session(s)
Check if NAT session is load-balancing.
struct nat_6t_flow_t::@735 rewrite
uword * thread_registrations_by_name
u32 nat44_ed_get_out2in_worker_index(vlib_buffer_t *b, ip4_header_t *ip, u32 rx_fib_index, u8 is_output)
#define FIB_SOURCE_PRIORITY_LOW
snat_address_t * twice_nat_addresses
#define VNET_FEATURES(...)
static uword is_pow2(uword x)
void nat_free_session_data(snat_main_t *sm, snat_session_t *s, u32 thread_index, u8 is_ha)
Free NAT44 session data (lookup keys, external address port)
static u32 ed_value_get_session_index(clib_bihash_kv_16_8_t *value)
static u32 ed_value_get_thread_index(clib_bihash_kv_16_8_t *value)
ip4_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
u8 * format_nat_ed_translation_error(u8 *s, va_list *args)
static_always_inline int nat_ed_ses_o2i_flow_hash_add_del(snat_main_t *sm, u32 thread_idx, snat_session_t *s, int is_add)
static void nat_ed_session_delete(snat_main_t *sm, snat_session_t *ses, u32 thread_index, int lru_delete)
u32 stat_segment_new_entry(u8 *name, stat_directory_type_t t)
#define nat_elog_debug_handoff(_pm, _str, _tid, _fib, _src, _dst)
u32 unk_proto_lru_head_index
#define nat_interface_is_inside(i)
Check if NAT interface is inside.
static void split_ed_kv(clib_bihash_kv_16_8_t *kv, ip4_address_t *l_addr, ip4_address_t *r_addr, u8 *proto, u32 *fib_index, u16 *l_port, u16 *r_port)
#define FIB_NODE_INDEX_INVALID
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_main_t vlib_node_runtime_t * node
u32 tcp_trans_lru_head_index
VLIB buffer representation.
u32 tcp_estab_lru_head_index
snat_main_per_thread_data_t * per_thread_data
format_function_t format_snat_key
#define NAT_FLOW_OP_ICMP_ID_REWRITE
#define ip_csum_update(sum, old, new, type, field)
#define fail_if_disabled()
u32 affinity_per_service_list_head_index
snat_address_t * addresses
#define hash_get_mem(h, key)
void update_per_vrf_sessions_vec(u32 fib_index, int is_del)
u32 nat_calc_bihash_buckets(u32 n_elts)
snat_static_map_resolve_t * to_resolve
static api_main_t * vlibapi_get_main(void)
int snat_static_mapping_match(vlib_main_t *vm, snat_main_t *sm, ip4_address_t match_addr, u16 match_port, u32 match_fib_index, nat_protocol_t match_protocol, ip4_address_t *mapping_addr, u16 *mapping_port, u32 *mapping_fib_index, u8 by_external, u8 *is_addr_only, twice_nat_type_t *twice_nat, lb_nat_type_t *lb, ip4_address_t *ext_host_addr, u8 *is_identity_nat, snat_static_mapping_t **out)
Match NAT44 static mapping.
void nat_6t_l3_l4_csum_calc(nat_6t_flow_t *f)
static u32 random_u32(u32 *seed)
32-bit random number generator
ip4_main_t ip4_main
Global ip4 main structure.
NAT port/address allocation lib.
static vlib_thread_main_t * vlib_get_thread_main()
int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
Enable/disable NAT44 feature on the interface.
#define vec_foreach(var, vec)
Vector iterator.
u8 * format_session_kvp(u8 *s, va_list *args)
f64 end
end of the time range
#define is_lb_static_mapping(sm)
Check if NAT static mapping is load-balancing.
static_always_inline int nat_ed_ses_i2o_flow_hash_add_del(snat_main_t *sm, u32 thread_idx, snat_session_t *s, int is_add)
clib_bihash_16_8_t flow_hash
static clib_error_t * nat_ip_table_add_del(vnet_main_t *vnm, u32 table_id, u32 is_add)
#define NAT_FLOW_OP_DPORT_REWRITE
int snat_set_workers(uword *bitmap)
Set NAT plugin workers.
int snat_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside, int is_del)
Enable/disable NAT44 output feature on the interface (postrouting NAT)
static void snat_add_static_mapping_when_resolved(snat_main_t *sm, ip4_address_t l_addr, u16 l_port, u32 sw_if_index, u16 e_port, u32 vrf_id, nat_protocol_t proto, int addr_only, u8 *tag, int twice_nat, int out2in_only, int identity_nat, ip4_address_t pool_addr, int exact)
#define NAT_INTERFACE_FLAG_IS_INSIDE
vlib_simple_counter_main_t total_sessions
ip_lookup_main_t * ip4_lookup_main
int nat44_plugin_enable(nat44_config_t c)
Enable NAT44 plugin.
void expire_per_vrf_sessions(u32 fib_index)
snat_session_t * sessions
static void init_nat_k(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto)
clib_bihash_8_8_t static_mapping_by_local
static u16 ip_csum_fold(ip_csum_t c)
snat_interface_t * interfaces
static ip_csum_t ip_csum_add_even(ip_csum_t c, ip_csum_t x)
void stat_segment_set_state_counter(u32 index, u64 value)
void nat_ipfix_logging_nat44_ses_delete(u32 thread_index, u32 src_ip, u32 nat_src_ip, nat_protocol_t nat_proto, u16 src_port, u16 nat_src_port, u32 fib_index)
Generate NAT44 session delete event.
static uword pool_elts(void *v)
Number of active elements in a pool.