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, 154 static inline snat_session_t *
170 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
191 s->outside_address_index = ~0;
201 kv0.
key = s->in2out.as_u64;
207 kv0.
key = s->out2in.as_u64;
215 s->out2in.addr.as_u32,
219 s->in2out.fib_index);
227 icmp46_header_t *icmp0;
232 icmp46_header_t *inner_icmp0;
251 case SNAT_PROTOCOL_ICMP:
252 inner_icmp0 = (icmp46_header_t*)l4_header;
256 case SNAT_PROTOCOL_UDP:
257 case SNAT_PROTOCOL_TCP:
261 return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
271 icmp46_header_t *icmp0;
276 icmp46_header_t *inner_icmp0;
283 key0.
proto = IP_PROTOCOL_ICMP;
297 case SNAT_PROTOCOL_ICMP:
298 inner_icmp0 = (icmp46_header_t*)l4_header;
302 case SNAT_PROTOCOL_UDP:
303 case SNAT_PROTOCOL_TCP:
342 if (ip->
protocol == IP_PROTOCOL_ICMP)
347 else if (ip->
protocol == IP_PROTOCOL_UDP || ip->
protocol == IP_PROTOCOL_TCP)
368 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &kv, 1))
390 u8 *p_dont_translate,
void *d,
void *e)
392 icmp46_header_t *icmp0;
397 snat_session_t *s0 = 0;
398 u8 dont_translate = 0;
413 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
437 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
455 (icmp0->type != ICMP4_echo_request || !is_addr_only)))
457 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
475 icmp0->type != ICMP4_echo_request &&
478 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
492 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
499 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
516 *p_value = s0->in2out;
517 *p_dont_translate = dont_translate;
519 *(snat_session_t**)d = s0;
540 u8 *p_dont_translate,
void *d,
void *e)
542 icmp46_header_t *icmp0;
547 u8 dont_translate = 0;
573 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
579 (icmp0->type != ICMP4_echo_request || !is_addr_only) &&
582 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
591 *p_dont_translate = dont_translate;
598 icmp46_header_t * icmp0,
612 icmp46_header_t *inner_icmp0;
614 u32 new_addr0, old_addr0;
615 u16 old_id0, new_id0;
623 &protocol, &sm0, &dont_translate, d, e);
632 if (checksum0 != 0 && checksum0 != 0xffff)
647 if (icmp0->checksum == 0)
648 icmp0->checksum = 0xffff;
659 sum0 = icmp0->checksum;
680 sum0 = icmp0->checksum;
687 case SNAT_PROTOCOL_ICMP:
688 inner_icmp0 = (icmp46_header_t*)l4_header;
695 sum0 = icmp0->checksum;
700 case SNAT_PROTOCOL_UDP:
701 case SNAT_PROTOCOL_TCP:
706 sum0 = icmp0->checksum;
724 icmp46_header_t * icmp0,
730 snat_session_t ** p_s0)
732 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
733 next0, thread_index, p_s0, 0);
734 snat_session_t * s0 = *p_s0;
738 s0->last_heard = now;
745 s0->per_user_list_head_index,
751 static snat_session_t *
765 u32 old_addr, new_addr;
783 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
792 b->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
803 b->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
830 s->outside_address_index = ~0;
831 s->out2in.addr.as_u32 = old_addr;
832 s->out2in.fib_index = rx_fib_index;
833 s->in2out.addr.as_u32 = new_addr;
835 s->in2out.port = s->out2in.port = ip->
protocol;
840 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &s_kv, 1))
847 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &s_kv, 1))
870 static snat_session_t *
884 snat_session_t *s = 0;
887 u32 old_addr, new_addr;
889 u16 new_port, old_port;
907 if (!clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
915 b->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
945 s->outside_address_index = ~0;
952 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &s_kv, 1))
959 thread_index, &eh_key,
964 b->
error = node->
errors[SNAT_OUT2IN_ERROR_OUT_OF_PORTS];
968 key.
r_port = s->ext_host_nat_port = eh_key.
port;
976 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &s_kv, 1))
993 old_port = tcp->dst_port;
994 tcp->dst_port = s->in2out.port;
995 new_port = tcp->dst_port;
1007 tcp->src_port = s->ext_host_nat_port;
1017 udp->
src_port = s->ext_host_nat_port;
1026 s->last_heard = now;
1042 u32 n_left_from, * from, * to_next;
1044 u32 pkts_processed = 0;
1053 while (n_left_from > 0)
1058 to_next, n_left_to_next);
1060 while (n_left_from >= 4 && n_left_to_next >= 2)
1066 u32 sw_if_index0, sw_if_index1;
1069 u32 new_addr0, old_addr0;
1070 u16 new_port0, old_port0;
1071 u32 new_addr1, old_addr1;
1072 u16 new_port1, old_port1;
1075 icmp46_header_t * icmp0, * icmp1;
1077 u32 rx_fib_index0, rx_fib_index1;
1079 snat_session_t * s0 = 0, * s1 = 0;
1097 to_next[0] = bi0 = from[0];
1098 to_next[1] = bi1 = from[1];
1102 n_left_to_next -= 2;
1113 icmp0 = (icmp46_header_t *) udp0;
1123 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1134 thread_index, now, vm, node);
1144 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1145 next0, now, thread_index, &s0);
1171 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1178 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
1238 old_port0 = tcp0->dst_port;
1239 tcp0->dst_port = s0->in2out.port;
1240 new_port0 = tcp0->dst_port;
1242 sum0 = tcp0->checksum;
1260 s0->last_heard = now;
1265 s0->per_user_index);
1267 s0->per_user_list_head_index,
1268 s0->per_user_index);
1272 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
1289 icmp1 = (icmp46_header_t *) udp1;
1299 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1310 thread_index, now, vm, node);
1320 (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
1321 next1, now, thread_index, &s1);
1347 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1354 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
1414 old_port1 = tcp1->dst_port;
1415 tcp1->dst_port = s1->in2out.port;
1416 new_port1 = tcp1->dst_port;
1418 sum1 = tcp1->checksum;
1436 s1->last_heard = now;
1441 s1->per_user_index);
1443 s1->per_user_list_head_index,
1444 s1->per_user_index);
1448 && (b1->
flags & VLIB_BUFFER_IS_TRACED)))
1463 to_next, n_left_to_next,
1464 bi0, bi1, next0, next1);
1467 while (n_left_from > 0 && n_left_to_next > 0)
1475 u32 new_addr0, old_addr0;
1476 u16 new_port0, old_port0;
1479 icmp46_header_t * icmp0;
1483 snat_session_t * s0 = 0;
1492 n_left_to_next -= 1;
1501 icmp0 = (icmp46_header_t *) udp0;
1512 thread_index, now, vm, node);
1523 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1532 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1533 next0, now, thread_index, &s0);
1559 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1566 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
1626 old_port0 = tcp0->dst_port;
1627 tcp0->dst_port = s0->in2out.port;
1628 new_port0 = tcp0->dst_port;
1630 sum0 = tcp0->checksum;
1648 s0->last_heard = now;
1653 s0->per_user_index);
1655 s0->per_user_list_head_index,
1656 s0->per_user_index);
1660 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
1675 to_next, n_left_to_next,
1683 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
1690 .name =
"nat44-out2in",
1691 .vector_size =
sizeof (
u32),
1718 u32 n_left_from, *from, *to_next;
1720 u32 pkts_processed = 0;
1726 u32 *fragments_to_drop = 0;
1727 u32 *fragments_to_loopback = 0;
1733 while (n_left_from > 0)
1739 while (n_left_from > 0 && n_left_to_next > 0)
1741 u32 bi0, sw_if_index0, proto0, rx_fib_index0, new_addr0, old_addr0;
1746 nat_reass_ip4_t *reass0;
1751 snat_session_t * s0 = 0;
1752 u16 old_port0, new_port0;
1761 n_left_to_next -= 1;
1773 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_DROP_FRAGMENT];
1787 &fragments_to_drop);
1792 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_REASS];
1804 if (clib_bihash_search_8_8 (&per_thread_data->
out2in, &kv0, &value0))
1812 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1819 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
1844 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1848 reass0->sess_index = s0 - per_thread_data->
sessions;
1849 reass0->thread_index = thread_index;
1855 reass0->sess_index = value0.
value;
1865 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_MAX_FRAG];
1873 reass0->sess_index);
1891 old_port0 = tcp0->dst_port;
1892 tcp0->dst_port = s0->in2out.port;
1893 new_port0 = tcp0->dst_port;
1895 sum0 = tcp0->checksum;
1914 s0->last_heard = now;
1919 s0->per_user_index);
1921 s0->per_user_list_head_index,
1922 s0->per_user_index);
1926 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
1946 to_next, n_left_to_next,
1950 if (n_left_from == 0 &&
vec_len (fragments_to_loopback))
1975 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
1979 &node->
errors[SNAT_OUT2IN_ERROR_DROP_FRAGMENT],
1989 .name =
"nat44-out2in-reass",
1990 .vector_size =
sizeof (
u32),
2019 u32 n_left_from, * from, * to_next;
2021 u32 pkts_processed = 0;
2029 while (n_left_from > 0)
2034 to_next, n_left_to_next);
2036 while (n_left_from >= 4 && n_left_to_next >= 2)
2042 u32 sw_if_index0, sw_if_index1;
2046 u16 new_port0, old_port0, old_port1, new_port1;
2053 u32 rx_fib_index0, rx_fib_index1;
2054 icmp46_header_t * icmp0, * icmp1;
2071 to_next[0] = bi0 = from[0];
2072 to_next[1] = bi1 = from[1];
2076 n_left_to_next -= 2;
2091 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2102 icmp0 = (icmp46_header_t *) udp0;
2104 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
2105 rx_fib_index0, node, next0, thread_index,
2120 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2125 clib_net_to_host_u16(tcp0->dst), &new_addr0);
2130 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2132 clib_net_to_host_u16 (tcp0->src),
2134 clib_net_to_host_u16 (tcp0->dst),
2137 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2155 ses0->
state = SNAT_SESSION_TCP_CLOSE_WAIT;
2156 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_LAST_ACK)
2159 old_port0 = tcp0->dst;
2160 tcp0->dst = new_port0;
2162 sum0 = tcp0->checksum;
2182 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2207 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2218 icmp1 = (icmp46_header_t *) udp1;
2220 next1 =
icmp_out2in(sm, b1, ip1, icmp1, sw_if_index1,
2221 rx_fib_index1, node, next1, thread_index,
2236 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2241 clib_net_to_host_u16(tcp1->dst), &new_addr1);
2246 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2248 clib_net_to_host_u16 (tcp1->src),
2250 clib_net_to_host_u16 (tcp1->dst),
2253 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2256 new_port1 = ses1->in_port;
2270 if (tcp1->flags &
TCP_FLAG_FIN && ses1->state == SNAT_SESSION_TCP_ESTABLISHED)
2271 ses1->state = SNAT_SESSION_TCP_CLOSE_WAIT;
2272 else if (tcp1->flags &
TCP_FLAG_ACK && ses1->state == SNAT_SESSION_TCP_LAST_ACK)
2275 old_port1 = tcp1->dst;
2276 tcp1->dst = new_port1;
2278 sum1 = tcp1->checksum;
2298 && (b1->
flags & VLIB_BUFFER_IS_TRACED)))
2313 to_next, n_left_to_next,
2314 bi0, bi1, next0, next1);
2317 while (n_left_from > 0 && n_left_to_next > 0)
2326 u16 new_port0, old_port0;
2334 icmp46_header_t * icmp0;
2342 n_left_to_next -= 1;
2356 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2367 icmp0 = (icmp46_header_t *) udp0;
2369 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
2370 rx_fib_index0, node, next0, thread_index,
2385 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2390 clib_net_to_host_u16(tcp0->dst), &new_addr0);
2395 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2397 clib_net_to_host_u16 (tcp0->src),
2399 clib_net_to_host_u16 (tcp0->dst),
2402 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2420 ses0->
state = SNAT_SESSION_TCP_CLOSE_WAIT;
2421 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_LAST_ACK)
2424 old_port0 = tcp0->dst;
2425 tcp0->dst = new_port0;
2427 sum0 = tcp0->checksum;
2447 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2462 to_next, n_left_to_next,
2470 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
2477 .name =
"nat44-det-out2in",
2478 .vector_size =
sizeof (
u32),
2518 u8 *p_dont_translate,
void *d,
void *e)
2520 icmp46_header_t *icmp0;
2524 u8 dont_translate = 0;
2528 void *l4_header = 0;
2529 icmp46_header_t *inner_icmp0;
2541 protocol = SNAT_PROTOCOL_ICMP;
2556 case SNAT_PROTOCOL_ICMP:
2557 inner_icmp0 = (icmp46_header_t*)l4_header;
2562 case SNAT_PROTOCOL_UDP:
2563 case SNAT_PROTOCOL_TCP:
2568 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
2590 clib_net_to_host_u16(key0.
out_port), &new_addr0);
2602 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
2606 clib_net_to_host_u16 (key0.
out_port),
2608 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2616 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
2624 *p_proto = protocol;
2627 p_value->
addr = new_addr0;
2631 *p_dont_translate = dont_translate;
2649 u32 n_left_from, *from, *to_next = 0;
2656 u32 n_left_to_next_worker = 0, *to_next_worker = 0;
2657 u32 next_worker_index = 0;
2658 u32 current_worker_index = ~0;
2675 while (n_left_from > 0)
2701 if (next_worker_index != current_worker_index)
2708 handoff_queue_elt_by_worker_index);
2712 current_worker_index = next_worker_index;
2716 to_next_worker[0] = bi0;
2718 n_left_to_next_worker--;
2720 if (n_left_to_next_worker == 0)
2724 current_worker_index = ~0;
2725 handoff_queue_elt_by_worker_index[next_worker_index] = 0;
2745 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2761 for (i = 0; i <
vec_len (handoff_queue_elt_by_worker_index); i++)
2763 if (handoff_queue_elt_by_worker_index[i])
2765 hf = handoff_queue_elt_by_worker_index[
i];
2773 handoff_queue_elt_by_worker_index[
i] = 0;
2778 congested_handoff_queue_by_worker_index[
i] =
2782 current_worker_index = ~0;
2788 .name =
"nat44-out2in-worker-handoff",
2789 .vector_size =
sizeof (
u32),
2807 u32 n_left_from, * from, * to_next;
2809 u32 pkts_processed = 0;
2816 while (n_left_from > 0)
2821 to_next, n_left_to_next);
2823 while (n_left_from > 0 && n_left_to_next > 0)
2831 u32 new_addr0, old_addr0;
2832 u16 new_port0, old_port0;
2835 icmp46_header_t * icmp0;
2846 n_left_to_next -= 1;
2853 icmp0 = (icmp46_header_t *) udp0;
2864 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2877 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
2878 rx_fib_index0, node, next0, ~0, 0, 0);
2888 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2893 new_port0 = sm0.
port;
2908 old_port0 = tcp0->dst_port;
2909 tcp0->dst_port = new_port0;
2911 sum0 = tcp0->checksum;
2932 sum0 = tcp0->checksum;
2944 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2956 to_next, n_left_to_next,
2964 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
2971 .name =
"nat44-out2in-fast",
2972 .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
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)
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.
static void user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static)
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
static int next_src_nat(snat_main_t *sm, ip4_header_t *ip, u32 proto, u16 src_port, u32 thread_index)
#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.
#define VLIB_REGISTER_NODE(x,...)
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 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)
static void create_bypass_for_fwd(snat_main_t *sm, ip4_header_t *ip)
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)
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.
struct _vlib_node_registration vlib_node_registration_t
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
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 VLIB_NODE_FLAG_TRACE
#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 int icmp_get_ed_key(ip4_header_t *ip0, nat_ed_ses_key_t *p_key0)
static_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)