52 s =
format (s,
"NAT44_OUT2IN: sw_if_index %d, next index %d, session index %d",
63 s =
format (s,
"NAT44_OUT2IN_FAST: sw_if_index %d, next index %d",
76 m = t->
do_handoff ?
"next worker" :
"same worker";
94 s =
format (s,
"NAT44_OUT2IN_REASS: sw_if_index %d, next index %d, status %s",
96 t->
cached ?
"cached" :
"translated");
107 #define foreach_snat_out2in_error \ 108 _(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \ 109 _(OUT2IN_PACKETS, "Good out2in packets processed") \ 110 _(OUT_OF_PORTS, "Out of ports") \ 111 _(BAD_ICMP_TYPE, "unsupported ICMP type") \ 112 _(NO_TRANSLATION, "No translation") \ 113 _(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \ 114 _(DROP_FRAGMENT, "Drop fragment") \ 115 _(MAX_REASS, "Maximum reassemblies exceeded") \ 116 _(MAX_FRAG, "Maximum fragments per reassembly exceeded") 119 #define _(sym,str) SNAT_OUT2IN_ERROR_##sym, 126 #define _(sym,string) string, 153 static inline snat_session_t *
169 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
190 s->outside_address_index = ~0;
200 kv0.
key = s->in2out.as_u64;
206 kv0.
key = s->out2in.as_u64;
214 s->out2in.addr.as_u32,
218 s->in2out.fib_index);
226 icmp46_header_t *icmp0;
231 icmp46_header_t *inner_icmp0;
250 case SNAT_PROTOCOL_ICMP:
251 inner_icmp0 = (icmp46_header_t*)l4_header;
255 case SNAT_PROTOCOL_UDP:
256 case SNAT_PROTOCOL_TCP:
260 return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
285 u8 *p_dont_translate,
void *d,
void *e)
287 icmp46_header_t *icmp0;
292 snat_session_t *s0 = 0;
293 u8 dont_translate = 0;
308 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
332 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
344 (icmp0->type != ICMP4_echo_request || !is_addr_only)))
346 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
364 icmp0->type != ICMP4_echo_request &&
367 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
379 *p_value = s0->in2out;
380 *p_dont_translate = dont_translate;
382 *(snat_session_t**)d = s0;
403 u8 *p_dont_translate,
void *d,
void *e)
405 icmp46_header_t *icmp0;
410 u8 dont_translate = 0;
436 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
442 (icmp0->type != ICMP4_echo_request || !is_addr_only) &&
445 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
454 *p_dont_translate = dont_translate;
461 icmp46_header_t * icmp0,
475 icmp46_header_t *inner_icmp0;
477 u32 new_addr0, old_addr0;
478 u16 old_id0, new_id0;
486 &protocol, &sm0, &dont_translate, d, e);
495 if (checksum0 != 0 && checksum0 != 0xffff)
519 sum0 = icmp0->checksum;
540 sum0 = icmp0->checksum;
547 case SNAT_PROTOCOL_ICMP:
548 inner_icmp0 = (icmp46_header_t*)l4_header;
555 sum0 = icmp0->checksum;
560 case SNAT_PROTOCOL_UDP:
561 case SNAT_PROTOCOL_TCP:
566 sum0 = icmp0->checksum;
584 icmp46_header_t * icmp0,
590 snat_session_t ** p_s0)
592 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
593 next0, thread_index, p_s0, 0);
594 snat_session_t * s0 = *p_s0;
598 s0->last_heard = now;
605 s0->per_user_list_head_index,
611 static snat_session_t *
625 u32 old_addr, new_addr;
643 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
652 b->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
663 b->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
690 s->outside_address_index = ~0;
691 s->out2in.addr.as_u32 = old_addr;
692 s->out2in.fib_index = rx_fib_index;
693 s->in2out.addr.as_u32 = new_addr;
695 s->in2out.port = s->out2in.port = ip->
protocol;
700 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &s_kv, 1))
707 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &s_kv, 1))
730 static snat_session_t *
744 snat_session_t *s = 0;
747 u32 old_addr, new_addr;
749 u16 new_port, old_port;
767 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
775 b->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
805 s->outside_address_index = ~0;
812 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &s_kv, 1))
819 thread_index, &eh_key,
824 b->
error = node->
errors[SNAT_OUT2IN_ERROR_OUT_OF_PORTS];
828 key.
r_port = s->ext_host_nat_port = eh_key.
port;
836 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &s_kv, 1))
853 old_port = tcp->dst_port;
854 tcp->dst_port = s->in2out.port;
855 new_port = tcp->dst_port;
867 tcp->src_port = s->ext_host_nat_port;
877 udp->
src_port = s->ext_host_nat_port;
902 u32 n_left_from, * from, * to_next;
904 u32 pkts_processed = 0;
913 while (n_left_from > 0)
918 to_next, n_left_to_next);
920 while (n_left_from >= 4 && n_left_to_next >= 2)
926 u32 sw_if_index0, sw_if_index1;
929 u32 new_addr0, old_addr0;
930 u16 new_port0, old_port0;
931 u32 new_addr1, old_addr1;
932 u16 new_port1, old_port1;
935 icmp46_header_t * icmp0, * icmp1;
937 u32 rx_fib_index0, rx_fib_index1;
939 snat_session_t * s0 = 0, * s1 = 0;
957 to_next[0] = bi0 = from[0];
958 to_next[1] = bi1 = from[1];
973 icmp0 = (icmp46_header_t *) udp0;
983 ICMP4_time_exceeded_ttl_exceeded_in_transit,
994 thread_index, now, vm, node);
1003 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1004 next0, now, thread_index, &s0);
1030 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1035 if (proto0 != SNAT_PROTOCOL_UDP
1037 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
1085 old_port0 = tcp0->dst_port;
1086 tcp0->dst_port = s0->in2out.port;
1087 new_port0 = tcp0->dst_port;
1089 sum0 = tcp0->checksum;
1107 s0->last_heard = now;
1112 s0->per_user_index);
1114 s0->per_user_list_head_index,
1115 s0->per_user_index);
1136 icmp1 = (icmp46_header_t *) udp1;
1146 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1157 thread_index, now, vm, node);
1166 (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
1167 next1, now, thread_index, &s1);
1193 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1198 if (proto1 != SNAT_PROTOCOL_UDP
1200 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
1248 old_port1 = tcp1->dst_port;
1249 tcp1->dst_port = s1->in2out.port;
1250 new_port1 = tcp1->dst_port;
1252 sum1 = tcp1->checksum;
1270 s1->last_heard = now;
1275 s1->per_user_index);
1277 s1->per_user_list_head_index,
1278 s1->per_user_index);
1297 to_next, n_left_to_next,
1298 bi0, bi1, next0, next1);
1301 while (n_left_from > 0 && n_left_to_next > 0)
1309 u32 new_addr0, old_addr0;
1310 u16 new_port0, old_port0;
1313 icmp46_header_t * icmp0;
1317 snat_session_t * s0 = 0;
1326 n_left_to_next -= 1;
1335 icmp0 = (icmp46_header_t *) udp0;
1346 thread_index, now, vm, node);
1356 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1365 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1366 next0, now, thread_index, &s0);
1392 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1397 if (proto0 != SNAT_PROTOCOL_UDP
1399 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
1447 old_port0 = tcp0->dst_port;
1448 tcp0->dst_port = s0->in2out.port;
1449 new_port0 = tcp0->dst_port;
1451 sum0 = tcp0->checksum;
1469 s0->last_heard = now;
1474 s0->per_user_index);
1476 s0->per_user_list_head_index,
1477 s0->per_user_index);
1496 to_next, n_left_to_next,
1504 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
1511 .name =
"nat44-out2in",
1512 .vector_size =
sizeof (
u32),
1538 u32 n_left_from, *from, *to_next;
1540 u32 pkts_processed = 0;
1546 u32 *fragments_to_drop = 0;
1547 u32 *fragments_to_loopback = 0;
1553 while (n_left_from > 0)
1559 while (n_left_from > 0 && n_left_to_next > 0)
1561 u32 bi0, sw_if_index0, proto0, rx_fib_index0, new_addr0, old_addr0;
1566 nat_reass_ip4_t *reass0;
1571 snat_session_t * s0 = 0;
1572 u16 old_port0, new_port0;
1581 n_left_to_next -= 1;
1593 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_DROP_FRAGMENT];
1607 &fragments_to_drop);
1612 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_REASS];
1624 if (clib_bihash_search_8_8 (&per_thread_data->
out2in, &kv0, &value0))
1632 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1637 if (proto0 != SNAT_PROTOCOL_UDP
1639 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
1652 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1656 reass0->sess_index = s0 - per_thread_data->
sessions;
1657 reass0->thread_index = thread_index;
1663 reass0->sess_index = value0.
value;
1673 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_FRAG];
1681 reass0->sess_index);
1699 old_port0 = tcp0->dst_port;
1700 tcp0->dst_port = s0->in2out.port;
1701 new_port0 = tcp0->dst_port;
1703 sum0 = tcp0->checksum;
1722 s0->last_heard = now;
1727 s0->per_user_index);
1729 s0->per_user_list_head_index,
1730 s0->per_user_index);
1754 to_next, n_left_to_next,
1758 if (n_left_from == 0 &&
vec_len (fragments_to_loopback))
1783 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
1787 &node->
errors[SNAT_OUT2IN_ERROR_DROP_FRAGMENT],
1797 .name =
"nat44-out2in-reass",
1798 .vector_size =
sizeof (
u32),
1826 u32 n_left_from, * from, * to_next;
1828 u32 pkts_processed = 0;
1836 while (n_left_from > 0)
1841 to_next, n_left_to_next);
1843 while (n_left_from >= 4 && n_left_to_next >= 2)
1849 u32 sw_if_index0, sw_if_index1;
1853 u16 new_port0, old_port0, old_port1, new_port1;
1860 u32 rx_fib_index0, rx_fib_index1;
1861 icmp46_header_t * icmp0, * icmp1;
1878 to_next[0] = bi0 = from[0];
1879 to_next[1] = bi1 = from[1];
1883 n_left_to_next -= 2;
1898 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1909 icmp0 = (icmp46_header_t *) udp0;
1911 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
1912 rx_fib_index0, node, next0, thread_index,
1927 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1932 clib_net_to_host_u16(tcp0->dst), &new_addr0);
1937 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
1939 clib_net_to_host_u16 (tcp0->src),
1941 clib_net_to_host_u16 (tcp0->dst),
1944 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1962 ses0->
state = SNAT_SESSION_TCP_CLOSE_WAIT;
1963 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_LAST_ACK)
1966 old_port0 = tcp0->dst;
1967 tcp0->dst = new_port0;
1969 sum0 = tcp0->checksum;
2014 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2025 icmp1 = (icmp46_header_t *) udp1;
2027 next1 =
icmp_out2in(sm, b1, ip1, icmp1, sw_if_index1,
2028 rx_fib_index1, node, next1, thread_index,
2043 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2048 clib_net_to_host_u16(tcp1->dst), &new_addr1);
2053 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2055 clib_net_to_host_u16 (tcp1->src),
2057 clib_net_to_host_u16 (tcp1->dst),
2060 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2063 new_port1 = ses1->in_port;
2077 if (tcp1->flags &
TCP_FLAG_FIN && ses1->state == SNAT_SESSION_TCP_ESTABLISHED)
2078 ses1->state = SNAT_SESSION_TCP_CLOSE_WAIT;
2079 else if (tcp1->flags &
TCP_FLAG_ACK && ses1->state == SNAT_SESSION_TCP_LAST_ACK)
2082 old_port1 = tcp1->dst;
2083 tcp1->dst = new_port1;
2085 sum1 = tcp1->checksum;
2120 to_next, n_left_to_next,
2121 bi0, bi1, next0, next1);
2124 while (n_left_from > 0 && n_left_to_next > 0)
2133 u16 new_port0, old_port0;
2141 icmp46_header_t * icmp0;
2149 n_left_to_next -= 1;
2163 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2174 icmp0 = (icmp46_header_t *) udp0;
2176 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
2177 rx_fib_index0, node, next0, thread_index,
2192 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2197 clib_net_to_host_u16(tcp0->dst), &new_addr0);
2202 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2204 clib_net_to_host_u16 (tcp0->src),
2206 clib_net_to_host_u16 (tcp0->dst),
2209 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2227 ses0->
state = SNAT_SESSION_TCP_CLOSE_WAIT;
2228 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_LAST_ACK)
2231 old_port0 = tcp0->dst;
2232 tcp0->dst = new_port0;
2234 sum0 = tcp0->checksum;
2269 to_next, n_left_to_next,
2277 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
2284 .name =
"nat44-det-out2in",
2285 .vector_size =
sizeof (
u32),
2324 u8 *p_dont_translate,
void *d,
void *e)
2326 icmp46_header_t *icmp0;
2330 u8 dont_translate = 0;
2334 void *l4_header = 0;
2335 icmp46_header_t *inner_icmp0;
2347 protocol = SNAT_PROTOCOL_ICMP;
2362 case SNAT_PROTOCOL_ICMP:
2363 inner_icmp0 = (icmp46_header_t*)l4_header;
2368 case SNAT_PROTOCOL_UDP:
2369 case SNAT_PROTOCOL_TCP:
2374 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
2396 clib_net_to_host_u16(key0.
out_port), &new_addr0);
2408 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2412 clib_net_to_host_u16 (key0.
out_port),
2414 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2422 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
2430 *p_proto = protocol;
2433 p_value->
addr = new_addr0;
2437 *p_dont_translate = dont_translate;
2455 u32 n_left_from, *from, *to_next = 0;
2462 u32 n_left_to_next_worker = 0, *to_next_worker = 0;
2463 u32 next_worker_index = 0;
2464 u32 current_worker_index = ~0;
2481 while (n_left_from > 0)
2507 if (next_worker_index != current_worker_index)
2514 handoff_queue_elt_by_worker_index);
2518 current_worker_index = next_worker_index;
2522 to_next_worker[0] = bi0;
2524 n_left_to_next_worker--;
2526 if (n_left_to_next_worker == 0)
2530 current_worker_index = ~0;
2531 handoff_queue_elt_by_worker_index[next_worker_index] = 0;
2567 for (i = 0; i <
vec_len (handoff_queue_elt_by_worker_index); i++)
2569 if (handoff_queue_elt_by_worker_index[i])
2571 hf = handoff_queue_elt_by_worker_index[
i];
2579 handoff_queue_elt_by_worker_index[
i] = 0;
2584 congested_handoff_queue_by_worker_index[
i] =
2588 current_worker_index = ~0;
2594 .name =
"nat44-out2in-worker-handoff",
2595 .vector_size =
sizeof (
u32),
2613 u32 n_left_from, * from, * to_next;
2615 u32 pkts_processed = 0;
2622 while (n_left_from > 0)
2627 to_next, n_left_to_next);
2629 while (n_left_from > 0 && n_left_to_next > 0)
2637 u32 new_addr0, old_addr0;
2638 u16 new_port0, old_port0;
2641 icmp46_header_t * icmp0;
2652 n_left_to_next -= 1;
2659 icmp0 = (icmp46_header_t *) udp0;
2670 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2683 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
2684 rx_fib_index0, node, next0, ~0, 0, 0);
2694 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2699 new_port0 = sm0.
port;
2714 old_port0 = tcp0->dst_port;
2715 tcp0->dst_port = new_port0;
2717 sum0 = tcp0->checksum;
2738 sum0 = tcp0->checksum;
2762 to_next, n_left_to_next,
2770 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
2777 .name =
"nat44-out2in-fast",
2778 .vector_size =
sizeof (
u32),
vlib_node_registration_t snat_out2in_fast_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_fast_node)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
VLIB_NODE_FUNCTION_MULTIARCH(snat_out2in_node, snat_out2in_node_fn)
clib_bihash_16_8_t out2in_ed
sll srl srl sll sra u16x4 i
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...
static u8 * format_snat_out2in_fast_trace(u8 *s, va_list *args)
static u32 icmp_out2in_slow_path(snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0, vlib_node_runtime_t *node, u32 next0, f64 now, u32 thread_index, snat_session_t **p_s0)
static int ip4_header_bytes(ip4_header_t *i)
static f64 vlib_time_now(vlib_main_t *vm)
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.
int nat_ip4_reass_add_fragment(nat_reass_ip4_t *reass, u32 bi)
Cache fragment.
static void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
struct _vlib_node_registration vlib_node_registration_t
u32 icmp_match_out2in_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...
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
static snat_session_t * snat_out2in_lb(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, u32 rx_fib_index, u32 thread_index, f64 now, vlib_main_t *vm, vlib_node_runtime_t *node)
clib_bihash_16_8_t in2out_ed
int snat_static_mapping_match(snat_main_t *sm, snat_session_key_t match, snat_session_key_t *mapping, u8 by_external, u8 *is_addr_only, u8 *twice_nat)
Match NAT44 static mapping.
u32 buffer_index[VLIB_FRAME_SIZE]
vlib_error_t * errors
Vector of errors for this node.
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
struct _tcp_header tcp_header_t
static void snat_det_reverse(snat_det_map_t *dm, ip4_address_t *out_addr, u16 out_port, ip4_address_t *in_addr)
static snat_session_t * snat_out2in_unknown_proto(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, u32 rx_fib_index, u32 thread_index, f64 now, vlib_main_t *vm, vlib_node_runtime_t *node)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
#define static_always_inline
static uword ip4_header_checksum_is_valid(ip4_header_t *i)
vlib_node_registration_t snat_det_out2in_node
(constructor) VLIB_REGISTER_NODE (snat_det_out2in_node)
ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
ip4_address_t ext_host_addr
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
static void * ip4_next_header(ip4_header_t *i)
#define foreach_snat_out2in_error
static uword nat44_out2in_reass_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword snat_out2in_worker_handoff_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static int ip4_is_fragment(ip4_header_t *i)
snat_user_t * nat_user_get_or_create(snat_main_t *sm, ip4_address_t *addr, u32 fib_index, u32 thread_index)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
snat_det_session_t * sessions
static snat_det_map_t * snat_det_map_by_out(snat_main_t *sm, ip4_address_t *out_addr)
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
snat_static_mapping_t * static_mappings
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
void snat_ipfix_logging_nat44_ses_create(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 create event.
static vlib_frame_queue_elt_t * vlib_get_worker_handoff_queue_elt(u32 frame_queue_index, u32 vlib_worker_index, vlib_frame_queue_elt_t **handoff_queue_elt_by_worker_index)
clib_bihash_8_8_t static_mapping_by_external
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
vlib_node_registration_t snat_out2in_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_node)
#define SNAT_SESSION_FLAG_UNKNOWN_PROTO
static_always_inline void vnet_feature_next(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
static u32 icmp_out2in(snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0, vlib_node_runtime_t *node, u32 next0, u32 thread_index, void *d, void *e)
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
static snat_session_t * create_session_for_static_mapping(snat_main_t *sm, vlib_buffer_t *b0, snat_session_key_t in2out, snat_session_key_t out2in, vlib_node_runtime_t *node, u32 thread_index)
Create session for static mapping.
static_always_inline uword vlib_get_thread_index(void)
u8 nat_reass_is_drop_frag(u8 is_ip6)
Get status of virtual fragmentation reassembly.
#define CLIB_PREFETCH(addr, size, type)
#define vec_free(V)
Free vector's memory (no header).
void icmp4_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
deterministic NAT definitions
#define clib_warning(format, args...)
#define VLIB_BUFFER_IS_TRACED
#define clib_memcpy(a, b, c)
static int ip4_is_first_fragment(ip4_header_t *i)
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.
static u8 * format_nat44_out2in_reass_trace(u8 *s, va_list *args)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
snat_get_worker_function_t * worker_out2in_cb
static u32 ip_proto_to_snat_proto(u8 ip_proto)
snat_icmp_match_function_t * icmp_match_out2in_cb
#define SNAT_SESSION_FLAG_TWICE_NAT
static uword snat_det_out2in_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define VLIB_NODE_FLAG_TRACE
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
vlib_node_registration_t nat44_out2in_reass_node
(constructor) VLIB_REGISTER_NODE (nat44_out2in_reass_node)
snat_address_t * twice_nat_addresses
snat_session_t * nat_session_alloc_or_recycle(snat_main_t *sm, snat_user_t *u, u32 thread_index)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define vec_elt(v, i)
Get vector value at index i.
vlib_node_registration_t snat_out2in_worker_handoff_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_worker_handoff_node)
int snat_alloc_outside_address_and_port(snat_address_t *addresses, u32 fib_index, u32 thread_index, snat_session_key_t *k, u32 *address_indexp, u16 port_per_thread, u32 snat_thread_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static char * snat_out2in_error_strings[]
static_always_inline u8 is_interface_addr(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, u32 ip4_addr)
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 ip_csum_update(sum, old, new, type, field)
static_always_inline snat_out2in_error_t icmp_get_key(ip4_header_t *ip0, snat_session_key_t *p_key0)
static u8 * format_snat_out2in_trace(u8 *s, va_list *args)
nat_reass_ip4_t * nat_ip4_reass_find_or_create(ip4_address_t src, ip4_address_t dst, u16 frag_id, u8 proto, u8 reset_timeout, u32 **bi_to_drop)
Find or create reassembly.
static void vlib_put_frame_queue_elt(vlib_frame_queue_elt_t *hf)
static uword snat_out2in_fast_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static snat_det_session_t * snat_det_get_ses_by_out(snat_det_map_t *dm, ip4_address_t *in_addr, u64 out_key)
#define SNAT_SESSION_FLAG_STATIC_MAPPING
#define VLIB_REGISTER_NODE(x,...)
static vlib_thread_main_t * vlib_get_thread_main()
static uword snat_out2in_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static_always_inline void nat_send_all_to_node(vlib_main_t *vm, u32 *bi_vector, vlib_node_runtime_t *node, vlib_error_t *error, u32 next)
u16 flags
Copy of main node flags.
#define is_twice_nat_session(s)
Check if NAT session is twice NAT.
void nat_ip4_reass_get_frags(nat_reass_ip4_t *reass, u32 **bi)
Get cached fragments.
NAT plugin virtual fragmentation reassembly.
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static u8 maximum_sessions_exceeded(snat_main_t *sm, u32 thread_index)
snat_session_t * sessions
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
#define SNAT_SESSION_FLAG_LOAD_BALANCING
static u16 ip_csum_fold(ip_csum_t c)
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.
static u8 * format_snat_out2in_worker_handoff_trace(u8 *s, va_list *args)
static_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)