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);
982 if (vec_len(m->locals))
984 if (m->external_port == e_port && m->external_addr.as_u32 == e_addr->as_u32)
987 vec_foreach (ap, m->locals)
989 if (ap->port == local->port && ap->addr.as_u32 == local->addr.as_u32)
1012 u32 worker_index = 0, elt_index, head_index, ses_index;
1019 m_key.
addr = e_addr;
1020 m_key.
port = e_port;
1032 return VNET_API_ERROR_VALUE_EXIST;
1035 return VNET_API_ERROR_INVALID_VALUE;
1053 #define _(N, j, n, s) \ 1054 case SNAT_PROTOCOL_##N: \ 1055 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 1056 return VNET_API_ERROR_INVALID_VALUE; \ 1057 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 1058 if (e_port > 1024) \ 1060 a->busy_##n##_ports++; \ 1061 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]++; \ 1068 return VNET_API_ERROR_INVALID_VALUE_2;
1075 return VNET_API_ERROR_NO_SUCH_ENTRY;
1079 memset (m, 0,
sizeof (*m));
1096 clib_warning (
"static_mapping_by_external key add failed");
1097 return VNET_API_ERROR_UNSPECIFIED;
1114 if (clib_bihash_add_del_8_8(&tsm->
out2in, &kv, 1))
1117 return VNET_API_ERROR_UNSPECIFIED;
1121 for (i = 0; i <
vec_len (locals); i++)
1128 locals[
i].
prefix = (i == 0) ? locals[i].probability :\
1129 (locals[i - 1].prefix + locals[i].probability);
1132 m_key.
port = clib_host_to_net_u16 (locals[i].port);
1135 if (clib_bihash_add_del_8_8(&tsm->
in2out, &kv, 1))
1138 return VNET_API_ERROR_UNSPECIFIED;
1145 return VNET_API_ERROR_NO_SUCH_ENTRY;
1159 #define _(N, j, n, s) \ 1160 case SNAT_PROTOCOL_##N: \ 1161 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 1162 if (e_port > 1024) \ 1164 a->busy_##n##_ports--; \ 1165 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]--; \ 1172 return VNET_API_ERROR_INVALID_VALUE_2;
1187 clib_warning (
"static_mapping_by_external key del failed");
1188 return VNET_API_ERROR_UNSPECIFIED;
1193 if (clib_bihash_add_del_8_8(&tsm->
out2in, &kv, 0))
1196 return VNET_API_ERROR_UNSPECIFIED;
1207 clib_warning (
"static_mapping_by_local key del failed");
1208 return VNET_API_ERROR_UNSPECIFIED;
1213 m_key.
port = clib_host_to_net_u16 (local->
port);
1215 if (clib_bihash_add_del_8_8(&tsm->
in2out, &kv, 0))
1218 return VNET_API_ERROR_UNSPECIFIED;
1225 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1232 elt_index = head->
next;
1234 ses_index = elt->
value;
1235 while (ses_index != ~0)
1239 ses_index = elt->
value;
1241 if ((s->in2out.addr.as_u32 != local->
addr.
as_u32) &&
1242 (clib_net_to_host_u16 (s->in2out.port) != local->
port))
1267 snat_session_t *ses;
1268 u32 *ses_to_be_removed = 0, *ses_index;
1279 for (i=0; i <
vec_len (addresses); i++)
1288 return VNET_API_ERROR_NO_SUCH_ENTRY;
1294 if (m->external_addr.as_u32 == addr.as_u32)
1295 (void) snat_add_static_mapping (m->local_addr, m->external_addr,
1296 m->local_port, m->external_port,
1297 m->vrf_id, m->addr_only, ~0,
1298 m->proto, 0, m->twice_nat);
1307 return VNET_API_ERROR_UNSPECIFIED;
1316 if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
1321 if (ses->out2in.addr.as_u32 == addr.as_u32)
1323 ses->outside_address_index = ~0;
1324 nat_free_session_data (sm, ses, tsm - sm->per_thread_data);
1325 clib_dlist_remove (tsm->list_pool, ses->per_user_index);
1326 pool_put_index (tsm->list_pool, ses->per_user_index);
1327 vec_add1 (ses_to_be_removed, ses - tsm->sessions);
1328 user_key.addr = ses->in2out.addr;
1329 user_key.fib_index = ses->in2out.fib_index;
1330 kv.key = user_key.as_u64;
1331 if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
1333 u = pool_elt_at_index (tsm->users, value.value);
1357 if (nat_interface_is_inside(interface))
1360 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1363 pool_foreach (interface, sm->output_feature_interfaces,
1365 if (nat_interface_is_inside(interface))
1368 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1379 const char * feature_name, *del_feature_name;
1386 if (i->sw_if_index == sw_if_index)
1387 return VNET_API_ERROR_VALUE_EXIST;
1391 feature_name = is_inside ?
"nat44-in2out-fast" :
"nat44-out2in-fast";
1395 feature_name = is_inside ?
"nat44-in2out-worker-handoff" :
"nat44-out2in-worker-handoff";
1397 feature_name = is_inside ?
"nat44-det-in2out" :
"nat44-det-out2in";
1399 feature_name = is_inside ?
"nat44-in2out" :
"nat44-out2in";
1410 if (i->sw_if_index == sw_if_index)
1414 if (nat_interface_is_inside(i) && nat_interface_is_outside(i))
1417 i->flags &= ~NAT_INTERFACE_FLAG_IS_INSIDE;
1419 i->flags &= ~NAT_INTERFACE_FLAG_IS_OUTSIDE;
1421 if (sm->num_workers > 1 && !sm->deterministic)
1422 del_feature_name =
"nat44-handoff-classify";
1423 else if (sm->deterministic)
1424 del_feature_name =
"nat44-det-classify";
1426 del_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);
1435 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1436 sw_if_index, 0, 0, 0);
1437 pool_put (sm->interfaces, i);
1442 if ((nat_interface_is_inside(i) && is_inside) ||
1443 (nat_interface_is_outside(i) && !is_inside))
1446 if (sm->num_workers > 1 && !sm->deterministic)
1448 del_feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1449 "nat44-out2in-worker-handoff";
1450 feature_name =
"nat44-handoff-classify";
1452 else if (sm->deterministic)
1454 del_feature_name = !is_inside ?
"nat44-det-in2out" :
1456 feature_name =
"nat44-det-classify";
1460 del_feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
1461 feature_name =
"nat44-classify";
1464 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1465 sw_if_index, 0, 0, 0);
1466 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1467 sw_if_index, 1, 0, 0);
1476 return VNET_API_ERROR_NO_SUCH_ENTRY;
1479 i->sw_if_index = sw_if_index;
1494 sw_if_index, !is_del, 0, 0);
1503 if (!(m->addr_only) || (m->local_addr.as_u32 == m->external_addr.as_u32))
1506 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1511 snat_add_del_addr_to_fib(&dm->out_addr, dm->out_plen, sw_if_index, !is_del);
1528 return VNET_API_ERROR_UNSUPPORTED;
1532 if (i->sw_if_index == sw_if_index)
1533 return VNET_API_ERROR_VALUE_EXIST;
1539 sw_if_index, !is_del, 0, 0);
1541 sw_if_index, !is_del, 0, 0);
1548 sw_if_index, !is_del, 0, 0);
1550 "nat44-in2out-output-worker-handoff",
1551 sw_if_index, !is_del, 0, 0);
1558 sw_if_index, !is_del, 0, 0);
1571 if (i->sw_if_index == sw_if_index)
1574 pool_put (sm->output_feature_interfaces, i);
1576 return VNET_API_ERROR_VALUE_EXIST;
1583 return VNET_API_ERROR_NO_SUCH_ENTRY;
1585 pool_get (sm->output_feature_interfaces,
i);
1586 i->sw_if_index = sw_if_index;
1603 if (!(m->addr_only))
1606 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1618 return VNET_API_ERROR_FEATURE_DISABLED;
1621 return VNET_API_ERROR_INVALID_WORKER;
1644 u32 if_address_index,
1652 u32 * address_indexp,
1653 u16 port_per_thread,
1654 u32 snat_thread_index);
1747 u16 port_host_byte_order = clib_net_to_host_u16 (k->
port);
1751 a = addresses + address_index;
1755 #define _(N, i, n, s) \ 1756 case SNAT_PROTOCOL_##N: \ 1757 ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \ 1758 port_host_byte_order) == 1); \ 1759 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \ 1760 port_host_byte_order, 0); \ 1761 a->busy_##n##_ports--; \ 1762 a->busy_##n##_ports_per_thread[thread_index]--; \ 1802 m_key.
port = clib_net_to_host_u16 (match.
port);
1808 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
1814 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
1828 mid = ((
hi -
lo) >> 1) +
lo;
1877 u32 * address_indexp,
1878 u16 port_per_thread,
1879 u32 snat_thread_index)
1884 address_indexp, port_per_thread,
1893 u32 * address_indexp,
1894 u16 port_per_thread,
1895 u32 snat_thread_index)
1901 for (i = 0; i <
vec_len (addresses); i++)
1906 #define _(N, j, n, s) \ 1907 case SNAT_PROTOCOL_##N: \ 1908 if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \ 1910 if (a->fib_index == fib_index) \ 1914 portnum = (port_per_thread * \ 1915 snat_thread_index) + \ 1916 snat_random_port(1, port_per_thread) + 1024; \ 1917 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 1919 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 1920 a->busy_##n##_ports_per_thread[thread_index]++; \ 1921 a->busy_##n##_ports++; \ 1922 k->addr = a->addr; \ 1923 k->port = clib_host_to_net_u16(portnum); \ 1924 *address_indexp = i; \ 1928 else if (a->fib_index == ~0) \ 1949 #define _(N, j, n, s) \ 1950 case SNAT_PROTOCOL_##N: \ 1953 portnum = (port_per_thread * \ 1954 snat_thread_index) + \ 1955 snat_random_port(1, port_per_thread) + 1024; \ 1956 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 1958 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 1959 a->busy_##n##_ports_per_thread[thread_index]++; \ 1960 a->busy_##n##_ports++; \ 1961 k->addr = a->addr; \ 1962 k->port = clib_host_to_net_u16(portnum); \ 1963 *address_indexp = gi; \ 1985 u32 * address_indexp,
1986 u16 port_per_thread,
1987 u32 snat_thread_index)
1991 u16 m, ports, portnum, A, j;
2000 #define _(N, i, n, s) \ 2001 case SNAT_PROTOCOL_##N: \ 2002 if (a->busy_##n##_ports < ports) \ 2006 A = snat_random_port(1, pow2_mask(sm->psid_offset)); \ 2007 j = snat_random_port(0, pow2_mask(m)); \ 2008 portnum = A | (sm->psid << sm->psid_offset) | (j << (16 - m)); \ 2009 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2011 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2012 a->busy_##n##_ports++; \ 2013 k->addr = a->addr; \ 2014 k->port = clib_host_to_net_u16 (portnum); \ 2015 *address_indexp = i; \ 2041 u32 start_host_order, end_host_order;
2055 if (
unformat (line_input,
"%U - %U",
2059 else if (
unformat (line_input,
"tenant-vrf %u", &vrf_id))
2062 end_addr = start_addr;
2063 else if (
unformat (line_input,
"twice-nat"))
2065 else if (
unformat (line_input,
"del"))
2081 start_host_order = clib_host_to_net_u32 (start_addr.
as_u32);
2082 end_host_order = clib_host_to_net_u32 (end_addr.
as_u32);
2084 if (end_host_order < start_host_order)
2090 count = (end_host_order - start_host_order) + 1;
2098 this_addr = start_addr;
2100 for (i = 0; i <
count; i++)
2109 case VNET_API_ERROR_NO_SUCH_ENTRY:
2112 case VNET_API_ERROR_UNSPECIFIED:
2129 .path =
"nat44 add address",
2130 .short_help =
"nat44 add address <ip4-range-start> [- <ip4-range-end>] " 2131 "[tenant-vrf <vrf-id>] [twice-nat] [del]",
2144 u32 * inside_sw_if_indices = 0;
2145 u32 * outside_sw_if_indices = 0;
2146 u8 is_output_feature = 0;
2160 vec_add1 (inside_sw_if_indices, sw_if_index);
2163 vec_add1 (outside_sw_if_indices, sw_if_index);
2164 else if (
unformat (line_input,
"output-feature"))
2165 is_output_feature = 1;
2166 else if (
unformat (line_input,
"del"))
2176 if (
vec_len (inside_sw_if_indices))
2178 for (i = 0; i <
vec_len(inside_sw_if_indices); i++)
2180 sw_if_index = inside_sw_if_indices[
i];
2181 if (is_output_feature)
2186 is_del ?
"del" :
"add",
2197 is_del ?
"del" :
"add",
2206 if (
vec_len (outside_sw_if_indices))
2208 for (i = 0; i <
vec_len(outside_sw_if_indices); i++)
2210 sw_if_index = outside_sw_if_indices[
i];
2211 if (is_output_feature)
2216 is_del ?
"del" :
"add",
2227 is_del ?
"del" :
"add",
2245 .path =
"set interface nat44",
2247 .short_help =
"set interface nat44 in <intfc> out <intfc> [output-feature] " 2254 u32 *r = va_arg (*args,
u32 *);
2257 #define _(N, i, n, s) else if (unformat (input, s)) *r = SNAT_PROTOCOL_##N; 2273 #define _(N, j, n, str) case SNAT_PROTOCOL_##N: t = (u8 *) str; break; 2277 s =
format (s,
"unknown");
2292 u32 l_port = 0, e_port = 0, vrf_id = ~0;
2295 u32 sw_if_index = ~0;
2319 else if (
unformat (line_input,
"external %U %u",
2324 else if (
unformat (line_input,
"external %U",
2327 else if (
unformat (line_input,
"vrf %u", &vrf_id))
2331 else if (
unformat (line_input,
"twice-nat"))
2333 else if (
unformat (line_input,
"del"))
2343 if (twice_nat && addr_only)
2349 if (!addr_only && !proto_set)
2356 vrf_id, addr_only, sw_if_index, proto, is_add,
2361 case VNET_API_ERROR_INVALID_VALUE:
2364 case VNET_API_ERROR_NO_SUCH_ENTRY:
2370 case VNET_API_ERROR_NO_SUCH_FIB:
2373 case VNET_API_ERROR_VALUE_EXIST:
2401 .path =
"nat44 add static mapping",
2404 "nat44 add static mapping tcp|udp|icmp local <addr> [<port>] " 2405 "external <addr> [<port>] [vrf <table-id>] [twice-nat] [del]",
2416 u32 port = 0, vrf_id = ~0;
2419 u32 sw_if_index = ~0;
2434 else if (
unformat (line_input,
"external %U",
2437 else if (
unformat (line_input,
"vrf %u", &vrf_id))
2442 else if (
unformat (line_input,
"del"))
2453 vrf_id, addr_only, sw_if_index, proto, is_add,
2458 case VNET_API_ERROR_INVALID_VALUE:
2461 case VNET_API_ERROR_NO_SUCH_ENTRY:
2467 case VNET_API_ERROR_NO_SUCH_FIB:
2470 case VNET_API_ERROR_VALUE_EXIST:
2497 .path =
"nat44 add identity mapping",
2499 .short_help =
"nat44 add identity mapping <interface>|<ip4-addr> " 2500 "[<protocol> <port>] [vrf <table-id>] [del]",
2511 u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
2525 if (
unformat (line_input,
"local %U:%u probability %u",
2528 memset (&local, 0,
sizeof (local));
2529 local.addr = l_addr;
2530 local.port = (
u16) l_port;
2531 local.probability = (
u8) probability;
2537 else if (
unformat (line_input,
"vrf %u", &vrf_id))
2542 else if (
unformat (line_input,
"twice-nat"))
2544 else if (
unformat (line_input,
"del"))
2567 locals, is_add, twice_nat);
2571 case VNET_API_ERROR_INVALID_VALUE:
2574 case VNET_API_ERROR_NO_SUCH_ENTRY:
2580 case VNET_API_ERROR_VALUE_EXIST:
2595 .path =
"nat44 add load-balancing static mapping",
2598 "nat44 add load-balancing static mapping protocol tcp|udp " 2599 "external <addr>:<port> local <addr>:<port> probability <n> [twice-nat] " 2600 "[vrf <table-id>] [del]",
2641 case VNET_API_ERROR_INVALID_WORKER:
2644 case VNET_API_ERROR_FEATURE_DISABLED:
2646 "Supported only if 2 or more workes available.");
2666 .path =
"set nat workers",
2669 "set nat workers <workers-list>",
2690 if (
unformat (line_input,
"domain %d", &domain_id))
2692 else if (
unformat (line_input,
"src-port %d", &src_port))
2694 else if (
unformat (line_input,
"disable"))
2728 .path =
"nat ipfix logging",
2730 .short_help =
"nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
2737 u32 next_worker_index = 0;
2745 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
2749 return next_worker_index;
2767 u32 next_worker_index = 0;
2795 nat_reass_ip4_t *reass;
2800 if (reass && (reass->thread_index != (
u32) ~ 0))
2801 return reass->thread_index;
2819 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
2841 icmp46_header_t * icmp = (icmp46_header_t *) udp;
2852 case SNAT_PROTOCOL_ICMP:
2853 icmp = (icmp46_header_t*)l4_header;
2857 case SNAT_PROTOCOL_UDP:
2858 case SNAT_PROTOCOL_TCP:
2870 m_key.addr = ip0->dst_address;
2871 m_key.port = clib_net_to_host_u16 (port);
2872 m_key.protocol = proto;
2873 m_key.fib_index = rx_fib_index0;
2874 kv.key = m_key.as_u64;
2875 if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
2878 return m->worker_index;
2883 next_worker_index = sm->first_worker_index;
2884 next_worker_index +=
2885 sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
2886 return next_worker_index;
2893 u32 translation_buckets = 1024;
2894 u32 translation_memory_size = 128<<20;
2895 u32 user_buckets = 128;
2896 u32 user_memory_size = 64<<20;
2897 u32 max_translations_per_user = 100;
2898 u32 outside_vrf_id = 0;
2899 u32 inside_vrf_id = 0;
2900 u32 static_mapping_buckets = 1024;
2901 u32 static_mapping_memory_size = 64<<20;
2902 u32 nat64_bib_buckets = 1024;
2903 u32 nat64_bib_memory_size = 128 << 20;
2904 u32 nat64_st_buckets = 2048;
2905 u32 nat64_st_memory_size = 256 << 20;
2906 u8 static_mapping_only = 0;
2907 u8 static_mapping_connection_tracking = 0;
2914 if (
unformat (input,
"translation hash buckets %d", &translation_buckets))
2916 else if (
unformat (input,
"translation hash memory %d",
2917 &translation_memory_size));
2918 else if (
unformat (input,
"user hash buckets %d", &user_buckets))
2920 else if (
unformat (input,
"user hash memory %d",
2923 else if (
unformat (input,
"max translations per user %d",
2924 &max_translations_per_user))
2926 else if (
unformat (input,
"outside VRF id %d",
2929 else if (
unformat (input,
"inside VRF id %d",
2932 else if (
unformat (input,
"static mapping only"))
2934 static_mapping_only = 1;
2935 if (
unformat (input,
"connection tracking"))
2936 static_mapping_connection_tracking = 1;
2938 else if (
unformat (input,
"deterministic"))
2940 else if (
unformat (input,
"nat64 bib hash buckets %d",
2941 &nat64_bib_buckets))
2943 else if (
unformat (input,
"nat64 bib hash memory %d",
2944 &nat64_bib_memory_size))
2946 else if (
unformat (input,
"nat64 st hash buckets %d", &nat64_st_buckets))
2948 else if (
unformat (input,
"nat64 st hash memory %d",
2949 &nat64_st_memory_size))
2975 nat64_set_hash(nat64_bib_buckets, nat64_bib_memory_size, nat64_st_buckets,
2976 nat64_st_memory_size);
2993 if (!static_mapping_only ||
2994 (static_mapping_only && static_mapping_connection_tracking))
3001 clib_bihash_init_8_8 (&tsm->
in2out,
"in2out", translation_buckets,
3002 translation_memory_size);
3004 clib_bihash_init_8_8 (&tsm->
out2in,
"out2in", translation_buckets,
3005 translation_memory_size);
3007 clib_bihash_init_8_8 (&tsm->
user_hash,
"users", user_buckets,
3011 clib_bihash_init_16_8 (&sm->
in2out_ed,
"in2out-ed",
3012 translation_buckets, translation_memory_size);
3014 clib_bihash_init_16_8 (&sm->
out2in_ed,
"out2in-ed",
3015 translation_buckets, translation_memory_size);
3023 "static_mapping_by_local", static_mapping_buckets,
3024 static_mapping_memory_size);
3027 "static_mapping_by_external", static_mapping_buckets,
3028 static_mapping_memory_size);
3043 #define _(v, N, str) case SNAT_SESSION_##N: t = (u8 *) str; break; 3047 t =
format (t,
"unknown");
3057 s =
format (s,
"%U proto %U port %d fib %d",
3067 snat_session_t * sess = va_arg (*args, snat_session_t *);
3071 s =
format (s,
" i2o %U proto %u fib %u\n",
3073 clib_net_to_host_u16 (sess->in2out.port),
3074 sess->in2out.fib_index);
3075 s =
format (s,
" o2i %U proto %u fib %u\n",
3077 clib_net_to_host_u16 (sess->out2in.port),
3078 sess->out2in.fib_index);
3087 s =
format (s,
" external host o2i %U:%d i2o %U:%d\n",
3089 clib_net_to_host_u16 (sess->ext_host_port),
3091 clib_net_to_host_u16 (sess->ext_host_nat_port));
3095 if (sess->ext_host_addr.as_u32)
3096 s =
format (s,
" external host %U\n",
3099 s =
format (s,
" last heard %.2f\n", sess->last_heard);
3100 s =
format (s,
" total pkts %d, total bytes %lld\n",
3101 sess->total_pkts, sess->total_bytes);
3103 s =
format (s,
" static translation\n");
3105 s =
format (s,
" dynamic translation\n");
3107 s =
format (s,
" load-balancing\n");
3109 s =
format (s,
" twice-nat\n");
3118 int verbose = va_arg (*args,
int);
3120 u32 elt_index, head_index;
3122 snat_session_t * sess;
3124 s =
format (s,
"%U: %d dynamic translations, %d static translations\n",
3135 elt_index = head->
next;
3137 session_index = elt->
value;
3139 while (session_index != ~0)
3145 elt_index = elt->
next;
3147 session_index = elt->
value;
3160 s =
format (s,
"local %U external %U vrf %d %s",
3168 s =
format (s,
"%U vrf %d external %U:%d %s",
3174 s =
format (s,
"\n local %U:%d probability %d\%",
3179 s =
format (s,
"%U local %U:%d external %U:%d vrf %d %s",
3194 s =
format (s,
"local %U external %U vrf %d",
3199 s =
format (s,
"%U local %U:%d external %U:%d vrf %d",
3212 u32 in_offset, out_offset;
3214 u32 *
i = va_arg (*args,
u32 *);
3217 in_addr.
as_u32 = clib_host_to_net_u32 (
3218 clib_net_to_host_u32(det_map->
in_addr.
as_u32) + user_index);
3219 in_offset = clib_net_to_host_u32(in_addr.
as_u32) -
3222 out_addr.
as_u32 = clib_host_to_net_u32(
3224 s =
format (s,
"in %U:%d out %U:%d external host %U:%d state: %U expire: %d\n",
3226 clib_net_to_host_u16 (ses->
in_port),
3250 u32 users_num = 0, sessions_num = 0, *worker, *sw_if_index;
3258 else if (
unformat (input,
"verbose"))
3264 vlib_cli_output (vm,
"NAT plugin mode: static mapping only connection " 3275 vlib_cli_output (vm,
"NAT plugin mode: dynamic translations enabled");
3282 vlib_cli_output (vm,
"%U %s", format_vnet_sw_if_index_name, vnm,
3284 (nat_interface_is_inside(i) &&
3285 nat_interface_is_outside(i)) ?
"in out" :
3286 (nat_interface_is_inside(i) ?
"in" :
"out"));
3291 vlib_cli_output (vm,
"%U output-feature %s",
3292 format_vnet_sw_if_index_name, vnm, i->sw_if_index,
3293 (nat_interface_is_inside(i) &&
3294 nat_interface_is_outside(i)) ?
"in out" :
3295 (nat_interface_is_inside(i) ?
"in" :
"out"));
3327 #define _(N, i, n, s) \ 3328 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s); 3342 #define _(N, i, n, s) \ 3343 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s); 3377 vlib_cli_output (vm,
"in %U/%d out %U/%d\n",
3378 format_ip4_address, &dm->in_addr, dm->in_plen,
3379 format_ip4_address, &dm->out_addr, dm->out_plen);
3380 vlib_cli_output (vm,
" outside address sharing ratio: %d\n",
3382 vlib_cli_output (vm,
" number of ports per inside host: %d\n",
3383 dm->ports_per_host);
3384 vlib_cli_output (vm,
" sessions number: %d\n", dm->ses_num);
3387 vec_foreach_index (j, dm->sessions)
3389 ses = vec_elt_at_index (dm->sessions, j);
3391 vlib_cli_output (vm,
" %U", format_det_map_ses, dm, ses,
3400 if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking))
3409 vlib_cli_output (vm,
"%U", format_snat_static_mapping, m);
3418 sessions_num +=
pool_elts (tsm->sessions);
3422 " %d static mappings, %d twice-nat addresses",
3427 vec_len (sm->twice_nat_addresses));
3454 vlib_cli_output (vm,
" %U", format_snat_user, tsm, u,
3464 vlib_cli_output (vm,
"%U", format_snat_static_mapping, m);
3466 for (j = 0; j <
vec_len (sm->to_resolve); j++)
3468 rp = sm->to_resolve + j;
3481 .path =
"show nat44",
3482 .short_help =
"show nat44",
3493 u32 if_address_index,
3498 u32 *indices_to_delete = 0;
3525 for (j = 0; j <
vec_len(addresses); j++)
3526 if (addresses[j].
addr.as_u32 == address->
as_u32)
3560 if (
vec_len(indices_to_delete))
3563 for (j =
vec_len(indices_to_delete)-1; j >= 0; j--)
3583 u32 *indices_to_delete = 0;
3585 u32 *auto_add_sw_if_indices =
3591 for (i = 0; i <
vec_len(auto_add_sw_if_indices); i++)
3593 if (auto_add_sw_if_indices[i] == sw_if_index)
3608 if (
vec_len(indices_to_delete))
3610 for (j =
vec_len(indices_to_delete)-1; j >= 0; j--)
3621 return VNET_API_ERROR_VALUE_EXIST;
3628 return VNET_API_ERROR_NO_SUCH_ENTRY;
3665 else if (
unformat (line_input,
"twice-nat"))
3667 else if (
unformat (line_input,
"del"))
3697 .path =
"nat44 add interface address",
3698 .short_help =
"nat44 add interface address <interface> [twice-nat] [del]",
3712 clib_bihash_8_8_t *t;
3725 key.
port = clib_host_to_net_u16 (port);
3729 t = is_in ? &tsm->in2out : &tsm->out2in;
3730 if (!clib_bihash_search_8_8 (t, &kv, &value))
3733 kv.
key = s->in2out.as_u64;
3734 clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0);
3735 kv.
key = s->out2in.as_u64;
3736 clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0);
3737 u_key.
addr = s->in2out.addr;
3740 if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
3750 return VNET_API_ERROR_NO_SUCH_ENTRY;
3776 else if (
unformat (line_input,
"in"))
3781 else if (
unformat (line_input,
"vrf %u", &vrf_id))
3810 .path =
"nat44 del session",
3811 .short_help =
"nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>]",
3823 u32 psid, psid_offset, psid_length;
3831 if (
unformat (line_input,
"default"))
3833 else if (
unformat (line_input,
"map-e psid %d psid-offset %d psid-len %d",
3834 &psid, &psid_offset, &psid_length))
3856 .path =
"nat addr-port-assignment-alg",
3857 .short_help =
"nat addr-port-assignment-alg <alg-name> [<alg-params>]",
3869 u32 in_plen, out_plen;
3883 else if (
unformat (line_input,
"del"))
3920 .path =
"nat44 deterministic add",
3921 .short_help =
"nat44 deterministic add in <addr>/<plen> out <addr>/<plen> [del]",
3980 .path =
"nat44 deterministic forward",
3981 .short_help =
"nat44 deterministic forward <addr>",
4013 if (out_port < 1024 || out_port > 65535)
4044 .path =
"nat44 deterministic reverse",
4045 .short_help =
"nat44 deterministic reverse <addr>:<port>",
4066 else if (
unformat (line_input,
"tcp-established %u",
4069 else if (
unformat (line_input,
"tcp-transitory %u",
4074 else if (
unformat (line_input,
"reset"))
4106 .path =
"set nat44 deterministic timeout",
4109 "set nat44 deterministic timeout [udp <sec> | tcp-established <sec> " 4110 "tcp-transitory <sec> | icmp <sec> | reset]",
4121 u32 out_port, ext_port;
4133 if (
unformat (line_input,
"%U:%d %U:%d",
4178 .path =
"nat44 deterministic close session out",
4179 .short_help =
"nat44 deterministic close session out " 4180 "<out_addr>:<out_port> <ext_addr>:<ext_port>",
4192 u32 in_port, ext_port;
4204 if (
unformat (line_input,
"%U:%d %U:%d",
4247 .path =
"nat44 deterministic close session in",
4248 .short_help =
"nat44 deterministic close session in " 4249 "<in_addr>:<in_port> <ext_addr>:<ext_port>",
4260 u8 forwarding_enable;
4261 u8 forwarding_enable_set = 0;
4270 if (!forwarding_enable_set &&
unformat (line_input,
"enable"))
4272 forwarding_enable = 1;
4273 forwarding_enable_set = 1;
4275 else if (!forwarding_enable_set &&
unformat (line_input,
"disable"))
4277 forwarding_enable = 0;
4278 forwarding_enable_set = 1;
4288 if (!forwarding_enable_set)
4315 .path =
"nat44 forwarding",
4316 .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
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.
format_function_t format_vnet_sw_if_index_name
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)
#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)
static int lb_local_exists(nat44_lb_addr_port_t *local, ip4_address_t *e_addr, u16 e_port)
#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.