34 #include <vpp/app/version.h> 41 .arc_name =
"ip4-unicast",
42 .node_name =
"nat44-in2out",
46 .arc_name =
"ip4-unicast",
47 .node_name =
"nat44-out2in",
49 "ip4-dhcp-client-detect"),
52 .arc_name =
"ip4-unicast",
53 .node_name =
"nat44-classify",
57 .arc_name =
"ip4-unicast",
58 .node_name =
"nat44-det-in2out",
62 .arc_name =
"ip4-unicast",
63 .node_name =
"nat44-det-out2in",
65 "ip4-dhcp-client-detect"),
68 .arc_name =
"ip4-unicast",
69 .node_name =
"nat44-det-classify",
73 .arc_name =
"ip4-unicast",
74 .node_name =
"nat44-ed-in2out",
78 .arc_name =
"ip4-unicast",
79 .node_name =
"nat44-ed-out2in",
81 "ip4-dhcp-client-detect"),
84 .arc_name =
"ip4-unicast",
85 .node_name =
"nat44-ed-classify",
89 .arc_name =
"ip4-unicast",
90 .node_name =
"nat44-in2out-worker-handoff",
94 .arc_name =
"ip4-unicast",
95 .node_name =
"nat44-out2in-worker-handoff",
97 "ip4-dhcp-client-detect"),
100 .arc_name =
"ip4-unicast",
101 .node_name =
"nat44-handoff-classify",
105 .arc_name =
"ip4-unicast",
106 .node_name =
"nat44-in2out-fast",
110 .arc_name =
"ip4-unicast",
111 .node_name =
"nat44-out2in-fast",
113 "ip4-dhcp-client-detect"),
116 .arc_name =
"ip4-unicast",
117 .node_name =
"nat44-hairpin-dst",
121 .arc_name =
"ip4-unicast",
122 .node_name =
"nat44-ed-hairpin-dst",
128 .arc_name =
"ip4-output",
129 .node_name =
"nat44-in2out-output",
133 .arc_name =
"ip4-output",
134 .node_name =
"nat44-in2out-output-worker-handoff",
138 .arc_name =
"ip4-output",
139 .node_name =
"nat44-hairpin-src",
143 .arc_name =
"ip4-output",
144 .node_name =
"nat44-ed-in2out-output",
148 .arc_name =
"ip4-output",
149 .node_name =
"nat44-ed-hairpin-src",
156 .arc_name =
"ip4-local",
157 .node_name =
"nat44-hairpinning",
162 .arc_name =
"ip4-local",
163 .node_name =
"nat44-ed-hairpinning",
170 .version = VPP_BUILD_VER,
171 .description =
"Network Address Translation",
200 ed_key.
l_addr = s->in2out.addr;
201 ed_key.
r_addr = s->ext_host_addr;
202 ed_key.
l_port = s->in2out.port;
203 ed_key.
r_port = s->ext_host_port;
208 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &ed_kv, 0))
216 ed_key.
l_addr = s->out2in.addr;
217 ed_key.
r_addr = s->ext_host_addr;
221 ed_key.
proto = s->in2out.port;
228 ed_key.
l_port = s->out2in.port;
229 ed_key.
r_port = s->ext_host_port;
233 if (clib_bihash_add_del_16_8 (&tsm->
out2in_ed, &ed_kv, 0))
236 ed_key.
l_addr = s->in2out.addr;
239 ed_key.
l_port = s->in2out.port;
242 ed_key.
r_addr = s->ext_host_nat_addr;
243 ed_key.
r_port = s->ext_host_nat_port;
247 if (clib_bihash_add_del_16_8 (&tsm->
in2out_ed, &ed_kv, 0))
252 kv.
key = s->in2out.as_u64;
253 if (clib_bihash_add_del_8_8 (&tsm->
in2out, &kv, 0))
255 kv.
key = s->out2in.as_u64;
256 if (clib_bihash_add_del_8_8 (&tsm->
out2in, &kv, 0))
265 s->out2in.addr.as_u32,
269 s->in2out.fib_index);
277 key.
port = s->ext_host_nat_port;
279 if (a->
addr.
as_u32 == s->ext_host_nat_addr.as_u32)
282 thread_index, &key, i);
291 if (s->outside_address_index != ~0)
293 &s->out2in, s->outside_address_index);
311 if (clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
315 memset (u, 0,
sizeof (*u));
329 if (clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 1))
345 u32 oldest_per_user_translation_list_index, session_index;
346 dlist_elt_t * oldest_per_user_translation_list_elt;
352 oldest_per_user_translation_list_index =
356 ASSERT (oldest_per_user_translation_list_index != ~0);
361 oldest_per_user_translation_list_index);
363 oldest_per_user_translation_list_elt =
365 oldest_per_user_translation_list_index);
368 session_index = oldest_per_user_translation_list_elt->
value;
377 s->outside_address_index = ~0;
382 s->ext_host_addr.as_u32 = 0;
383 s->ext_host_port = 0;
384 s->ext_host_nat_addr.as_u32 = 0;
385 s->ext_host_nat_port = 0;
390 memset (s, 0,
sizeof (*s));
391 s->outside_address_index = ~0;
396 per_user_translation_list_elt - tsm->
list_pool);
399 s->per_user_index = per_user_translation_list_elt - tsm->
list_pool;
403 s->per_user_list_head_index,
404 per_user_translation_list_elt - tsm->
list_pool);
421 next = t->
next_in2out ?
"nat44-in2out" :
"nat44-out2in";
423 s =
format (s,
"nat44-classify: next %s", next);
433 u32 n_left_from, * from, * to_next;
442 while (n_left_from > 0)
447 to_next, n_left_to_next);
449 while (n_left_from > 0 && n_left_to_next > 0)
507 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
516 to_next, n_left_to_next,
536 .name =
"nat44-classify",
537 .vector_size =
sizeof (
u32),
559 .name =
"nat44-ed-classify",
560 .vector_size =
sizeof (
u32),
583 .name =
"nat44-det-classify",
584 .vector_size =
sizeof (
u32),
607 .name =
"nat44-handoff-classify",
608 .vector_size =
sizeof (
u32),
641 .ip4.as_u32 = addr->
as_u32,
674 return VNET_API_ERROR_FEATURE_DISABLED;
680 return VNET_API_ERROR_VALUE_EXIST;
695 #define _(N, i, n, s) \ 696 clib_bitmap_alloc (ap->busy_##n##_port_bitmap, 65535); \ 697 ap->busy_##n##_ports = 0; \ 698 vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); 708 if (nat_interface_is_inside(i) || sm->out2in_dpo)
711 snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
716 if (nat_interface_is_inside(i) || sm->out2in_dpo)
719 snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
732 if (m->external_addr.as_u32 == addr.as_u32)
743 v = clib_net_to_host_u32(a->
as_u32) + 1;
744 a->
as_u32 = clib_host_to_net_u32(v);
797 u16 l_port,
u16 e_port,
u32 vrf_id,
int addr_only,
815 u32 elt_index, head_index;
823 if (twice_nat || out2in_only)
824 return VNET_API_ERROR_FEATURE_DISABLED;
828 if (sw_if_index != ~0)
857 return VNET_API_ERROR_VALUE_EXIST;
860 (sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto,
861 addr_only, is_add, tag);
864 if (first_int_addr == 0)
879 return VNET_API_ERROR_NO_SUCH_ENTRY;
896 m_key.
port = addr_only ? 0 : e_port;
897 m_key.
protocol = addr_only ? 0 : proto;
908 return VNET_API_ERROR_VALUE_EXIST;
910 if (twice_nat && addr_only)
911 return VNET_API_ERROR_UNSUPPORTED;
918 return VNET_API_ERROR_NO_SUCH_FIB;
931 m_key.
port = addr_only ? 0 : l_port;
932 m_key.
protocol = addr_only ? 0 : proto;
936 return VNET_API_ERROR_VALUE_EXIST;
951 #define _(N, j, n, s) \ 952 case SNAT_PROTOCOL_##N: \ 953 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 954 return VNET_API_ERROR_INVALID_VALUE; \ 955 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 958 a->busy_##n##_ports++; \ 959 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]++; \ 966 return VNET_API_ERROR_INVALID_VALUE_2;
974 if (sw_if_index != ~0)
991 return VNET_API_ERROR_NO_SUCH_ENTRY;
996 memset (m, 0,
sizeof (*m));
1045 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1047 user_index = value.
value;
1053 elt_index = head->
next;
1055 ses_index = elt->
value;
1056 while (ses_index != ~0)
1060 ses_index = elt->
value;
1065 if (!addr_only && (clib_net_to_host_u16 (s->in2out.port) != m->
local_port))
1082 if (sw_if_index != ~0)
1085 return VNET_API_ERROR_NO_SUCH_ENTRY;
1098 #define _(N, j, n, s) \ 1099 case SNAT_PROTOCOL_##N: \ 1100 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 1101 if (e_port > 1024) \ 1103 a->busy_##n##_ports--; \ 1104 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]--; \ 1111 return VNET_API_ERROR_INVALID_VALUE_2;
1144 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1146 user_index = value.
value;
1152 elt_index = head->
next;
1154 ses_index = elt->
value;
1155 while (ses_index != ~0)
1159 ses_index = elt->
value;
1163 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) &&
1164 (clib_net_to_host_u16 (s->out2in.port) != e_port))
1183 clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 0);
1201 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1204 snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add);
1209 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1212 snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add);
1233 u32 elt_index, head_index, ses_index;
1242 return VNET_API_ERROR_FEATURE_DISABLED;
1244 m_key.
addr = e_addr;
1245 m_key.
port = e_port;
1257 return VNET_API_ERROR_VALUE_EXIST;
1260 return VNET_API_ERROR_INVALID_VALUE;
1278 #define _(N, j, n, s) \ 1279 case SNAT_PROTOCOL_##N: \ 1280 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \ 1281 return VNET_API_ERROR_INVALID_VALUE; \ 1282 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \ 1283 if (e_port > 1024) \ 1285 a->busy_##n##_ports++; \ 1286 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]++; \ 1293 return VNET_API_ERROR_INVALID_VALUE_2;
1300 return VNET_API_ERROR_NO_SUCH_ENTRY;
1304 memset (m, 0,
sizeof (*m));
1323 nat_log_err (
"static_mapping_by_external key add failed");
1324 return VNET_API_ERROR_UNSPECIFIED;
1328 for (i = 0; i <
vec_len (locals); i++)
1338 locals[
i].
prefix = (i == 0) ? locals[i].probability :\
1339 (locals[i - 1].prefix + locals[i].probability);
1363 return VNET_API_ERROR_NO_SUCH_ENTRY;
1377 #define _(N, j, n, s) \ 1378 case SNAT_PROTOCOL_##N: \ 1379 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \ 1380 if (e_port > 1024) \ 1382 a->busy_##n##_ports--; \ 1383 a->busy_##n##_ports_per_thread[(e_port - 1024) / sm->port_per_thread]--; \ 1390 return VNET_API_ERROR_INVALID_VALUE_2;
1404 nat_log_err (
"static_mapping_by_external key del failed");
1405 return VNET_API_ERROR_UNSPECIFIED;
1418 nat_log_err (
"static_mapping_by_local key del failed");
1419 return VNET_API_ERROR_UNSPECIFIED;
1438 if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
1445 elt_index = head->
next;
1447 ses_index = elt->
value;
1448 while (ses_index != ~0)
1452 ses_index = elt->
value;
1457 if ((s->in2out.addr.as_u32 != local->
addr.
as_u32) &&
1458 (clib_net_to_host_u16 (s->in2out.port) != local->
port))
1482 snat_session_t *ses;
1483 u32 *ses_to_be_removed = 0, *ses_index;
1491 for (i=0; i <
vec_len (addresses); i++)
1500 return VNET_API_ERROR_NO_SUCH_ENTRY;
1506 if (m->external_addr.as_u32 == addr.as_u32)
1507 (void) snat_add_static_mapping (m->local_addr, m->external_addr,
1508 m->local_port, m->external_port,
1509 m->vrf_id, m->addr_only, ~0,
1510 m->proto, 0, m->twice_nat,
1511 m->out2in_only, m->tag);
1520 return VNET_API_ERROR_UNSPECIFIED;
1529 if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
1534 if (ses->out2in.addr.as_u32 == addr.as_u32)
1536 ses->outside_address_index = ~0;
1537 nat_free_session_data (sm, ses, tsm - sm->per_thread_data);
1538 vec_add1 (ses_to_be_removed, ses - tsm->sessions);
1563 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1566 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1569 pool_foreach (interface, sm->output_feature_interfaces,
1571 if (nat_interface_is_inside(interface) || sm->out2in_dpo)
1574 snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
1585 const char * feature_name, *del_feature_name;
1591 return VNET_API_ERROR_UNSUPPORTED;
1595 if (i->sw_if_index == sw_if_index)
1596 return VNET_API_ERROR_VALUE_EXIST;
1600 feature_name = is_inside ?
"nat44-in2out-fast" :
"nat44-out2in-fast";
1604 feature_name = is_inside ?
"nat44-in2out-worker-handoff" :
"nat44-out2in-worker-handoff";
1606 feature_name = is_inside ?
"nat44-det-in2out" :
"nat44-det-out2in";
1608 feature_name = is_inside ?
"nat44-ed-in2out" :
"nat44-ed-out2in";
1610 feature_name = is_inside ?
"nat44-in2out" :
"nat44-out2in";
1623 if (i->sw_if_index == sw_if_index)
1627 if (nat_interface_is_inside(i) && nat_interface_is_outside(i))
1630 i->flags &= ~NAT_INTERFACE_FLAG_IS_INSIDE;
1632 i->flags &= ~NAT_INTERFACE_FLAG_IS_OUTSIDE;
1634 if (sm->num_workers > 1 && !sm->deterministic)
1636 del_feature_name =
"nat44-handoff-classify";
1637 feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1638 "nat44-out2in-worker-handoff";
1640 else if (sm->deterministic)
1642 del_feature_name =
"nat44-det-classify";
1643 feature_name = !is_inside ?
"nat44-det-in2out" :
1646 else if (sm->endpoint_dependent)
1648 del_feature_name =
"nat44-ed-classify";
1649 feature_name = !is_inside ?
"nat44-ed-in2out" :
1654 del_feature_name =
"nat44-classify";
1655 feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
1658 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1659 sw_if_index, 0, 0, 0);
1660 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1661 sw_if_index, 1, 0, 0);
1664 if (sm->endpoint_dependent)
1665 vnet_feature_enable_disable (
"ip4-local",
1666 "nat44-ed-hairpinning",
1667 sw_if_index, 1, 0, 0);
1669 vnet_feature_enable_disable (
"ip4-local",
1670 "nat44-hairpinning",
1671 sw_if_index, 1, 0, 0);
1676 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1677 sw_if_index, 0, 0, 0);
1678 pool_put (sm->interfaces, i);
1681 if (sm->endpoint_dependent)
1682 vnet_feature_enable_disable (
"ip4-local",
1683 "nat44-ed-hairpinning",
1684 sw_if_index, 0, 0, 0);
1686 vnet_feature_enable_disable (
"ip4-local",
1687 "nat44-hairpinning",
1688 sw_if_index, 0, 0, 0);
1694 if ((nat_interface_is_inside(i) && is_inside) ||
1695 (nat_interface_is_outside(i) && !is_inside))
1698 if (sm->num_workers > 1 && !sm->deterministic)
1700 del_feature_name = !is_inside ?
"nat44-in2out-worker-handoff" :
1701 "nat44-out2in-worker-handoff";
1702 feature_name =
"nat44-handoff-classify";
1704 else if (sm->deterministic)
1706 del_feature_name = !is_inside ?
"nat44-det-in2out" :
1708 feature_name =
"nat44-det-classify";
1710 else if (sm->endpoint_dependent)
1712 del_feature_name = !is_inside ?
"nat44-ed-in2out" :
1714 feature_name =
"nat44-ed-classify";
1718 del_feature_name = !is_inside ?
"nat44-in2out" :
"nat44-out2in";
1719 feature_name =
"nat44-classify";
1722 vnet_feature_enable_disable (
"ip4-unicast", del_feature_name,
1723 sw_if_index, 0, 0, 0);
1724 vnet_feature_enable_disable (
"ip4-unicast", feature_name,
1725 sw_if_index, 1, 0, 0);
1728 if (sm->endpoint_dependent)
1729 vnet_feature_enable_disable (
"ip4-local",
"nat44-ed-hairpinning",
1730 sw_if_index, 0, 0, 0);
1732 vnet_feature_enable_disable (
"ip4-local",
"nat44-hairpinning",
1733 sw_if_index, 0, 0, 0);
1743 return VNET_API_ERROR_NO_SUCH_ENTRY;
1746 i->sw_if_index = sw_if_index;
1750 if (is_inside && !sm->out2in_dpo)
1752 if (sm->endpoint_dependent)
1754 sw_if_index, 1, 0, 0);
1757 sw_if_index, 1, 0, 0);
1776 if (!(m->addr_only) || (m->local_addr.as_u32 == m->external_addr.as_u32))
1779 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1784 snat_add_del_addr_to_fib(&dm->out_addr, dm->out_plen, sw_if_index, !is_del);
1801 return VNET_API_ERROR_UNSUPPORTED;
1805 if (i->sw_if_index == sw_if_index)
1806 return VNET_API_ERROR_VALUE_EXIST;
1814 sw_if_index, !is_del, 0, 0);
1816 sw_if_index, !is_del, 0, 0);
1821 sw_if_index, !is_del, 0, 0);
1823 sw_if_index, !is_del, 0, 0);
1831 "nat44-out2in-worker-handoff",
1832 sw_if_index, !is_del, 0, 0);
1834 "nat44-in2out-output-worker-handoff",
1835 sw_if_index, !is_del, 0, 0);
1842 sw_if_index, !is_del, 0, 0);
1844 sw_if_index, !is_del, 0, 0);
1849 sw_if_index, !is_del, 0, 0);
1851 sw_if_index, !is_del, 0, 0);
1865 if (i->sw_if_index == sw_if_index)
1868 pool_put (sm->output_feature_interfaces, i);
1870 return VNET_API_ERROR_VALUE_EXIST;
1877 return VNET_API_ERROR_NO_SUCH_ENTRY;
1879 pool_get (sm->output_feature_interfaces,
i);
1880 i->sw_if_index = sw_if_index;
1897 if (!(m->addr_only) || (m->local_addr.as_u32 == m->external_addr.as_u32))
1900 snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del);
1912 return VNET_API_ERROR_FEATURE_DISABLED;
1915 return VNET_API_ERROR_INVALID_WORKER;
1938 u32 if_address_index,
1947 u32 if_address_index,
1955 u32 * address_indexp,
1956 u16 port_per_thread,
1957 u32 snat_thread_index);
2062 u16 port_host_byte_order = clib_net_to_host_u16 (k->
port);
2066 a = addresses + address_index;
2070 #define _(N, i, n, s) \ 2071 case SNAT_PROTOCOL_##N: \ 2072 ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \ 2073 port_host_byte_order) == 1); \ 2074 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \ 2075 port_host_byte_order, 0); \ 2076 a->busy_##n##_ports--; \ 2077 a->busy_##n##_ports_per_thread[thread_index]--; \ 2119 m_key.
port = clib_net_to_host_u16 (match.
port);
2125 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2131 if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
2146 mid = ((
hi -
lo) >> 1) +
lo;
2206 u32 * address_indexp,
2207 u16 port_per_thread,
2208 u32 snat_thread_index)
2213 address_indexp, port_per_thread,
2222 u32 * address_indexp,
2223 u16 port_per_thread,
2224 u32 snat_thread_index)
2230 for (i = 0; i <
vec_len (addresses); i++)
2235 #define _(N, j, n, s) \ 2236 case SNAT_PROTOCOL_##N: \ 2237 if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \ 2239 if (a->fib_index == fib_index) \ 2243 portnum = (port_per_thread * \ 2244 snat_thread_index) + \ 2245 snat_random_port(1, port_per_thread) + 1024; \ 2246 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2248 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2249 a->busy_##n##_ports_per_thread[thread_index]++; \ 2250 a->busy_##n##_ports++; \ 2251 k->addr = a->addr; \ 2252 k->port = clib_host_to_net_u16(portnum); \ 2253 *address_indexp = i; \ 2257 else if (a->fib_index == ~0) \ 2278 #define _(N, j, n, s) \ 2279 case SNAT_PROTOCOL_##N: \ 2282 portnum = (port_per_thread * \ 2283 snat_thread_index) + \ 2284 snat_random_port(1, port_per_thread) + 1024; \ 2285 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2287 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2288 a->busy_##n##_ports_per_thread[thread_index]++; \ 2289 a->busy_##n##_ports++; \ 2290 k->addr = a->addr; \ 2291 k->port = clib_host_to_net_u16(portnum); \ 2292 *address_indexp = gi; \ 2314 u32 * address_indexp,
2315 u16 port_per_thread,
2316 u32 snat_thread_index)
2320 u16 m, ports, portnum, A, j;
2329 #define _(N, i, n, s) \ 2330 case SNAT_PROTOCOL_##N: \ 2331 if (a->busy_##n##_ports < ports) \ 2335 A = snat_random_port(1, pow2_mask(sm->psid_offset)); \ 2336 j = snat_random_port(0, pow2_mask(m)); \ 2337 portnum = A | (sm->psid << sm->psid_offset) | (j << (16 - m)); \ 2338 if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \ 2340 clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \ 2341 a->busy_##n##_ports++; \ 2342 k->addr = a->addr; \ 2343 k->port = clib_host_to_net_u16 (portnum); \ 2344 *address_indexp = i; \ 2369 .fp_addr.ip4.as_u32 = addr.
as_u32,
2388 u32 *r = va_arg (*args,
u32 *);
2391 #define _(N, i, n, s) else if (unformat (input, s)) *r = SNAT_PROTOCOL_##N; 2407 #define _(N, j, n, str) case SNAT_PROTOCOL_##N: t = (u8 *) str; break; 2411 s =
format (s,
"unknown");
2469 s =
format (s,
"local %U:%d remote %U:%d proto %U fib %d session-index %llu",
2481 u32 next_worker_index = 0;
2489 next_worker_index += sm->
workers[hash & (_vec_len (sm->
workers) - 1)];
2493 return next_worker_index;
2506 u32 next_worker_index = 0;
2534 nat_reass_ip4_t *reass;
2539 if (reass && (reass->thread_index != (
u32) ~ 0))
2540 return reass->thread_index;
2555 icmp46_header_t * icmp = (icmp46_header_t *) udp;
2566 case SNAT_PROTOCOL_ICMP:
2567 icmp = (icmp46_header_t*)l4_header;
2571 case SNAT_PROTOCOL_UDP:
2572 case SNAT_PROTOCOL_TCP:
2584 m_key.addr = ip0->dst_address;
2585 m_key.port = clib_net_to_host_u16 (port);
2586 m_key.protocol = proto;
2587 m_key.fib_index = rx_fib_index0;
2588 kv.key = m_key.as_u64;
2589 if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
2592 return m->workers[0];
2597 next_worker_index = sm->first_worker_index;
2598 next_worker_index +=
2599 sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
2600 return next_worker_index;
2608 u32 proto, next_worker_index = 0;
2639 icmp46_header_t * icmp = (icmp46_header_t *) udp;
2650 case SNAT_PROTOCOL_ICMP:
2651 icmp = (icmp46_header_t*)l4_header;
2655 case SNAT_PROTOCOL_UDP:
2656 case SNAT_PROTOCOL_TCP:
2668 make_sm_kv (&kv, &ip->dst_address, proto, rx_fib_index,
2669 clib_net_to_host_u16 (port));
2670 if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
2674 return m->workers[0];
2676 hash = ip->src_address.as_u32 + (ip->src_address.as_u32 >> 8) +
2677 (ip->src_address.as_u32 >> 16) + (ip->src_address.as_u32 >>24);
2680 return m->workers[hash & (_vec_len (m->workers) - 1)];
2682 return m->workers[hash % _vec_len (m->workers)];
2687 next_worker_index = sm->first_worker_index;
2688 next_worker_index +=
2689 sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
2691 return next_worker_index;
2699 u32 translation_buckets = 1024;
2700 u32 translation_memory_size = 128<<20;
2701 u32 user_buckets = 128;
2702 u32 user_memory_size = 64<<20;
2703 u32 max_translations_per_user = 100;
2704 u32 outside_vrf_id = 0;
2705 u32 outside_ip6_vrf_id = 0;
2706 u32 inside_vrf_id = 0;
2707 u32 static_mapping_buckets = 1024;
2708 u32 static_mapping_memory_size = 64<<20;
2709 u32 nat64_bib_buckets = 1024;
2710 u32 nat64_bib_memory_size = 128 << 20;
2711 u32 nat64_st_buckets = 2048;
2712 u32 nat64_st_memory_size = 256 << 20;
2713 u8 static_mapping_only = 0;
2714 u8 static_mapping_connection_tracking = 0;
2724 if (
unformat (input,
"translation hash buckets %d", &translation_buckets))
2726 else if (
unformat (input,
"translation hash memory %d",
2727 &translation_memory_size));
2728 else if (
unformat (input,
"user hash buckets %d", &user_buckets))
2730 else if (
unformat (input,
"user hash memory %d",
2733 else if (
unformat (input,
"max translations per user %d",
2734 &max_translations_per_user))
2736 else if (
unformat (input,
"outside VRF id %d",
2739 else if (
unformat (input,
"outside ip6 VRF id %d",
2740 &outside_ip6_vrf_id))
2742 else if (
unformat (input,
"inside VRF id %d",
2745 else if (
unformat (input,
"static mapping only"))
2747 static_mapping_only = 1;
2748 if (
unformat (input,
"connection tracking"))
2749 static_mapping_connection_tracking = 1;
2751 else if (
unformat (input,
"deterministic"))
2753 else if (
unformat (input,
"nat64 bib hash buckets %d",
2754 &nat64_bib_buckets))
2756 else if (
unformat (input,
"nat64 bib hash memory %d",
2757 &nat64_bib_memory_size))
2759 else if (
unformat (input,
"nat64 st hash buckets %d", &nat64_st_buckets))
2761 else if (
unformat (input,
"nat64 st hash memory %d",
2762 &nat64_st_memory_size))
2764 else if (
unformat (input,
"out2in dpo"))
2766 else if (
unformat (input,
"dslite ce"))
2768 else if (
unformat (input,
"endpoint-dependent"))
2798 nat64_set_hash(nat64_bib_buckets, nat64_bib_memory_size, nat64_st_buckets,
2799 nat64_st_memory_size);
2831 if (!static_mapping_only ||
2832 (static_mapping_only && static_mapping_connection_tracking))
2838 clib_bihash_init_16_8 (&tsm->
in2out_ed,
"in2out-ed",
2839 translation_buckets,
2840 translation_memory_size);
2841 clib_bihash_set_kvp_format_fn_16_8 (&tsm->
in2out_ed,
2844 clib_bihash_init_16_8 (&tsm->
out2in_ed,
"out2in-ed",
2845 translation_buckets,
2846 translation_memory_size);
2847 clib_bihash_set_kvp_format_fn_16_8 (&tsm->
out2in_ed,
2852 clib_bihash_init_8_8 (&tsm->
in2out,
"in2out",
2853 translation_buckets,
2854 translation_memory_size);
2855 clib_bihash_set_kvp_format_fn_8_8 (&tsm->
in2out,
2858 clib_bihash_init_8_8 (&tsm->
out2in,
"out2in",
2859 translation_buckets,
2860 translation_memory_size);
2861 clib_bihash_set_kvp_format_fn_8_8 (&tsm->
out2in,
2865 clib_bihash_init_8_8 (&tsm->
user_hash,
"users", user_buckets,
2867 clib_bihash_set_kvp_format_fn_8_8 (&tsm->
user_hash,
2878 "static_mapping_by_local", static_mapping_buckets,
2879 static_mapping_memory_size);
2884 "static_mapping_by_external", static_mapping_buckets,
2885 static_mapping_memory_size);
2902 #define _(v, N, str) case SNAT_SESSION_##N: t = (u8 *) str; break; 2906 t =
format (t,
"unknown");
2916 s =
format (s,
"%U proto %U port %d fib %d",
2926 snat_session_t * sess = va_arg (*args, snat_session_t *);
2930 s =
format (s,
" i2o %U proto %u fib %u\n",
2932 clib_net_to_host_u16 (sess->in2out.port),
2933 sess->in2out.fib_index);
2934 s =
format (s,
" o2i %U proto %u fib %u\n",
2936 clib_net_to_host_u16 (sess->out2in.port),
2937 sess->out2in.fib_index);
2948 s =
format (s,
" external host o2i %U:%d i2o %U:%d\n",
2950 clib_net_to_host_u16 (sess->ext_host_port),
2952 clib_net_to_host_u16 (sess->ext_host_nat_port));
2956 if (sess->ext_host_addr.as_u32)
2957 s =
format (s,
" external host %U:%u\n",
2959 clib_net_to_host_u16 (sess->ext_host_port));
2963 s =
format (s,
" last heard %.2f\n", sess->last_heard);
2964 s =
format (s,
" total pkts %d, total bytes %lld\n",
2965 sess->total_pkts, sess->total_bytes);
2967 s =
format (s,
" static translation\n");
2969 s =
format (s,
" dynamic translation\n");
2971 s =
format (s,
" forwarding-bypass\n");
2973 s =
format (s,
" load-balancing\n");
2975 s =
format (s,
" twice-nat\n");
2984 int verbose = va_arg (*args,
int);
2986 u32 elt_index, head_index;
2988 snat_session_t * sess;
2990 s =
format (s,
"%U: %d dynamic translations, %d static translations\n",
3001 elt_index = head->
next;
3003 session_index = elt->
value;
3005 while (session_index != ~0)
3011 elt_index = elt->
next;
3013 session_index = elt->
value;
3026 s =
format (s,
"local %U external %U vrf %d %s %s",
3037 s =
format (s,
"%U vrf %d external %U:%d %s %s",
3045 s =
format (s,
"\n local %U:%d probability %d\%",
3050 s =
format (s,
"%U local %U:%d external %U:%d vrf %d %s %s",
3068 s =
format (s,
"local %U external %U vrf %d",
3073 s =
format (s,
"%U local %U:%d external %U:%d vrf %d",
3086 u32 in_offset, out_offset;
3088 u32 *
i = va_arg (*args,
u32 *);
3091 in_addr.
as_u32 = clib_host_to_net_u32 (
3092 clib_net_to_host_u32(det_map->
in_addr.
as_u32) + user_index);
3093 in_offset = clib_net_to_host_u32(in_addr.
as_u32) -
3096 out_addr.
as_u32 = clib_host_to_net_u32(
3098 s =
format (s,
"in %U:%d out %U:%d external host %U:%d state: %U expire: %d\n",
3100 clib_net_to_host_u16 (ses->
in_port),
3117 u32 if_address_index,
3188 u32 if_address_index,
3219 for (j = 0; j <
vec_len(addresses); j++)
3220 if (addresses[j].
addr.as_u32 == address->
as_u32)
3269 u32 *indices_to_delete = 0;
3271 u32 *auto_add_sw_if_indices =
3277 for (i = 0; i <
vec_len(auto_add_sw_if_indices); i++)
3279 if (auto_add_sw_if_indices[i] == sw_if_index)
3294 if (
vec_len(indices_to_delete))
3296 for (j =
vec_len(indices_to_delete)-1; j >= 0; j--)
3307 return VNET_API_ERROR_VALUE_EXIST;
3314 return VNET_API_ERROR_NO_SUCH_ENTRY;
3339 clib_bihash_8_8_t *t;
3342 return VNET_API_ERROR_UNSUPPORTED;
3353 key.
port = clib_host_to_net_u16 (port);
3357 t = is_in ? &tsm->in2out : &tsm->out2in;
3358 if (!clib_bihash_search_8_8 (t, &kv, &value))
3361 return VNET_API_ERROR_UNSPECIFIED;
3369 return VNET_API_ERROR_NO_SUCH_ENTRY;
3375 u32 vrf_id,
int is_in)
3378 clib_bihash_16_8_t *t;
3386 return VNET_API_ERROR_FEATURE_DISABLED;
3396 t = is_in ? &tsm->in2out_ed : &tsm->out2in_ed;
3399 key.
l_port = clib_host_to_net_u16 (port);
3400 key.
r_port = clib_host_to_net_u16 (eh_port);
3402 key.
fib_index = clib_host_to_net_u32 (fib_index);
3405 if (clib_bihash_search_16_8 (t, &kv, &value))
3406 return VNET_API_ERROR_NO_SUCH_ENTRY;
3409 return VNET_API_ERROR_UNSPECIFIED;
ip4_address_t external_addr
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
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)
void dslite_set_ce(dslite_main_t *dm, u8 set)
fib_protocol_t fp_proto
protocol type
#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
int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
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)
Add static mapping.
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.
vlib_node_registration_t nat44_ed_in2out_node
(constructor) VLIB_REGISTER_NODE (nat44_ed_in2out_node)
#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)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
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, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag)
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)
ip_lookup_main_t lookup_main
vlib_node_registration_t nat44_ed_in2out_output_node
(constructor) VLIB_REGISTER_NODE (nat44_ed_in2out_output_node)
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)
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.
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)
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
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
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)
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
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)
u8 * format_ed_session_kvp(u8 *s, va_list *args)
#define SNAT_DET_SES_PER_USER
A high priority source a plugin can use.
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, u8 *lb)
Match NAT44 static mapping.
#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.
u16 fp_len
The mask length.
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)
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 void nat44_delete_session(snat_main_t *sm, snat_session_t *ses, u32 thread_index)
static int ip4_is_fragment(ip4_header_t *i)
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)
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)
void nat_dpo_module_init(void)
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
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_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 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
#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.
void nat_set_alloc_addr_and_port_default(void)
#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).
#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
static uword nat44_handoff_classify_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define VLIB_REGISTER_NODE(x,...)
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)
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.
void nat44_add_del_address_dpo(ip4_address_t addr, u8 is_add)
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 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)
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
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.
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
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...
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.
#define NAT_INTERFACE_FLAG_IS_INSIDE
u8 * format_snat_static_map_to_resolve(u8 *s, va_list *args)
snat_get_worker_function_t * worker_out2in_cb
snat_icmp_match_function_t * icmp_match_out2in_cb
vlib_log_class_t log_class
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
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(...)
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)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
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.
struct _vlib_node_registration vlib_node_registration_t
NAT64 global declarations.
void increment_v4_address(ip4_address_t *a)
static u32 ip_proto_to_snat_proto(u8 ip_proto)
The NAT inline functions.
int snat_alloc_outside_address_and_port(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u32 *address_indexp, u16 port_per_thread, u32 snat_thread_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
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.
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
static uword nat44_ed_classify_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
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)
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)
snat_static_map_resolve_t * to_resolve
static u32 random_u32(u32 *seed)
32-bit random number generator
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)
ip4_main_t ip4_main
Global ip4 main structure.
u8 * format_snat_key(u8 *s, va_list *args)
static vlib_thread_main_t * vlib_get_thread_main()
static u8 * format_nat44_classify_trace(u8 *s, va_list *args)
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)
vlib_node_registration_t nat44_ed_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_ed_classify_node)
vlib_node_registration_t nat44_det_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_det_classify_node)
int snat_set_workers(uword *bitmap)
u16 flags
Copy of main node flags.
#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)
NAT plugin virtual fragmentation reassembly.
#define VLIB_NODE_FLAG_TRACE
void nat_set_alloc_addr_and_port_mape(u16 psid, u16 psid_offset, u16 psid_length)
NAT66 global declarations.
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
#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)
snat_session_t * sessions
u8 * format_snat_session_state(u8 *s, va_list *args)
A low (below routing) priority source a plugin can use.
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
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 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.