36 #include <vpp/app/version.h> 44 .arc_name =
"ip4-unicast",
45 .node_name =
"nat44-in2out",
49 .arc_name =
"ip4-unicast",
50 .node_name =
"nat44-out2in",
52 "ip4-dhcp-client-detect"),
55 .arc_name =
"ip4-unicast",
56 .node_name =
"nat44-classify",
60 .arc_name =
"ip4-unicast",
61 .node_name =
"nat44-det-in2out",
65 .arc_name =
"ip4-unicast",
66 .node_name =
"nat44-det-out2in",
68 "ip4-dhcp-client-detect"),
71 .arc_name =
"ip4-unicast",
72 .node_name =
"nat44-det-classify",
76 .arc_name =
"ip4-unicast",
77 .node_name =
"nat44-ed-in2out",
81 .arc_name =
"ip4-unicast",
82 .node_name =
"nat44-ed-out2in",
84 "ip4-dhcp-client-detect"),
87 .arc_name =
"ip4-unicast",
88 .node_name =
"nat44-ed-classify",
92 .arc_name =
"ip4-unicast",
93 .node_name =
"nat44-in2out-worker-handoff",
97 .arc_name =
"ip4-unicast",
98 .node_name =
"nat44-out2in-worker-handoff",
100 "ip4-dhcp-client-detect"),
103 .arc_name =
"ip4-unicast",
104 .node_name =
"nat44-handoff-classify",
108 .arc_name =
"ip4-unicast",
109 .node_name =
"nat44-in2out-fast",
113 .arc_name =
"ip4-unicast",
114 .node_name =
"nat44-out2in-fast",
116 "ip4-dhcp-client-detect"),
119 .arc_name =
"ip4-unicast",
120 .node_name =
"nat44-hairpin-dst",
124 .arc_name =
"ip4-unicast",
125 .node_name =
"nat44-ed-hairpin-dst",
131 .arc_name =
"ip4-output",
132 .node_name =
"nat44-in2out-output",
136 .arc_name =
"ip4-output",
137 .node_name =
"nat44-in2out-output-worker-handoff",
141 .arc_name =
"ip4-output",
142 .node_name =
"nat44-hairpin-src",
146 .arc_name =
"ip4-output",
147 .node_name =
"nat44-ed-in2out-output",
151 .arc_name =
"ip4-output",
152 .node_name =
"nat44-ed-hairpin-src",
159 .arc_name =
"ip4-local",
160 .node_name =
"nat44-hairpinning",
165 .arc_name =
"ip4-local",
166 .node_name =
"nat44-ed-hairpinning",
172 .version = VPP_BUILD_VER,
173 .description =
"Network Address Translation (NAT)",
189 ed_key.
l_addr = s->in2out.addr;
190 ed_key.
r_addr = s->ext_host_addr;
191 ed_key.
l_port = s->in2out.port;
192 ed_key.
r_port = s->ext_host_port;
197 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &ed_kv, 0))
207 s->in2out.protocol, s->out2in.port);
208 ed_key.
l_addr = s->out2in.addr;
209 ed_key.
r_addr = s->ext_host_addr;
213 ed_key.
proto = s->in2out.port;
220 ed_key.
l_port = s->out2in.port;
221 ed_key.
r_port = s->ext_host_port;
225 if (clib_bihash_add_del_16_8 (&tsm->
out2in_ed, &ed_kv, 0))
227 ed_key.
l_addr = s->in2out.addr;
230 ed_key.
l_port = s->in2out.port;
233 ed_key.
r_addr = s->ext_host_nat_addr;
234 ed_key.
r_port = s->ext_host_nat_port;
238 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &ed_kv, 0))
242 &s->in2out.addr, s->in2out.port,
243 &s->ext_host_nat_addr, s->ext_host_nat_port,
244 &s->out2in.addr, s->out2in.port,
245 &s->ext_host_addr, s->ext_host_port,
250 kv.
key = s->in2out.as_u64;
251 if (clib_bihash_add_del_8_8 (&tsm->
in2out, &kv, 0))
253 kv.
key = s->out2in.as_u64;
254 if (clib_bihash_add_del_8_8 (&tsm->
out2in, &kv, 0))
258 &s->in2out.addr, s->in2out.port,
259 &s->out2in.addr, s->out2in.port,
268 s->out2in.addr.as_u32,
271 s->out2in.port, s->in2out.fib_index);
277 key.
port = s->ext_host_nat_port;
278 key.
addr.
as_u32 = s->ext_host_nat_addr.as_u32;
305 if (clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
323 if (clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 1))
343 u32 oldest_per_user_translation_list_index, session_index;
350 oldest_per_user_translation_list_index =
354 ASSERT (oldest_per_user_translation_list_index != ~0);
359 oldest_per_user_translation_list_index);
361 oldest_per_user_translation_list_elt =
363 oldest_per_user_translation_list_index);
366 session_index = oldest_per_user_translation_list_elt->
value;
379 s->ext_host_addr.as_u32 = 0;
380 s->ext_host_port = 0;
381 s->ext_host_nat_addr.as_u32 = 0;
382 s->ext_host_nat_port = 0;
392 per_user_translation_list_elt - tsm->
list_pool);
395 s->per_user_index = per_user_translation_list_elt - tsm->
list_pool;
399 s->per_user_list_head_index,
400 per_user_translation_list_elt - tsm->
list_pool);
402 s->user_index = u - tsm->
users;
416 dlist_elt_t *per_user_translation_list_elt, *oldest_elt;
418 u64 sess_timeout_time;
429 if (now >= sess_timeout_time)
442 s->ext_host_addr.as_u32 = 0;
443 s->ext_host_port = 0;
444 s->ext_host_nat_addr.as_u32 = 0;
445 s->ext_host_nat_port = 0;
469 per_user_translation_list_elt - tsm->
list_pool);
472 s->per_user_index = per_user_translation_list_elt - tsm->
list_pool;
476 s->per_user_list_head_index,
477 per_user_translation_list_elt - tsm->
list_pool);
495 .ip4.as_u32 = addr->
as_u32,
524 return VNET_API_ERROR_FEATURE_DISABLED;
531 return VNET_API_ERROR_VALUE_EXIST;
547 #define _(N, i, n, s) \ 548 clib_bitmap_alloc (ap->busy_##n##_port_bitmap, 65535); \ 549 ap->busy_##n##_ports = 0; \ 550 ap->busy_##n##_ports_per_thread = 0;\ 551 vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); 561 if (nat_interface_is_inside(i) || sm->out2in_dpo)
564 snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
569 if (nat_interface_is_inside(i) || sm->out2in_dpo)
572 snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
587 if (is_addr_only_static_mapping (m) ||
588 is_out2in_only_static_mapping (m) ||
589 is_identity_static_mapping (m))
591 if (m->external_addr.as_u32 == addr.as_u32)
604 v = clib_net_to_host_u32 (a->
as_u32) + 1;
605 a->
as_u32 = clib_host_to_net_u32 (v);
616 int addr_only,
int is_add,
u8 * tag,
617 int twice_nat,
int out2in_only,
653 u16 l_port,
u16 e_port,
u32 vrf_id,
int addr_only,
670 u32 elt_index, head_index;
680 if (twice_nat || out2in_only)
681 return VNET_API_ERROR_FEATURE_DISABLED;
685 if (sw_if_index != ~0)
700 || rp->
proto != proto)
715 return VNET_API_ERROR_VALUE_EXIST;
718 (sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto,
719 addr_only, is_add, tag, twice_nat, out2in_only, identity_nat);
722 if (first_int_addr == 0)
737 return VNET_API_ERROR_NO_SUCH_ENTRY;
754 m_key.
port = addr_only ? 0 : e_port;
755 m_key.
protocol = addr_only ? 0 : proto;
772 if (local->vrf_id == vrf_id)
773 return VNET_API_ERROR_VALUE_EXIST;
791 return VNET_API_ERROR_VALUE_EXIST;
794 if (twice_nat && addr_only)
795 return VNET_API_ERROR_UNSUPPORTED;
809 if (!(out2in_only || identity_nat))
812 m_key.
port = addr_only ? 0 : l_port;
813 m_key.
protocol = addr_only ? 0 : proto;
816 if (!clib_bihash_search_8_8
818 return VNET_API_ERROR_VALUE_EXIST;
833 #define _(N, j, n, s) \ 834 case SNAT_PROTOCOL_##N: \ 835 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 836 return VNET_API_ERROR_INVALID_VALUE; \ 837 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 840 a->busy_##n##_ports++; \ 841 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \ 848 return VNET_API_ERROR_INVALID_VALUE_2;
856 if (sw_if_index != ~0)
873 return VNET_API_ERROR_NO_SUCH_ENTRY;
939 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
941 user_index = value.
value;
947 elt_index = head->
next;
949 ses_index = elt->
value;
950 while (ses_index != ~0)
954 ses_index = elt->
value;
960 && (clib_net_to_host_u16 (s->in2out.port) !=
979 if (sw_if_index != ~0)
982 return VNET_API_ERROR_NO_SUCH_ENTRY;
993 if (local->vrf_id == vrf_id)
994 find = local - m->locals;
998 return VNET_API_ERROR_NO_SUCH_ENTRY;
1017 #define _(N, j, n, s) \ 1018 case SNAT_PROTOCOL_##N: \ 1019 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 1020 if (e_port > 1024) \ 1022 a->busy_##n##_ports--; \ 1023 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \ 1030 return VNET_API_ERROR_INVALID_VALUE_2;
1057 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1059 user_index = value.
value;
1065 elt_index = head->
next;
1067 ses_index = elt->
value;
1068 while (ses_index != ~0)
1072 ses_index = elt->
value;
1076 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) ||
1077 (clib_net_to_host_u16 (s->out2in.port) !=
1122 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1125 snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add);
1130 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1133 snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add);
1146 u8 * tag,
u32 affinity)
1155 u32 elt_index, head_index, ses_index;
1164 return VNET_API_ERROR_FEATURE_DISABLED;
1166 m_key.
addr = e_addr;
1167 m_key.
port = e_port;
1179 return VNET_API_ERROR_VALUE_EXIST;
1182 return VNET_API_ERROR_INVALID_VALUE;
1196 #define _(N, j, n, s) \ 1197 case SNAT_PROTOCOL_##N: \ 1198 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 1199 return VNET_API_ERROR_INVALID_VALUE; \ 1200 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 1201 if (e_port > 1024) \ 1203 a->busy_##n##_ports++; \ 1204 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \ 1211 return VNET_API_ERROR_INVALID_VALUE_2;
1218 return VNET_API_ERROR_NO_SUCH_ENTRY;
1247 nat_log_err (
"static_mapping_by_external key add failed");
1248 return VNET_API_ERROR_UNSPECIFIED;
1252 for (i = 0; i <
vec_len (locals); i++)
1267 locals[
i].
prefix = (i == 0) ? locals[i].probability :
1268 (locals[i - 1].
prefix + locals[i].probability);
1296 return VNET_API_ERROR_NO_SUCH_ENTRY;
1299 return VNET_API_ERROR_INVALID_VALUE;
1311 #define _(N, j, n, s) \ 1312 case SNAT_PROTOCOL_##N: \ 1313 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 1314 if (e_port > 1024) \ 1316 a->busy_##n##_ports--; \ 1317 a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \ 1324 return VNET_API_ERROR_INVALID_VALUE_2;
1338 nat_log_err (
"static_mapping_by_external key del failed");
1339 return VNET_API_ERROR_UNSPECIFIED;
1345 fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4,
1346 FIB_SOURCE_PLUGIN_LOW);
1347 m_key.addr = local->addr;
1350 m_key.port = local->port;
1351 m_key.fib_index = local->fib_index;
1352 kv.key = m_key.as_u64;
1353 if (clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0))
1355 nat_log_err (
"static_mapping_by_local key del failed");
1356 return VNET_API_ERROR_UNSPECIFIED;
1363 .src_address = local->addr,
1375 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1382 elt_index = head->
next;
1384 ses_index = elt->
value;
1385 while (ses_index != ~0)
1389 ses_index = elt->
value;
1394 if ((s->in2out.addr.as_u32 != local->
addr.
as_u32) ||
1395 (clib_net_to_host_u16 (s->in2out.port) != local->
port))
1421 u8 probability,
u8 is_add)
1433 u32 elt_index, head_index, ses_index, *locals = 0;
1438 return VNET_API_ERROR_FEATURE_DISABLED;
1440 m_key.
addr = e_addr;
1441 m_key.
port = e_port;
1449 return VNET_API_ERROR_NO_SUCH_ENTRY;
1452 return VNET_API_ERROR_INVALID_VALUE;
1457 if ((local->addr.as_u32 == l_addr.as_u32) && (local->port == l_port) &&
1458 (local->vrf_id == vrf_id))
1460 match_local = local;
1469 return VNET_API_ERROR_VALUE_EXIST;
1473 local->addr.as_u32 = l_addr.as_u32;
1474 local->port = l_port;
1475 local->probability = probability;
1476 local->vrf_id = vrf_id;
1483 m_key.addr = l_addr;
1484 m_key.port = l_port;
1485 m_key.fib_index = local->fib_index;
1486 kv.key = m_key.as_u64;
1487 kv.value = m - sm->static_mappings;
1488 if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1))
1489 nat_log_err (
"static_mapping_by_local key add failed");
1495 return VNET_API_ERROR_NO_SUCH_ENTRY;
1498 return VNET_API_ERROR_UNSPECIFIED;
1505 m_key.addr = l_addr;
1506 m_key.port = l_port;
1507 m_key.fib_index = match_local->fib_index;
1508 kv.key = m_key.as_u64;
1509 if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0))
1510 nat_log_err (
"static_mapping_by_local key del failed");
1513 if (sm->num_workers > 1)
1519 sm->worker_in2out_cb (&ip, m->fib_index));
1525 u_key.addr = match_local->addr;
1526 u_key.fib_index = match_local->fib_index;
1527 kv.key = u_key.as_u64;
1528 if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
1531 if (u->nstaticsessions)
1533 head_index = u->sessions_per_user_list_head_index;
1535 elt_index = head->next;
1537 ses_index = elt->value;
1538 while (ses_index != ~0)
1542 ses_index = elt->value;
1547 if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) ||
1548 (clib_net_to_host_u16 (s->in2out.port) !=
1566 vec_add1 (locals, local - m->locals);
1567 if (sm->num_workers > 1)
1570 ip.src_address.as_u32 = local->addr.as_u32,
1571 bitmap = clib_bitmap_set (bitmap,
1572 sm->worker_in2out_cb (&ip, local->fib_index),
1581 local->prefix = local->probability;
1586 local->prefix = local->probability + prev_local->prefix;
1590 if (sm->num_workers > 1)
1605 snat_session_t *ses;
1606 u32 *ses_to_be_removed = 0, *ses_index;
1615 for (i = 0; i <
vec_len (addresses); i++)
1624 return VNET_API_ERROR_NO_SUCH_ENTRY;
1631 if (m->external_addr.as_u32 == addr.as_u32)
1632 (void) snat_add_static_mapping (m->local_addr, m->external_addr,
1633 m->local_port, m->external_port,
1634 m->vrf_id, is_addr_only_static_mapping(m), ~0,
1635 m->proto, 0, m->twice_nat,
1636 is_out2in_only_static_mapping(m), m->tag, is_identity_static_mapping(m));
1646 return VNET_API_ERROR_UNSPECIFIED;
1654 if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
1660 if (ses->out2in.addr.as_u32 == addr.as_u32)
1662 nat_free_session_data (sm, ses, tsm - sm->per_thread_data);
1663 vec_add1 (ses_to_be_removed, ses - tsm->sessions);
1678 #define _(N, i, n, s) \ 1679 clib_bitmap_free (a->busy_##n##_port_bitmap); \ 1680 vec_free (a->busy_##n##_ports_per_thread); 1695 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1698 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1701 pool_foreach (interface, sm->output_feature_interfaces,
1703 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1706 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1719 const char *feature_name, *del_feature_name;
1728 return VNET_API_ERROR_UNSUPPORTED;
1733 if (i->sw_if_index == sw_if_index)
1734 return VNET_API_ERROR_VALUE_EXIST;
1739 feature_name = is_inside ?
"nat44-in2out-fast" :
"nat44-out2in-fast";
1744 is_inside ?
"nat44-in2out-worker-handoff" :
1745 "nat44-out2in-worker-handoff";
1747 feature_name = is_inside ?
"nat44-det-in2out" :
"nat44-det-out2in";
1749 feature_name = is_inside ?
"nat44-ed-in2out" :
"nat44-ed-out2in";
1751 feature_name = is_inside ?
"nat44-in2out" :
"nat44-out2in";
1767 if (outside_fib->
fib_index == fib_index)
1792 if (i->sw_if_index == sw_if_index)
1796 if (nat_interface_is_inside(i) && nat_interface_is_outside(i))
1799 i->flags &= ~NAT_INTERFACE_FLAG_IS_INSIDE;
1801 i->flags &= ~NAT_INTERFACE_FLAG_IS_OUTSIDE;
1803 if (sm->num_workers > 1 && !sm->deterministic)
1805 del_feature_name =
"nat44-handoff-classify";
1806 feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1807 "nat44-out2in-worker-handoff";
1809 else if (sm->deterministic)
1811 del_feature_name =
"nat44-det-classify";
1812 feature_name = !is_inside ?
"nat44-det-in2out" :
1815 else if (sm->endpoint_dependent)
1817 del_feature_name =
"nat44-ed-classify";
1818 feature_name = !is_inside ?
"nat44-ed-in2out" :
1823 del_feature_name =
"nat44-classify";
1824 feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
1827 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1828 sw_if_index, 0, 0, 0);
1829 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1830 sw_if_index, 1, 0, 0);
1833 if (sm->endpoint_dependent)
1834 vnet_feature_enable_disable (
"ip4-local",
1835 "nat44-ed-hairpinning",
1836 sw_if_index, 1, 0, 0);
1837 else if (!sm->deterministic)
1838 vnet_feature_enable_disable (
"ip4-local",
1839 "nat44-hairpinning",
1840 sw_if_index, 1, 0, 0);
1845 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1846 sw_if_index, 0, 0, 0);
1847 pool_put (sm->interfaces, i);
1850 if (sm->endpoint_dependent)
1851 vnet_feature_enable_disable (
"ip4-local",
1852 "nat44-ed-hairpinning",
1853 sw_if_index, 0, 0, 0);
1854 else if (!sm->deterministic)
1855 vnet_feature_enable_disable (
"ip4-local",
1856 "nat44-hairpinning",
1857 sw_if_index, 0, 0, 0);
1863 if ((nat_interface_is_inside(i) && is_inside) ||
1864 (nat_interface_is_outside(i) && !is_inside))
1867 if (sm->num_workers > 1 && !sm->deterministic)
1869 del_feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1870 "nat44-out2in-worker-handoff";
1871 feature_name =
"nat44-handoff-classify";
1873 else if (sm->deterministic)
1875 del_feature_name = !is_inside ?
"nat44-det-in2out" :
1877 feature_name =
"nat44-det-classify";
1879 else if (sm->endpoint_dependent)
1881 del_feature_name = !is_inside ?
"nat44-ed-in2out" :
1883 feature_name =
"nat44-ed-classify";
1887 del_feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
1888 feature_name =
"nat44-classify";
1891 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1892 sw_if_index, 0, 0, 0);
1893 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1894 sw_if_index, 1, 0, 0);
1897 if (sm->endpoint_dependent)
1898 vnet_feature_enable_disable (
"ip4-local",
"nat44-ed-hairpinning",
1899 sw_if_index, 0, 0, 0);
1900 else if (!sm->deterministic)
1901 vnet_feature_enable_disable (
"ip4-local",
"nat44-hairpinning",
1902 sw_if_index, 0, 0, 0);
1913 return VNET_API_ERROR_NO_SUCH_ENTRY;
1921 if (is_inside && !sm->out2in_dpo)
1923 if (sm->endpoint_dependent)
1926 else if (!sm->deterministic)
1948 if (!(is_addr_only_static_mapping(m)) || (m->local_addr.as_u32 == m->external_addr.as_u32))
1951 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1956 snat_add_del_addr_to_fib(&dm->out_addr, dm->out_plen, sw_if_index, !is_del);
1965 u8 is_inside,
int is_del)
1974 return VNET_API_ERROR_UNSUPPORTED;
1979 if (i->sw_if_index == sw_if_index)
1980 return VNET_API_ERROR_VALUE_EXIST;
1989 sw_if_index, !is_del, 0, 0);
1991 sw_if_index, !is_del, 0, 0);
1996 sw_if_index, !is_del, 0, 0);
1998 sw_if_index, !is_del, 0, 0);
2006 "nat44-out2in-worker-handoff",
2007 sw_if_index, !is_del, 0, 0);
2009 "nat44-in2out-output-worker-handoff",
2010 sw_if_index, !is_del, 0, 0);
2017 sw_if_index, !is_del, 0, 0);
2019 sw_if_index, !is_del, 0, 0);
2024 sw_if_index, !is_del, 0, 0);
2026 sw_if_index, !is_del, 0, 0);
2042 if (i->sw_if_index == sw_if_index)
2045 pool_put (sm->output_feature_interfaces, i);
2047 return VNET_API_ERROR_VALUE_EXIST;
2055 return VNET_API_ERROR_NO_SUCH_ENTRY;
2057 pool_get (sm->output_feature_interfaces,
i);
2076 if (!((is_addr_only_static_mapping(m))) || (m->local_addr.as_u32 == m->external_addr.as_u32))
2079 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
2093 return VNET_API_ERROR_FEATURE_DISABLED;
2096 return VNET_API_ERROR_INVALID_WORKER;
2121 u32 if_address_index,
u32 is_delete);
2129 u32 if_address_index,
u32 is_delete);
2136 u16 port_per_thread,
u32 snat_thread_index);
2254 u16 port_host_byte_order = clib_net_to_host_u16 (k->
port);
2256 for (address_index = 0; address_index <
vec_len (addresses);
2263 ASSERT (address_index < vec_len (addresses));
2265 a = addresses + address_index;
2269 #define _(N, i, n, s) \ 2270 case SNAT_PROTOCOL_##N: \ 2271 ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \ 2272 port_host_byte_order) == 1); \ 2273 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \ 2274 port_host_byte_order, 0); \ 2275 a->busy_##n##_ports--; \ 2276 a->busy_##n##_ports_per_thread[thread_index]--; \ 2294 u8 * is_identity_nat)
2300 u32 rand,
lo = 0,
hi, mid, *tmp = 0,
i;
2312 m_key.
port = clib_net_to_host_u16 (match.
port);
2317 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2323 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2344 mapping->
port = clib_host_to_net_u16 (local->
port);
2360 mid = ((hi -
lo) >> 1) +
lo;
2362 (rand > local->
prefix) ? (lo = mid + 1) : (hi = mid);
2365 if (!(local->
prefix >= rand))
2377 mapping->
port = clib_host_to_net_u16 (local->
port);
2436 u16 port_per_thread,
2437 u32 snat_thread_index)
2442 port_per_thread, snat_thread_index);
2450 u16 port_per_thread,
u32 snat_thread_index)
2456 for (i = 0; i <
vec_len (addresses); i++)
2461 #define _(N, j, n, s) \ 2462 case SNAT_PROTOCOL_##N: \ 2463 if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \ 2465 if (a->fib_index == fib_index) \ 2469 portnum = (port_per_thread * \ 2470 snat_thread_index) + \ 2471 snat_random_port(1, port_per_thread) + 1024; \ 2472 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2474 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2475 a->busy_##n##_ports_per_thread[thread_index]++; \ 2476 a->busy_##n##_ports++; \ 2477 k->addr = a->addr; \ 2478 k->port = clib_host_to_net_u16(portnum); \ 2482 else if (a->fib_index == ~0) \ 2502 #define _(N, j, n, s) \ 2503 case SNAT_PROTOCOL_##N: \ 2506 portnum = (port_per_thread * \ 2507 snat_thread_index) + \ 2508 snat_random_port(1, port_per_thread) + 1024; \ 2509 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2511 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2512 a->busy_##n##_ports_per_thread[thread_index]++; \ 2513 a->busy_##n##_ports++; \ 2514 k->addr = a->addr; \ 2515 k->port = clib_host_to_net_u16(portnum); \ 2537 u16 port_per_thread,
u32 snat_thread_index)
2541 u16 m, ports, portnum,
A, j;
2550 #define _(N, i, n, s) \ 2551 case SNAT_PROTOCOL_##N: \ 2552 if (a->busy_##n##_ports < ports) \ 2556 A = snat_random_port(1, pow2_mask(sm->psid_offset)); \ 2557 j = snat_random_port(0, pow2_mask(m)); \ 2558 portnum = A | (sm->psid << sm->psid_offset) | (j << (16 - m)); \ 2559 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2561 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2562 a->busy_##n##_ports++; \ 2563 k->addr = a->addr; \ 2564 k->port = clib_host_to_net_u16 (portnum); \ 2587 u16 port_per_thread,
u32 snat_thread_index)
2600 #define _(N, i, n, s) \ 2601 case SNAT_PROTOCOL_##N: \ 2602 if (a->busy_##n##_ports < ports) \ 2606 portnum = snat_random_port(sm->start_port, sm->end_port); \ 2607 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2609 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2610 a->busy_##n##_ports++; \ 2611 k->addr = a->addr; \ 2612 k->port = clib_host_to_net_u16 (portnum); \ 2637 .fp_addr.ip4.as_u32 = addr.
as_u32,
2674 s =
format (s,
"%U static-mapping-index %llu",
2704 format (s,
"local %U:%d remote %U:%d proto %U fib %d session-index %llu",
2716 u32 next_worker_index = 0;
2724 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
2728 return next_worker_index;
2741 u32 next_worker_index = 0;
2751 if (!clib_bihash_search_8_8
2770 nat_reass_ip4_t *reass;
2775 if (reass && (reass->thread_index != (
u32) ~ 0))
2776 return reass->thread_index;
2791 icmp46_header_t *icmp = (icmp46_header_t *) udp;
2802 case SNAT_PROTOCOL_ICMP:
2803 icmp = (icmp46_header_t *) l4_header;
2807 case SNAT_PROTOCOL_UDP:
2808 case SNAT_PROTOCOL_TCP:
2820 m_key.addr = ip0->dst_address;
2821 m_key.port = clib_net_to_host_u16 (port);
2822 m_key.protocol = proto;
2823 m_key.fib_index = rx_fib_index0;
2824 kv.key = m_key.as_u64;
2825 if (!clib_bihash_search_8_8
2826 (&sm->static_mapping_by_external, &kv, &value))
2829 return m->workers[0];
2834 next_worker_index = sm->first_worker_index;
2835 next_worker_index +=
2836 sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
2837 return next_worker_index;
2845 u32 proto, next_worker_index = 0;
2855 if (!clib_bihash_search_8_8
2877 icmp46_header_t *icmp = (icmp46_header_t *) udp;
2888 case SNAT_PROTOCOL_ICMP:
2889 icmp = (icmp46_header_t *) l4_header;
2893 case SNAT_PROTOCOL_UDP:
2894 case SNAT_PROTOCOL_TCP:
2907 clib_net_to_host_u16 (port));
2908 if (!clib_bihash_search_8_8
2909 (&sm->static_mapping_by_external, &kv, &value))
2913 return m->workers[0];
2919 return m->workers[hash & (_vec_len (m->workers) - 1)];
2921 return m->workers[hash % _vec_len (m->workers)];
2926 next_worker_index = sm->first_worker_index;
2927 next_worker_index +=
2928 sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
2930 return next_worker_index;
2938 u32 translation_buckets = 1024;
2939 u32 translation_memory_size = 128 << 20;
2940 u32 user_buckets = 128;
2941 u32 user_memory_size = 64 << 20;
2942 u32 max_translations_per_user = 100;
2943 u32 outside_vrf_id = 0;
2944 u32 outside_ip6_vrf_id = 0;
2945 u32 inside_vrf_id = 0;
2946 u32 static_mapping_buckets = 1024;
2947 u32 static_mapping_memory_size = 64 << 20;
2948 u32 nat64_bib_buckets = 1024;
2949 u32 nat64_bib_memory_size = 128 << 20;
2950 u32 nat64_st_buckets = 2048;
2951 u32 nat64_st_memory_size = 256 << 20;
2952 u8 static_mapping_only = 0;
2953 u8 static_mapping_connection_tracking = 0;
2964 (input,
"translation hash buckets %d", &translation_buckets))
2966 else if (
unformat (input,
"translation hash memory %d",
2967 &translation_memory_size));
2968 else if (
unformat (input,
"user hash buckets %d", &user_buckets))
2970 else if (
unformat (input,
"user hash memory %d", &user_memory_size))
2972 else if (
unformat (input,
"max translations per user %d",
2973 &max_translations_per_user))
2975 else if (
unformat (input,
"outside VRF id %d", &outside_vrf_id))
2977 else if (
unformat (input,
"outside ip6 VRF id %d", &outside_ip6_vrf_id))
2979 else if (
unformat (input,
"inside VRF id %d", &inside_vrf_id))
2981 else if (
unformat (input,
"static mapping only"))
2983 static_mapping_only = 1;
2984 if (
unformat (input,
"connection tracking"))
2985 static_mapping_connection_tracking = 1;
2987 else if (
unformat (input,
"deterministic"))
2989 else if (
unformat (input,
"nat64 bib hash buckets %d",
2990 &nat64_bib_buckets))
2992 else if (
unformat (input,
"nat64 bib hash memory %d",
2993 &nat64_bib_memory_size))
2996 if (
unformat (input,
"nat64 st hash buckets %d", &nat64_st_buckets))
2998 else if (
unformat (input,
"nat64 st hash memory %d",
2999 &nat64_st_memory_size))
3001 else if (
unformat (input,
"out2in dpo"))
3003 else if (
unformat (input,
"dslite ce"))
3005 else if (
unformat (input,
"endpoint-dependent"))
3014 "deterministic and endpoint-dependent modes are mutually exclusive");
3018 "static mapping only mode available only for simple nat");
3022 "out2in dpo mode available only for simple nat");
3047 nat64_set_hash (nat64_bib_buckets, nat64_bib_memory_size, nat64_st_buckets,
3048 nat64_st_memory_size);
3081 if (!static_mapping_only ||
3082 (static_mapping_only && static_mapping_connection_tracking))
3089 clib_bihash_init_16_8 (&tsm->
in2out_ed,
"in2out-ed",
3090 translation_buckets,
3091 translation_memory_size);
3092 clib_bihash_set_kvp_format_fn_16_8 (&tsm->
in2out_ed,
3095 clib_bihash_init_16_8 (&tsm->
out2in_ed,
"out2in-ed",
3096 translation_buckets,
3097 translation_memory_size);
3098 clib_bihash_set_kvp_format_fn_16_8 (&tsm->
out2in_ed,
3103 clib_bihash_init_8_8 (&tsm->
in2out,
"in2out",
3104 translation_buckets,
3105 translation_memory_size);
3106 clib_bihash_set_kvp_format_fn_8_8 (&tsm->
in2out,
3109 clib_bihash_init_8_8 (&tsm->
out2in,
"out2in",
3110 translation_buckets,
3111 translation_memory_size);
3112 clib_bihash_set_kvp_format_fn_8_8 (&tsm->
out2in,
3116 clib_bihash_init_8_8 (&tsm->
user_hash,
"users", user_buckets,
3118 clib_bihash_set_kvp_format_fn_8_8 (&tsm->
user_hash,
3130 "static_mapping_by_local", static_mapping_buckets,
3131 static_mapping_memory_size);
3136 "static_mapping_by_external",
3137 static_mapping_buckets,
3138 static_mapping_memory_size);
3154 u32 if_address_index,
u32 is_delete)
3222 u32 if_address_index,
u32 is_delete)
3252 for (j = 0; j <
vec_len (addresses); j++)
3253 if (addresses[j].
addr.as_u32 == address->
as_u32)
3304 u32 *indices_to_delete = 0;
3306 u32 *auto_add_sw_if_indices =
3313 for (i = 0; i <
vec_len (auto_add_sw_if_indices); i++)
3315 if (auto_add_sw_if_indices[i] == sw_if_index)
3330 if (vec_len (indices_to_delete))
3332 for (j = vec_len (indices_to_delete) - 1; j >= 0; j--)
3343 return VNET_API_ERROR_VALUE_EXIST;
3350 return VNET_API_ERROR_NO_SUCH_ENTRY;
3375 clib_bihash_8_8_t *t;
3378 return VNET_API_ERROR_UNSUPPORTED;
3389 key.
port = clib_host_to_net_u16 (port);
3393 t = is_in ? &tsm->in2out : &tsm->out2in;
3394 if (!clib_bihash_search_8_8 (t, &kv, &value))
3397 return VNET_API_ERROR_UNSPECIFIED;
3405 return VNET_API_ERROR_NO_SUCH_ENTRY;
3411 u32 vrf_id,
int is_in)
3414 clib_bihash_16_8_t *t;
3422 return VNET_API_ERROR_FEATURE_DISABLED;
3432 t = is_in ? &tsm->in2out_ed : &tsm->out2in_ed;
3435 key.
l_port = clib_host_to_net_u16 (port);
3436 key.
r_port = clib_host_to_net_u16 (eh_port);
3441 if (clib_bihash_search_16_8 (t, &kv, &value))
3442 return VNET_API_ERROR_NO_SUCH_ENTRY;
3445 return VNET_API_ERROR_UNSPECIFIED;
ip4_address_t external_addr
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
clib_error_t * snat_api_init(vlib_main_t *vm, snat_main_t *sm)
void dslite_set_ce(dslite_main_t *dm, u8 set)
fib_protocol_t fp_proto
protocol type
nat_outside_fib_t * outside_fibs
#define nat_log_info(...)
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
u32 sessions_per_user_list_head_index
vlib_node_registration_t nat44_ed_in2out_output_node
(constructor) VLIB_REGISTER_NODE (nat44_ed_in2out_output_node)
int nat_affinity_create_and_lock(ip4_address_t client_addr, ip4_address_t service_addr, u8 proto, u16 service_port, u8 backend_index, u32 sticky_time, u32 affinity_per_service_list_head_index)
Create affinity record and take reference counting lock.
int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
Delete external address from NAT44 pool.
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.
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
vnet_main_t * vnet_get_main(void)
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, u8 *tag, int twice_nat, int out2in_only, int identity_nat)
static u32 nat44_session_get_timeout(snat_main_t *sm, snat_session_t *s)
u32 fq_in2out_output_index
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...
clib_error_t * nat_reass_init(vlib_main_t *vm)
Initialize NAT virtual fragmentation reassembly.
static int nat_alloc_addr_and_port_range(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u16 port_per_thread, u32 snat_thread_index)
#define SNAT_TCP_ESTABLISHED_TIMEOUT
#define is_ed_session(s)
Check if NAT session is endpoint dependent.
static_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
static void make_sm_kv(clib_bihash_kv_8_8_t *kv, ip4_address_t *addr, u8 proto, u32 fib_index, u16 port)
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).
#define nat_log_warn(...)
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 uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
u8 * format_user_kvp(u8 *s, va_list *args)
void nat_syslog_nat44_sdel(u32 ssubix, u32 sfibix, ip4_address_t *isaddr, u16 isport, ip4_address_t *idaddr, u16 idport, ip4_address_t *xsaddr, u16 xsport, ip4_address_t *xdaddr, u16 xdport, snat_protocol_t proto, u8 is_twicenat)
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.
int nat44_del_ed_session(snat_main_t *sm, ip4_address_t *addr, u16 port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 vrf_id, int is_in)
Delete NAT44 endpoint-dependent session.
format_function_t format_snat_key
void snat_add_del_addr_to_fib(ip4_address_t *addr, u8 p_len, u32 sw_if_index, int is_add)
Add/del NAT address to FIB.
nat_alloc_out_addr_and_port_function_t * alloc_addr_and_port
static void snat_ip4_add_del_interface_address_cb(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
#define snat_is_unk_proto_session(s)
Check if SNAT session for unknown protocol.
static int nat_alloc_addr_and_port_mape(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u16 port_per_thread, u32 snat_thread_index)
static int nat_alloc_addr_and_port_default(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u16 port_per_thread, u32 snat_thread_index)
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)
Enable/disable NAT44 feature on the interface.
u32 icmp_match_out2in_ed(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
nat44_lb_addr_port_t * locals
clib_bihash_8_8_t user_hash
static int ip4_is_fragment(const ip4_header_t *i)
int nat44_add_del_lb_static_mapping(ip4_address_t e_addr, u16 e_port, snat_protocol_t proto, nat44_lb_addr_port_t *locals, u8 is_add, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag, u32 affinity)
Add/delete static mapping with load-balancing (multiple backends)
#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
u32 max_translations_per_user
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)
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
u8 * format_static_mapping_kvp(u8 *s, va_list *args)
static u32 snat_get_worker_in2out_cb(ip4_header_t *ip0, u32 rx_fib_index0)
int snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
Add external address to NAT44 pool.
u8 * format_ed_session_kvp(u8 *s, va_list *args)
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...)
#define is_fwd_bypass_session(s)
Check if NAT session is forwarding bypass.
void snat_ipfix_logging_init(vlib_main_t *vm)
Initialize NAT plugin IPFIX logging.
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 void nat_ip4_add_del_addr_only_sm_cb(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete)
void nat_affinity_unlock(ip4_address_t client_addr, ip4_address_t service_addr, u8 proto, u16 service_port)
Release a reference counting lock for affinity.
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, twice_nat_type_t *twice_nat, lb_nat_type_t *lb, ip4_address_t *ext_host_addr, u8 *is_identity_nat)
Match NAT44 static mapping.
void snat_free_outside_address_and_port(snat_address_t *addresses, u32 thread_index, snat_session_key_t *k)
Free outside address and port pair.
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 void nat44_delete_session(snat_main_t *sm, snat_session_t *ses, u32 thread_index)
char * name
The counter collection's name.
twice_nat_type_t twice_nat
VNET_FEATURE_INIT(ip4_snat_in2out, static)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
u32 * auto_add_sw_if_indices_twice_nat
vlib_node_registration_t nat44_ed_out2in_node
(constructor) VLIB_REGISTER_NODE (nat44_ed_out2in_node)
int snat_alloc_outside_address_and_port(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u16 port_per_thread, u32 snat_thread_index)
Alloc outside address and port.
snat_user_t * nat_user_get_or_create(snat_main_t *sm, ip4_address_t *addr, u32 fib_index, u32 thread_index)
Find or create NAT user.
#define 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)
Free NAT44 session data (lookup keys, external addrres port)
void nat_dpo_module_init(void)
nat_addr_and_port_alloc_alg_t addr_and_port_alloc_alg
clib_bihash_16_8_t out2in_ed
static uword clib_bitmap_last_set(uword *ai)
Return the higest numbered set bit in a bitmap.
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
snat_session_t * nat_ed_session_alloc(snat_main_t *sm, snat_user_t *u, u32 thread_index, f64 now)
Allocate NAT endpoint-dependent session.
snat_static_mapping_t * static_mappings
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.
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
#define VLIB_CONFIG_FUNCTION(x, n,...)
#define vec_del1(v, i)
Delete the element at index I.
clib_bihash_8_8_t static_mapping_by_external
static void vlib_set_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 value)
Set a simple counter.
void nat_set_alloc_addr_and_port_default(void)
Set address and port assignment algorithm to default/standard.
#define nat_log_notice(...)
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
#define is_lb_session(s)
Check if NAT session is load-balancing.
snat_interface_t * output_feature_interfaces
#define pool_free(p)
Free a pool.
vlib_node_registration_t snat_det_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_det_in2out_node)
#define is_affinity_sessions(s)
Check if NAT session has affinity record.
static u32 nat44_ed_get_worker_out2in_cb(ip4_header_t *ip, u32 rx_fib_index)
static u8 snat_proto_to_ip_proto(snat_protocol_t snat_proto)
#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT
u32 nat_affinity_get_per_service_list_head_index(void)
Get new affinity per service list head index.
static void clib_dlist_addhead(dlist_elt_t *pool, u32 head_index, u32 new_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.
void nat44_add_del_address_dpo(ip4_address_t addr, u8 is_add)
Add/delete external address to FIB DPO (out2in DPO mode)
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
deterministic NAT definitions
int nat_affinity_find_and_lock(ip4_address_t client_addr, ip4_address_t service_addr, u8 proto, u16 service_port, u8 *backend_index)
Find service backend index for client-IP and take a reference counting lock.
int snat_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside, int is_del)
Enable/disable NAT44 output feature on the interface (postrouting NAT)
dslite_main_t dslite_main
u8 * format_session_kvp(u8 *s, va_list *args)
#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
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
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_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, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag, u8 identity_nat)
Add/delete NAT44 static mapping.
u32 * auto_add_sw_if_indices
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
static_always_inline u16 snat_random_port(u16 min, u16 max)
#define NAT_INTERFACE_FLAG_IS_INSIDE
#define is_addr_only_static_mapping(sm)
Check if NAT static mapping is address only (1:1NAT).
#define is_identity_static_mapping(sm)
Check if NAT static mapping is identity NAT.
snat_get_worker_function_t * worker_out2in_cb
clib_error_t * nat_affinity_init(vlib_main_t *vm)
Initialize NAT client-IP based affinity.
snat_icmp_match_function_t * icmp_match_out2in_cb
vlib_log_class_t log_class
void nat_set_alloc_addr_and_port_range(u16 start_port, u16 end_port)
Set address and port assignment algorithm for port range.
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
void snat_ipfix_logging_max_entries_per_user(u32 limit, u32 src_ip)
Generate maximum entries per user exceeded event.
#define clib_bitmap_free(v)
Free a bitmap.
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
uword * thread_registrations_by_name
vlib_node_registration_t nat44_ed_in2out_node
(constructor) VLIB_REGISTER_NODE (nat44_ed_in2out_node)
int nat44_del_session(snat_main_t *sm, ip4_address_t *addr, u16 port, snat_protocol_t proto, u32 vrf_id, int is_in)
Delete NAT44 session.
snat_address_t * twice_nat_addresses
#define VNET_FEATURES(...)
void nat_syslog_nat44_apmdel(u32 ssubix, u32 sfibix, ip4_address_t *isaddr, u16 isport, ip4_address_t *xsaddr, u16 xsport, snat_protocol_t proto)
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)
Allocate new NAT session or recycle last used.
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.
#define is_lb_static_mapping(sm)
Check if NAT static mapping is load-balancing.
void increment_v4_address(ip4_address_t *a)
Increment IPv4 address.
char * stat_segment_name
Name in stat segment directory.
vlib_simple_counter_main_t total_users
static int ip4_is_first_fragment(const ip4_header_t *i)
static u32 ip_proto_to_snat_proto(u8 ip_proto)
The NAT inline functions.
format_function_t format_static_mapping_key
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define is_out2in_only_static_mapping(sm)
Check if NAT static mapping match only out2in direction.
void snat_ipfix_logging_addresses_exhausted(u32 pool_id)
Generate NAT addresses exhausted event.
snat_main_per_thread_data_t * per_thread_data
void nat_affinity_flush_service(u32 affinity_per_service_list_head_index)
Flush all service affinity data.
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
u32 affinity_per_service_list_head_index
snat_address_t * addresses
void nat_dpo_create(dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del, u8 twice_nat)
Add/delete NAT44 pool address from specific interfce.
#define hash_get_mem(h, key)
#define SNAT_ICMP_TIMEOUT
snat_static_map_resolve_t * to_resolve
static u32 random_u32(u32 *seed)
32-bit random number generator
ip4_main_t ip4_main
Global ip4 main structure.
static vlib_thread_main_t * vlib_get_thread_main()
static u32 get_thread_idx_by_port(u16 e_port)
u32 translation_memory_size
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
#define vec_foreach(var, vec)
Vector iterator.
vlib_node_registration_t snat_in2out_output_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_output_node)
int snat_set_workers(uword *bitmap)
Set NAT plugin workers.
u32 icmp_match_in2out_ed(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b, ip4_header_t *ip, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
#define is_twice_nat_session(s)
Check if NAT session is twice NAT.
clib_bihash_16_8_t in2out_ed
static clib_error_t * snat_config(vlib_main_t *vm, unformat_input_t *input)
#define pool_foreach_index(i, v, body)
Iterate pool by index.
NAT plugin virtual fragmentation reassembly.
void nat_set_alloc_addr_and_port_mape(u16 psid, u16 psid_offset, u16 psid_length)
Set address and port assignment algorithm for MAP-E CE.
NAT66 global declarations.
NAT plugin client-IP based session affinity for load-balancing.
vlib_simple_counter_main_t total_sessions
#define SNAT_TCP_TRANSITORY_TIMEOUT
ip_lookup_main_t * ip4_lookup_main
#define NAT_STATIC_MAPPING_FLAG_LB
static int is_snat_address_used_in_static_mapping(snat_main_t *sm, ip4_address_t addr)
#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY
snat_session_t * sessions
A low (below routing) priority source a plugin can use.
snat_icmp_match_function_t * icmp_match_in2out_cb
clib_bihash_8_8_t static_mapping_by_local
static u32 snat_get_worker_out2in_cb(ip4_header_t *ip0, u32 rx_fib_index0)
int nat44_lb_static_mapping_add_del_local(ip4_address_t e_addr, u16 e_port, ip4_address_t l_addr, u16 l_port, snat_protocol_t proto, u32 vrf_id, u8 probability, u8 is_add)
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 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.