|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
19 #include <vpp/app/version.h>
49 #define skip_if_disabled() \
52 nat44_ei_main_t *nm = &nat44_ei_main; \
53 if (PREDICT_FALSE (!nm->enabled)) \
58 #define fail_if_enabled() \
61 nat44_ei_main_t *nm = &nat44_ei_main; \
62 if (PREDICT_FALSE (nm->enabled)) \
64 nat44_ei_log_err ("plugin enabled"); \
70 #define fail_if_disabled() \
73 nat44_ei_main_t *nm = &nat44_ei_main; \
74 if (PREDICT_FALSE (!nm->enabled)) \
76 nat44_ei_log_err ("plugin disabled"); \
84 .arc_name =
"ip4-unicast",
85 .node_name =
"nat44-ei-classify",
87 "ip4-sv-reassembly-feature"),
90 .arc_name =
"ip4-unicast",
91 .node_name =
"nat44-ei-handoff-classify",
93 "ip4-sv-reassembly-feature"),
96 .arc_name =
"ip4-unicast",
97 .node_name =
"nat44-ei-in2out",
99 "ip4-sv-reassembly-feature"),
102 .arc_name =
"ip4-unicast",
103 .node_name =
"nat44-ei-out2in",
105 "ip4-sv-reassembly-feature",
106 "ip4-dhcp-client-detect"),
109 .arc_name =
"ip4-output",
110 .node_name =
"nat44-ei-in2out-output",
112 "ip4-sv-reassembly-output-feature"),
115 .arc_name =
"ip4-unicast",
116 .node_name =
"nat44-ei-in2out-fast",
118 "ip4-sv-reassembly-feature"),
121 .arc_name =
"ip4-unicast",
122 .node_name =
"nat44-ei-out2in-fast",
124 "ip4-sv-reassembly-feature",
125 "ip4-dhcp-client-detect"),
128 .arc_name =
"ip4-unicast",
129 .node_name =
"nat44-ei-hairpin-dst",
131 "ip4-sv-reassembly-feature"),
134 .arc_name =
"ip4-output",
135 .node_name =
"nat44-ei-hairpin-src",
137 "ip4-sv-reassembly-output-feature"),
140 .arc_name =
"ip4-local",
141 .node_name =
"nat44-ei-hairpinning",
145 .arc_name =
"ip4-unicast",
146 .node_name =
"nat44-ei-in2out-worker-handoff",
150 .arc_name =
"ip4-unicast",
151 .node_name =
"nat44-ei-out2in-worker-handoff",
153 "ip4-dhcp-client-detect"),
156 .arc_name =
"ip4-output",
157 .node_name =
"nat44-ei-in2out-output-worker-handoff",
159 "ip4-sv-reassembly-output-feature"),
163 .version = VPP_BUILD_VER,
164 .description =
"IPv4 Endpoint-Independent NAT (NAT44 EI)",
167 #define foreach_nat44_ei_classify_error \
168 _ (NEXT_IN2OUT, "next in2out") \
169 _ (NEXT_OUT2IN, "next out2in") \
170 _ (FRAG_CACHED, "fragment cached")
174 #define _(sym, str) NAT44_EI_CLASSIFY_ERROR_##sym,
181 #define _(sym, string) string,
212 s =
format (s,
"nat44-ei-classify: fragment cached");
216 s =
format (s,
"nat44-ei-classify: next %s",
next);
229 u32 address_length,
u32 if_address_index,
u32 is_delete);
233 u32 address_length,
u32 if_address_index,
u32 is_delete);
258 return VNET_API_ERROR_FEATURE_DISABLED;
261 return VNET_API_ERROR_INVALID_WORKER;
277 #define nat_validate_simple_counter(c, i) \
280 vlib_validate_simple_counter (&c, i); \
281 vlib_zero_simple_counter (&c, i); \
285 #define nat_init_simple_counter(c, n, sn) \
289 c.stat_segment_name = sn; \
290 nat_validate_simple_counter (c, 0); \
298 nat_validate_simple_counter (nm->counters.fastpath.in2out.x, sw_if_index); \
299 nat_validate_simple_counter (nm->counters.fastpath.out2in.x, sw_if_index); \
300 nat_validate_simple_counter (nm->counters.slowpath.in2out.x, sw_if_index); \
301 nat_validate_simple_counter (nm->counters.slowpath.out2in.x, sw_if_index);
315 u32 i, num_threads = 0;
316 uword *p, *bitmap = 0;
338 "/nat44-ei/total-users");
340 "/nat44-ei/total-sessions");
342 "/nat44-ei/user-limit-reached");
345 nat_init_simple_counter (nm->counters.fastpath.in2out.x, #x, \
346 "/nat44-ei/in2out/fastpath/" #x); \
347 nat_init_simple_counter (nm->counters.fastpath.out2in.x, #x, \
348 "/nat44-ei/out2in/fastpath/" #x); \
349 nat_init_simple_counter (nm->counters.slowpath.in2out.x, #x, \
350 "/nat44-ei/in2out/slowpath/" #x); \
351 nat_init_simple_counter (nm->counters.slowpath.out2in.x, #x, \
352 "/nat44-ei/out2in/slowpath/" #x);
356 "/nat44-ei/hairpinning");
429 c.sessions = 10 * 1024;
431 if (!
c.user_sessions)
432 c.user_sessions =
c.sessions;
443 nm->
pat = (!
c.static_mapping_only ||
444 (
c.static_mapping_only &&
c.connection_tracking));
487 #define _(N, i, n, s) vec_free (ap->busy_##n##_ports_per_thread);
498 const char *feature_name, *del_feature_name;
512 return VNET_API_ERROR_UNSUPPORTED;
520 return VNET_API_ERROR_VALUE_EXIST;
525 feature_name = is_inside ?
"nat44-ei-in2out-fast" :
"nat44-ei-out2in-fast";
529 feature_name = is_inside ?
"nat44-ei-in2out-worker-handoff" :
530 "nat44-ei-out2in-worker-handoff";
532 feature_name = is_inside ?
"nat44-ei-in2out" :
"nat44-ei-out2in";
586 del_feature_name =
"nat44-ei-handoff-classify";
588 "del_feature_name = nat44-ei-handoff-classify");
589 feature_name = !is_inside ?
590 "nat44-ei-in2out-worker-handoff" :
591 "nat44-ei-out2in-worker-handoff";
595 del_feature_name =
"nat44-ei-classify";
598 !is_inside ?
"nat44-ei-in2out" :
"nat44-ei-out2in";
606 "ip4-unicast", del_feature_name,
sw_if_index, 0, 0, 0);
610 "ip4-unicast", feature_name,
sw_if_index, 1, 0, 0);
616 "nat44-ei-hairpinning",
629 "ip4-unicast", feature_name,
sw_if_index, 0, 0, 0);
636 "nat44-ei-hairpinning",
651 del_feature_name = !is_inside ?
652 "nat44-ei-in2out-worker-handoff" :
653 "nat44-ei-out2in-worker-handoff";
654 feature_name =
"nat44-ei-handoff-classify";
655 clib_warning (
"feature_name = nat44-ei-handoff-classify");
660 !is_inside ?
"nat44-ei-in2out" :
"nat44-ei-out2in";
661 feature_name =
"nat44-ei-classify";
670 "ip4-unicast", del_feature_name,
sw_if_index, 0, 0, 0);
680 "ip4-local",
"nat44-ei-hairpinning",
sw_if_index, 0, 0, 0);
694 return VNET_API_ERROR_NO_SUCH_ENTRY;
763 return VNET_API_ERROR_UNSUPPORTED;
771 return VNET_API_ERROR_VALUE_EXIST;
832 "nat44-ei-out2in-worker-handoff",
837 "ip4-output",
"nat44-ei-in2out-output-worker-handoff",
sw_if_index,
877 return VNET_API_ERROR_VALUE_EXIST;
886 return VNET_API_ERROR_NO_SUCH_ENTRY;
990 u16 port_host_byte_order = clib_net_to_host_u16 (
port);
992 for (address_index = 0; address_index <
vec_len (addresses); address_index++)
994 if (addresses[address_index].
addr.as_u32 !=
addr.as_u32)
997 a = addresses + address_index;
1000 #define _(N, j, n, s) \
1001 case NAT_PROTOCOL_##N: \
1002 if (a->busy_##n##_port_refcounts[port_host_byte_order]) \
1003 return VNET_API_ERROR_INSTANCE_IN_USE; \
1004 ++a->busy_##n##_port_refcounts[port_host_byte_order]; \
1005 a->busy_##n##_ports_per_thread[thread_index]++; \
1006 a->busy_##n##_ports++; \
1015 return VNET_API_ERROR_NO_SUCH_ENTRY;
1026 .fp_addr.ip4.as_u32 =
addr.as_u32,
1050 u16 port_host_byte_order = clib_net_to_host_u16 (
port);
1052 for (address_index = 0; address_index <
vec_len (addresses); address_index++)
1054 if (addresses[address_index].
addr.as_u32 ==
addr->as_u32)
1060 a = addresses + address_index;
1064 #define _(N, i, n, s) \
1065 case NAT_PROTOCOL_##N: \
1066 ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \
1067 --a->busy_##n##_port_refcounts[port_host_byte_order]; \
1068 a->busy_##n##_ports--; \
1069 a->busy_##n##_ports_per_thread[thread_index]--; \
1086 if (clib_bihash_add_del_8_8 (&
nm->
in2out, &kv, 0))
1089 if (clib_bihash_add_del_8_8 (&
nm->
out2in, &kv, 0))
1094 &s->in2out.addr, s->in2out.port, &s->out2in.addr,
1095 s->out2in.port, s->nat_proto);
1104 thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32,
1105 s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index);
1107 nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
1108 s->ext_host_port, s->nat_proto, s->out2in.fib_index,
1116 &s->out2in.addr, s->out2in.port,
1124 nat44_ei_user_t *u = 0;
1148 u->addr.as_u32 =
addr->as_u32;
1149 u->fib_index = fib_index;
1153 u->sessions_per_user_list_head_index =
1179 nat44_ei_session_t *
1183 nat44_ei_session_t *s;
1185 u32 oldest_per_user_translation_list_index, session_index;
1186 dlist_elt_t *oldest_per_user_translation_list_elt;
1195 ASSERT (oldest_per_user_translation_list_index != ~0);
1199 oldest_per_user_translation_list_index);
1202 tnm->
list_pool, oldest_per_user_translation_list_index);
1205 session_index = oldest_per_user_translation_list_elt->
value;
1212 u->nstaticsessions--;
1219 s->ext_host_addr.as_u32 = 0;
1220 s->ext_host_port = 0;
1221 s->ext_host_nat_addr.as_u32 = 0;
1222 s->ext_host_nat_port = 0;
1235 s->per_user_index = per_user_translation_list_elt -
tnm->
list_pool;
1236 s->per_user_list_head_index = u->sessions_per_user_list_head_index;
1246 s->ha_last_refreshed =
now;
1258 if (clib_bihash_add_del_8_8 (&
nm->
in2out, &kv, 0))
1262 if (clib_bihash_add_del_8_8 (&
nm->
out2in, &kv, 0))
1268 &s->in2out.addr, s->in2out.port,
1269 &s->out2in.addr, s->out2in.port, s->nat_proto);
1272 thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32,
1273 s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index);
1275 nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
1276 s->ext_host_port, s->nat_proto, s->out2in.fib_index,
1284 &s->out2in.addr, s->out2in.port,
1292 nat44_ei_session_t *s;
1303 while (
elt->value != ~0)
1366 nat44_ei_session_t *s;
1367 u32 elt_index, head_index, ses_index;
1371 user_index =
value.value;
1373 if (u->nstaticsessions)
1375 head_index = u->sessions_per_user_list_head_index;
1377 elt_index = head->
next;
1379 ses_index =
elt->value;
1380 while (ses_index != ~0)
1384 ses_index =
elt->value;
1388 if ((s->out2in.addr.as_u32 != e_addr.
as_u32) ||
1389 (s->out2in.port != e_port))
1412 u32 next_worker_index = 0;
1424 return next_worker_index;
1429 u32 rx_fib_index0,
u8 is_output)
1437 u32 next_worker_index = 0;
1464 icmp46_header_t *
icmp = (icmp46_header_t *) udp;
1477 case NAT_PROTOCOL_ICMP:
1478 icmp = (icmp46_header_t *) l4_header;
1482 case NAT_PROTOCOL_UDP:
1483 case NAT_PROTOCOL_TCP:
1506 next_worker_index +=
1508 return next_worker_index;
1516 u32 snat_thread_index)
1528 for (
i = s_addr_offset;
i <
vec_len (addresses); ++
i)
1533 #define _(N, j, n, s) \
1534 case NAT_PROTOCOL_##N: \
1535 if (a->busy_##n##_ports_per_thread[thread_index] < port_per_thread) \
1537 if (a->fib_index == fib_index) \
1541 portnum = (port_per_thread * snat_thread_index) + \
1542 nat_random_port (&nm->random_seed, 0, \
1543 port_per_thread - 1) + \
1545 if (a->busy_##n##_port_refcounts[portnum]) \
1547 --a->busy_##n##_port_refcounts[portnum]; \
1548 a->busy_##n##_ports_per_thread[thread_index]++; \
1549 a->busy_##n##_ports++; \
1551 *port = clib_host_to_net_u16 (portnum); \
1555 else if (a->fib_index == ~0) \
1568 for (
i = 0;
i < s_addr_offset; ++
i)
1604 u16 port_per_thread,
u32 snat_thread_index)
1617 #define _(N, i, n, s) \
1618 case NAT_PROTOCOL_##N: \
1619 if (a->busy_##n##_ports < ports) \
1623 portnum = nat_random_port (&nm->random_seed, nm->start_port, \
1625 if (a->busy_##n##_port_refcounts[portnum]) \
1627 ++a->busy_##n##_port_refcounts[portnum]; \
1628 a->busy_##n##_ports++; \
1630 *port = clib_host_to_net_u16 (portnum); \
1651 u16 port_per_thread,
u32 snat_thread_index)
1655 u16 m, ports, portnum,
A, j;
1664 #define _(N, i, n, s) \
1665 case NAT_PROTOCOL_##N: \
1666 if (a->busy_##n##_ports < ports) \
1670 A = nat_random_port (&nm->random_seed, 1, \
1671 pow2_mask (nm->psid_offset)); \
1672 j = nat_random_port (&nm->random_seed, 0, pow2_mask (m)); \
1673 portnum = A | (nm->psid << nm->psid_offset) | (j << (16 - m)); \
1674 if (a->busy_##n##_port_refcounts[portnum]) \
1676 ++a->busy_##n##_port_refcounts[portnum]; \
1677 a->busy_##n##_ports++; \
1679 *port = clib_host_to_net_u16 (portnum); \
1732 int addr_only,
int identity_nat,
1761 .fib_index = ses->in2out.fib_index };
1776 u->nstaticsessions--;
1791 nat44_ei_session_t *s;
1792 clib_bihash_8_8_t *t;
1796 if (!clib_bihash_search_8_8 (t, &kv, &
value))
1804 return VNET_API_ERROR_UNSPECIFIED;
1812 return VNET_API_ERROR_NO_SUCH_ENTRY;
1837 .ip4.as_u32 =
addr->as_u32,
1856 u8 identity_nat,
u8 *tag,
u8 is_add)
1868 u32 elt_index, head_index;
1871 nat44_ei_session_t *s;
1907 return VNET_API_ERROR_VALUE_EXIST;
1914 if (!first_int_addr)
1925 return VNET_API_ERROR_NO_SUCH_ENTRY;
1929 if (!first_int_addr)
1939 init_nat_k (&kv, e_addr, addr_only ? 0 : e_port, 0, addr_only ? 0 :
proto);
1953 return VNET_API_ERROR_VALUE_EXIST;
1964 return VNET_API_ERROR_VALUE_EXIST;
1983 init_nat_k (&kv, l_addr, addr_only ? 0 : l_port, fib_index,
1984 addr_only ? 0 :
proto);
1987 return VNET_API_ERROR_VALUE_EXIST;
2002 #define _(N, j, n, s) \
2003 case NAT_PROTOCOL_##N: \
2004 if (a->busy_##n##_port_refcounts[e_port]) \
2005 return VNET_API_ERROR_INVALID_VALUE; \
2006 ++a->busy_##n##_port_refcounts[e_port]; \
2007 if (e_port > 1024) \
2009 a->busy_##n##_ports++; \
2010 a->busy_##n##_ports_per_thread[nat44_ei_get_thread_idx_by_port ( \
2017 return VNET_API_ERROR_INVALID_VALUE_2;
2042 return VNET_API_ERROR_NO_SUCH_ENTRY;
2103 user_index =
value.value;
2107 head_index = u->sessions_per_user_list_head_index;
2109 elt_index = head->
next;
2111 ses_index =
elt->value;
2112 while (ses_index != ~0)
2116 ses_index =
elt->value;
2121 if (!addr_only && s->in2out.port != m->
local_port)
2143 return VNET_API_ERROR_NO_SUCH_ENTRY;
2154 find = local - m->
locals;
2157 return VNET_API_ERROR_NO_SUCH_ENTRY;
2176 #define _(N, j, n, s) \
2177 case NAT_PROTOCOL_##N: \
2178 --a->busy_##n##_port_refcounts[e_port]; \
2179 if (e_port > 1024) \
2181 a->busy_##n##_ports--; \
2182 a->busy_##n##_ports_per_thread[nat44_ei_get_thread_idx_by_port ( \
2188 default :
return VNET_API_ERROR_INVALID_VALUE_2;
2254 u32 match_fib_index,
2257 u32 *mapping_fib_index,
u8 by_external,
2258 u8 *is_addr_only,
u8 *is_identity_nat)
2267 init_nat_k (&kv, match_addr, match_port, 0, match_protocol);
2285 init_nat_k (&kv, match_addr, match_port, match_fib_index,
2290 init_nat_k (&kv, match_addr, 0, match_fib_index, 0);
2304 *mapping_port = match_port;
2306 *mapping_port =
port;
2365 s =
format (s,
"%U thread-index %llu session-index %llu",
2385 u32 translations,
u32 translation_buckets,
2394 clib_bihash_init_8_8 (&
tnm->
user_hash,
"users", user_buckets, 0);
2432 clib_bihash_free_8_8 (&
nm->
in2out);
2433 clib_bihash_free_8_8 (&
nm->
out2in);
2447 u32 static_mapping_buckets = 1024;
2448 u32 static_mapping_memory_size = 64 << 20;
2451 "static_mapping_by_local", static_mapping_buckets,
2452 static_mapping_memory_size);
2454 "static_mapping_by_external", static_mapping_buckets,
2455 static_mapping_memory_size);
2463 clib_bihash_init_8_8 (&
nm->
in2out,
"in2out", translation_buckets, 0);
2464 clib_bihash_init_8_8 (&
nm->
out2in,
"out2in", translation_buckets, 0);
2465 clib_bihash_set_kvp_format_fn_8_8 (&
nm->
in2out,
2467 clib_bihash_set_kvp_format_fn_8_8 (&
nm->
out2in,
2485 clib_bihash_free_8_8 (&
nm->
in2out);
2486 clib_bihash_free_8_8 (&
nm->
out2in);
2489 clib_bihash_set_kvp_format_fn_8_8 (&
nm->
in2out,
2491 clib_bihash_set_kvp_format_fn_8_8 (&
nm->
out2in,
2508 u32 new_fib_index,
u32 old_fib_index)
2516 if (!
nm->
enabled || (new_fib_index == old_fib_index) ||
2547 if (outside_fib->
fib_index == old_fib_index)
2558 if (outside_fib->
fib_index == new_fib_index)
2587 return VNET_API_ERROR_VALUE_EXIST;
2600 #define _(N, i, n, s) \
2601 clib_memset (ap->busy_##n##_port_refcounts, 0, \
2602 sizeof (ap->busy_##n##_port_refcounts)); \
2603 ap->busy_##n##_ports = 0; \
2604 ap->busy_##n##_ports_per_thread = 0; \
2605 vec_validate_init_empty (ap->busy_##n##_ports_per_thread, \
2606 tm->n_vlib_mains - 1, 0);
2638 u32 *indices_to_delete = 0;
2645 for (
i = 0;
i <
vec_len (auto_add_sw_if_indices);
i++)
2662 if (
vec_len (indices_to_delete))
2664 for (j =
vec_len (indices_to_delete) - 1; j >= 0; j--)
2672 return VNET_API_ERROR_VALUE_EXIST;
2679 return VNET_API_ERROR_NO_SUCH_ENTRY;
2711 nat44_ei_session_t *ses;
2712 u32 *ses_to_be_removed = 0, *ses_index;
2730 return VNET_API_ERROR_NO_SUCH_ENTRY;
2751 return VNET_API_ERROR_UNSPECIFIED;
2755 if (
a->fib_index != ~0)
2759 if (
a->busy_tcp_ports ||
a->busy_udp_ports ||
a->busy_icmp_ports)
2765 if (ses->out2in.addr.as_u32 ==
addr.as_u32)
2781 #define _(N, i, n, s) vec_free (a->busy_##n##_ports_per_thread);
2811 u32 if_address_index,
u32 is_delete)
2835 for (j = 0; j <
vec_len (addresses); j++)
2861 nm,
"nat44_ei_add_del_static_mapping returned %d",
"i4",
rv);
2885 u32 address_length,
u32 if_address_index,
2953 u32 next_in2out = 0, next_out2in = 0;
2980 n_left_to_next -= 1;
3020 (b0->
flags & VLIB_BUFFER_IS_TRACED)))
3033 n_left_to_next, bi0, next0);
3040 vm,
node->node_index, NAT44_EI_CLASSIFY_ERROR_NEXT_IN2OUT, next_in2out);
3042 vm,
node->node_index, NAT44_EI_CLASSIFY_ERROR_NEXT_OUT2IN, next_out2in);
3043 return frame->n_vectors;
3053 .name =
"nat44-ei-classify",
3054 .vector_size =
sizeof (
u32),
3074 .name =
"nat44-ei-handoff-classify",
3075 .vector_size =
sizeof (
u32),
void nat44_ei_add_del_address_dpo(ip4_address_t addr, u8 is_add)
vlib_node_registration_t nat44_ei_in2out_hairpinning_finish_interface_output_node
(constructor) VLIB_REGISTER_NODE (nat44_ei_in2out_hairpinning_finish_interface_output_node)
nat44_ei_main_per_thread_data_t * tnm
#define foreach_nat44_ei_classify_error
static u32 clib_dlist_remove_head(dlist_elt_t *pool, u32 head_index)
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
static u32 nat_value_get_thread_index(clib_bihash_kv_8_8_t *value)
vnet_interface_main_t * im
nat44_ei_config_t rconfig
u32 fq_in2out_output_index
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
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 void nat44_ei_update_outside_fib(ip4_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
struct app_rx_mq_elt_ * next
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
void nat44_ei_free_session_data_v2(nat44_ei_main_t *nm, nat44_ei_session_t *s, u32 thread_index, u8 is_ha)
ip_lookup_main_t lookup_main
#define nat_elog_warn(_pm, nat_elog_str)
#define NAT44_EI_STATIC_MAPPING_FLAG_IDENTITY_NAT
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
nat44_ei_hairpin_src_next_t next_index
@ NAT44_EI_CLASSIFY_NEXT_DROP
ip4_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
ip4_main_t ip4_main
Global ip4 main structure.
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.
nat44_ei_static_mapping_t * static_mappings
#define nat_init_simple_counter(c, n, sn)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static int nat44_ei_alloc_default_cb(nat44_ei_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t s_addr, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
clib_error_t * nat44_ei_api_hookup(vlib_main_t *vm)
void nat44_ei_delete_session(nat44_ei_main_t *nm, nat44_ei_session_t *ses, u32 thread_index)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u32 nat44_ei_get_out2in_worker_index(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index0, u8 is_output)
nat44_ei_interface_t * interfaces
static nat_protocol_t ip_proto_to_nat_proto(u8 ip_proto)
Common NAT inline functions.
vlib_node_registration_t nat44_ei_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_ei_classify_node)
@ VLIB_NODE_TYPE_INTERNAL
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
vlib_node_registration_t nat44_ei_hairpinning_node
(constructor) VLIB_REGISTER_NODE (nat44_ei_hairpinning_node)
vlib_main_t vlib_node_runtime_t * node
@ NAT44_EI_CLASSIFY_N_NEXT
#define nat44_ei_interface_is_outside(ip)
void nat_dpo_create(dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
@ NAT44_EI_CLASSIFY_NEXT_IN2OUT
int nat44_ei_plugin_enable(nat44_ei_config_t c)
#define pool_put(P, E)
Free an object E in pool P.
#define NAT_FQ_NELTS_DEFAULT
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
static int nat44_ei_is_address_used_in_static_mapping(ip4_address_t addr)
NAT port/address allocation lib.
int nat44_ei_set_frame_queue_nelts(u32 frame_queue_nelts)
nat44_ei_addr_and_port_alloc_alg_t addr_and_port_alloc_alg
nat44_ei_address_t * addresses
@ FIB_ENTRY_FLAG_EXCLUSIVE
static_always_inline uword nat44_ei_classify_inline_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
struct nat44_ei_main_s::@81 counters
u32 max_translations_per_thread
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
int ip4_sv_reass_enable_disable_with_refcnt(u32 sw_if_index, int is_enable)
u8 * format_nat44_ei_user_kvp(u8 *s, va_list *args)
#define pool_put_index(p, i)
Free pool element with given index.
void nat_ha_disable()
Disable NAT HA.
void nat_ipfix_logging_addresses_exhausted(u32 thread_index, u32 pool_id)
Generate NAT addresses exhausted event.
int nat44_ei_static_mapping_match(ip4_address_t match_addr, u16 match_port, u32 match_fib_index, nat_protocol_t match_protocol, ip4_address_t *mapping_addr, u16 *mapping_port, u32 *mapping_fib_index, u8 by_external, u8 *is_addr_only, u8 *is_identity_nat)
Match NAT44-EI static mapping.
nat44_ei_session_t * sessions
clib_error_t * nat44_ei_init(vlib_main_t *vm)
u32 vlib_frame_queue_main_init(u32 node_index, u32 frame_queue_nelts)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
u32 tcp_trans_lru_head_index
static void nat44_ei_db_init(u32 translations, u32 translation_buckets, u32 user_buckets)
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.
#define pool_foreach(VAR, POOL)
Iterate through pool.
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
static int nat44_ei_alloc_range_cb(nat44_ei_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t s_addr, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
#define nat44_ei_is_session_static(sp)
nat44_ei_static_map_resolve_t * to_resolve
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void nat44_ei_add_del_addr_to_fib(ip4_address_t *addr, u8 p_len, u32 sw_if_index, int is_add)
u32 nat44_ei_get_in2out_worker_index(ip4_header_t *ip0, u32 rx_fib_index0, u8 is_output)
IPv4 shallow virtual reassembly.
#define VLIB_NODE_FN(node)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define nat_validate_simple_counter(c, i)
vlib_simple_counter_main_t hairpinning
static u32 nat_value_get_session_index(clib_bihash_kv_8_8_t *value)
int nat44_ei_add_address(nat44_ei_main_t *nm, ip4_address_t *addr, u32 vrf_id)
nat44_ei_main_t nat44_ei_main
#define vec_dup(V)
Return copy of vector (no header, no alignment)
@ NAT44_EI_CLASSIFY_N_ERROR
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
int nat44_ei_set_outside_address_and_port(nat44_ei_address_t *addresses, u32 thread_index, ip4_address_t addr, u16 port, nat_protocol_t protocol)
vnet_main_t * vnet_get_main(void)
static void init_nat_kv(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto, u32 thread_index, u32 session_index)
#define VLIB_NODE_FLAG_TRACE
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.
static_always_inline uword vlib_get_thread_index(void)
int nat44_ei_user_del(ip4_address_t *addr, u32 fib_index)
Delete specific NAT44 EI user and his sessions.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
@ NAT44_EI_CLASSIFY_NEXT_OUT2IN
u32 unk_proto_lru_head_index
#define static_always_inline
static u8 * format_nat44_ei_classify_trace(u8 *s, va_list *args)
u32 max_translations_per_user
void nat44_ei_free_session_data(nat44_ei_main_t *nm, nat44_ei_session_t *s, u32 thread_index, u8 is_ha)
static void nat44_ei_worker_db_free(nat44_ei_main_per_thread_data_t *tnm)
static_always_inline u32 nat_calc_bihash_buckets(u32 n_elts)
vlib_log_class_t log_class
void nat_ha_sdel(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 session_thread_index)
Create session delete HA event.
#define clib_bitmap_free(v)
Free a bitmap.
static void nat44_ei_worker_db_init(nat44_ei_main_per_thread_data_t *tnm, u32 translations, u32 translation_buckets, u32 user_buckets)
void nat44_ei_free_outside_address_and_port(nat44_ei_address_t *addresses, u32 thread_index, ip4_address_t *addr, u16 port, nat_protocol_t protocol)
uword * thread_registrations_by_name
nat44_ei_classify_error_t
u32 in2out_hairpinning_finish_interface_output_node_fq_index
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
static api_main_t * vlibapi_get_main(void)
nat44_ei_session_t * nat44_ei_session_alloc_or_recycle(nat44_ei_main_t *nm, nat44_ei_user_t *u, u32 thread_index, f64 now)
int nat44_ei_add_del_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port, nat_protocol_t proto, u32 sw_if_index, u32 vrf_id, u8 addr_only, u8 identity_nat, u8 *tag, u8 is_add)
Add/delete NAT44-EI static mapping.
int nat44_ei_add_interface_address(nat44_ei_main_t *nm, u32 sw_if_index, int is_del)
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
void nat_dpo_module_init(void)
nat44_ei_main_per_thread_data_t * per_thread_data
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
int ip4_sv_reass_output_enable_disable_with_refcnt(u32 sw_if_index, int is_enable)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
manual_print typedef address
u8 * format_nat44_ei_session_kvp(u8 *s, va_list *args)
void nat44_ei_set_alloc_mape(u16 psid, u16 psid_offset, u16 psid_length)
Set address and port assignment algorithm for MAP-E CE.
void nat44_ei_set_alloc_range(u16 start_port, u16 end_port)
Set address and port assignment algorithm for port range.
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.
int nat44_ei_del_session(nat44_ei_main_t *nm, ip4_address_t *addr, u16 port, nat_protocol_t proto, u32 vrf_id, int is_in)
Delete NAT44-EI session.
ip4_address_t external_addr
clib_bihash_8_8_t static_mapping_by_external
#define nat44_ei_interface_is_inside(ip)
struct _vlib_node_registration vlib_node_registration_t
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
nat44_ei_user_t * nat44_ei_user_get_or_create(nat44_ei_main_t *nm, ip4_address_t *addr, u32 fib_index, u32 thread_index)
void nat44_ei_set_node_indexes(nat44_ei_main_t *nm, vlib_main_t *vm)
nat44_ei_interface_t * output_feature_interfaces
nat44_ei_alloc_out_addr_and_port_function_t * alloc_addr_and_port
#define FIB_SOURCE_PRIORITY_HI
Some priority values that plugins might use when they are not to concerned where in the list they'll ...
#define nat_elog_notice_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
#define NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE
#define hash_get_mem(h, key)
ip4_add_del_interface_address_function_t * function
static int nat44_ei_alloc_mape_cb(nat44_ei_address_t *addresses, u32 fib_index, u32 thread_index, nat_protocol_t proto, ip4_address_t s_addr, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index)
#define vec_free(V)
Free vector's memory (no header).
vlib_node_registration_t nat44_ei_in2out_hairpinning_finish_ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (nat44_ei_in2out_hairpinning_finish_ip4_lookup_node)
#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.
clib_bihash_8_8_t user_hash
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
static void vlib_set_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 value)
Set a simple counter.
int nat44_ei_plugin_disable()
format_function_t format_nat_protocol
@ FIB_ENTRY_FLAG_CONNECTED
vlib_node_registration_t nat44_ei_hairpin_dst_node
(constructor) VLIB_REGISTER_NODE (nat44_ei_hairpin_dst_node)
clib_bihash_8_8_t static_mapping_by_local
#define nat_elog_info(_pm, nat_elog_str)
description fragment has unexpected format
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.
static_always_inline void nat_reset_timeouts(nat_timeouts_t *timeouts)
int nat44_ei_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
vlib_put_next_frame(vm, node, next_index, 0)
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.
VNET_FEATURE_INIT(ip4_nat_classify, static)
@ FIB_ROUTE_PATH_FLAG_NONE
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
u32 nat44_ei_get_thread_idx_by_port(u16 e_port)
#define VLIB_INIT_FUNCTION(x)
static void nat44_ei_delete_user_with_no_session(nat44_ei_main_t *nm, nat44_ei_user_t *u, u32 thread_index)
u8 static_mapping_connection_tracking
vl_api_ip_proto_t protocol
static void nat44_ei_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 void nat44_ei_add_static_mapping_when_resolved(ip4_address_t l_addr, u16 l_port, u16 e_port, nat_protocol_t proto, u32 sw_if_index, u32 vrf_id, int addr_only, int identity_nat, u8 *tag)
#define vec_foreach(var, vec)
Vector iterator.
int nat44_ei_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside, int is_del)
vlib_simple_counter_main_t user_limit_reached
8 octet key, 8 octet key value pair
int nat44_ei_set_workers(uword *bitmap)
static uword pool_elts(void *v)
Number of active elements in a pool.
ip4_table_bind_function_t * function
#define foreach_nat_counter
static void nat44_ei_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)
fib_protocol_t fp_proto
protocol type
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)
void nat_ha_enable()
Enable NAT HA.
static_always_inline void nat44_ei_user_del_sessions(nat44_ei_user_t *u, u32 thread_index)
static char * nat44_ei_classify_error_strings[]
static uword clib_bitmap_last_set(uword *ai)
Return the higest numbered set bit in a bitmap.
u8 * format_nat44_ei_key(u8 *s, va_list *args)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
void nat_syslog_nat44_apmdel(u32 ssubix, u32 sfibix, ip4_address_t *isaddr, u16 isport, ip4_address_t *xsaddr, u16 xsport, nat_protocol_t proto)
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static void init_nat_i2o_k(clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s)
#define nat44_ei_is_identity_static_mapping(mp)
#define VNET_FEATURES(...)
u32 in2out_hairpinning_finish_ip4_lookup_node_fq_index
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define pool_dup(P)
Return copy of pool without alignment.
u32 in2out_output_node_index
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
static void split_nat_key(u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto)
#define fail_if_enabled()
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
@ FIB_SOURCE_BH_SIMPLE
add paths without path extensions
#define nat44_ei_log_err(...)
#define pool_free(p)
Free a pool.
#define FIB_SOURCE_PRIORITY_LOW
#define NAT44_EI_STATIC_MAPPING_FLAG_ADDR_ONLY
#define clib_warning(format, args...)
#define pool_alloc(P, N)
Allocate N more free elements to pool (unspecified alignment).
vlib_simple_counter_main_t total_users
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
void nat_ipfix_logging_nat44_ses_delete(u32 thread_index, u32 src_ip, u32 nat_src_ip, nat_protocol_t nat_proto, u16 src_port, u16 nat_src_port, u32 fib_index)
Generate NAT44 session delete event.
#define nat44_ei_is_unk_proto_session(sp)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
ip_lookup_main_t * ip4_lookup_main
void nat44_ei_static_mapping_del_sessions(nat44_ei_main_t *nm, nat44_ei_main_per_thread_data_t *tnm, nat44_ei_user_key_t u_key, int addr_only, ip4_address_t e_addr, u16 e_port)
Delete session for static mapping.
#define clib_bitmap_foreach(i, ai)
Macro to iterate across set bits in a bitmap.
#define nat44_ei_is_addr_only_static_mapping(mp)
u32 tcp_estab_lru_head_index
vlib_simple_counter_main_t total_sessions
void nat44_ei_sessions_clear()
Clear all active NAT44-EI sessions.
#define fail_if_disabled()
void nat_ha_init(vlib_main_t *vm, u32 num_workers, u32 num_threads)
Initialize NAT HA.
static void init_nat_o2i_k(clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s)
static vlib_thread_main_t * vlib_get_thread_main()
static uword is_pow2(uword x)
vlib_node_registration_t nat44_ei_handoff_classify_node
(constructor) VLIB_REGISTER_NODE (nat44_ei_handoff_classify_node)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
static void nat44_ei_db_free()
vl_api_interface_index_t sw_if_index
int nat44_ei_del_address(nat44_ei_main_t *nm, ip4_address_t addr, u8 delete_sm)
#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).
u8 * format_nat44_ei_static_mapping_kvp(u8 *s, va_list *args)
static void init_nat_k(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto)
void nat44_ei_set_alloc_default()
Set address and port assignment algorithm to default/standard.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
nat44_ei_outside_fib_t * outside_fibs
void nat44_ei_addresses_free(nat44_ei_address_t **addresses)
Aggregate type for a prefix.
static_always_inline void nat_validate_interface_counters(nat44_ei_main_t *nm, u32 sw_if_index)
vl_api_fib_path_type_t type
#define vec_del1(v, i)
Delete the element at index I.
#define NAT44_EI_INTERFACE_FLAG_IS_INSIDE
nat44_ei_lb_addr_port_t * locals
static void * ip4_next_header(ip4_header_t *i)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
VLIB buffer representation.
#define VLIB_REGISTER_NODE(x,...)