51 s =
format (s,
"SNAT_OUT2IN: sw_if_index %d, next index %d, session index %d",
62 s =
format (s,
"SNAT_OUT2IN_FAST: sw_if_index %d, next index %d",
75 m = t->
do_handoff ?
"next worker" :
"same worker";
86 #define foreach_snat_out2in_error \ 87 _(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \ 88 _(OUT2IN_PACKETS, "Good out2in packets processed") \ 89 _(BAD_ICMP_TYPE, "unsupported ICMP type") \ 90 _(NO_TRANSLATION, "No translation") 93 #define _(sym,str) SNAT_OUT2IN_ERROR_##sym, 100 #define _(sym,string) string, 126 static inline snat_session_t *
146 if (clib_bihash_search_8_8 (&sm->user_hash, &kv0, &value0))
149 pool_get (sm->per_thread_data[thread_index].users, u);
150 memset (u, 0,
sizeof (*u));
154 pool_get (sm->per_thread_data[thread_index].list_pool,
155 per_user_list_head_elt);
158 sm->per_thread_data[thread_index].list_pool;
163 kv0.
value = u - sm->per_thread_data[thread_index].users;
166 clib_bihash_add_del_8_8 (&sm->user_hash, &kv0, 1 );
169 kv0.
value = thread_index;
170 clib_bihash_add_del_8_8 (&sm->worker_by_in, &kv0, 1);
178 pool_get (sm->per_thread_data[thread_index].sessions, s);
179 memset (s, 0,
sizeof (*s));
181 s->outside_address_index = ~0;
186 pool_get (sm->per_thread_data[thread_index].list_pool,
187 per_user_translation_list_elt);
189 per_user_translation_list_elt -
190 sm->per_thread_data[thread_index].list_pool);
192 per_user_translation_list_elt->
value =
193 s - sm->per_thread_data[thread_index].sessions;
195 per_user_translation_list_elt - sm->per_thread_data[thread_index].list_pool;
199 s->per_user_list_head_index,
200 per_user_translation_list_elt -
201 sm->per_thread_data[thread_index].list_pool);
208 kv0.
key = s->in2out.as_u64;
209 kv0.
value = s - sm->per_thread_data[thread_index].sessions;
210 if (clib_bihash_add_del_8_8 (&sm->in2out, &kv0, 1 ))
213 kv0.
key = s->out2in.as_u64;
214 kv0.
value = s - sm->per_thread_data[thread_index].sessions;
216 if (clib_bihash_add_del_8_8 (&sm->out2in, &kv0, 1 ))
221 s->out2in.addr.as_u32,
225 s->in2out.fib_index);
233 icmp46_header_t *icmp0;
238 icmp46_header_t *inner_icmp0;
257 case SNAT_PROTOCOL_ICMP:
258 inner_icmp0 = (icmp46_header_t*)l4_header;
262 case SNAT_PROTOCOL_UDP:
263 case SNAT_PROTOCOL_TCP:
267 return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
291 u8 *p_dont_translate,
void *d,
void *e)
294 icmp46_header_t *icmp0;
299 snat_session_t *s0 = 0;
300 u8 dont_translate = 0;
316 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
324 if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
337 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
343 (icmp0->type != ICMP4_echo_request || !is_addr_only)))
345 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
363 icmp0->type != ICMP4_echo_request &&
366 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
378 *p_value = s0->in2out;
379 *p_dont_translate = dont_translate;
381 *(snat_session_t**)d = s0;
401 u8 *p_dont_translate,
void *d,
void *e)
404 icmp46_header_t *icmp0;
409 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;
485 next0_tmp = sm->icmp_match_out2in_cb(sm, node, thread_index, b0,
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;
607 s0->per_user_list_head_index,
623 u32 old_addr, new_addr;
631 if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
650 u32 n_left_from, * from, * to_next;
652 u32 pkts_processed = 0;
661 while (n_left_from > 0)
666 to_next, n_left_to_next);
668 while (n_left_from >= 4 && n_left_to_next >= 2)
674 u32 sw_if_index0, sw_if_index1;
677 u32 new_addr0, old_addr0;
678 u16 new_port0, old_port0;
679 u32 new_addr1, old_addr1;
680 u16 new_port1, old_port1;
683 icmp46_header_t * icmp0, * icmp1;
685 u32 rx_fib_index0, rx_fib_index1;
687 snat_session_t * s0 = 0, * s1 = 0;
705 to_next[0] = bi0 = from[0];
706 to_next[1] = bi1 = from[1];
718 icmp0 = (icmp46_header_t *) udp0;
721 rx_fib_index0 =
vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
728 ICMP4_time_exceeded_ttl_exceeded_in_transit,
745 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
746 next0, now, thread_index, &s0);
757 if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
763 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
768 if (proto0 != SNAT_PROTOCOL_UDP
770 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
780 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
802 old_port0 = tcp0->dst_port;
803 tcp0->dst_port = s0->in2out.port;
804 new_port0 = tcp0->dst_port;
806 sum0 = tcp0->checksum;
824 s0->last_heard = now;
833 s0->per_user_list_head_index,
847 t->
session_index = s0 - sm->per_thread_data[thread_index].sessions;
856 icmp1 = (icmp46_header_t *) udp1;
859 rx_fib_index1 =
vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
866 ICMP4_time_exceeded_ttl_exceeded_in_transit,
883 (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
884 next1, now, thread_index, &s1);
895 if (clib_bihash_search_8_8 (&sm->out2in, &kv1, &value1))
901 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
906 if (proto1 != SNAT_PROTOCOL_UDP
908 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
918 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
940 old_port1 = tcp1->dst_port;
941 tcp1->dst_port = s1->in2out.port;
942 new_port1 = tcp1->dst_port;
944 sum1 = tcp1->checksum;
962 s1->last_heard = now;
971 s1->per_user_list_head_index,
985 t->
session_index = s1 - sm->per_thread_data[thread_index].sessions;
992 to_next, n_left_to_next,
993 bi0, bi1, next0, next1);
996 while (n_left_from > 0 && n_left_to_next > 0)
1004 u32 new_addr0, old_addr0;
1005 u16 new_port0, old_port0;
1008 icmp46_header_t * icmp0;
1012 snat_session_t * s0 = 0;
1021 n_left_to_next -= 1;
1028 icmp0 = (icmp46_header_t *) udp0;
1031 rx_fib_index0 =
vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
1046 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1055 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1056 next0, now, thread_index, &s0);
1067 if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
1073 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1078 if (proto0 != SNAT_PROTOCOL_UDP
1080 != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client)))
1091 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1113 old_port0 = tcp0->dst_port;
1114 tcp0->dst_port = s0->in2out.port;
1115 new_port0 = tcp0->dst_port;
1117 sum0 = tcp0->checksum;
1135 s0->last_heard = now;
1142 s0->per_user_index);
1144 s0->per_user_list_head_index,
1145 s0->per_user_index);
1158 t->
session_index = s0 - sm->per_thread_data[thread_index].sessions;
1165 to_next, n_left_to_next,
1173 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
1180 .name =
"snat-out2in",
1181 .vector_size =
sizeof (
u32),
1209 u32 n_left_from, * from, * to_next;
1211 u32 pkts_processed = 0;
1219 while (n_left_from > 0)
1224 to_next, n_left_to_next);
1226 while (n_left_from >= 4 && n_left_to_next >= 2)
1232 u32 sw_if_index0, sw_if_index1;
1236 u16 new_port0, old_port0, old_port1, new_port1;
1243 u32 rx_fib_index0, rx_fib_index1;
1244 icmp46_header_t * icmp0, * icmp1;
1261 to_next[0] = bi0 = from[0];
1262 to_next[1] = bi1 = from[1];
1266 n_left_to_next -= 2;
1281 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1292 icmp0 = (icmp46_header_t *) udp0;
1294 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
1295 rx_fib_index0, node, next0, thread_index,
1310 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1315 clib_net_to_host_u16(tcp0->dst), &new_addr0);
1320 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
1322 clib_net_to_host_u16 (tcp0->src),
1324 clib_net_to_host_u16 (tcp0->dst),
1327 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1345 ses0->
state = SNAT_SESSION_TCP_CLOSE_WAIT;
1346 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_LAST_ACK)
1349 old_port0 = tcp0->dst;
1350 tcp0->dst = new_port0;
1352 sum0 = tcp0->checksum;
1397 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1408 icmp1 = (icmp46_header_t *) udp1;
1410 next1 =
icmp_out2in(sm, b1, ip1, icmp1, sw_if_index1,
1411 rx_fib_index1, node, next1, thread_index,
1426 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1431 clib_net_to_host_u16(tcp1->dst), &new_addr1);
1436 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
1438 clib_net_to_host_u16 (tcp1->src),
1440 clib_net_to_host_u16 (tcp1->dst),
1443 b1->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1446 new_port1 = ses1->in_port;
1460 if (tcp1->flags &
TCP_FLAG_FIN && ses1->state == SNAT_SESSION_TCP_ESTABLISHED)
1461 ses1->state = SNAT_SESSION_TCP_CLOSE_WAIT;
1462 else if (tcp1->flags &
TCP_FLAG_ACK && ses1->state == SNAT_SESSION_TCP_LAST_ACK)
1465 old_port1 = tcp1->dst;
1466 tcp1->dst = new_port1;
1468 sum1 = tcp1->checksum;
1503 to_next, n_left_to_next,
1504 bi0, bi1, next0, next1);
1507 while (n_left_from > 0 && n_left_to_next > 0)
1516 u16 new_port0, old_port0;
1524 icmp46_header_t * icmp0;
1532 n_left_to_next -= 1;
1546 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1557 icmp0 = (icmp46_header_t *) udp0;
1559 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
1560 rx_fib_index0, node, next0, thread_index,
1575 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1580 clib_net_to_host_u16(tcp0->dst), &new_addr0);
1585 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
1587 clib_net_to_host_u16 (tcp0->src),
1589 clib_net_to_host_u16 (tcp0->dst),
1592 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1610 ses0->
state = SNAT_SESSION_TCP_CLOSE_WAIT;
1611 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_LAST_ACK)
1614 old_port0 = tcp0->dst;
1615 tcp0->dst = new_port0;
1617 sum0 = tcp0->checksum;
1652 to_next, n_left_to_next,
1660 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
1667 .name =
"snat-det-out2in",
1668 .vector_size =
sizeof (
u32),
1705 u8 *p_dont_translate,
void *d,
void *e)
1708 icmp46_header_t *icmp0;
1712 u8 dont_translate = 0;
1716 void *l4_header = 0;
1717 icmp46_header_t *inner_icmp0;
1730 protocol = SNAT_PROTOCOL_ICMP;
1745 case SNAT_PROTOCOL_ICMP:
1746 inner_icmp0 = (icmp46_header_t*)l4_header;
1751 case SNAT_PROTOCOL_UDP:
1752 case SNAT_PROTOCOL_TCP:
1757 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
1779 clib_net_to_host_u16(key0.
out_port), &new_addr0);
1791 clib_warning(
"no match src %U:%d dst %U:%d for user %U",
1795 clib_net_to_host_u16 (key0.
out_port),
1797 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
1805 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
1813 *p_proto = protocol;
1816 p_value->
addr = new_addr0;
1817 p_value->
fib_index = sm->inside_fib_index;
1820 *p_dont_translate = dont_translate;
1838 u32 n_left_from, *from, *to_next = 0;
1845 u32 n_left_to_next_worker = 0, *to_next_worker = 0;
1846 u32 next_worker_index = 0;
1847 u32 current_worker_index = ~0;
1857 sm->first_worker_index + sm->num_workers - 1,
1864 while (n_left_from > 0)
1884 next_worker_index = sm->worker_out2in_cb(ip0, rx_fib_index0);
1890 if (next_worker_index != current_worker_index)
1897 handoff_queue_elt_by_worker_index);
1901 current_worker_index = next_worker_index;
1905 to_next_worker[0] = bi0;
1907 n_left_to_next_worker--;
1909 if (n_left_to_next_worker == 0)
1913 current_worker_index = ~0;
1914 handoff_queue_elt_by_worker_index[next_worker_index] = 0;
1950 for (i = 0; i <
vec_len (handoff_queue_elt_by_worker_index); i++)
1952 if (handoff_queue_elt_by_worker_index[i])
1954 hf = handoff_queue_elt_by_worker_index[
i];
1962 handoff_queue_elt_by_worker_index[
i] = 0;
1967 congested_handoff_queue_by_worker_index[
i] =
1971 current_worker_index = ~0;
1977 .name =
"snat-out2in-worker-handoff",
1978 .vector_size =
sizeof (
u32),
1996 u32 n_left_from, * from, * to_next;
1998 u32 pkts_processed = 0;
2005 while (n_left_from > 0)
2010 to_next, n_left_to_next);
2012 while (n_left_from > 0 && n_left_to_next > 0)
2020 u32 new_addr0, old_addr0;
2021 u16 new_port0, old_port0;
2024 icmp46_header_t * icmp0;
2035 n_left_to_next -= 1;
2042 icmp0 = (icmp46_header_t *) udp0;
2053 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2066 next0 =
icmp_out2in(sm, b0, ip0, icmp0, sw_if_index0,
2067 rx_fib_index0, node, next0, ~0, 0, 0);
2077 b0->
error = node->
errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
2082 new_port0 = sm0.
port;
2097 old_port0 = tcp0->dst_port;
2098 tcp0->dst_port = new_port0;
2100 sum0 = tcp0->checksum;
2121 sum0 = tcp0->checksum;
2145 to_next, n_left_to_next,
2153 SNAT_OUT2IN_ERROR_OUT2IN_PACKETS,
2160 .name =
"snat-out2in-fast",
2161 .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_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
VLIB_NODE_FUNCTION_MULTIARCH(snat_out2in_node, snat_out2in_node_fn)
u32 sessions_per_user_list_head_index
sll srl srl sll sra u16x4 i
static void clib_dlist_init(dlist_elt_t *pool, u32 index)
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)
static void snat_det_reverse(snat_det_map_t *dm, ip4_address_t *out_addr, u16 out_port, ip4_address_t *in_addr)
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_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)
static snat_det_map_t * snat_det_map_by_out(snat_main_t *sm, ip4_address_t *out_addr)
struct _vlib_node_registration vlib_node_registration_t
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.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
struct _tcp_header tcp_header_t
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.
static_always_inline u8 is_interface_addr(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, u32 ip4_addr)
static void * ip4_next_header(ip4_header_t *i)
#define foreach_snat_out2in_error
static uword snat_out2in_worker_handoff_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
deterministic NAT definitions
snat_det_session_t * sessions
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
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)
#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)
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).
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)
Match SNAT static mapping.
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)
#define CLIB_PREFETCH(addr, size, type)
void icmp4_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
#define clib_warning(format, args...)
#define VLIB_BUFFER_IS_TRACED
8 octet key, 8 octet key value pair
u32 icmp_match_out2in_det(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, 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 packet SNAT translation and create session if needed...
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static uword snat_det_out2in_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 icmp_match_out2in_slow(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, 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 packet SNAT translation and create session if needed...
#define VLIB_NODE_FLAG_TRACE
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
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 snat_det_session_t * snat_det_get_ses_by_out(snat_det_map_t *dm, ip4_address_t *in_addr, u64 out_key)
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.
static void snat_out2in_unknown_proto(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, u32 rx_fib_index)
vlib_node_registration_t snat_out2in_worker_handoff_node
(constructor) VLIB_REGISTER_NODE (snat_out2in_worker_handoff_node)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static char * snat_out2in_error_strings[]
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)
static void vlib_put_frame_queue_elt(vlib_frame_queue_elt_t *hf)
static u32 ip_proto_to_snat_proto(u8 ip_proto)
static uword snat_out2in_fast_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
#define VLIB_REGISTER_NODE(x,...)
u32 icmp_match_out2in_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, 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 packet SNAT translation.
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)
u16 flags
Copy of main node flags.
#define SNAT_SESSION_FLAG_STATIC_MAPPING
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
#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_IS_TRACED: trace this buffer.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
static u16 ip_csum_fold(ip_csum_t c)
static u8 * format_snat_out2in_worker_handoff_trace(u8 *s, va_list *args)