53 tag = t->
is_slow_path ?
"NAT44_IN2OUT_SLOW_PATH" :
"NAT44_IN2OUT_FAST_PATH";
55 s =
format (s,
"%s: sw_if_index %d, next index %d, session %d", tag,
67 s =
format (s,
"NAT44_IN2OUT_FAST: sw_if_index %d, next index %d",
81 m = t->
do_handoff ?
"next worker" :
"same worker";
99 s =
format (s,
"NAT44_IN2OUT_REASS: sw_if_index %d, next index %d, status %s",
101 t->
cached ?
"cached" :
"translated");
120 #define foreach_snat_in2out_error \ 121 _(UNSUPPORTED_PROTOCOL, "Unsupported protocol") \ 122 _(IN2OUT_PACKETS, "Good in2out packets processed") \ 123 _(OUT_OF_PORTS, "Out of ports") \ 124 _(BAD_OUTSIDE_FIB, "Outside VRF ID not found") \ 125 _(BAD_ICMP_TYPE, "unsupported ICMP type") \ 126 _(NO_TRANSLATION, "No translation") \ 127 _(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \ 128 _(DROP_FRAGMENT, "Drop fragment") \ 129 _(MAX_REASS, "Maximum reassemblies exceeded") \ 130 _(MAX_FRAG, "Maximum fragments per reassembly exceeded") 133 #define _(sym,str) SNAT_IN2OUT_ERROR_##sym, 140 #define _(sym,string) string, 203 if (sw_if_index == ~0)
213 if ((nat_interface_is_outside(i)) && (sw_if_index == i->sw_if_index))
224 u32 rx_fib_index0,
u32 thread_index)
258 u32 thread_index,
u32 sw_if_index)
266 key0.
port = src_port;
277 key0.
port = dst_port;
287 if ((nat_interface_is_inside(i)) && (sw_if_index == i->sw_if_index))
300 snat_session_t ** sessionp,
309 u32 address_index = ~0;
310 u32 outside_fib_index;
317 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
325 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_BAD_OUTSIDE_FIB];
328 outside_fib_index = p[0];
350 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_OUT_OF_PORTS];
367 s->outside_address_index = address_index;
371 s->out2in.fib_index = outside_fib_index;
377 kv0.
key = s->in2out.as_u64;
383 kv0.
key = s->out2in.as_u64;
392 s->out2in.addr.as_u32,
396 s->in2out.fib_index);
404 icmp46_header_t *icmp0;
409 icmp46_header_t *inner_icmp0;
428 case SNAT_PROTOCOL_ICMP:
429 inner_icmp0 = (icmp46_header_t*)l4_header;
433 case SNAT_PROTOCOL_UDP:
434 case SNAT_PROTOCOL_TCP:
438 return SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL;
448 icmp46_header_t *icmp0;
453 icmp46_header_t *inner_icmp0;
460 key0.
proto = IP_PROTOCOL_ICMP;
474 case SNAT_PROTOCOL_ICMP:
475 inner_icmp0 = (icmp46_header_t*)l4_header;
479 case SNAT_PROTOCOL_UDP:
480 case SNAT_PROTOCOL_TCP:
485 return SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL;
502 if (ip->
protocol == IP_PROTOCOL_ICMP)
507 else if (ip->
protocol == IP_PROTOCOL_UDP || ip->
protocol == IP_PROTOCOL_TCP)
527 if (!clib_bihash_search_16_8 (&sm->
in2out_ed, &kv, &value))
528 return value.
value == ~0ULL;
551 u8 *p_dont_translate,
void *d,
void *e)
553 icmp46_header_t *icmp0;
557 snat_session_t *s0 = 0;
558 u8 dont_translate = 0;
584 ip0, SNAT_PROTOCOL_ICMP, key0.
port, key0.
port, thread_index, sw_if_index0)))
593 ip0, SNAT_PROTOCOL_ICMP, rx_fib_index0, thread_index)))
602 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
607 next0 =
slow_path (sm, b0, ip0, rx_fib_index0, &key0,
608 &s0, node, next0, thread_index);
616 icmp0->type != ICMP4_echo_reply &&
619 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
633 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
640 if (!clib_bihash_search_16_8 (&sm->
in2out_ed, &s_kv, &s_value))
657 *p_value = s0->out2in;
658 *p_dont_translate = dont_translate;
660 *(snat_session_t**)d = s0;
681 u8 *p_dont_translate,
void *d,
void *e)
683 icmp46_header_t *icmp0;
688 u8 dont_translate = 0;
709 IP_PROTOCOL_ICMP, rx_fib_index0)))
721 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
727 (icmp0->type != ICMP4_echo_reply || !is_addr_only) &&
730 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
739 *p_dont_translate = dont_translate;
746 icmp46_header_t * icmp0,
760 icmp46_header_t *inner_icmp0;
762 u32 new_addr0, old_addr0;
763 u16 old_id0, new_id0;
771 &protocol, &sm0, &dont_translate, d, e);
796 if (icmp0->checksum == 0)
797 icmp0->checksum = 0xffff;
808 sum0 = icmp0->checksum;
829 sum0 = icmp0->checksum;
836 case SNAT_PROTOCOL_ICMP:
837 inner_icmp0 = (icmp46_header_t*)l4_header;
844 sum0 = icmp0->checksum;
849 case SNAT_PROTOCOL_UDP:
850 case SNAT_PROTOCOL_TCP:
855 sum0 = icmp0->checksum;
895 u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si;
896 u16 new_dst_port0, old_dst_port0;
908 new_dst_port0 = sm0.
port;
924 new_dst_addr0 = s0->in2out.addr.as_u32;
925 new_dst_port0 = s0->in2out.port;
940 old_dst_port0 = tcp0->dst;
945 tcp0->dst = new_dst_port0;
946 sum0 = tcp0->checksum;
963 sum0 = tcp0->checksum;
978 icmp46_header_t * icmp0)
982 u32 new_dst_addr0 = 0, old_dst_addr0, si, ti = 0;
991 key0.
port = icmp_id0;
1017 new_dst_addr0 = s0->in2out.addr.as_u32;
1020 sum0 = icmp0->checksum;
1043 icmp46_header_t * icmp0,
1050 snat_session_t ** p_s0)
1052 next0 =
icmp_in2out(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
1053 next0, thread_index, p_s0, 0);
1054 snat_session_t * s0 = *p_s0;
1061 s0->last_heard = now;
1066 s0->per_user_index);
1068 s0->per_user_list_head_index,
1069 s0->per_user_index);
1078 u32 old_addr, new_addr = 0, ti = 0;
1096 if (clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
1128 static snat_session_t *
1142 u32 old_addr, new_addr = 0;
1147 u32 elt_index, head_index, ses_index;
1150 u32 address_index = ~0;
1165 if (!clib_bihash_search_16_8 (&sm->
in2out_ed, &s_kv, &s_value))
1174 b->
error = node->
errors[SNAT_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
1205 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
1209 elt_index = head->
next;
1211 ses_index = elt->
value;
1212 while (ses_index != ~0)
1215 elt_index = elt->
next;
1217 ses_index = elt->
value;
1222 address_index = s->outside_address_index;
1228 if (clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
1241 if (clib_bihash_search_16_8 (&sm->
out2in_ed, &s_kv, &s_value))
1261 s->outside_address_index = address_index;
1262 s->out2in.addr.as_u32 = new_addr;
1264 s->in2out.addr.as_u32 = old_addr;
1265 s->in2out.fib_index = rx_fib_index;
1266 s->in2out.port = s->out2in.port = ip->
protocol;
1279 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &s_kv, 1))
1286 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &s_kv, 1))
1296 s->last_heard = now;
1314 static snat_session_t *
1328 snat_session_t *s = 0;
1330 u32 old_addr, new_addr;
1331 u16 new_port, old_port;
1348 if (!clib_bihash_search_16_8 (&sm->
in2out_ed, &s_kv, &s_value))
1350 if (s_value.
value == ~0ULL)
1358 b->
error = node->
errors[SNAT_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
1388 s->outside_address_index = ~0;
1396 if (clib_bihash_add_del_16_8 (&sm->
in2out_ed, &s_kv, 1))
1404 if (clib_bihash_add_del_16_8 (&sm->
out2in_ed, &s_kv, 1))
1420 old_port = tcp->src_port;
1421 tcp->src_port = s->out2in.port;
1422 new_port = tcp->src_port;
1424 sum = tcp->checksum;
1434 tcp->dst_port = s->ext_host_port;
1454 s->last_heard = now;
1468 int is_output_feature)
1470 u32 n_left_from, * from, * to_next;
1472 u32 pkts_processed = 0;
1475 u32 stats_node_index;
1485 while (n_left_from > 0)
1490 to_next, n_left_to_next);
1492 while (n_left_from >= 4 && n_left_to_next >= 2)
1497 u32 sw_if_index0, sw_if_index1;
1500 u32 new_addr0, old_addr0, new_addr1, old_addr1;
1501 u16 old_port0, new_port0, old_port1, new_port1;
1504 icmp46_header_t * icmp0, * icmp1;
1506 u32 rx_fib_index0, rx_fib_index1;
1508 snat_session_t * s0 = 0, * s1 = 0;
1510 u32 iph_offset0 = 0, iph_offset1 = 0;
1527 to_next[0] = bi0 = from[0];
1528 to_next[1] = bi1 = from[1];
1532 n_left_to_next -= 2;
1537 if (is_output_feature)
1538 iph_offset0 =
vnet_buffer (b0)->ip.save_rewrite_length;
1545 icmp0 = (icmp46_header_t *) udp0;
1557 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1571 thread_index, now, vm, node);
1580 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0,
1581 node, next0, now, thread_index, &s0);
1587 if (is_output_feature)
1593 if (
PREDICT_FALSE (proto0 == ~0 || proto0 == SNAT_PROTOCOL_ICMP))
1618 if (is_output_feature)
1627 ip0, proto0, rx_fib_index0, thread_index)))
1631 next0 =
slow_path (sm, b0, ip0, rx_fib_index0, &key0,
1632 &s0, node, next0, thread_index);
1649 thread_index, now, vm, node);
1668 b0->
flags |= VNET_BUFFER_F_IS_NATED;
1673 if (!is_output_feature)
1684 old_port0 = tcp0->src_port;
1685 tcp0->src_port = s0->out2in.port;
1686 new_port0 = tcp0->src_port;
1688 sum0 = tcp0->checksum;
1705 s0->last_heard = now;
1710 s0->per_user_index);
1712 s0->per_user_list_head_index,
1713 s0->per_user_index);
1717 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
1731 if (is_output_feature)
1732 iph_offset1 =
vnet_buffer (b1)->ip.save_rewrite_length;
1739 icmp1 = (icmp46_header_t *) udp1;
1749 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1763 thread_index, now, vm, node);
1772 (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
1773 next1, now, thread_index, &s1);
1779 if (is_output_feature)
1785 if (
PREDICT_FALSE (proto1 == ~0 || proto1 == SNAT_PROTOCOL_ICMP))
1810 if (is_output_feature)
1819 ip1, proto1, rx_fib_index1, thread_index)))
1823 next1 =
slow_path (sm, b1, ip1, rx_fib_index1, &key1,
1824 &s1, node, next1, thread_index);
1841 thread_index, now, vm, node);
1860 b1->
flags |= VNET_BUFFER_F_IS_NATED;
1865 if (!is_output_feature)
1876 old_port1 = tcp1->src_port;
1877 tcp1->src_port = s1->out2in.port;
1878 new_port1 = tcp1->src_port;
1880 sum1 = tcp1->checksum;
1897 s1->last_heard = now;
1902 s1->per_user_index);
1904 s1->per_user_list_head_index,
1905 s1->per_user_index);
1909 && (b1->
flags & VLIB_BUFFER_IS_TRACED)))
1924 to_next, n_left_to_next,
1925 bi0, bi1, next0, next1);
1928 while (n_left_from > 0 && n_left_to_next > 0)
1936 u32 new_addr0, old_addr0;
1937 u16 old_port0, new_port0;
1940 icmp46_header_t * icmp0;
1944 snat_session_t * s0 = 0;
1946 u32 iph_offset0 = 0;
1954 n_left_to_next -= 1;
1959 if (is_output_feature)
1960 iph_offset0 =
vnet_buffer (b0)->ip.save_rewrite_length;
1967 icmp0 = (icmp46_header_t *) udp0;
1977 ICMP4_time_exceeded_ttl_exceeded_in_transit,
1991 thread_index, now, vm, node);
2000 (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
2001 next0, now, thread_index, &s0);
2007 if (is_output_feature)
2013 if (
PREDICT_FALSE (proto0 == ~0 || proto0 == SNAT_PROTOCOL_ICMP))
2038 if (is_output_feature)
2047 ip0, proto0, rx_fib_index0, thread_index)))
2051 next0 =
slow_path (sm, b0, ip0, rx_fib_index0, &key0,
2052 &s0, node, next0, thread_index);
2070 thread_index, now, vm, node);
2089 b0->
flags |= VNET_BUFFER_F_IS_NATED;
2094 if (!is_output_feature)
2105 old_port0 = tcp0->src_port;
2106 tcp0->src_port = s0->out2in.port;
2107 new_port0 = tcp0->src_port;
2109 sum0 = tcp0->checksum;
2126 s0->last_heard = now;
2131 s0->per_user_index);
2133 s0->per_user_list_head_index,
2134 s0->per_user_index);
2138 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2154 to_next, n_left_to_next,
2162 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
2177 .name =
"nat44-in2out",
2178 .vector_size =
sizeof (
u32),
2211 .name =
"nat44-in2out-output",
2212 .vector_size =
sizeof (
u32),
2246 .name =
"nat44-in2out-slowpath",
2247 .vector_size =
sizeof (
u32),
2281 .name =
"nat44-in2out-output-slowpath",
2282 .vector_size =
sizeof (
u32),
2313 u32 n_left_from, * from, * to_next;
2315 u32 pkts_processed = 0;
2325 while (n_left_from > 0)
2330 to_next, n_left_to_next);
2332 while (n_left_from > 0 && n_left_to_next > 0)
2348 n_left_to_next -= 1;
2367 to_next, n_left_to_next,
2375 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
2382 .name =
"nat44-hairpinning",
2383 .vector_size =
sizeof (
u32),
2406 snat_session_t * s0;
2409 u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si;
2410 u16 new_dst_port0, old_dst_port0;
2426 new_dst_port0 = sm0.
port;
2441 new_dst_addr0 = s0->in2out.addr.as_u32;
2442 new_dst_port0 = s0->in2out.port;
2457 old_dst_port0 = dport;
2464 tcp0->dst = new_dst_port0;
2465 sum0 = tcp0->checksum;
2483 sum0 = tcp0->checksum;
2497 u32 n_left_from, *from, *to_next;
2499 u32 pkts_processed = 0;
2505 u32 *fragments_to_drop = 0;
2506 u32 *fragments_to_loopback = 0;
2512 while (n_left_from > 0)
2518 while (n_left_from > 0 && n_left_to_next > 0)
2520 u32 bi0, sw_if_index0, proto0, rx_fib_index0, new_addr0, old_addr0;
2525 nat_reass_ip4_t *reass0;
2530 snat_session_t * s0 = 0;
2531 u16 old_port0, new_port0;
2540 n_left_to_next -= 1;
2552 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_DROP_FRAGMENT];
2566 &fragments_to_drop);
2571 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_MAX_REASS];
2583 if (clib_bihash_search_8_8 (&per_thread_data->
in2out, &kv0, &value0))
2586 ip0, proto0, rx_fib_index0, thread_index)))
2589 next0 =
slow_path (sm, b0, ip0, rx_fib_index0, &key0,
2590 &s0, node, next0, thread_index);
2595 reass0->sess_index = s0 - per_thread_data->
sessions;
2601 reass0->sess_index = value0.
value;
2611 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_MAX_FRAG];
2619 reass0->sess_index);
2637 old_port0 = tcp0->src_port;
2638 tcp0->src_port = s0->out2in.port;
2639 new_port0 = tcp0->src_port;
2641 sum0 = tcp0->checksum;
2660 s0->ext_host_port, proto0);
2663 s0->last_heard = now;
2668 s0->per_user_index);
2670 s0->per_user_list_head_index,
2671 s0->per_user_index);
2675 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2695 to_next, n_left_to_next,
2699 if (n_left_from == 0 &&
vec_len (fragments_to_loopback))
2724 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
2728 &node->
errors[SNAT_IN2OUT_ERROR_DROP_FRAGMENT],
2738 .name =
"nat44-in2out-reass",
2739 .vector_size =
sizeof (
u32),
2767 u32 n_left_from, * from, * to_next;
2769 u32 pkts_processed = 0;
2778 while (n_left_from > 0)
2783 to_next, n_left_to_next);
2785 while (n_left_from >= 4 && n_left_to_next >= 2)
2790 u32 sw_if_index0, sw_if_index1;
2794 u16 old_port0, new_port0, lo_port0, i0;
2795 u16 old_port1, new_port1, lo_port1, i1;
2802 u32 rx_fib_index0, rx_fib_index1;
2803 icmp46_header_t * icmp0, * icmp1;
2820 to_next[0] = bi0 = from[0];
2821 to_next[1] = bi1 = from[1];
2825 n_left_to_next -= 2;
2843 ICMP4_time_exceeded_ttl_exceeded_in_transit,
2854 icmp0 = (icmp46_header_t *) udp0;
2856 next0 =
icmp_in2out(sm, b0, ip0, icmp0, sw_if_index0,
2857 rx_fib_index0, node, next0, thread_index,
2868 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
2882 key0.
out_port = clib_host_to_net_u16 (lo_port0 +
2883 ((i0 + clib_net_to_host_u16 (tcp0->src)) % dm0->
ports_per_host));
2897 ICMP4_destination_unreachable_destination_unreachable_host,
2919 ses0->
state = SNAT_SESSION_TCP_SYN_SENT;
2920 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_SYN_SENT)
2921 ses0->
state = SNAT_SESSION_TCP_ESTABLISHED;
2922 else if (tcp0->flags &
TCP_FLAG_FIN && ses0->
state == SNAT_SESSION_TCP_ESTABLISHED)
2923 ses0->
state = SNAT_SESSION_TCP_FIN_WAIT;
2924 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_FIN_WAIT)
2926 else if (tcp0->flags &
TCP_FLAG_FIN && ses0->
state == SNAT_SESSION_TCP_CLOSE_WAIT)
2927 ses0->
state = SNAT_SESSION_TCP_LAST_ACK;
2928 else if (tcp0->flags == 0 && ses0->
state == SNAT_SESSION_UNKNOWN)
2929 ses0->
state = SNAT_SESSION_TCP_ESTABLISHED;
2931 old_port0 = tcp0->src;
2932 tcp0->src = new_port0;
2934 sum0 = tcp0->checksum;
2945 ses0->
state = SNAT_SESSION_UDP_ACTIVE;
2953 case SNAT_SESSION_UDP_ACTIVE:
2956 case SNAT_SESSION_TCP_SYN_SENT:
2957 case SNAT_SESSION_TCP_FIN_WAIT:
2958 case SNAT_SESSION_TCP_CLOSE_WAIT:
2959 case SNAT_SESSION_TCP_LAST_ACK:
2962 case SNAT_SESSION_TCP_ESTABLISHED:
2969 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
2993 ICMP4_time_exceeded_ttl_exceeded_in_transit,
3004 icmp1 = (icmp46_header_t *) udp1;
3006 next1 =
icmp_in2out(sm, b1, ip1, icmp1, sw_if_index1,
3007 rx_fib_index1, node, next1, thread_index,
3018 b1->
error = node->
errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
3032 key1.
out_port = clib_host_to_net_u16 (lo_port1 +
3033 ((i1 + clib_net_to_host_u16 (tcp1->src)) % dm1->
ports_per_host));
3047 ICMP4_destination_unreachable_destination_unreachable_host,
3054 new_port1 = ses1->out.out_port;
3069 ses1->state = SNAT_SESSION_TCP_SYN_SENT;
3070 else if (tcp1->flags &
TCP_FLAG_ACK && ses1->state == SNAT_SESSION_TCP_SYN_SENT)
3071 ses1->state = SNAT_SESSION_TCP_ESTABLISHED;
3072 else if (tcp1->flags &
TCP_FLAG_FIN && ses1->state == SNAT_SESSION_TCP_ESTABLISHED)
3073 ses1->state = SNAT_SESSION_TCP_FIN_WAIT;
3074 else if (tcp1->flags &
TCP_FLAG_ACK && ses1->state == SNAT_SESSION_TCP_FIN_WAIT)
3076 else if (tcp1->flags &
TCP_FLAG_FIN && ses1->state == SNAT_SESSION_TCP_CLOSE_WAIT)
3077 ses1->state = SNAT_SESSION_TCP_LAST_ACK;
3078 else if (tcp1->flags == 0 && ses1->state == SNAT_SESSION_UNKNOWN)
3079 ses1->state = SNAT_SESSION_TCP_ESTABLISHED;
3081 old_port1 = tcp1->src;
3082 tcp1->src = new_port1;
3084 sum1 = tcp1->checksum;
3095 ses1->state = SNAT_SESSION_UDP_ACTIVE;
3103 case SNAT_SESSION_UDP_ACTIVE:
3106 case SNAT_SESSION_TCP_SYN_SENT:
3107 case SNAT_SESSION_TCP_FIN_WAIT:
3108 case SNAT_SESSION_TCP_CLOSE_WAIT:
3109 case SNAT_SESSION_TCP_LAST_ACK:
3112 case SNAT_SESSION_TCP_ESTABLISHED:
3119 && (b1->
flags & VLIB_BUFFER_IS_TRACED)))
3135 to_next, n_left_to_next,
3136 bi0, bi1, next0, next1);
3139 while (n_left_from > 0 && n_left_to_next > 0)
3148 u16 old_port0, new_port0, lo_port0, i0;
3156 icmp46_header_t * icmp0;
3164 n_left_to_next -= 1;
3179 ICMP4_time_exceeded_ttl_exceeded_in_transit,
3190 icmp0 = (icmp46_header_t *) udp0;
3192 next0 =
icmp_in2out(sm, b0, ip0, icmp0, sw_if_index0,
3193 rx_fib_index0, node, next0, thread_index,
3204 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
3218 key0.
out_port = clib_host_to_net_u16 (lo_port0 +
3219 ((i0 + clib_net_to_host_u16 (tcp0->src)) % dm0->
ports_per_host));
3233 ICMP4_destination_unreachable_destination_unreachable_host,
3255 ses0->
state = SNAT_SESSION_TCP_SYN_SENT;
3256 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_SYN_SENT)
3257 ses0->
state = SNAT_SESSION_TCP_ESTABLISHED;
3258 else if (tcp0->flags &
TCP_FLAG_FIN && ses0->
state == SNAT_SESSION_TCP_ESTABLISHED)
3259 ses0->
state = SNAT_SESSION_TCP_FIN_WAIT;
3260 else if (tcp0->flags &
TCP_FLAG_ACK && ses0->
state == SNAT_SESSION_TCP_FIN_WAIT)
3262 else if (tcp0->flags &
TCP_FLAG_FIN && ses0->
state == SNAT_SESSION_TCP_CLOSE_WAIT)
3263 ses0->
state = SNAT_SESSION_TCP_LAST_ACK;
3264 else if (tcp0->flags == 0 && ses0->
state == SNAT_SESSION_UNKNOWN)
3265 ses0->
state = SNAT_SESSION_TCP_ESTABLISHED;
3267 old_port0 = tcp0->src;
3268 tcp0->src = new_port0;
3270 sum0 = tcp0->checksum;
3281 ses0->
state = SNAT_SESSION_UDP_ACTIVE;
3289 case SNAT_SESSION_UDP_ACTIVE:
3292 case SNAT_SESSION_TCP_SYN_SENT:
3293 case SNAT_SESSION_TCP_FIN_WAIT:
3294 case SNAT_SESSION_TCP_CLOSE_WAIT:
3295 case SNAT_SESSION_TCP_LAST_ACK:
3298 case SNAT_SESSION_TCP_ESTABLISHED:
3305 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
3321 to_next, n_left_to_next,
3329 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
3336 .name =
"nat44-det-in2out",
3337 .vector_size =
sizeof (
u32),
3376 u8 *p_dont_translate,
void *d,
void *e)
3378 icmp46_header_t *icmp0;
3383 u8 dont_translate = 0;
3387 void *l4_header = 0;
3388 icmp46_header_t *inner_icmp0;
3403 protocol = SNAT_PROTOCOL_ICMP;
3415 case SNAT_PROTOCOL_ICMP:
3416 inner_icmp0 = (icmp46_header_t*)l4_header;
3420 case SNAT_PROTOCOL_UDP:
3421 case SNAT_PROTOCOL_TCP:
3425 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
3437 IP_PROTOCOL_ICMP, rx_fib_index0)))
3443 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
3456 IP_PROTOCOL_ICMP, rx_fib_index0)))
3461 if (icmp0->type != ICMP4_echo_request)
3463 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
3469 key0.
out_port = clib_host_to_net_u16 (lo_port0 +
3481 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_OUT_OF_PORTS];
3489 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
3496 ses0->
state = SNAT_SESSION_ICMP_ACTIVE;
3500 *p_proto = protocol;
3503 p_value->
addr = new_addr0;
3507 *p_dont_translate = dont_translate;
3526 u32 n_left_from, *from, *to_next = 0;
3533 u32 n_left_to_next_worker = 0, *to_next_worker = 0;
3534 u32 next_worker_index = 0;
3535 u32 current_worker_index = ~0;
3565 while (n_left_from > 0)
3591 if (next_worker_index != current_worker_index)
3598 handoff_queue_elt_by_worker_index);
3602 current_worker_index = next_worker_index;
3606 to_next_worker[0] = bi0;
3608 n_left_to_next_worker--;
3610 if (n_left_to_next_worker == 0)
3614 current_worker_index = ~0;
3615 handoff_queue_elt_by_worker_index[next_worker_index] = 0;
3635 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
3651 for (i = 0; i <
vec_len (handoff_queue_elt_by_worker_index); i++)
3653 if (handoff_queue_elt_by_worker_index[i])
3655 hf = handoff_queue_elt_by_worker_index[
i];
3663 handoff_queue_elt_by_worker_index[
i] = 0;
3668 congested_handoff_queue_by_worker_index[
i] =
3672 current_worker_index = ~0;
3686 .name =
"nat44-in2out-worker-handoff",
3687 .vector_size =
sizeof (
u32),
3711 .name =
"nat44-in2out-output-worker-handoff",
3712 .vector_size =
sizeof (
u32),
3755 u32 n_left_from, * from, * to_next;
3757 u32 pkts_processed = 0;
3764 while (n_left_from > 0)
3769 to_next, n_left_to_next);
3771 while (n_left_from > 0 && n_left_to_next > 0)
3785 n_left_to_next -= 1;
3796 if (proto0 == SNAT_PROTOCOL_TCP || proto0 == SNAT_PROTOCOL_UDP)
3803 else if (proto0 == SNAT_PROTOCOL_ICMP)
3821 to_next, n_left_to_next,
3829 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
3836 .name =
"nat44-hairpin-dst",
3837 .vector_size =
sizeof (
u32),
3856 u32 n_left_from, * from, * to_next;
3858 u32 pkts_processed = 0;
3865 while (n_left_from > 0)
3870 to_next, n_left_to_next);
3872 while (n_left_from > 0 && n_left_to_next > 0)
3886 n_left_to_next -= 1;
3895 if ((nat_interface_is_inside(i)) && (sw_if_index0 == i->sw_if_index))
3897 if (PREDICT_FALSE ((vnet_buffer (b0)->snat.flags) &
3898 SNAT_FLAG_HAIRPINNING))
3900 if (PREDICT_TRUE (sm->num_workers > 1))
3901 next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH;
3903 next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT;
3913 to_next, n_left_to_next,
3921 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
3923 return frame->n_vectors;
3928 .name =
"nat44-hairpin-src",
3929 .vector_size =
sizeof (
u32),
3950 u32 n_left_from, * from, * to_next;
3952 u32 pkts_processed = 0;
3954 u32 stats_node_index;
3962 while (n_left_from > 0)
3967 to_next, n_left_to_next);
3969 while (n_left_from > 0 && n_left_to_next > 0)
3977 u32 new_addr0, old_addr0;
3978 u16 old_port0, new_port0;
3981 icmp46_header_t * icmp0;
3992 n_left_to_next -= 1;
4000 icmp0 = (icmp46_header_t *) udp0;
4009 ICMP4_time_exceeded_ttl_exceeded_in_transit,
4022 next0 =
icmp_in2out(sm, b0, ip0, icmp0, sw_if_index0,
4023 rx_fib_index0, node, next0, ~0, 0, 0);
4034 b0->
error = node->
errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
4040 new_port0 = sm0.
port;
4055 old_port0 = tcp0->src_port;
4056 tcp0->src_port = new_port0;
4058 sum0 = tcp0->checksum;
4078 sum0 = tcp0->checksum;
4091 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
4103 to_next, n_left_to_next,
4111 SNAT_IN2OUT_ERROR_IN2OUT_PACKETS,
4119 .name =
"nat44-in2out-fast",
4120 .vector_size =
sizeof (
u32),
ip4_address_t external_addr
void nat_ipfix_logging_max_sessions(u32 limit)
Generate maximum session entries exceeded event.
vnet_config_main_t config_main
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static snat_session_t * snat_in2out_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)
fib_protocol_t fp_proto
protocol type
u32 sessions_per_user_list_head_index
static u8 * format_snat_in2out_trace(u8 *s, va_list *args)
clib_bihash_16_8_t out2in_ed
static uword snat_in2out_slow_path_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
static int nat_not_translate_output_feature(snat_main_t *sm, ip4_header_t *ip0, u32 proto0, u16 src_port, u16 dst_port, u32 thread_index, u32 sw_if_index)
u32 fq_in2out_output_index
static u8 * format_snat_in2out_fast_trace(u8 *s, va_list *args)
static uword snat_in2out_node_fn_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_slow_path, int is_output_feature)
static int ip4_header_bytes(ip4_header_t *i)
static f64 vlib_time_now(vlib_main_t *vm)
static char * snat_in2out_error_strings[]
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 uword snat_in2out_worker_handoff_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void snat_icmp_hairpinning(snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, icmp46_header_t *icmp0)
static void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
static snat_det_session_t * snat_det_find_ses_by_in(snat_det_map_t *dm, ip4_address_t *in_addr, u16 in_port, snat_det_out_key_t out_key)
static void snat_det_forward(snat_det_map_t *dm, ip4_address_t *in_addr, ip4_address_t *out_addr, u16 *lo_port)
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
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
VLIB_NODE_FUNCTION_MULTIARCH(snat_in2out_node, snat_in2out_fast_path_fn)
u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
clib_bihash_8_8_t user_hash
vlib_node_registration_t snat_hairpin_dst_node
(constructor) VLIB_REGISTER_NODE (snat_hairpin_dst_node)
static uword snat_in2out_output_slow_path_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vlib_node_registration_t snat_in2out_output_slowpath_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_output_slowpath_node)
static void user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static)
u32 in2out_output_node_index
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)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
vlib_node_registration_t snat_in2out_output_worker_handoff_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_output_worker_handoff_node)
ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
vlib_node_registration_t snat_in2out_fast_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_fast_node)
static uword snat_in2out_output_worker_handoff_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
ip4_address_t ext_host_addr
static int snat_not_translate(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, ip4_header_t *ip0, u32 proto0, u32 rx_fib_index0, u32 thread_index)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
static uword snat_det_in2out_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Aggregrate type for a prefix.
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
static u8 * format_snat_in2out_worker_handoff_trace(u8 *s, va_list *args)
static void * ip4_next_header(ip4_header_t *i)
static u32 slow_path(snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, u32 rx_fib_index0, snat_session_key_t *key0, snat_session_t **sessionp, vlib_node_runtime_t *node, u32 next0, u32 thread_index)
vlib_node_registration_t snat_in2out_slowpath_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_slowpath_node)
static uword snat_in2out_worker_handoff_fn_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_output)
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
static u8 * format_nat44_in2out_reass_trace(u8 *s, va_list *args)
#define foreach_snat_in2out_error
static int ip4_is_fragment(ip4_header_t *i)
static void nat44_reass_hairpinning(snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, u16 sport, u16 dport, u32 proto0)
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.
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
static uword nat44_in2out_reass_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
snat_det_session_t * sessions
static u32 icmp_in2out_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 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.
static_always_inline int icmp_get_ed_key(ip4_header_t *ip0, nat_ed_ses_key_t *p_key0)
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
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.
#define SNAT_SESSION_FLAG_UNKNOWN_PROTO
#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)
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
snat_interface_t * output_feature_interfaces
static void snat_hairpinning_unknown_proto(snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip)
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
static_always_inline int is_hairpinning(snat_main_t *sm, ip4_address_t *dst_addr)
vlib_node_registration_t nat44_in2out_reass_node
(constructor) VLIB_REGISTER_NODE (nat44_in2out_reass_node)
#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)
static uword snat_in2out_output_fast_path_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vlib_node_registration_t snat_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_node)
snat_get_worker_function_t * worker_in2out_cb
#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...)
static int nat_not_translate_output_feature_fwd(snat_main_t *sm, ip4_header_t *ip)
#define clib_memcpy(a, b, c)
static int ip4_is_first_fragment(ip4_header_t *i)
static uword snat_in2out_fast_static_map_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 fib_node_index_t
A typedef of a node index.
8 octet key, 8 octet key value pair
static_always_inline snat_in2out_error_t icmp_get_key(ip4_header_t *ip0, snat_session_key_t *p_key0)
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.
u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation and create session if needed...
u32 tcp_transitory_timeout
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static snat_det_map_t * snat_det_map_by_user(snat_main_t *sm, ip4_address_t *user_addr)
static uword nat44_hairpinning_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
snat_get_worker_function_t * worker_out2in_cb
static u32 ip_proto_to_snat_proto(u8 ip_proto)
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
static int snat_not_translate_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, ip4_header_t *ip0, u32 proto0, u32 rx_fib_index0)
Check if packet should be translated.
vlib_node_registration_t nat44_hairpinning_node
(constructor) VLIB_REGISTER_NODE (nat44_hairpinning_node)
snat_session_t * nat_session_alloc_or_recycle(snat_main_t *sm, snat_user_t *u, u32 thread_index)
vlib_node_registration_t snat_det_in2out_node
(constructor) VLIB_REGISTER_NODE (snat_det_in2out_node)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define vec_elt(v, i)
Get vector value at index i.
struct _vlib_node_registration vlib_node_registration_t
static uword snat_hairpin_src_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define FIB_NODE_INDEX_INVALID
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)
vlib_node_registration_t snat_in2out_worker_handoff_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_worker_handoff_node)
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
#define SNAT_FLAG_HAIRPINNING
static int snat_hairpinning(snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, udp_header_t *udp0, tcp_header_t *tcp0, u32 proto0)
Hairpinning.
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)
vlib_node_registration_t snat_hairpin_src_node
(constructor) VLIB_REGISTER_NODE (snat_hairpin_src_node)
static snat_session_t * snat_in2out_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)
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.
snat_address_t * addresses
static void vlib_put_frame_queue_elt(vlib_frame_queue_elt_t *hf)
u32 icmp_match_in2out_det(snat_main_t *sm, vlib_node_runtime_t *node, u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0, u8 *p_proto, snat_session_key_t *p_value, u8 *p_dont_translate, void *d, void *e)
Get address and port values to be used for ICMP packet translation and create session if needed...
struct _vnet_feature_arc_registration vnet_feature_arc_registration_t
feature registration object
vnet_feature_arc_registration_t vnet_feat_arc_ip4_local
static uword snat_in2out_fast_path_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()
#define vec_foreach(var, vec)
Vector iterator.
vlib_node_registration_t snat_in2out_output_node
(constructor) VLIB_REGISTER_NODE (snat_in2out_output_node)
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.
static uword snat_hairpin_dst_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
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
vnet_feature_config_main_t * feature_config_mains
feature config main objects
#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 snat_det_session_t * snat_det_ses_create(snat_det_map_t *dm, ip4_address_t *in_addr, u16 in_port, snat_det_out_key_t *out)
static u8 maximum_sessions_exceeded(snat_main_t *sm, u32 thread_index)
vnet_feature_main_t feature_main
snat_session_t * sessions
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
snat_icmp_match_function_t * icmp_match_in2out_cb
#define SNAT_SESSION_FLAG_LOAD_BALANCING
clib_bihash_8_8_t static_mapping_by_local
static u16 ip_csum_fold(ip_csum_t c)
snat_interface_t * interfaces
static_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)
u32 tcp_established_timeout
static u32 icmp_in2out(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)