31 #include <vpp/app/version.h> 38 .arc_name =
"ip4-unicast",
39 .node_name =
"nat44-in2out",
43 .arc_name =
"ip4-unicast",
44 .node_name =
"nat44-out2in",
48 .arc_name =
"ip4-unicast",
49 .node_name =
"nat44-classify",
53 .arc_name =
"ip4-unicast",
54 .node_name =
"nat44-det-in2out",
58 .arc_name =
"ip4-unicast",
59 .node_name =
"nat44-det-out2in",
63 .arc_name =
"ip4-unicast",
64 .node_name =
"nat44-det-classify",
68 .arc_name =
"ip4-unicast",
69 .node_name =
"nat44-in2out-worker-handoff",
73 .arc_name =
"ip4-unicast",
74 .node_name =
"nat44-out2in-worker-handoff",
78 .arc_name =
"ip4-unicast",
79 .node_name =
"nat44-handoff-classify",
83 .arc_name =
"ip4-unicast",
84 .node_name =
"nat44-in2out-fast",
88 .arc_name =
"ip4-unicast",
89 .node_name =
"nat44-out2in-fast",
93 .arc_name =
"ip4-unicast",
94 .node_name =
"nat44-hairpin-dst",
100 .arc_name =
"ip4-output",
101 .node_name =
"nat44-in2out-output",
105 .arc_name =
"ip4-output",
106 .node_name =
"nat44-in2out-output-worker-handoff",
110 .arc_name =
"ip4-output",
111 .node_name =
"nat44-hairpin-src",
118 .arc_name =
"ip4-local",
119 .node_name =
"nat44-hairpinning",
126 .version = VPP_BUILD_VER,
127 .description =
"Network Address Translation",
156 ed_key.
l_addr = s->out2in.addr;
157 ed_key.
r_addr = s->ext_host_addr;
161 ed_key.
proto = s->in2out.port;
168 ed_key.
l_port = s->out2in.port;
169 ed_key.
r_port = s->ext_host_port;
173 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &ed_kv, 0))
176 ed_key.
l_addr = s->in2out.addr;
179 ed_key.
l_port = s->in2out.port;
182 ed_key.
r_addr = s->ext_host_nat_addr;
183 ed_key.
r_port = s->ext_host_nat_port;
187 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &ed_kv, 0))
196 s->out2in.addr.as_u32,
200 s->in2out.fib_index);
208 key.
port = s->ext_host_nat_port;
210 if (a->
addr.
as_u32 == s->ext_host_nat_addr.as_u32)
213 thread_index, &key, i);
223 kv.
key = s->in2out.as_u64;
224 if (clib_bihash_add_del_8_8 (&tsm->
in2out, &kv, 0))
226 kv.
key = s->out2in.as_u64;
227 if (clib_bihash_add_del_8_8 (&tsm->
out2in, &kv, 0))
233 if (s->outside_address_index != ~0)
235 &s->out2in, s->outside_address_index);
253 if (clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
257 memset (u, 0,
sizeof (*u));
271 if (clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 1))
287 u32 oldest_per_user_translation_list_index, session_index;
288 dlist_elt_t * oldest_per_user_translation_list_elt;
294 oldest_per_user_translation_list_index =
298 ASSERT (oldest_per_user_translation_list_index != ~0);
303 oldest_per_user_translation_list_index);
305 oldest_per_user_translation_list_elt =
307 oldest_per_user_translation_list_index);
310 session_index = oldest_per_user_translation_list_elt->
value;
315 s->outside_address_index = ~0;
323 memset (s, 0,
sizeof (*s));
324 s->outside_address_index = ~0;
329 per_user_translation_list_elt - tsm->
list_pool);
332 s->per_user_index = per_user_translation_list_elt - tsm->
list_pool;
336 s->per_user_list_head_index,
337 per_user_translation_list_elt - tsm->
list_pool);
348 u32 n_left_from, * from, * to_next;
356 while (n_left_from > 0)
361 to_next, n_left_to_next);
363 while (n_left_from > 0 && n_left_to_next > 0)
407 to_next, n_left_to_next,
427 .name =
"nat44-classify",
428 .vector_size =
sizeof (
u32),
450 .name =
"nat44-det-classify",
451 .vector_size =
sizeof (
u32),
473 .name =
"nat44-handoff-classify",
474 .vector_size =
sizeof (
u32),
506 .ip4.as_u32 = addr->
as_u32,
557 #define _(N, i, n, s) \ 558 clib_bitmap_alloc (ap->busy_##n##_port_bitmap, 65535); \ 559 ap->busy_##n##_ports = 0; \ 560 vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); 570 if (nat_interface_is_inside(i))
573 snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
578 if (nat_interface_is_inside(i))
581 snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
592 if (m->external_addr.as_u32 == addr.as_u32)
603 v = clib_net_to_host_u32(a->
as_u32) + 1;
604 a->
as_u32 = clib_host_to_net_u32(v);
649 u16 l_port,
u16 e_port,
u32 vrf_id,
int addr_only,
665 if (sw_if_index != ~0)
674 if (first_int_addr == 0)
677 (sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto,
691 m_key.
port = addr_only ? 0 : e_port;
692 m_key.
protocol = addr_only ? 0 : proto;
703 return VNET_API_ERROR_VALUE_EXIST;
705 if (twice_nat && addr_only)
706 return VNET_API_ERROR_UNSUPPORTED;
713 return VNET_API_ERROR_NO_SUCH_FIB;
735 #define _(N, j, n, s) \ 736 case SNAT_PROTOCOL_##N: \ 737 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 738 return VNET_API_ERROR_INVALID_VALUE; \ 739 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 742 a->busy_##n##_ports++; \ 743 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]++; \ 750 return VNET_API_ERROR_INVALID_VALUE_2;
757 return VNET_API_ERROR_NO_SUCH_ENTRY;
761 memset (m, 0,
sizeof (*m));
795 m_key.
port = clib_host_to_net_u16 (l_port);
798 if (clib_bihash_add_del_8_8(&tsm->
in2out, &kv, 1))
810 m_key.
port = clib_host_to_net_u16 (e_port);
813 if (clib_bihash_add_del_8_8(&tsm->
out2in, &kv, 1))
821 return VNET_API_ERROR_NO_SUCH_ENTRY;
833 #define _(N, j, n, s) \ 834 case SNAT_PROTOCOL_##N: \ 835 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 838 a->busy_##n##_ports--; \ 839 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]--; \ 846 return VNET_API_ERROR_INVALID_VALUE_2;
869 if (clib_bihash_add_del_8_8(&tsm->
in2out, &kv, 0))
883 if (clib_bihash_add_del_8_8(&tsm->
out2in, &kv, 0))
894 u32 elt_index, head_index;
902 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
904 user_index = value.
value;
910 elt_index = head->
next;
912 ses_index = elt->
value;
913 while (ses_index != ~0)
917 ses_index = elt->
value;
921 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) &&
922 (clib_net_to_host_u16 (s->out2in.port) != e_port))
938 clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 0);
954 if (nat_interface_is_inside(interface))
957 snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add);
962 if (nat_interface_is_inside(interface))
965 snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add);
985 u32 worker_index = 0, elt_index, head_index, ses_index;
1005 return VNET_API_ERROR_VALUE_EXIST;
1008 return VNET_API_ERROR_INVALID_VALUE;
1026 #define _(N, j, n, s) \ 1027 case SNAT_PROTOCOL_##N: \ 1028 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 1029 return VNET_API_ERROR_INVALID_VALUE; \ 1030 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 1031 if (e_port > 1024) \ 1033 a->busy_##n##_ports++; \ 1034 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]++; \ 1041 return VNET_API_ERROR_INVALID_VALUE_2;
1048 return VNET_API_ERROR_NO_SUCH_ENTRY;
1052 memset (m, 0,
sizeof (*m));
1069 clib_warning (
"static_mapping_by_external key add failed");
1070 return VNET_API_ERROR_UNSPECIFIED;
1087 if (clib_bihash_add_del_8_8(&tsm->
out2in, &kv, 1))
1090 return VNET_API_ERROR_UNSPECIFIED;
1094 for (i = 0; i <
vec_len (locals); i++)
1101 locals[
i].
prefix = (i == 0) ? locals[i].probability :\
1102 (locals[i - 1].prefix + locals[i].probability);
1105 m_key.
port = clib_host_to_net_u16 (locals[i].port);
1108 if (clib_bihash_add_del_8_8(&tsm->
in2out, &kv, 1))
1111 return VNET_API_ERROR_UNSPECIFIED;
1118 return VNET_API_ERROR_NO_SUCH_ENTRY;
1132 #define _(N, j, n, s) \ 1133 case SNAT_PROTOCOL_##N: \ 1134 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 1135 if (e_port > 1024) \ 1137 a->busy_##n##_ports--; \ 1138 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]--; \ 1145 return VNET_API_ERROR_INVALID_VALUE_2;
1160 clib_warning (
"static_mapping_by_external key del failed");
1161 return VNET_API_ERROR_UNSPECIFIED;
1166 if (clib_bihash_add_del_8_8(&tsm->
out2in, &kv, 0))
1169 return VNET_API_ERROR_UNSPECIFIED;
1180 clib_warning (
"static_mapping_by_local key del failed");
1181 return VNET_API_ERROR_UNSPECIFIED;
1184 m_key.
port = clib_host_to_net_u16 (local->
port);
1186 if (clib_bihash_add_del_8_8(&tsm->
in2out, &kv, 0))
1189 return VNET_API_ERROR_UNSPECIFIED;
1195 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1202 elt_index = head->
next;
1204 ses_index = elt->
value;
1205 while (ses_index != ~0)
1209 ses_index = elt->
value;
1211 if ((s->in2out.addr.as_u32 != local->
addr.
as_u32) &&
1212 (clib_net_to_host_u16 (s->in2out.port) != local->
port))
1237 snat_session_t *ses;
1238 u32 *ses_to_be_removed = 0, *ses_index;
1249 for (i=0; i <
vec_len (addresses); i++)
1258 return VNET_API_ERROR_NO_SUCH_ENTRY;
1264 if (m->external_addr.as_u32 == addr.as_u32)
1265 (void) snat_add_static_mapping (m->local_addr, m->external_addr,
1266 m->local_port, m->external_port,
1267 m->vrf_id, m->addr_only, ~0,
1268 m->proto, 0, m->twice_nat);
1277 return VNET_API_ERROR_UNSPECIFIED;
1286 if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
1291 if (ses->out2in.addr.as_u32 == addr.as_u32)
1293 ses->outside_address_index = ~0;
1294 nat_free_session_data (sm, ses, tsm - sm->per_thread_data);
1295 clib_dlist_remove (tsm->list_pool, ses->per_user_index);
1296 pool_put_index (tsm->list_pool, ses->per_user_index);
1297 vec_add1 (ses_to_be_removed, ses - tsm->sessions);
1298 user_key.addr = ses->in2out.addr;
1299 user_key.fib_index = ses->in2out.fib_index;
1300 kv.key = user_key.as_u64;
1301 if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
1303 u = pool_elt_at_index (tsm->users, value.value);
1327 if (nat_interface_is_inside(interface))
1330 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1333 pool_foreach (interface, sm->output_feature_interfaces,
1335 if (nat_interface_is_inside(interface))
1338 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1349 const char * feature_name, *del_feature_name;
1355 feature_name = is_inside ?
"nat44-in2out-fast" :
"nat44-out2in-fast";
1359 feature_name = is_inside ?
"nat44-in2out-worker-handoff" :
"nat44-out2in-worker-handoff";
1361 feature_name = is_inside ?
"nat44-det-in2out" :
"nat44-det-out2in";
1363 feature_name = is_inside ?
"nat44-in2out" :
"nat44-out2in";
1374 if (i->sw_if_index == sw_if_index)
1378 if (nat_interface_is_inside(i) && nat_interface_is_outside(i))
1381 i->flags &= ~NAT_INTERFACE_FLAG_IS_INSIDE;
1383 i->flags &= ~NAT_INTERFACE_FLAG_IS_OUTSIDE;
1385 if (sm->num_workers > 1 && !sm->deterministic)
1386 del_feature_name =
"nat44-handoff-classify";
1387 else if (sm->deterministic)
1388 del_feature_name =
"nat44-det-classify";
1390 del_feature_name =
"nat44-classify";
1392 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1393 sw_if_index, 0, 0, 0);
1394 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1395 sw_if_index, 1, 0, 0);
1399 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1400 sw_if_index, 0, 0, 0);
1401 pool_put (sm->interfaces, i);
1406 if ((nat_interface_is_inside(i) && is_inside) ||
1407 (nat_interface_is_outside(i) && !is_inside))
1410 if (sm->num_workers > 1 && !sm->deterministic)
1412 del_feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1413 "nat44-out2in-worker-handoff";
1414 feature_name =
"nat44-handoff-classify";
1416 else if (sm->deterministic)
1418 del_feature_name = !is_inside ?
"nat44-det-in2out" :
1420 feature_name =
"nat44-det-classify";
1424 del_feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
1425 feature_name =
"nat44-classify";
1428 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1429 sw_if_index, 0, 0, 0);
1430 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1431 sw_if_index, 1, 0, 0);
1440 return VNET_API_ERROR_NO_SUCH_ENTRY;
1443 i->sw_if_index = sw_if_index;
1458 sw_if_index, !is_del, 0, 0);
1467 if (!(m->addr_only) || (m->local_addr.as_u32 == m->external_addr.as_u32))
1470 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1475 snat_add_del_addr_to_fib(&dm->out_addr, dm->out_plen, sw_if_index, !is_del);
1492 return VNET_API_ERROR_UNSUPPORTED;
1497 sw_if_index, !is_del, 0, 0);
1499 sw_if_index, !is_del, 0, 0);
1506 sw_if_index, !is_del, 0, 0);
1508 "nat44-in2out-output-worker-handoff",
1509 sw_if_index, !is_del, 0, 0);
1516 sw_if_index, !is_del, 0, 0);
1529 if (i->sw_if_index == sw_if_index)
1532 pool_put (sm->output_feature_interfaces, i);
1534 return VNET_API_ERROR_VALUE_EXIST;
1541 return VNET_API_ERROR_NO_SUCH_ENTRY;
1543 pool_get (sm->output_feature_interfaces,
i);
1544 i->sw_if_index = sw_if_index;
1561 if (!(m->addr_only))
1564 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1576 return VNET_API_ERROR_FEATURE_DISABLED;
1579 return VNET_API_ERROR_INVALID_WORKER;
1602 u32 if_address_index,
1610 u32 * address_indexp,
1611 u16 port_per_thread,
1612 u32 snat_thread_index);
1705 u16 port_host_byte_order = clib_net_to_host_u16 (k->
port);
1709 a = addresses + address_index;
1713 #define _(N, i, n, s) \ 1714 case SNAT_PROTOCOL_##N: \ 1715 ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \ 1716 port_host_byte_order) == 1); \ 1717 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \ 1718 port_host_byte_order, 0); \ 1719 a->busy_##n##_ports--; \ 1720 a->busy_##n##_ports_per_thread[thread_index]--; \ 1760 m_key.
port = clib_net_to_host_u16 (match.
port);
1766 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
1772 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
1786 mid = ((
hi -
lo) >> 1) +
lo;
1835 u32 * address_indexp,
1836 u16 port_per_thread,
1837 u32 snat_thread_index)
1842 address_indexp, port_per_thread,
1851 u32 * address_indexp,
1852 u16 port_per_thread,
1853 u32 snat_thread_index)
1859 for (i = 0; i <
vec_len (addresses); i++)
1864 #define _(N, j, n, s) \ 1865 case SNAT_PROTOCOL_##N: \ 1866 if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \ 1868 if (a->fib_index == fib_index) \ 1872 portnum = (port_per_thread * \ 1873 snat_thread_index) + \ 1874 snat_random_port(1, port_per_thread) + 1024; \ 1875 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 1877 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 1878 a->busy_##n##_ports_per_thread[thread_index]++; \ 1879 a->busy_##n##_ports++; \ 1880 k->addr = a->addr; \ 1881 k->port = clib_host_to_net_u16(portnum); \ 1882 *address_indexp = i; \ 1886 else if (a->fib_index == ~0) \ 1907 #define _(N, j, n, s) \ 1908 case SNAT_PROTOCOL_##N: \ 1911 portnum = (port_per_thread * \ 1912 snat_thread_index) + \ 1913 snat_random_port(1, port_per_thread) + 1024; \ 1914 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 1916 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 1917 a->busy_##n##_ports_per_thread[thread_index]++; \ 1918 a->busy_##n##_ports++; \ 1919 k->addr = a->addr; \ 1920 k->port = clib_host_to_net_u16(portnum); \ 1921 *address_indexp = gi; \ 1943 u32 * address_indexp,
1944 u16 port_per_thread,
1945 u32 snat_thread_index)
1949 u16 m, ports, portnum, A, j;
1958 #define _(N, i, n, s) \ 1959 case SNAT_PROTOCOL_##N: \ 1960 if (a->busy_##n##_ports < ports) \ 1964 A = snat_random_port(1, pow2_mask(sm->psid_offset)); \ 1965 j = snat_random_port(0, pow2_mask(m)); \ 1966 portnum = A | (sm->psid << sm->psid_offset) | (j << (16 - m)); \ 1967 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 1969 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 1970 a->busy_##n##_ports++; \ 1971 k->addr = a->addr; \ 1972 k->port = clib_host_to_net_u16 (portnum); \ 1973 *address_indexp = i; \ 1999 u32 start_host_order, end_host_order;
2013 if (
unformat (line_input,
"%U - %U",
2017 else if (
unformat (line_input,
"tenant-vrf %u", &vrf_id))
2020 end_addr = start_addr;
2021 else if (
unformat (line_input,
"twice-nat"))
2023 else if (
unformat (line_input,
"del"))
2039 start_host_order = clib_host_to_net_u32 (start_addr.
as_u32);
2040 end_host_order = clib_host_to_net_u32 (end_addr.
as_u32);
2042 if (end_host_order < start_host_order)
2048 count = (end_host_order - start_host_order) + 1;
2056 this_addr = start_addr;
2058 for (i = 0; i <
count; i++)
2067 case VNET_API_ERROR_NO_SUCH_ENTRY:
2070 case VNET_API_ERROR_UNSPECIFIED:
2087 .path =
"nat44 add address",
2088 .short_help =
"nat44 add address <ip4-range-start> [- <ip4-range-end>] " 2089 "[tenant-vrf <vrf-id>] [twice-nat] [del]",
2102 u32 * inside_sw_if_indices = 0;
2103 u32 * outside_sw_if_indices = 0;
2104 u8 is_output_feature = 0;
2118 vec_add1 (inside_sw_if_indices, sw_if_index);
2121 vec_add1 (outside_sw_if_indices, sw_if_index);
2122 else if (
unformat (line_input,
"output-feature"))
2123 is_output_feature = 1;
2124 else if (
unformat (line_input,
"del"))
2134 if (
vec_len (inside_sw_if_indices))
2136 for (i = 0; i <
vec_len(inside_sw_if_indices); i++)
2138 sw_if_index = inside_sw_if_indices[
i];
2139 if (is_output_feature)
2144 is_del ?
"del" :
"add",
2156 is_del ?
"del" :
"add",
2166 if (
vec_len (outside_sw_if_indices))
2168 for (i = 0; i <
vec_len(outside_sw_if_indices); i++)
2170 sw_if_index = outside_sw_if_indices[
i];
2171 if (is_output_feature)
2176 is_del ?
"del" :
"add",
2188 is_del ?
"del" :
"add",
2207 .path =
"set interface nat44",
2209 .short_help =
"set interface nat44 in <intfc> out <intfc> [output-feature] " 2216 u32 *r = va_arg (*args,
u32 *);
2219 #define _(N, i, n, s) else if (unformat (input, s)) *r = SNAT_PROTOCOL_##N; 2235 #define _(N, j, n, str) case SNAT_PROTOCOL_##N: t = (u8 *) str; break; 2239 s =
format (s,
"unknown");
2254 u32 l_port = 0, e_port = 0, vrf_id = ~0;
2257 u32 sw_if_index = ~0;
2281 else if (
unformat (line_input,
"external %U %u",
2286 else if (
unformat (line_input,
"external %U",
2289 else if (
unformat (line_input,
"vrf %u", &vrf_id))
2293 else if (
unformat (line_input,
"twice-nat"))
2295 else if (
unformat (line_input,
"del"))
2305 if (twice_nat && addr_only)
2311 if (!addr_only && !proto_set)
2318 vrf_id, addr_only, sw_if_index, proto, is_add,
2323 case VNET_API_ERROR_INVALID_VALUE:
2326 case VNET_API_ERROR_NO_SUCH_ENTRY:
2332 case VNET_API_ERROR_NO_SUCH_FIB:
2335 case VNET_API_ERROR_VALUE_EXIST:
2363 .path =
"nat44 add static mapping",
2366 "nat44 add static mapping tcp|udp|icmp local <addr> [<port>] " 2367 "external <addr> [<port>] [vrf <table-id>] [twice-nat] [del]",
2378 u32 port = 0, vrf_id = ~0;
2381 u32 sw_if_index = ~0;
2396 else if (
unformat (line_input,
"external %U",
2399 else if (
unformat (line_input,
"vrf %u", &vrf_id))
2404 else if (
unformat (line_input,
"del"))
2415 vrf_id, addr_only, sw_if_index, proto, is_add,
2420 case VNET_API_ERROR_INVALID_VALUE:
2423 case VNET_API_ERROR_NO_SUCH_ENTRY:
2429 case VNET_API_ERROR_NO_SUCH_FIB:
2432 case VNET_API_ERROR_VALUE_EXIST:
2459 .path =
"nat44 add identity mapping",
2461 .short_help =
"nat44 add identity mapping <interface>|<ip4-addr> " 2462 "[<protocol> <port>] [vrf <table-id>] [del]",
2473 u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
2487 if (
unformat (line_input,
"local %U:%u probability %u",
2490 memset (&local, 0,
sizeof (local));
2491 local.addr = l_addr;
2492 local.port = (
u16) l_port;
2493 local.probability = (
u8) probability;
2499 else if (
unformat (line_input,
"vrf %u", &vrf_id))
2504 else if (
unformat (line_input,
"twice-nat"))
2506 else if (
unformat (line_input,
"del"))
2529 locals, is_add, twice_nat);
2533 case VNET_API_ERROR_INVALID_VALUE:
2536 case VNET_API_ERROR_NO_SUCH_ENTRY:
2542 case VNET_API_ERROR_VALUE_EXIST:
2557 .path =
"nat44 add load-balancing static mapping",
2560 "nat44 add load-balancing static mapping protocol tcp|udp " 2561 "external <addr>:<port> local <addr>:<port> probability <n> [twice-nat] " 2562 "[vrf <table-id>] [del]",
2603 case VNET_API_ERROR_INVALID_WORKER:
2606 case VNET_API_ERROR_FEATURE_DISABLED:
2608 "Supported only if 2 or more workes available.");
2628 .path =
"set nat workers",
2631 "set nat workers <workers-list>",
2652 if (
unformat (line_input,
"domain %d", &domain_id))
2654 else if (
unformat (line_input,
"src-port %d", &src_port))
2656 else if (
unformat (line_input,
"disable"))
2690 .path =
"nat ipfix logging",
2692 .short_help =
"nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
2699 u32 next_worker_index = 0;
2707 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
2711 return next_worker_index;
2729 u32 next_worker_index = 0;
2757 nat_reass_ip4_t *reass;
2762 if (reass && (reass->thread_index != (
u32) ~ 0))
2763 return reass->thread_index;
2781 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
2803 icmp46_header_t * icmp = (icmp46_header_t *) udp;
2814 case SNAT_PROTOCOL_ICMP:
2815 icmp = (icmp46_header_t*)l4_header;
2819 case SNAT_PROTOCOL_UDP:
2820 case SNAT_PROTOCOL_TCP:
2832 m_key.addr = ip0->dst_address;
2833 m_key.port = clib_net_to_host_u16 (port);
2834 m_key.protocol = proto;
2835 m_key.fib_index = rx_fib_index0;
2836 kv.key = m_key.as_u64;
2837 if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
2840 return m->worker_index;
2845 next_worker_index = sm->first_worker_index;
2846 next_worker_index +=
2847 sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
2848 return next_worker_index;
2855 u32 translation_buckets = 1024;
2856 u32 translation_memory_size = 128<<20;
2857 u32 user_buckets = 128;
2858 u32 user_memory_size = 64<<20;
2859 u32 max_translations_per_user = 100;
2860 u32 outside_vrf_id = 0;
2861 u32 inside_vrf_id = 0;
2862 u32 static_mapping_buckets = 1024;
2863 u32 static_mapping_memory_size = 64<<20;
2864 u32 nat64_bib_buckets = 1024;
2865 u32 nat64_bib_memory_size = 128 << 20;
2866 u32 nat64_st_buckets = 2048;
2867 u32 nat64_st_memory_size = 256 << 20;
2868 u8 static_mapping_only = 0;
2869 u8 static_mapping_connection_tracking = 0;
2876 if (
unformat (input,
"translation hash buckets %d", &translation_buckets))
2878 else if (
unformat (input,
"translation hash memory %d",
2879 &translation_memory_size));
2880 else if (
unformat (input,
"user hash buckets %d", &user_buckets))
2882 else if (
unformat (input,
"user hash memory %d",
2885 else if (
unformat (input,
"max translations per user %d",
2886 &max_translations_per_user))
2888 else if (
unformat (input,
"outside VRF id %d",
2891 else if (
unformat (input,
"inside VRF id %d",
2894 else if (
unformat (input,
"static mapping only"))
2896 static_mapping_only = 1;
2897 if (
unformat (input,
"connection tracking"))
2898 static_mapping_connection_tracking = 1;
2900 else if (
unformat (input,
"deterministic"))
2902 else if (
unformat (input,
"nat64 bib hash buckets %d",
2903 &nat64_bib_buckets))
2905 else if (
unformat (input,
"nat64 bib hash memory %d",
2906 &nat64_bib_memory_size))
2908 else if (
unformat (input,
"nat64 st hash buckets %d", &nat64_st_buckets))
2910 else if (
unformat (input,
"nat64 st hash memory %d",
2911 &nat64_st_memory_size))
2937 nat64_set_hash(nat64_bib_buckets, nat64_bib_memory_size, nat64_st_buckets,
2938 nat64_st_memory_size);
2955 if (!static_mapping_only ||
2956 (static_mapping_only && static_mapping_connection_tracking))
2963 clib_bihash_init_8_8 (&tsm->
in2out,
"in2out", translation_buckets,
2964 translation_memory_size);
2966 clib_bihash_init_8_8 (&tsm->
out2in,
"out2in", translation_buckets,
2967 translation_memory_size);
2969 clib_bihash_init_8_8 (&tsm->
user_hash,
"users", user_buckets,
2973 clib_bihash_init_16_8 (&sm->
in2out_ed,
"in2out-ed",
2974 translation_buckets, translation_memory_size);
2976 clib_bihash_init_16_8 (&sm->
out2in_ed,
"out2in-ed",
2977 translation_buckets, translation_memory_size);
2985 "static_mapping_by_local", static_mapping_buckets,
2986 static_mapping_memory_size);
2989 "static_mapping_by_external", static_mapping_buckets,
2990 static_mapping_memory_size);
3005 #define _(v, N, str) case SNAT_SESSION_##N: t = (u8 *) str; break; 3009 t =
format (t,
"unknown");
3019 s =
format (s,
"%U proto %U port %d fib %d",
3029 snat_session_t * sess = va_arg (*args, snat_session_t *);
3033 s =
format (s,
" i2o %U proto %u fib %u\n",
3035 clib_net_to_host_u16 (sess->in2out.port),
3036 sess->in2out.fib_index);
3037 s =
format (s,
" o2i %U proto %u fib %u\n",
3039 clib_net_to_host_u16 (sess->out2in.port),
3040 sess->out2in.fib_index);
3049 s =
format (s,
" external host o2i %U:%d i2o %U:%d\n",
3051 clib_net_to_host_u16 (sess->ext_host_port),
3053 clib_net_to_host_u16 (sess->ext_host_nat_port));
3057 if (sess->ext_host_addr.as_u32)
3058 s =
format (s,
" external host %U\n",
3061 s =
format (s,
" last heard %.2f\n", sess->last_heard);
3062 s =
format (s,
" total pkts %d, total bytes %lld\n",
3063 sess->total_pkts, sess->total_bytes);
3065 s =
format (s,
" static translation\n");
3067 s =
format (s,
" dynamic translation\n");
3069 s =
format (s,
" load-balancing\n");
3071 s =
format (s,
" twice-nat\n");
3080 int verbose = va_arg (*args,
int);
3082 u32 elt_index, head_index;
3084 snat_session_t * sess;
3086 s =
format (s,
"%U: %d dynamic translations, %d static translations\n",
3097 elt_index = head->
next;
3099 session_index = elt->
value;
3101 while (session_index != ~0)
3107 elt_index = elt->
next;
3109 session_index = elt->
value;
3122 s =
format (s,
"local %U external %U vrf %d %s",
3130 s =
format (s,
"%U vrf %d external %U:%d %s",
3136 s =
format (s,
"\n local %U:%d probability %d\%",
3141 s =
format (s,
"%U local %U:%d external %U:%d vrf %d %s",
3156 s =
format (s,
"local %U external %U vrf %d",
3162 s =
format (s,
"%U local %U:%d external %U:%d vrf %d",
3176 u32 in_offset, out_offset;
3178 u32 *
i = va_arg (*args,
u32 *);
3181 in_addr.
as_u32 = clib_host_to_net_u32 (
3182 clib_net_to_host_u32(det_map->
in_addr.
as_u32) + user_index);
3183 in_offset = clib_net_to_host_u32(in_addr.
as_u32) -
3186 out_addr.
as_u32 = clib_host_to_net_u32(
3188 s =
format (s,
"in %U:%d out %U:%d external host %U:%d state: %U expire: %d\n",
3190 clib_net_to_host_u16 (ses->
in_port),
3214 u32 users_num = 0, sessions_num = 0, *worker, *sw_if_index;
3222 else if (
unformat (input,
"verbose"))
3228 vlib_cli_output (vm,
"NAT plugin mode: static mapping only connection " 3239 vlib_cli_output (vm,
"NAT plugin mode: dynamic translations enabled");
3246 vlib_cli_output (vm,
"%U %s", format_vnet_sw_interface_name, vnm,
3247 vnet_get_sw_interface (vnm, i->sw_if_index),
3248 (nat_interface_is_inside(i) &&
3249 nat_interface_is_outside(i)) ?
"in out" :
3250 (nat_interface_is_inside(i) ?
"in" :
"out"));
3255 vlib_cli_output (vm,
"%U output-feature %s",
3256 format_vnet_sw_interface_name, vnm,
3257 vnet_get_sw_interface (vnm, i->sw_if_index),
3258 (nat_interface_is_inside(i) &&
3259 nat_interface_is_outside(i)) ?
"in out" :
3260 (nat_interface_is_inside(i) ?
"in" :
"out"));
3292 #define _(N, i, n, s) \ 3293 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s); 3307 #define _(N, i, n, s) \ 3308 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s); 3342 vlib_cli_output (vm,
"in %U/%d out %U/%d\n",
3343 format_ip4_address, &dm->in_addr, dm->in_plen,
3344 format_ip4_address, &dm->out_addr, dm->out_plen);
3345 vlib_cli_output (vm,
" outside address sharing ratio: %d\n",
3347 vlib_cli_output (vm,
" number of ports per inside host: %d\n",
3348 dm->ports_per_host);
3349 vlib_cli_output (vm,
" sessions number: %d\n", dm->ses_num);
3352 vec_foreach_index (j, dm->sessions)
3354 ses = vec_elt_at_index (dm->sessions, j);
3356 vlib_cli_output (vm,
" %U", format_det_map_ses, dm, ses,
3365 if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking))
3374 vlib_cli_output (vm,
"%U", format_snat_static_mapping, m);
3383 sessions_num +=
pool_elts (tsm->sessions);
3387 " %d static mappings, %d twice-nat addresses",
3392 vec_len (sm->twice_nat_addresses));
3419 vlib_cli_output (vm,
" %U", format_snat_user, tsm, u,
3429 vlib_cli_output (vm,
"%U", format_snat_static_mapping, m);
3431 for (j = 0; j <
vec_len (sm->to_resolve); j++)
3433 rp = sm->to_resolve + j;
3446 .path =
"show nat44",
3447 .short_help =
"show nat44",
3458 u32 if_address_index,
3463 u32 *indices_to_delete = 0;
3490 for (j = 0; j <
vec_len(addresses); j++)
3491 if (addresses[j].
addr.as_u32 == address->
as_u32)
3525 if (
vec_len(indices_to_delete))
3528 for (j =
vec_len(indices_to_delete)-1; j >= 0; j--)
3548 u32 *indices_to_delete = 0;
3550 u32 *auto_add_sw_if_indices =
3556 for (i = 0; i <
vec_len(auto_add_sw_if_indices); i++)
3558 if (auto_add_sw_if_indices[i] == sw_if_index)
3573 if (
vec_len(indices_to_delete))
3575 for (j =
vec_len(indices_to_delete)-1; j >= 0; j--)
3586 return VNET_API_ERROR_VALUE_EXIST;
3593 return VNET_API_ERROR_NO_SUCH_ENTRY;
3630 else if (
unformat (line_input,
"twice-nat"))
3632 else if (
unformat (line_input,
"del"))
3662 .path =
"nat44 add interface address",
3663 .short_help =
"nat44 add interface address <interface> [twice-nat] [del]",
3677 clib_bihash_8_8_t *t;
3690 key.
port = clib_host_to_net_u16 (port);
3694 t = is_in ? &tsm->in2out : &tsm->out2in;
3695 if (!clib_bihash_search_8_8 (t, &kv, &value))
3698 kv.
key = s->in2out.as_u64;
3699 clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0);
3700 kv.
key = s->out2in.as_u64;
3701 clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0);
3702 u_key.
addr = s->in2out.addr;
3705 if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
3715 return VNET_API_ERROR_NO_SUCH_ENTRY;
3741 else if (
unformat (line_input,
"in"))
3746 else if (
unformat (line_input,
"vrf %u", &vrf_id))
3775 .path =
"nat44 del session",
3776 .short_help =
"nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>]",
3788 u32 psid, psid_offset, psid_length;
3796 if (
unformat (line_input,
"default"))
3798 else if (
unformat (line_input,
"map-e psid %d psid-offset %d psid-len %d",
3799 &psid, &psid_offset, &psid_length))
3821 .path =
"nat addr-port-assignment-alg",
3822 .short_help =
"nat addr-port-assignment-alg <alg-name> [<alg-params>]",
3834 u32 in_plen, out_plen;
3848 else if (
unformat (line_input,
"del"))
3885 .path =
"nat44 deterministic add",
3886 .short_help =
"nat44 deterministic add in <addr>/<plen> out <addr>/<plen> [del]",
3945 .path =
"nat44 deterministic forward",
3946 .short_help =
"nat44 deterministic forward <addr>",
3978 if (out_port < 1024 || out_port > 65535)
4009 .path =
"nat44 deterministic reverse",
4010 .short_help =
"nat44 deterministic reverse <addr>:<port>",
4031 else if (
unformat (line_input,
"tcp-established %u",
4034 else if (
unformat (line_input,
"tcp-transitory %u",
4039 else if (
unformat (line_input,
"reset"))
4071 .path =
"set nat44 deterministic timeout",
4074 "set nat44 deterministic timeout [udp <sec> | tcp-established <sec> " 4075 "tcp-transitory <sec> | icmp <sec> | reset]",
4086 u32 out_port, ext_port;
4098 if (
unformat (line_input,
"%U:%d %U:%d",
4143 .path =
"nat44 deterministic close session out",
4144 .short_help =
"nat44 deterministic close session out " 4145 "<out_addr>:<out_port> <ext_addr>:<ext_port>",
4157 u32 in_port, ext_port;
4169 if (
unformat (line_input,
"%U:%d %U:%d",
4212 .path =
"nat44 deterministic close session in",
4213 .short_help =
"nat44 deterministic close session in " 4214 "<in_addr>:<in_port> <ext_addr>:<ext_port>",
4225 u8 forwarding_enable;
4226 u8 forwarding_enable_set = 0;
4235 if (!forwarding_enable_set &&
unformat (line_input,
"enable"))
4237 forwarding_enable = 1;
4238 forwarding_enable_set = 1;
4240 else if (!forwarding_enable_set &&
unformat (line_input,
"disable"))
4242 forwarding_enable = 0;
4243 forwarding_enable_set = 1;
4253 if (!forwarding_enable_set)
4280 .path =
"nat44 forwarding",
4281 .short_help =
"nat44 forwarding enable|disable",
ip4_address_t external_addr
u8 * format_snat_user(u8 *s, va_list *args)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
clib_error_t * snat_api_init(vlib_main_t *vm, snat_main_t *sm)
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
u32 sessions_per_user_list_head_index
clib_bihash_16_8_t out2in_ed
sll srl srl sll sra u16x4 i
int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
vlib_node_registration_t nat44_handoff_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_handoff_classify_node)
void dslite_init(vlib_main_t *vm)
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
VLIB_NODE_FUNCTION_MULTIARCH(nat44_classify_node, nat44_classify_node_fn)
u8 * format_snat_protocol(u8 *s, va_list *args)
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
vnet_main_t * vnet_get_main(void)
static int nat_alloc_addr_and_port_mape(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u32 *address_indexp, u16 port_per_thread, u32 snat_thread_index)
u32 fq_in2out_output_index
clib_error_t * nat_reass_init(vlib_main_t *vm)
Initialize NAT virtual fragmentation reassembly.
#define SNAT_TCP_ESTABLISHED_TIMEOUT
#define is_ed_session(s)
Check if NAT session is endpoint dependent.
static clib_error_t * nat44_del_session_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
u32 vlib_frame_queue_main_init(u32 node_index, u32 frame_queue_nelts)
nat_reass_ip4_t * nat_ip4_reass_find(ip4_address_t src, ip4_address_t dst, u16 frag_id, u8 proto)
Find reassembly.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static clib_error_t * snat_det_map_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
struct _vlib_node_registration vlib_node_registration_t
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, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation and create session if needed...
#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
static snat_det_session_t * snat_det_find_ses_by_in(snat_det_map_t *dm, ip4_address_t *in_addr, u16 in_port, snat_det_out_key_t out_key)
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. ...
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, mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
static void snat_det_forward(snat_det_map_t *dm, ip4_address_t *in_addr, ip4_address_t *out_addr, u16 *lo_port)
ip_lookup_main_t lookup_main
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_node_registration_t snat_det_out2in_node
(constructor) VLIB_REGISTER_NODE (snat_det_out2in_node)
void nat64_set_hash(u32 bib_buckets, u32 bib_memory_size, u32 st_buckets, u32 st_memory_size)
Set NAT64 hash tables configuration.
unformat_function_t unformat_vnet_sw_interface
clib_bihash_16_8_t in2out_ed
int snat_static_mapping_match(snat_main_t *sm, snat_session_key_t match, snat_session_key_t *mapping, u8 by_external, u8 *is_addr_only, u8 *twice_nat)
Match NAT44 static mapping.
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.
snat_det_map_t * det_maps
static clib_error_t * snat_add_interface_address_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
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)
static clib_error_t * snat_det_close_session_in_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static void snat_det_reverse(snat_det_map_t *dm, ip4_address_t *out_addr, u16 out_port, ip4_address_t *in_addr)
#define snat_is_unk_proto_session(s)
Check if SNAT session for unknown protocol.
u8 * format_snat_static_mapping(u8 *s, va_list *args)
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, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation.
int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
static uword nat44_classify_node_fn_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
nat44_lb_addr_port_t * locals
clib_bihash_8_8_t user_hash
u32 max_translations_per_user
static clib_error_t * snat_feature_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 in2out_output_node_index
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
#define static_always_inline
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
vlib_node_registration_t snat_out2in_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_node)
ip4_address_t ext_host_addr
static u32 snat_get_worker_in2out_cb(ip4_header_t *ip0, u32 rx_fib_index0)
#define SNAT_DET_SES_PER_USER
A high priority source a plugin can use.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Aggregrate type for a prefix.
#define clib_error_return(e, args...)
int snat_ipfix_logging_enable_disable(int enable, u32 domain_id, u16 src_port)
Enable/disable NAT plugin IPFIX logging.
void snat_ipfix_logging_init(vlib_main_t *vm)
Initialize NAT plugin IPFIX logging.
u8 * format_snat_key(u8 *s, va_list *args)
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.
static clib_error_t * add_address_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u16 fp_len
The mask length.
static uword nat44_det_classify_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 icmp_match_out2in_det(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation and create session if needed...
static int ip4_is_fragment(ip4_header_t *i)
VNET_FEATURE_INIT(ip4_snat_in2out, static)
u32 * auto_add_sw_if_indices_twice_nat
vlib_worker_thread_t * vlib_worker_threads
snat_user_t * nat_user_get_or_create(snat_main_t *sm, ip4_address_t *addr, u32 fib_index, u32 thread_index)
format_function_t format_vnet_sw_interface_name
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void nat_free_session_data(snat_main_t *sm, snat_session_t *s, u32 thread_index)
static clib_error_t * snat_det_forward_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
static uword clib_bitmap_last_set(uword *ai)
Return the higest numbered set bit in a bitmap.
static clib_error_t * nat44_set_alloc_addr_and_port_alg_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static snat_det_map_t * snat_det_map_by_out(snat_main_t *sm, ip4_address_t *out_addr)
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
static clib_error_t * show_snat_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
snat_static_mapping_t * static_mappings
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
void snat_ipfix_logging_nat44_ses_delete(u32 src_ip, u32 nat_src_ip, snat_protocol_t snat_proto, u16 src_port, u16 nat_src_port, u32 vrf_id)
Generate NAT44 session delete event.
vlib_node_registration_t nat44_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_classify_node)
#define pool_put(P, E)
Free an object E in pool P.
#define VLIB_CONFIG_FUNCTION(x, n,...)
static clib_error_t * set_workers_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_del1(v, i)
Delete the element at index I.
clib_bihash_8_8_t static_mapping_by_external
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
static clib_error_t * add_lb_static_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
snat_interface_t * output_feature_interfaces
static uword nat44_handoff_classify_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
void snat_free_outside_address_and_port(snat_address_t *addresses, u32 thread_index, snat_session_key_t *k, u32 address_index)
static u32 random_u32_max(void)
Maximum value returned by random_u32()
static_always_inline uword vlib_get_thread_index(void)
u8 nat_reass_is_drop_frag(u8 is_ip6)
Get status of virtual fragmentation reassembly.
vlib_node_registration_t snat_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_node)
u8 static_mapping_connection_tracking
snat_get_worker_function_t * worker_in2out_cb
#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
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
deterministic NAT definitions
#define clib_warning(format, args...)
int snat_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside, int is_del)
static int ip4_is_first_fragment(ip4_header_t *i)
static uword nat44_classify_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static clib_error_t * add_identity_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
8 octet key, 8 octet key value pair
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
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, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation and create session if needed...
u32 tcp_transitory_timeout
int snat_det_add_map(snat_main_t *sm, ip4_address_t *in_addr, u8 in_plen, ip4_address_t *out_addr, u8 out_plen, int is_add)
Add/delete deterministic NAT mapping.
#define VLIB_CLI_COMMAND(x,...)
u32 * auto_add_sw_if_indices
static_always_inline u16 snat_random_port(u16 min, u16 max)
static int nat_alloc_addr_and_port_default(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u32 *address_indexp, u16 port_per_thread, u32 snat_thread_index)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static snat_det_map_t * snat_det_map_by_user(snat_main_t *sm, ip4_address_t *user_addr)
#define pool_put_index(p, i)
Free pool element with given index.
#define NAT_INTERFACE_FLAG_IS_INSIDE
u8 * format_snat_static_map_to_resolve(u8 *s, va_list *args)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
snat_get_worker_function_t * worker_out2in_cb
static u32 ip_proto_to_snat_proto(u8 ip_proto)
snat_icmp_match_function_t * icmp_match_out2in_cb
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.
uword * thread_registrations_by_name
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
int nat44_del_session(snat_main_t *sm, ip4_address_t *addr, u16 port, snat_protocol_t proto, u32 vrf_id, int is_in)
snat_address_t * twice_nat_addresses
#define VNET_FEATURES(...)
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, snat_protocol_t proto, int is_add, u8 twice_nat)
Add static mapping.
int nat44_add_del_lb_static_mapping(ip4_address_t e_addr, u16 e_port, snat_protocol_t proto, u32 vrf_id, nat44_lb_addr_port_t *locals, u8 is_add, u8 twice_nat)
static clib_error_t * snat_init(vlib_main_t *vm)
static uword is_pow2(uword x)
snat_session_t * nat_session_alloc_or_recycle(snat_main_t *sm, snat_user_t *u, u32 thread_index)
vlib_node_registration_t snat_det_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_det_in2out_node)
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, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation.
clib_error_t * nat64_init(vlib_main_t *vm)
Initialize NAT64.
NAT64 global declarations.
void increment_v4_address(ip4_address_t *a)
void snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
int snat_alloc_outside_address_and_port(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u32 *address_indexp, u16 port_per_thread, u32 snat_thread_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * set_timeout_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * snat_forwarding_set_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
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, snat_protocol_t proto, int addr_only, int is_add)
static uword unformat_bitmap_list(unformat_input_t *input, va_list *va)
unformat a list of bit ranges into a bitmap (eg "0-3,5-7,11" )
void snat_ipfix_logging_addresses_exhausted(u32 pool_id)
Generate NAT addresses exhausted event.
snat_main_per_thread_data_t * per_thread_data
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static clib_error_t * snat_det_reverse_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
snat_address_t * addresses
int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del, u8 twice_nat)
u32 icmp_match_in2out_det(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation and create session if needed...
u8 * format_snat_session(u8 *s, va_list *args)
#define hash_get_mem(h, key)
u8 * format_det_map_ses(u8 *s, va_list *args)
#define SNAT_ICMP_TIMEOUT
uword unformat_snat_protocol(unformat_input_t *input, va_list *args)
static snat_det_session_t * snat_det_get_ses_by_out(snat_det_map_t *dm, ip4_address_t *in_addr, u64 out_key)
snat_static_map_resolve_t * to_resolve
static u32 random_u32(u32 *seed)
32-bit random number generator
#define VLIB_REGISTER_NODE(x,...)
ip4_main_t ip4_main
Global ip4 main structure.
static clib_error_t * snat_ipfix_logging_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static vlib_thread_main_t * vlib_get_thread_main()
u32 translation_memory_size
#define vec_foreach(var, vec)
Vector iterator.
vlib_node_registration_t snat_in2out_output_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_output_node)
vlib_node_registration_t nat44_det_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_det_classify_node)
static clib_error_t * snat_det_close_session_out_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
int snat_set_workers(uword *bitmap)
#define is_twice_nat_session(s)
Check if NAT session is twice NAT.
static clib_error_t * add_static_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * snat_config(vlib_main_t *vm, unformat_input_t *input)
NAT plugin virtual fragmentation reassembly.
#define SNAT_TCP_TRANSITORY_TIMEOUT
ip_lookup_main_t * ip4_lookup_main
static int is_snat_address_used_in_static_mapping(snat_main_t *sm, ip4_address_t addr)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
snat_session_t * sessions
u8 * format_snat_session_state(u8 *s, va_list *args)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
snat_icmp_match_function_t * icmp_match_in2out_cb
#define SNAT_SESSION_FLAG_LOAD_BALANCING
clib_bihash_8_8_t static_mapping_by_local
static u32 snat_get_worker_out2in_cb(ip4_header_t *ip0, u32 rx_fib_index0)
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 u8 icmp_is_error_message(icmp46_header_t *icmp)
static u8 snat_proto_to_ip_proto(snat_protocol_t snat_proto)
static u32 clib_dlist_remove_head(dlist_elt_t *pool, u32 head_index)
u32 tcp_established_timeout
static uword pool_elts(void *v)
Number of active elements in a pool.