19 #ifndef __included_nat_inlines_h__ 20 #define __included_nat_inlines_h__ 29 ASSERT (fib_index <= (1 << 14) - 1);
30 ASSERT (proto <= (1 << 3) - 1);
31 return (
u64) addr.
as_u32 << 32 | (
u64) port << 16 | fib_index << 3 |
45 *port = (key >> 16) & (
u16) ~ 0;
49 *fib_index = key >> 3 & ((1 << 13) - 1);
76 return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
83 init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
91 return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
98 init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
108 u32 n_left_from, *from;
117 while (n_left_from >= 2)
120 u32 arc_next0, arc_next1;
154 if (b0->
flags & VLIB_BUFFER_IS_TRACED)
160 if (b1->
flags & VLIB_BUFFER_IS_TRACED)
174 while (n_left_from > 0)
188 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
207 u32 sw_if_index0,
u32 ip4_addr)
268 clib_bihash_add_del_8_8 (&tsm->
user_hash, &kv, 0);
283 .
addr = ses->in2out.addr,
284 .fib_index = ses->in2out.fib_index
300 if (!clib_bihash_search_8_8 (&tsm->
user_hash, &kv, &value))
321 u8 tcp_flags =
vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags;
326 if ((ses->state ==
NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
335 ses->i2o_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
340 if (clib_net_to_host_u32 (tcp_ack_number) > ses->o2i_fin_seq)
346 ses->last_lru_update = now;
367 snat_session_t * ses,
u8 tcp_flags,
368 u32 tcp_ack_number,
u32 tcp_seq_number,
374 if ((ses->state ==
NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
383 ses->o2i_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
388 if (clib_net_to_host_u32 (tcp_ack_number) > ses->i2o_fin_seq)
393 ses->last_lru_update = now;
413 switch (s->nat_proto)
415 case NAT_PROTOCOL_ICMP:
417 case NAT_PROTOCOL_UDP:
419 case NAT_PROTOCOL_TCP:
439 s->total_bytes += bytes;
440 nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
441 s->ext_host_port, s->nat_proto, s->out2in.fib_index,
442 s->total_pkts, s->total_bytes, thread_index,
443 &s->ha_last_refreshed, now);
452 if (s->last_heard > s->last_lru_update + 1)
459 s->per_user_list_head_index, s->per_user_index);
466 s->lru_head_index, s->lru_index);
468 s->last_lru_update = s->last_heard;
478 (
u64) r_port << 48 | (
u64) l_port << 32 | fib_index << 8 | proto;
484 u32 thread_index,
u32 session_index)
486 init_ed_k (kv, l_addr, l_port, r_addr, r_port, fib_index, proto);
487 kv->
value = (
u64) thread_index << 32 | session_index;
493 return value->
value >> 32;
519 u32 * fib_index,
u16 * l_port,
u16 * r_port)
531 *r_port = kv->
key[1] >> 48;
535 *l_port = (kv->
key[1] >> 32) & (
u16) ~ 0;
539 *fib_index = (kv->
key[1] >> 8) & ((1 << 24) - 1);
543 *proto = kv->
key[1] & (
u8) ~ 0;
549 u32 thread_index,
u32 session_index,
554 u16 _l_port, _r_port;
557 icmp46_header_t *icmp0;
561 icmp46_header_t *inner_icmp0;
567 (
vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
569 proto = IP_PROTOCOL_ICMP;
584 case NAT_PROTOCOL_ICMP:
585 inner_icmp0 = (icmp46_header_t *) l4_header;
590 case NAT_PROTOCOL_UDP:
591 case NAT_PROTOCOL_TCP:
596 return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
599 init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto,
600 thread_index, session_index);
618 u32 thread_index,
u32 session_index,
622 icmp46_header_t *icmp0;
625 u16 _l_port, _r_port;
629 icmp46_header_t *inner_icmp0;
635 (
vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
637 proto = IP_PROTOCOL_ICMP;
652 case NAT_PROTOCOL_ICMP:
653 inner_icmp0 = (icmp46_header_t *) l4_header;
658 case NAT_PROTOCOL_UDP:
659 case NAT_PROTOCOL_TCP:
667 init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto,
668 thread_index, session_index);
727 if (sw_if_index == ~0)
735 if (sw_if_index != ~0)
740 if (sw_if_index == ~0)
747 if ((nat_interface_is_outside (i)) && (sw_if_index == i->sw_if_index))
761 v = clib_net_to_host_u32 (a->
as_u32) + 1;
762 a->
as_u32 = clib_host_to_net_u32 (v);
774 if (r >= min && r <= max)
777 return min + (rwide % (max - min + 1));
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
fib_protocol_t fp_proto
protocol type
nat_outside_fib_t * outside_fibs
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
u32 sessions_per_user_list_head_index
static u64 calc_nat_key(ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
The NAT inline functions.
#define NAT44_SES_I2O_FIN
u8 runtime_data[0]
Function dependent node-runtime data.
static u32 nat44_session_get_timeout(snat_main_t *sm, snat_session_t *s)
static void init_nat_i2o_kv(clib_bihash_kv_8_8_t *kv, snat_session_t *s, u64 value)
static_always_inline int get_icmp_o2i_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index, u32 thread_index, u32 session_index, nat_protocol_t *nat_proto, u16 *l_port, u16 *r_port, clib_bihash_kv_16_8_t *kv)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
static void init_nat_i2o_k(clib_bihash_kv_8_8_t *kv, snat_session_t *s)
#define nat44_is_ses_closed(s)
Check if NAT44 endpoint-dependent TCP session is closed.
#define NAT44_SES_O2I_FIN
static void init_ed_kv(clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port, ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto, u32 thread_index, u32 session_index)
u32 max_translations_per_thread
static void split_nat_key(u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto)
clib_bihash_8_8_t user_hash
void nat_ha_sref(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 total_pkts, u64 total_bytes, u32 thread_index, f64 *last_refreshed, f64 now)
Create session refresh HA event.
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.
u32 max_translations_per_user
#define static_always_inline
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static nat_protocol_t ip_proto_to_nat_proto(u8 ip_proto)
Common NAT inline functions.
static_always_inline u16 snat_random_port(u16 min, u16 max)
static void init_nat_o2i_kv(clib_bihash_kv_8_8_t *kv, snat_session_t *s, u64 value)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Aggregate type for a prefix.
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
static void init_nat_o2i_k(clib_bihash_kv_8_8_t *kv, snat_session_t *s)
static void split_ed_kv(clib_bihash_kv_16_8_t *kv, ip4_address_t *l_addr, ip4_address_t *r_addr, u8 *proto, u32 *fib_index, u16 *l_port, u16 *r_port)
static void * ip4_next_header(ip4_header_t *i)
static_always_inline int get_icmp_i2o_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index, u32 thread_index, u32 session_index, nat_protocol_t *nat_proto, u16 *l_port, u16 *r_port, clib_bihash_kv_16_8_t *kv)
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 maximum_sessions_exceeded(snat_main_t *sm, u32 thread_index)
static void nat44_delete_session(snat_main_t *sm, snat_session_t *ses, u32 thread_index)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
static u32 ed_value_get_session_index(clib_bihash_kv_16_8_t *value)
#define pool_put(P, E)
Free an object E in pool P.
#define NAT44_SES_O2I_SYN
static void vlib_set_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 value)
Set a simple counter.
static void init_nat_k(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto)
static void split_ed_value(clib_bihash_kv_16_8_t *value, u32 *thread_index, u32 *session_index)
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
static int nat44_set_tcp_session_state_o2i(snat_main_t *sm, f64 now, snat_session_t *ses, u8 tcp_flags, u32 tcp_ack_number, u32 tcp_seq_number, u32 thread_index)
static void nat44_delete_user_with_no_session(snat_main_t *sm, snat_user_t *u, u32 thread_index)
#define CLIB_PREFETCH(addr, size, type)
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
sll srl srl sll sra u16x4 i
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
static void nat44_session_update_counters(snat_session_t *s, f64 now, uword bytes, u32 thread_index)
u32 fib_node_index_t
A typedef of a node index.
static void init_nat_kv(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto, u64 value)
8 octet key, 8 octet key value pair
static uword nat_pre_node_fn_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 def_next)
u32 tcp_transitory_timeout
vlib_main_t vlib_node_runtime_t * node
#define pool_put_index(p, i)
Free pool element with given index.
static int nat44_set_tcp_session_state_i2o(snat_main_t *sm, f64 now, snat_session_t *ses, vlib_buffer_t *b, u32 thread_index)
Set TCP session state.
static void nat44_session_update_lru(snat_main_t *sm, snat_session_t *s, u32 thread_index)
Per-user LRU list maintenance.
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
#define NAT44_SES_I2O_SYN
vlib_simple_counter_main_t total_users
#define FIB_NODE_INDEX_INVALID
static void user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static)
u32 tcp_trans_lru_head_index
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
VLIB buffer representation.
u32 tcp_estab_lru_head_index
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.
static u8 is_interface_addr(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, u32 ip4_addr)
static void init_ed_k(clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port, ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
static void increment_v4_address(ip4_address_t *a)
static u32 random_u32(u32 *seed)
32-bit random number generator
#define NAT44_SES_I2O_FIN_ACK
#define vec_foreach(var, vec)
Vector iterator.
u16 flags
Copy of main node flags.
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
#define VLIB_NODE_FLAG_TRACE
#define CLIB_CACHE_LINE_BYTES
#define NAT44_SES_O2I_FIN_ACK
vlib_simple_counter_main_t total_sessions
snat_session_t * sessions
static u32 ed_value_get_thread_index(clib_bihash_kv_16_8_t *value)
vl_api_interface_index_t sw_if_index
snat_interface_t * interfaces
u32 tcp_established_timeout
static uword pool_elts(void *v)
Number of active elements in a pool.