37 #include <vpp/app/version.h> 44 .arc_name =
"ip4-unicast",
45 .node_name =
"nat-pre-in2out",
47 "ip4-sv-reassembly-feature"),
50 .arc_name =
"ip4-unicast",
51 .node_name =
"nat-pre-out2in",
53 "ip4-dhcp-client-detect",
54 "ip4-sv-reassembly-feature"),
57 .arc_name =
"ip4-unicast",
58 .node_name =
"nat44-in2out-worker-handoff",
62 .arc_name =
"ip4-unicast",
63 .node_name =
"nat44-out2in-worker-handoff",
65 "ip4-dhcp-client-detect"),
68 .arc_name =
"ip4-unicast",
69 .node_name =
"nat44-in2out",
70 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
73 .arc_name =
"ip4-unicast",
74 .node_name =
"nat44-out2in",
75 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature",
76 "ip4-dhcp-client-detect"),
79 .arc_name =
"ip4-unicast",
80 .node_name =
"nat44-classify",
81 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
84 .arc_name =
"ip4-unicast",
85 .node_name =
"nat44-ed-in2out",
86 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
89 .arc_name =
"ip4-unicast",
90 .node_name =
"nat44-ed-out2in",
91 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature",
92 "ip4-dhcp-client-detect"),
95 .arc_name =
"ip4-unicast",
96 .node_name =
"nat44-ed-classify",
97 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
100 .arc_name =
"ip4-unicast",
101 .node_name =
"nat44-handoff-classify",
102 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
105 .arc_name =
"ip4-unicast",
106 .node_name =
"nat44-in2out-fast",
107 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
110 .arc_name =
"ip4-unicast",
111 .node_name =
"nat44-out2in-fast",
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-hairpin-dst",
118 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
121 .arc_name =
"ip4-unicast",
122 .node_name =
"nat44-ed-hairpin-dst",
123 .runs_after =
VNET_FEATURES (
"acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
128 .arc_name =
"ip4-output",
129 .node_name =
"nat44-in2out-output",
130 .runs_after =
VNET_FEATURES (
"acl-plugin-out-ip4-fa",
"ip4-sv-reassembly-output-feature"),
133 .arc_name =
"ip4-output",
134 .node_name =
"nat44-in2out-output-worker-handoff",
135 .runs_after =
VNET_FEATURES (
"acl-plugin-out-ip4-fa",
"ip4-sv-reassembly-output-feature"),
138 .arc_name =
"ip4-output",
139 .node_name =
"nat44-hairpin-src",
140 .runs_after =
VNET_FEATURES (
"acl-plugin-out-ip4-fa",
"ip4-sv-reassembly-output-feature"),
143 .arc_name =
"ip4-output",
144 .node_name =
"nat-pre-in2out-output",
145 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
149 .arc_name =
"ip4-output",
150 .node_name =
"nat44-ed-in2out-output",
151 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
155 .arc_name =
"ip4-output",
156 .node_name =
"nat44-ed-hairpin-src",
157 .runs_after =
VNET_FEATURES (
"ip4-sv-reassembly-output-feature"),
164 .arc_name =
"ip4-local",
165 .node_name =
"nat44-hairpinning",
170 .arc_name =
"ip4-local",
171 .node_name =
"nat44-ed-hairpinning",
177 .version = VPP_BUILD_VER,
178 .description =
"Network Address Translation (NAT)",
184 u32 rx_fib_index,
u8 is_output);
192 u32 rx_fib_index0,
u8 is_output);
215 s =
format (s,
"%U static-mapping-index %llu",
245 split_ed_kv (v, &l_addr, &r_addr, &proto, &fib_index, &l_port, &r_port);
248 "local %U:%d remote %U:%d proto %U fib %d thread-index %u session-index %u",
259 u32 thread_index,
u8 is_ha)
267 if (clib_bihash_add_del_8_8 (&tsm->
in2out, &kv, 0))
271 if (clib_bihash_add_del_8_8 (&tsm->
out2in, &kv, 0))
277 &s->in2out.addr, s->in2out.port,
278 &s->out2in.addr, s->out2in.port, s->nat_proto);
281 s->in2out.addr.as_u32,
282 s->out2in.addr.as_u32,
286 s->in2out.fib_index);
288 nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
289 s->ext_host_port, s->nat_proto, s->out2in.fib_index,
298 &s->out2in.
addr, s->out2in.port,
317 while (elt->
value != ~0)
350 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
364 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
397 init_ed_k (&ed_kv, s->in2out.addr, 0, s->ext_host_addr, 0, 0,
402 l_port = s->in2out.port;
403 r_port = s->ext_host_port;
404 l_addr = &s->in2out.addr;
405 r_addr = &s->ext_host_addr;
407 fib_index = s->in2out.fib_index;
408 init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index,
411 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &ed_kv, 0))
421 s->nat_proto, s->out2in.port);
422 l_addr = &s->out2in.addr;
423 r_addr = &s->ext_host_addr;
424 fib_index = s->out2in.fib_index;
427 proto = s->in2out.port;
434 l_port = s->out2in.port;
435 r_port = s->ext_host_port;
437 init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
438 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &ed_kv, 0))
440 l_addr = &s->in2out.addr;
441 fib_index = s->in2out.fib_index;
443 l_port = s->in2out.port;
446 r_addr = &s->ext_host_nat_addr;
447 r_port = s->ext_host_nat_port;
449 init_ed_k (&ed_kv, *l_addr, l_port, *r_addr, r_port, fib_index, proto);
450 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &ed_kv, 0))
455 &s->in2out.addr, s->in2out.port,
456 &s->ext_host_nat_addr, s->ext_host_nat_port,
457 &s->out2in.addr, s->out2in.port,
458 &s->ext_host_addr, s->ext_host_port,
464 if (clib_bihash_add_del_8_8 (&tsm->
in2out, &kv, 0))
467 if (clib_bihash_add_del_8_8 (&tsm->
out2in, &kv, 0))
472 &s->in2out.addr, s->in2out.port,
473 &s->out2in.addr, s->out2in.port,
484 s->in2out.addr.as_u32,
485 s->out2in.addr.as_u32,
489 s->in2out.fib_index);
491 nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
492 s->ext_host_port, s->nat_proto, s->out2in.fib_index,
501 &s->ext_host_nat_addr,
502 s->ext_host_nat_port, s->nat_proto);
509 &s->out2in.
addr, s->out2in.port,
528 if (clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
554 if (clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 1))
575 u32 thread_index,
f64 now)
579 u32 oldest_per_user_translation_list_index, session_index;
586 oldest_per_user_translation_list_index =
590 ASSERT (oldest_per_user_translation_list_index != ~0);
595 oldest_per_user_translation_list_index);
597 oldest_per_user_translation_list_elt =
599 oldest_per_user_translation_list_index);
602 session_index = oldest_per_user_translation_list_elt->
value;
617 s->ext_host_addr.as_u32 = 0;
618 s->ext_host_port = 0;
619 s->ext_host_nat_addr.as_u32 = 0;
620 s->ext_host_nat_port = 0;
630 per_user_translation_list_elt - tsm->
list_pool);
633 s->per_user_index = per_user_translation_list_elt - tsm->
list_pool;
637 s->per_user_list_head_index,
638 per_user_translation_list_elt - tsm->
list_pool);
640 s->user_index = u - tsm->
users;
645 s->ha_last_refreshed = now;
659 .ip4.as_u32 = addr->
as_u32,
690 return VNET_API_ERROR_UNSUPPORTED;
700 return VNET_API_ERROR_VALUE_EXIST;
719 #define _(N, i, n, s) \ 720 clib_memset(ap->busy_##n##_port_refcounts, 0, sizeof(ap->busy_##n##_port_refcounts));\ 721 ap->busy_##n##_ports = 0; \ 722 ap->busy_##n##_ports_per_thread = 0;\ 723 vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); 781 int addr_only,
int is_add,
u8 * tag,
782 int twice_nat,
int out2in_only,
831 u32 elt_index, head_index, ses_index;
833 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
835 user_index = value.
value;
841 elt_index = head->
next;
843 ses_index = elt->
value;
844 while (ses_index != ~0)
848 ses_index = elt->
value;
852 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) ||
853 (s->out2in.port != e_port))
879 u32 fib_index,
int addr_only,
883 u32 *indexes_to_free = NULL;
886 if (s->in2out.fib_index != fib_index ||
887 s->in2out.addr.as_u32 != l_addr.
as_u32)
893 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) ||
894 s->out2in.port != e_port ||
895 s->in2out.port != l_port ||
896 s->nat_proto != protocol)
937 u32 elt_index, head_index;
947 if (twice_nat || out2in_only)
948 return VNET_API_ERROR_UNSUPPORTED;
952 if (sw_if_index != ~0)
982 return VNET_API_ERROR_VALUE_EXIST;
985 (sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto,
986 addr_only, is_add, tag, twice_nat, out2in_only,
987 identity_nat, pool_addr, exact);
990 if (first_int_addr == 0)
1005 return VNET_API_ERROR_NO_SUCH_ENTRY;
1021 init_nat_k (&kv, e_addr, addr_only ? 0 : e_port, 0, addr_only ? 0 : proto);
1036 if (local->
vrf_id == vrf_id)
1037 return VNET_API_ERROR_VALUE_EXIST;
1052 return VNET_API_ERROR_VALUE_EXIST;
1055 if (twice_nat && addr_only)
1056 return VNET_API_ERROR_UNSUPPORTED;
1071 if (!(out2in_only || identity_nat))
1073 init_nat_k (&kv, l_addr, addr_only ? 0 : l_port, fib_index,
1074 addr_only ? 0 : proto);
1075 if (!clib_bihash_search_8_8
1077 return VNET_API_ERROR_VALUE_EXIST;
1092 #define _(N, j, n, s) \ 1093 case NAT_PROTOCOL_##N: \ 1094 if (a->busy_##n##_port_refcounts[e_port]) \ 1095 return VNET_API_ERROR_INVALID_VALUE; \ 1096 ++a->busy_##n##_port_refcounts[e_port]; \ 1097 if (e_port > 1024) \ 1099 a->busy_##n##_ports++; \ 1100 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \ 1107 return VNET_API_ERROR_INVALID_VALUE_2;
1115 if (sw_if_index != ~0)
1132 return VNET_API_ERROR_NO_SUCH_ENTRY;
1199 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1201 user_index = value.
value;
1207 elt_index = head->
next;
1209 ses_index = elt->
value;
1210 while (ses_index != ~0)
1214 ses_index = elt->
value;
1219 if (!addr_only && s->in2out.port != m->
local_port)
1237 if (sw_if_index != ~0)
1240 return VNET_API_ERROR_NO_SUCH_ENTRY;
1251 if (local->
vrf_id == vrf_id)
1252 find = local - m->
locals;
1256 return VNET_API_ERROR_NO_SUCH_ENTRY;
1275 #define _(N, j, n, s) \ 1276 case NAT_PROTOCOL_##N: \ 1277 --a->busy_##n##_port_refcounts[e_port]; \ 1278 if (e_port > 1024) \ 1280 a->busy_##n##_ports--; \ 1281 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \ 1288 return VNET_API_ERROR_INVALID_VALUE_2;
1312 fib_index, addr_only,
1369 u8 * tag,
u32 affinity)
1382 return VNET_API_ERROR_UNSUPPORTED;
1393 return VNET_API_ERROR_VALUE_EXIST;
1396 return VNET_API_ERROR_INVALID_VALUE;
1410 #define _(N, j, n, s) \ 1411 case NAT_PROTOCOL_##N: \ 1412 if (a->busy_##n##_port_refcounts[e_port]) \ 1413 return VNET_API_ERROR_INVALID_VALUE; \ 1414 ++a->busy_##n##_port_refcounts[e_port]; \ 1415 if (e_port > 1024) \ 1417 a->busy_##n##_ports++; \ 1418 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \ 1425 return VNET_API_ERROR_INVALID_VALUE_2;
1432 return VNET_API_ERROR_NO_SUCH_ENTRY;
1457 nat_elog_err (
"static_mapping_by_external key add failed");
1458 return VNET_API_ERROR_UNSPECIFIED;
1461 for (i = 0; i <
vec_len (locals); i++)
1470 locals[i].fib_index, m->
proto,
1504 return VNET_API_ERROR_NO_SUCH_ENTRY;
1507 return VNET_API_ERROR_INVALID_VALUE;
1519 #define _(N, j, n, s) \ 1520 case NAT_PROTOCOL_##N: \ 1521 --a->busy_##n##_port_refcounts[e_port]; \ 1522 if (e_port > 1024) \ 1524 a->busy_##n##_ports--; \ 1525 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \ 1532 return VNET_API_ERROR_INVALID_VALUE_2;
1542 nat_elog_err (
"static_mapping_by_external key del failed");
1543 return VNET_API_ERROR_UNSPECIFIED;
1556 nat_elog_err (
"static_mapping_by_local key del failed");
1557 return VNET_API_ERROR_UNSPECIFIED;
1577 if ((s->in2out.addr.as_u32 != local->
addr.
as_u32) ||
1578 s->in2out.port != local->
port)
1615 return VNET_API_ERROR_FEATURE_DISABLED;
1622 return VNET_API_ERROR_NO_SUCH_ENTRY;
1625 return VNET_API_ERROR_INVALID_VALUE;
1631 (local->
vrf_id == vrf_id))
1633 match_local = local;
1642 return VNET_API_ERROR_VALUE_EXIST;
1647 local->
port = l_port;
1659 nat_elog_err (
"static_mapping_by_local key add failed");
1665 return VNET_API_ERROR_NO_SUCH_ENTRY;
1668 return VNET_API_ERROR_UNSPECIFIED;
1677 nat_elog_err (
"static_mapping_by_local key del failed");
1698 if ((s->in2out.addr.as_u32 != match_local->
addr.
as_u32) ||
1699 s->in2out.port != match_local->
port)
1731 for (i = 1; i <
vec_len (locals); i++)
1754 snat_session_t *ses;
1755 u32 *ses_to_be_removed = 0, *ses_index;
1764 for (i = 0; i <
vec_len (addresses); i++)
1775 return VNET_API_ERROR_NO_SUCH_ENTRY;
1804 return VNET_API_ERROR_UNSPECIFIED;
1812 if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
1818 if (ses->out2in.addr.as_u32 == addr.
as_u32)
1847 #define _(N, i, n, s) \ 1848 vec_free (a->busy_##n##_ports_per_thread); 1886 vlib_validate_simple_counter (&sm->counters.fastpath.in2out.x, \ 1888 vlib_zero_simple_counter (&sm->counters.fastpath.in2out.x, sw_if_index); \ 1889 vlib_validate_simple_counter (&sm->counters.fastpath.out2in.x, \ 1891 vlib_zero_simple_counter (&sm->counters.fastpath.out2in.x, sw_if_index); \ 1892 vlib_validate_simple_counter (&sm->counters.slowpath.in2out.x, \ 1894 vlib_zero_simple_counter (&sm->counters.slowpath.in2out.x, sw_if_index); \ 1895 vlib_validate_simple_counter (&sm->counters.slowpath.out2in.x, \ 1897 vlib_zero_simple_counter (&sm->counters.slowpath.out2in.x, sw_if_index); \ 1898 vlib_validate_simple_counter (&sm->counters.fastpath.in2out_ed.x, \ 1900 vlib_zero_simple_counter (&sm->counters.fastpath.in2out_ed.x, sw_if_index); \ 1901 vlib_validate_simple_counter (&sm->counters.fastpath.out2in_ed.x, \ 1903 vlib_zero_simple_counter (&sm->counters.fastpath.out2in_ed.x, sw_if_index); \ 1904 vlib_validate_simple_counter (&sm->counters.slowpath.in2out_ed.x, \ 1906 vlib_zero_simple_counter (&sm->counters.slowpath.in2out_ed.x, sw_if_index); \ 1907 vlib_validate_simple_counter (&sm->counters.slowpath.out2in_ed.x, \ 1909 vlib_zero_simple_counter (&sm->counters.slowpath.out2in_ed.x, sw_if_index); 1919 per_vrf_sessions_t *per_vrf_sessions;
1928 if ((per_vrf_sessions->rx_fib_index == fib_index) ||
1929 (per_vrf_sessions->tx_fib_index == fib_index))
1931 per_vrf_sessions->expired = 1;
1980 const char *feature_name, *del_feature_name;
1990 return VNET_API_ERROR_UNSUPPORTED;
1996 return VNET_API_ERROR_UNSUPPORTED;
2004 nat_log_err (
"error interface already configured");
2005 return VNET_API_ERROR_VALUE_EXIST;
2011 feature_name = is_inside ?
"nat44-in2out-fast" :
"nat44-out2in-fast";
2016 is_inside ?
"nat44-in2out-worker-handoff" :
2017 "nat44-out2in-worker-handoff";
2020 feature_name = is_inside ?
"nat-pre-in2out" :
"nat-pre-out2in";
2023 feature_name = is_inside ?
"nat44-in2out" :
"nat44-out2in";
2042 if (outside_fib->
fib_index == fib_index)
2081 del_feature_name =
"nat44-handoff-classify";
2082 feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
2083 "nat44-out2in-worker-handoff";
2087 del_feature_name =
"nat44-ed-classify";
2088 feature_name = !is_inside ?
"nat-pre-in2out" :
2093 del_feature_name =
"nat44-classify";
2094 feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
2101 sw_if_index, 0, 0, 0);
2103 sw_if_index, 1, 0, 0);
2108 "nat44-ed-hairpinning",
2109 sw_if_index, 1, 0, 0);
2112 "nat44-hairpinning",
2113 sw_if_index, 1, 0, 0);
2122 sw_if_index, 0, 0, 0);
2128 "nat44-ed-hairpinning",
2129 sw_if_index, 0, 0, 0);
2132 "nat44-hairpinning",
2133 sw_if_index, 0, 0, 0);
2145 del_feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
2146 "nat44-out2in-worker-handoff";
2147 feature_name =
"nat44-handoff-classify";
2151 del_feature_name = !is_inside ?
"nat-pre-in2out" :
2154 feature_name =
"nat44-ed-classify";
2158 del_feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
2159 feature_name =
"nat44-classify";
2166 sw_if_index, 0, 0, 0);
2168 sw_if_index, 1, 0, 0);
2173 sw_if_index, 0, 0, 0);
2176 sw_if_index, 0, 0, 0);
2188 nat_log_err (
"error interface couldn't be found");
2189 return VNET_API_ERROR_NO_SUCH_ENTRY;
2208 sw_if_index, 1, 0, 0);
2211 sw_if_index, 1, 0, 0);
2243 u8 is_inside,
int is_del)
2256 return VNET_API_ERROR_UNSUPPORTED;
2262 return VNET_API_ERROR_UNSUPPORTED;
2270 nat_log_err (
"error interface already configured");
2271 return VNET_API_ERROR_VALUE_EXIST;
2284 if (outside_fib->
fib_index == fib_index)
2321 sw_if_index, !is_del, 0, 0);
2323 sw_if_index, !is_del, 0, 0);
2337 sw_if_index, !is_del, 0, 0);
2339 sw_if_index, !is_del, 0, 0);
2354 "nat44-out2in-worker-handoff",
2355 sw_if_index, !is_del, 0, 0);
2357 "nat44-in2out-output-worker-handoff",
2358 sw_if_index, !is_del, 0, 0);
2374 sw_if_index, !is_del, 0, 0);
2376 sw_if_index, !is_del, 0, 0);
2390 sw_if_index, !is_del, 0, 0);
2392 sw_if_index, !is_del, 0, 0);
2413 return VNET_API_ERROR_VALUE_EXIST;
2422 nat_log_err (
"error interface couldn't be found");
2423 return VNET_API_ERROR_NO_SUCH_ENTRY;
2463 return VNET_API_ERROR_FEATURE_DISABLED;
2466 return VNET_API_ERROR_INVALID_WORKER;
2495 if (!sm->
enabled || (new_fib_index == old_fib_index)
2528 if (outside_fib->
fib_index == old_fib_index)
2539 if (outside_fib->
fib_index == new_fib_index)
2566 u32 if_address_index,
u32 is_delete);
2574 u32 if_address_index,
u32 is_delete);
2580 u16 port_per_thread,
u32 snat_thread_index);
2586 l_addr.
as_u8[0] = 1;
2587 l_addr.
as_u8[1] = 1;
2588 l_addr.
as_u8[2] = 1;
2589 l_addr.
as_u8[3] = 1;
2591 r_addr.
as_u8[0] = 2;
2592 r_addr.
as_u8[1] = 2;
2593 r_addr.
as_u8[2] = 2;
2594 r_addr.
as_u8[3] = 2;
2598 u32 fib_index = 9000001;
2599 u32 thread_index = 3000000001;
2600 u32 session_index = 3000000221;
2602 init_ed_kv (&kv, l_addr, l_port, r_addr, r_port, fib_index, proto,
2603 thread_index, session_index);
2612 split_ed_kv (&kv, &l_addr2, &r_addr2, &proto2, &fib_index2, &l_port2,
2616 ASSERT (l_port == l_port2);
2617 ASSERT (r_port == r_port2);
2618 ASSERT (proto == proto2);
2619 ASSERT (fib_index == fib_index2);
2627 split_nat_key (key, &l_addr2, &l_port2, &fib_index2, &proto3);
2629 ASSERT (l_port == l_port2);
2630 ASSERT (proto == proto3);
2631 ASSERT (fib_index == fib_index2);
2646 if (fib_index != ~0)
2710 #define nat_init_simple_counter(c, n, sn) \ 2714 c.stat_segment_name = sn; \ 2715 vlib_validate_simple_counter (&c, 0); \ 2716 vlib_zero_simple_counter (&c, 0); \ 2727 u32 i, num_threads = 0;
2728 uword *p, *bitmap = 0;
2751 "/nat44/total-users");
2753 "/nat44/total-sessions");
2755 "/nat44/user-limit-reached");
2758 sm->counters.fastpath.in2out.x.name = #x; \ 2759 sm->counters.fastpath.in2out.x.stat_segment_name = \ 2760 "/nat44/in2out/fastpath/" #x; \ 2761 sm->counters.slowpath.in2out.x.name = #x; \ 2762 sm->counters.slowpath.in2out.x.stat_segment_name = \ 2763 "/nat44/in2out/slowpath/" #x; \ 2764 sm->counters.fastpath.out2in.x.name = #x; \ 2765 sm->counters.fastpath.out2in.x.stat_segment_name = \ 2766 "/nat44/out2in/fastpath/" #x; \ 2767 sm->counters.slowpath.out2in.x.name = #x; \ 2768 sm->counters.slowpath.out2in.x.stat_segment_name = \ 2769 "/nat44/out2in/slowpath/" #x; \ 2770 sm->counters.fastpath.in2out_ed.x.name = #x; \ 2771 sm->counters.fastpath.in2out_ed.x.stat_segment_name = \ 2772 "/nat44/ed/in2out/fastpath/" #x; \ 2773 sm->counters.slowpath.in2out_ed.x.name = #x; \ 2774 sm->counters.slowpath.in2out_ed.x.stat_segment_name = \ 2775 "/nat44/ed/in2out/slowpath/" #x; \ 2776 sm->counters.fastpath.out2in_ed.x.name = #x; \ 2777 sm->counters.fastpath.out2in_ed.x.stat_segment_name = \ 2778 "/nat44/ed/out2in/fastpath/" #x; \ 2779 sm->counters.slowpath.out2in_ed.x.name = #x; \ 2780 sm->counters.slowpath.out2in_ed.x.stat_segment_name = \ 2781 "/nat44/ed/out2in/slowpath/" #x; 2846 u32 static_mapping_buckets = 1024;
2847 u32 static_mapping_memory_size = 64 << 20;
2864 nat_log_err (
"unsupported combination of configuration");
2869 nat_log_err (
"unsupported combination of configuration");
2926 clib_bihash_init_16_8 (&sm->
out2in_ed,
"out2in-ed",
2928 clib_bihash_set_kvp_format_fn_16_8 (&sm->
out2in_ed,
2969 "static_mapping_by_local", static_mapping_buckets,
2970 static_mapping_memory_size);
2975 "static_mapping_by_external",
2976 static_mapping_buckets, static_mapping_memory_size);
2998 #define _(N, i, n, s) \ 2999 vec_free (ap->busy_##n##_ports_per_thread); 3035 nat_log_err (
"error occurred while removing interface %u",
3054 nat_log_err (
"error occurred while removing interface %u",
3115 u16 port_host_byte_order = clib_net_to_host_u16 (port);
3117 for (address_index = 0; address_index <
vec_len (addresses);
3120 if (addresses[address_index].addr.
as_u32 == addr->
as_u32)
3124 ASSERT (address_index < vec_len (addresses));
3126 a = addresses + address_index;
3130 #define _(N, i, n, s) \ 3131 case NAT_PROTOCOL_##N: \ 3132 ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \ 3133 --a->busy_##n##_port_refcounts[port_host_byte_order]; \ 3134 a->busy_##n##_ports--; \ 3135 a->busy_##n##_ports_per_thread[thread_index]--; \ 3152 u16 port_host_byte_order = clib_net_to_host_u16 (port);
3154 for (address_index = 0; address_index <
vec_len (addresses);
3157 if (addresses[address_index].addr.
as_u32 != addr.
as_u32)
3160 a = addresses + address_index;
3163 #define _(N, j, n, s) \ 3164 case NAT_PROTOCOL_##N: \ 3165 if (a->busy_##n##_port_refcounts[port_host_byte_order]) \ 3166 return VNET_API_ERROR_INSTANCE_IN_USE; \ 3167 ++a->busy_##n##_port_refcounts[port_host_byte_order]; \ 3168 a->busy_##n##_ports_per_thread[thread_index]++; \ 3169 a->busy_##n##_ports++; \ 3179 return VNET_API_ERROR_NO_SUCH_ENTRY;
3186 u32 match_fib_index,
3190 u32 * mapping_fib_index,
3198 clib_bihash_8_8_t *mapping_hash;
3200 u32 rand,
lo = 0,
hi, mid, *tmp = 0,
i;
3207 init_nat_k (&kv, match_addr, match_port, match_fib_index,
3209 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
3212 init_nat_k (&kv, match_addr, 0, match_fib_index, 0);
3213 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
3220 init_nat_k (&kv, match_addr, match_port, 0, match_protocol);
3221 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
3225 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
3245 *mapping_addr = local->
addr;
3246 *mapping_port = local->
port;
3286 mid = ((hi -
lo) >> 1) +
lo;
3288 (rand > local->
prefix) ? (lo = mid + 1) : (hi = mid);
3291 if (!(local->
prefix >= rand))
3293 *mapping_addr = local->
addr;
3294 *mapping_port = local->
port;
3299 match_protocol, match_port,
3349 u16 port_per_thread,
3350 u32 snat_thread_index)
3355 addr, port, port_per_thread,
3366 u16 port_per_thread,
u32 snat_thread_index)
3372 for (i = 0; i <
vec_len (addresses); i++)
3377 #define _(N, j, n, s) \ 3378 case NAT_PROTOCOL_##N: \ 3379 if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \ 3381 if (a->fib_index == fib_index) \ 3385 portnum = (port_per_thread * \ 3386 snat_thread_index) + \ 3387 snat_random_port(0, port_per_thread - 1) + 1024; \ 3388 if (a->busy_##n##_port_refcounts[portnum]) \ 3390 --a->busy_##n##_port_refcounts[portnum]; \ 3391 a->busy_##n##_ports_per_thread[thread_index]++; \ 3392 a->busy_##n##_ports++; \ 3394 *port = clib_host_to_net_u16(portnum); \ 3398 else if (a->fib_index == ~0) \ 3418 #define _(N, j, n, s) \ 3419 case NAT_PROTOCOL_##N: \ 3422 portnum = (port_per_thread * \ 3423 snat_thread_index) + \ 3424 snat_random_port(0, port_per_thread - 1) + 1024; \ 3425 if (a->busy_##n##_port_refcounts[portnum]) \ 3427 ++a->busy_##n##_port_refcounts[portnum]; \ 3428 a->busy_##n##_ports_per_thread[thread_index]++; \ 3429 a->busy_##n##_ports++; \ 3431 *port = clib_host_to_net_u16(portnum); \ 3452 u16 port_per_thread,
u32 snat_thread_index)
3456 u16 m, ports, portnum,
A, j;
3465 #define _(N, i, n, s) \ 3466 case NAT_PROTOCOL_##N: \ 3467 if (a->busy_##n##_ports < ports) \ 3471 A = snat_random_port(1, pow2_mask(sm->psid_offset)); \ 3472 j = snat_random_port(0, pow2_mask(m)); \ 3473 portnum = A | (sm->psid << sm->psid_offset) | (j << (16 - m)); \ 3474 if (a->busy_##n##_port_refcounts[portnum]) \ 3476 ++a->busy_##n##_port_refcounts[portnum]; \ 3477 a->busy_##n##_ports++; \ 3479 *port = clib_host_to_net_u16 (portnum); \ 3501 u16 port_per_thread,
u32 snat_thread_index)
3514 #define _(N, i, n, s) \ 3515 case NAT_PROTOCOL_##N: \ 3516 if (a->busy_##n##_ports < ports) \ 3520 portnum = snat_random_port(sm->start_port, sm->end_port); \ 3521 if (a->busy_##n##_port_refcounts[portnum]) \ 3523 ++a->busy_##n##_port_refcounts[portnum]; \ 3524 a->busy_##n##_ports++; \ 3526 *port = clib_host_to_net_u16 (portnum); \ 3552 .fp_addr.ip4.as_u32 = addr.
as_u32,
3573 u32 next_worker_index = 0;
3581 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
3585 return next_worker_index;
3590 u32 rx_fib_index0,
u8 is_output)
3598 u32 next_worker_index = 0;
3604 if (!clib_bihash_search_8_8
3625 icmp46_header_t *
icmp = (icmp46_header_t *) udp;
3628 (
vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
3638 case NAT_PROTOCOL_ICMP:
3639 icmp = (icmp46_header_t *) l4_header;
3643 case NAT_PROTOCOL_UDP:
3644 case NAT_PROTOCOL_TCP:
3657 if (!clib_bihash_search_8_8
3667 next_worker_index +=
3669 return next_worker_index;
3738 next_worker_index, fib_index,
3739 clib_net_to_host_u32 (ip->
3741 clib_net_to_host_u32 (ip->
3742 dst_address.as_u32));
3744 return next_worker_index;
3752 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
3759 next_worker_index, rx_fib_index,
3766 next_worker_index, rx_fib_index,
3771 return next_worker_index;
3776 u32 rx_fib_index,
u8 is_output)
3791 if (
PREDICT_TRUE (proto == NAT_PROTOCOL_UDP || proto == NAT_PROTOCOL_TCP))
3808 next_worker_index, rx_fib_index,
3809 clib_net_to_host_u32 (ip->
3811 clib_net_to_host_u32 (ip->
3812 dst_address.as_u32));
3813 return next_worker_index;
3816 else if (proto == NAT_PROTOCOL_ICMP)
3828 next_worker_index, rx_fib_index,
3829 clib_net_to_host_u32 (ip->
3831 clib_net_to_host_u32 (ip->
3832 dst_address.as_u32));
3833 return next_worker_index;
3842 if (!clib_bihash_search_8_8
3846 next_worker_index = m->
workers[0];
3864 icmp46_header_t *
icmp = (icmp46_header_t *) udp;
3867 (
vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
3877 case NAT_PROTOCOL_ICMP:
3878 icmp = (icmp46_header_t *) l4_header;
3882 case NAT_PROTOCOL_UDP:
3883 case NAT_PROTOCOL_TCP:
3897 if (!clib_bihash_search_8_8
3903 next_worker_index = m->
workers[0];
3921 next_worker_index +=
3928 return next_worker_index;
3951 .ip4.as_u32 = eh_addr->
as_u32,
3958 (sm->
addresses, thread_index, *out_addr, out_port, proto))
3975 s->out2in.addr.as_u32 = out_addr->
as_u32;
3976 s->out2in.port = out_port;
3977 s->nat_proto =
proto;
3978 s->last_heard = now;
3980 s->ext_host_addr.as_u32 = eh_addr->
as_u32;
3981 s->ext_host_port = eh_port;
4000 s->out2in.fib_index = outside_fib->
fib_index;
4009 if (clib_bihash_add_del_8_8 (&tsm->
out2in, &kv, 1))
4012 s->in2out.addr.as_u32 = in_addr->
as_u32;
4013 s->in2out.port = in_port;
4014 s->in2out.fib_index = fib_index;
4016 if (clib_bihash_add_del_8_8 (&tsm->
in2out, &kv, 1))
4034 (sm->
workers[(clib_net_to_host_u16 (out_port) -
4040 init_nat_k (&kv, *out_addr, out_port, fib_index, proto);
4041 if (clib_bihash_search_8_8 (&tsm->
out2in, &kv, &value))
4052 u32 total_pkts,
u64 total_bytes,
u32 thread_index)
4061 init_nat_k (&kv, *out_addr, out_port, fib_index, proto);
4062 if (clib_bihash_search_8_8 (&tsm->
out2in, &kv, &value))
4066 s->total_pkts = total_pkts;
4067 s->total_bytes = total_bytes;
4089 .ip4.as_u32 = eh_addr->
as_u32,
4097 (sm->
addresses, thread_index, *out_addr, out_port, proto))
4104 (sm->
addresses, thread_index, *ehn_addr, ehn_port, proto))
4112 s->last_heard = now;
4114 s->ext_host_nat_addr.as_u32 = s->ext_host_addr.as_u32 = eh_addr->
as_u32;
4115 s->ext_host_nat_port = s->ext_host_port = eh_port;
4118 s->ext_host_nat_addr.as_u32 = ehn_addr->
as_u32;
4119 s->ext_host_nat_port = ehn_port;
4138 s->out2in.fib_index = outside_fib->
fib_index;
4146 s->nat_proto =
proto;
4147 s->out2in.addr.as_u32 = out_addr->
as_u32;
4148 s->out2in.port = out_port;
4150 s->in2out.addr.as_u32 = in_addr->
as_u32;
4151 s->in2out.port = in_port;
4152 s->in2out.fib_index = fib_index;
4154 init_ed_kv (&kv, *in_addr, in_port, s->ext_host_nat_addr,
4157 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &kv, 1))
4160 init_ed_kv (&kv, *out_addr, out_port, *eh_addr, eh_port,
4163 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &kv, 1))
4181 (sm->
workers[(clib_net_to_host_u16 (out_port) -
4187 init_ed_k (&kv, *out_addr, out_port, *eh_addr, eh_port, fib_index, proto);
4188 if (clib_bihash_search_16_8 (&sm->
out2in_ed, &kv, &value))
4199 u32 fib_index,
u32 total_pkts,
u64 total_bytes,
4209 init_ed_k (&kv, *out_addr, out_port, *eh_addr, eh_port, fib_index, proto);
4210 if (clib_bihash_search_16_8 (&sm->
out2in_ed, &kv, &value))
4214 s->total_pkts = total_pkts;
4215 s->total_bytes = total_bytes;
4221 n_elts = n_elts / 2.5;
4223 while (lower_pow2 * 2 < n_elts)
4225 lower_pow2 = 2 * lower_pow2;
4227 u64 upper_pow2 = 2 * lower_pow2;
4228 if ((upper_pow2 - n_elts) < (n_elts - lower_pow2))
4230 if (upper_pow2 <= UINT32_MAX)
4242 u32 max_limit = 0,
len = 0;
4246 if (max_limit < sm->max_translations_per_fib[
len])
4259 if (len <= fib_index)
4319 clib_bihash_init_16_8 (&tsm->
in2out_ed,
"in2out-ed",
4321 clib_bihash_set_kvp_format_fn_16_8 (&tsm->
in2out_ed,
4356 clib_bihash_free_16_8 (&tsm->
in2out_ed);
4361 clib_bihash_free_8_8 (&tsm->
in2out);
4362 clib_bihash_free_8_8 (&tsm->
out2in);
4380 clib_bihash_init_16_8 (&sm->
out2in_ed,
"out2in-ed",
4384 clib_bihash_set_kvp_format_fn_16_8 (&sm->
out2in_ed,
4406 u32 if_address_index,
u32 is_delete)
4474 u32 if_address_index,
u32 is_delete)
4507 for (j = 0; j <
vec_len (addresses); j++)
4560 u32 *indices_to_delete = 0;
4562 u32 *auto_add_sw_if_indices =
4569 for (i = 0; i <
vec_len (auto_add_sw_if_indices); i++)
4571 if (auto_add_sw_if_indices[i] == sw_if_index)
4586 if (vec_len (indices_to_delete))
4588 for (j = vec_len (indices_to_delete) - 1; j >= 0; j--)
4599 return VNET_API_ERROR_VALUE_EXIST;
4606 return VNET_API_ERROR_NO_SUCH_ENTRY;
4630 clib_bihash_8_8_t *t;
4633 return VNET_API_ERROR_UNSUPPORTED;
4643 init_nat_k (&kv, *addr, port, fib_index, proto);
4644 t = is_in ? &tsm->in2out : &tsm->out2in;
4645 if (!clib_bihash_search_8_8 (t, &kv, &value))
4648 return VNET_API_ERROR_UNSPECIFIED;
4656 return VNET_API_ERROR_NO_SUCH_ENTRY;
4665 clib_bihash_16_8_t *t;
4672 return VNET_API_ERROR_FEATURE_DISABLED;
4682 t = is_in ? &tsm->in2out_ed : &sm->
out2in_ed;
4683 init_ed_k (&kv, *addr, port, *eh_addr, eh_port, fib_index, proto);
4684 if (clib_bihash_search_16_8 (t, &kv, &value))
4686 return VNET_API_ERROR_NO_SUCH_ENTRY;
4690 return VNET_API_ERROR_UNSPECIFIED;
4738 .name =
"nat-default",
4739 .vector_size =
sizeof (
u32),
ip4_address_t external_addr
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_always_inline void nat44_ei_user_del_sessions(snat_user_t *u, u32 thread_index)
fib_protocol_t fp_proto
protocol type
#define NAT_STATIC_MAPPING_FLAG_EXACT_ADDRESS
nat_outside_fib_t * outside_fibs
void nat_ha_disable()
Disable NAT HA.
u32 * max_translations_per_fib
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
u32 sessions_per_user_list_head_index
void nat44_db_init(snat_main_per_thread_data_t *tsm)
Initialize NAT44 data.
int snat_alloc_outside_address_and_port(snat_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
Alloc outside address and port.
vlib_node_registration_t nat_default_node
(constructor) VLIB_REGISTER_NODE (nat_default_node)
static u64 calc_nat_key(ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
The NAT inline functions.
#define nat_elog_debug_handoff(_str, _tid, _fib, _src, _dst)
clib_bihash_16_8_t out2in_ed
ip4_table_bind_function_t * function
#define pool_foreach_index(i, v)
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 snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
Delete external address from NAT44 pool.
u32 hairpin_dst_node_index
static void nat_validate_counters(snat_main_t *sm, u32 sw_if_index)
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
u32 ed_hairpinning_node_index
u32 icmp_match_out2in_ed(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
vl_api_wireguard_peer_flags_t flags
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
int ip4_sv_reass_enable_disable_with_refcnt(u32 sw_if_index, int is_enable)
void nat44_ei_free_session_data(snat_main_t *sm, snat_session_t *s, u32 thread_index, u8 is_ha)
static int nat_set_outside_address_and_port(snat_address_t *addresses, u32 thread_index, ip4_address_t addr, u16 port, nat_protocol_t protocol)
int nat44_del_session(snat_main_t *sm, ip4_address_t *addr, u16 port, nat_protocol_t proto, u32 vrf_id, int is_in)
Delete NAT44 session.
void nat_ipfix_logging_init(vlib_main_t *vm)
Initialize NAT plugin IPFIX logging.
vnet_main_t * vnet_get_main(void)
#define nat_elog_info(nat_elog_str)
void nat_ipfix_logging_addresses_exhausted(u32 thread_index, u32 pool_id)
Generate NAT addresses exhausted event.
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).
u32 ei_in2out_output_node_index
static clib_error_t * nat_ip_table_add_del(vnet_main_t *vnm, u32 table_id, u32 is_add)
static void init_nat_i2o_kv(clib_bihash_kv_8_8_t *kv, snat_session_t *s, u64 value)
#define is_ed_session(s)
Check if NAT session is endpoint dependent.
static_always_inline int get_icmp_o2i_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index, u32 thread_index, u32 session_index, nat_protocol_t *nat_proto, u16 *l_port, u16 *r_port, clib_bihash_kv_16_8_t *kv)
vl_api_ip_proto_t protocol
static u32 nat44_ed_get_worker_out2in_cb(vlib_buffer_t *b, ip4_header_t *ip, u32 rx_fib_index, u8 is_output)
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)
static f64 vlib_time_now(vlib_main_t *vm)
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.
static void snat_update_outside_fib(ip4_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
void nat_affinity_enable()
NAT affinity enable.
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)
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)
add paths without path extensions
int ip4_sv_reass_output_enable_disable_with_refcnt(u32 sw_if_index, int is_enable)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
void nat_ha_sref_ed_cb(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 total_pkts, u64 total_bytes, u32 thread_index)
u32 ed_out2in_slowpath_node_index
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define NAT_INTERFACE_FLAG_IS_OUTSIDE
void nat_ha_init(vlib_main_t *vm, u32 num_workers, u32 num_threads)
Initialize NAT HA.
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. ...
u8 * format_user_kvp(u8 *s, va_list *args)
ip_lookup_main_t lookup_main
static void init_nat_i2o_k(clib_bihash_kv_8_8_t *kv, snat_session_t *s)
#define nat_elog_warn(nat_elog_str)
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.
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
format_function_t format_snat_key
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.
#define VLIB_NODE_FN(node)
static void nat_ed_session_delete(snat_main_t *sm, snat_session_t *ses, u32 thread_index, int lru_delete)
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)
nat_alloc_out_addr_and_port_function_t * alloc_addr_and_port
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)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
#define snat_is_unk_proto_session(s)
Check if SNAT session for unknown protocol.
u32 max_translations_per_thread
void nat44_db_free(snat_main_per_thread_data_t *tsm)
Free NAT44 data.
vlib_simple_counter_main_t hairpinning
static_always_inline void nat_reset_timeouts(nat_timeouts_t *timeouts)
int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
Enable/disable NAT44 feature on the interface.
VNET_FEATURE_INIT(nat_pre_in2out, static)
nat44_lb_addr_port_t * locals
void nat44_set_node_indexes(snat_main_t *sm, vlib_main_t *vm)
static void split_nat_key(u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto)
clib_bihash_8_8_t user_hash
u32 ed_in2out_output_node_index
int nat44_plugin_enable(nat44_config_t c)
Enable NAT44 plugin.
#define nat_interface_is_outside(i)
Check if NAT interface is outside.
snat_session_t * nat_session_alloc_or_recycle(snat_main_t *sm, snat_user_t *u, u32 thread_index, f64 now)
Allocate new NAT session or recycle last used.
#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY
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.
u32 max_translations_per_user
void nat_ha_sadd_cb(ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, ip4_address_t *ehn_addr, u16 ehn_port, u8 proto, u32 fib_index, u16 flags, u32 thread_index)
void update_per_vrf_sessions_vec(u32 fib_index, int is_del)
u32 in2out_output_node_index
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
snat_get_worker_out2in_function_t * worker_out2in_cb
#define static_always_inline
static nat_protocol_t ip_proto_to_nat_proto(u8 ip_proto)
Common NAT inline functions.
#define VLIB_INIT_FUNCTION(x)
void nat_syslog_nat44_apmdel(u32 ssubix, u32 sfibix, ip4_address_t *isaddr, u16 isport, ip4_address_t *xsaddr, u16 xsport, nat_protocol_t proto)
u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
Get address and port values to be used for ICMP packet translation and create session if needed...
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
u8 * format_static_mapping_kvp(u8 *s, va_list *args)
int snat_static_mapping_match(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_ha_sadd_ed_cb(ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, ip4_address_t *ehn_addr, u16 ehn_port, u8 proto, u32 fib_index, u16 flags, u32 thread_index)
int snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
Add external address to NAT44 pool.
static void init_nat_o2i_kv(clib_bihash_kv_8_8_t *kv, snat_session_t *s, u64 value)
description fragment has unexpected format
u8 * format_ed_session_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.
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
#define is_fwd_bypass_session(s)
Check if NAT session is forwarding bypass.
static u32 snat_get_worker_in2out_cb(ip4_header_t *ip0, u32 rx_fib_index0, u8 is_output)
static void init_nat_o2i_k(clib_bihash_kv_8_8_t *kv, snat_session_t *s)
static int nat_alloc_addr_and_port_default(snat_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
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)
static void * ip4_next_header(ip4_header_t *i)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
void nat_ha_sdel_ed_cb(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 ti)
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 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)
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.
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
static void nat44_delete_session(snat_main_t *sm, snat_session_t *ses, u32 thread_index)
char * name
The counter collection's name.
vl_api_fib_path_type_t type
int nat44_set_session_limit(u32 session_limit, u32 vrf_id)
Set NAT44 session limit (session limit, vrf id)
twice_nat_type_t twice_nat
static u32 snat_get_worker_out2in_cb(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index0, u8 is_output)
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)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
u32 * auto_add_sw_if_indices_twice_nat
snat_user_t * nat_user_get_or_create(snat_main_t *sm, ip4_address_t *addr, u32 fib_index, u32 thread_index)
Find or create NAT user.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void nat_dpo_module_init(void)
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
nat_addr_and_port_alloc_alg_t addr_and_port_alloc_alg
int nat44_plugin_disable()
Disable NAT44 plugin.
#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.
void nat_ha_sdel_cb(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 ti)
IPv4 shallow virtual reassembly.
void nat_ha_sref_cb(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 total_pkts, u64 total_bytes, u32 thread_index)
u32 nat44_get_max_session_limit()
void nat_ei_static_mapping_del_sessions(snat_main_t *sm, snat_main_per_thread_data_t *tsm, snat_user_key_t u_key, int addr_only, ip4_address_t e_addr, u16 e_port)
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
u32 pre_in2out_node_index
static u32 ed_value_get_session_index(clib_bihash_kv_16_8_t *value)
snat_static_mapping_t * static_mappings
struct snat_main_s::@91 counters
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
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, int is_add, u8 *tag, int twice_nat, int out2in_only, int identity_nat, ip4_address_t pool_addr, int exact)
#define vec_del1(v, i)
Delete the element at index I.
u32 hairpin_src_node_index
clib_bihash_8_8_t static_mapping_by_external
#define nat_interface_is_inside(i)
Check if NAT interface is inside.
u32 in2out_slowpath_output_node_index
vl_api_address_union_t src_address
static void vlib_set_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 value)
Set a simple counter.
static_always_inline int nat_ed_lru_insert(snat_main_per_thread_data_t *tsm, snat_session_t *s, f64 now, u8 proto)
void nat_set_alloc_addr_and_port_default(void)
Set address and port assignment algorithm to default/standard.
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)
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
static_always_inline snat_session_t * nat_ed_session_alloc(snat_main_t *sm, u32 thread_index, f64 now, u8 proto)
#define is_lb_session(s)
Check if NAT session is load-balancing.
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
snat_interface_t * output_feature_interfaces
u32 pre_out2in_node_index
u32 ed_hairpin_src_node_index
void expire_per_vrf_sessions(u32 fib_index)
#define pool_free(p)
Free a pool.
static void nat44_delete_user_with_no_session(snat_main_t *sm, snat_user_t *u, u32 thread_index)
#define is_affinity_sessions(s)
Check if NAT session has affinity record.
#define VLIB_REGISTER_NODE(x,...)
#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT
u32 nat_affinity_get_per_service_list_head_index(void)
Get new affinity per service list head index.
static_always_inline uword vlib_get_thread_index(void)
u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
Get address and port values to be used for ICMP packet translation.
void nat44_add_del_address_dpo(ip4_address_t addr, u8 is_add)
Add/delete external address to FIB DPO (out2in DPO mode)
sll srl srl sll sra u16x4 i
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.
ip4_add_del_interface_address_function_t * function
int nat_affinity_find_and_lock(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.
void nat44_addresses_free(snat_address_t **addresses)
u32 ed_in2out_slowpath_node_index
static clib_error_t * nat_init(vlib_main_t *vm)
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)
#define nat_elog_notice_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
u8 * format_session_kvp(u8 *s, va_list *args)
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)
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, u64 value)
8 octet key, 8 octet key value pair
u32 ed_hairpin_dst_node_index
int nat44_update_session_limit(u32 session_limit, u32 vrf_id)
Update NAT44 session limit flushing all data (session limit, vrf id)
vlib_main_t vlib_node_runtime_t * node
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
u32 in2out_fast_node_index
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
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_INTERFACE_FLAG_IS_INSIDE
#define is_addr_only_static_mapping(sm)
Check if NAT static mapping is address only (1:1NAT).
#define is_identity_static_mapping(sm)
Check if NAT static mapping is identity NAT.
static int nat_alloc_addr_and_port_range(snat_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
clib_error_t * nat_affinity_init(vlib_main_t *vm)
Initialize NAT client-IP based affinity.
#define nat_init_simple_counter(c, n, sn)
u32 in2out_slowpath_node_index
snat_icmp_match_function_t * icmp_match_out2in_cb
static u32 nat_calc_bihash_buckets(u32 n_elts)
vlib_log_class_t log_class
#define SNAT_SESSION_FLAG_TWICE_NAT
#define foreach_nat_counter
void nat_set_alloc_addr_and_port_range(u16 start_port, u16 end_port)
Set address and port assignment algorithm for port range.
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.
#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.
uword * thread_registrations_by_name
#define FIB_SOURCE_PRIORITY_LOW
snat_address_t * twice_nat_addresses
#define VNET_FEATURES(...)
static vlib_main_t * vlib_get_main(void)
void nat_ha_sdel(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 thread_index)
Create session delete HA event.
static uword is_pow2(uword x)
ip4_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
#define is_lb_static_mapping(sm)
Check if NAT static mapping is load-balancing.
u32 unk_proto_lru_head_index
char * stat_segment_name
Name in stat segment directory.
vlib_simple_counter_main_t total_users
#define nat_elog_err(nat_elog_str)
void nat_affinity_disable()
NAT affinity disable.
#define FIB_NODE_INDEX_INVALID
void nat44_sessions_clear()
Free all NAT44 sessions.
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)
clib_error_t * nat44_api_hookup(vlib_main_t *vm)
static void user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 hairpinning_node_index
u32 tcp_trans_lru_head_index
#define is_out2in_only_static_mapping(sm)
Check if NAT static mapping match only out2in direction.
static_always_inline u8 nat_proto_to_ip_proto(nat_protocol_t nat_proto)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
VLIB buffer representation.
u32 tcp_estab_lru_head_index
snat_main_per_thread_data_t * per_thread_data
void nat_affinity_flush_service(u32 affinity_per_service_list_head_index)
Flush all service affinity data.
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
u32 affinity_per_service_list_head_index
snat_address_t * addresses
void nat_dpo_create(dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
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.
u32 out2in_fast_node_index
u32 icmp_match_out2in_slow(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
Get address and port values to be used for ICMP packet translation and create session if needed...
#define hash_get_mem(h, key)
snat_get_worker_in2out_function_t * worker_in2out_cb
snat_static_map_resolve_t * to_resolve
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)
static api_main_t * vlibapi_get_main(void)
static u32 random_u32(u32 *seed)
32-bit random number generator
#define SNAT_SESSION_FLAG_STATIC_MAPPING
ip4_main_t ip4_main
Global ip4 main structure.
static vlib_thread_main_t * vlib_get_thread_main()
static u32 get_thread_idx_by_port(u16 e_port)
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
#define vec_foreach(var, vec)
Vector iterator.
f64 end
end of the time range
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)
int snat_set_workers(uword *bitmap)
Set NAT plugin workers.
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.
#define is_twice_nat_session(s)
Check if NAT session is twice NAT.
clib_bihash_16_8_t in2out_ed
static int nat_alloc_addr_and_port_mape(snat_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
static u32 nat44_ed_get_worker_in2out_cb(ip4_header_t *ip, u32 rx_fib_index, u8 is_output)
int nat44_ei_user_del(ip4_address_t *addr, u32 fib_index)
Delete specific NAT44 EI user and his sessions.
void nat_set_alloc_addr_and_port_mape(u16 psid, u16 psid_offset, u16 psid_length)
Set address and port assignment algorithm for MAP-E CE.
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.
u32 icmp_match_out2in_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
Get address and port values to be used for ICMP packet translation.
NAT plugin client-IP based session affinity for load-balancing.
u32 icmp_match_in2out_ed(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b, ip4_header_t *ip, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto, void *d, void *e, u8 *dont_translate)
vlib_simple_counter_main_t total_sessions
ip_lookup_main_t * ip4_lookup_main
#define NAT_STATIC_MAPPING_FLAG_LB
static int is_snat_address_used_in_static_mapping(snat_main_t *sm, ip4_address_t addr)
#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY
snat_session_t * sessions
snat_icmp_match_function_t * icmp_match_in2out_cb
clib_bihash_8_8_t static_mapping_by_local
static u32 ed_value_get_thread_index(clib_bihash_kv_16_8_t *value)
vl_api_interface_index_t sw_if_index
snat_interface_t * interfaces
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)
static_always_inline void per_vrf_sessions_unregister_session(snat_session_t *s, u32 thread_index)
void nat_ha_enable(nat_ha_sadd_cb_t sadd_cb, nat_ha_sdel_cb_t sdel_cb, nat_ha_sref_cb_t sref_cb)
Enable NAT HA, set callbacks.
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.
VNET_IP_TABLE_ADD_DEL_FUNCTION(nat_ip_table_add_del)
void test_key_calc_split()
static u32 clib_dlist_remove_head(dlist_elt_t *pool, u32 head_index)
vlib_simple_counter_main_t user_limit_reached
static uword pool_elts(void *v)
Number of active elements in a pool.