16 #ifndef __CNAT_NODE_H__ 17 #define __CNAT_NODE_H__ 84 s =
format (s,
"created session");
86 s =
format (s,
"found session");
88 s =
format (s,
"session not found");
91 s =
format (s,
" [policy:skip]");
113 case ICMP4_destination_unreachable:
114 case ICMP4_time_exceeded:
115 case ICMP4_parameter_problem:
116 case ICMP4_source_quench:
118 case ICMP4_alternate_host_address:
129 case ICMP4_echo_request:
130 case ICMP4_echo_reply:
141 case ICMP6_echo_request:
142 case ICMP6_echo_reply:
153 case ICMP6_destination_unreachable:
154 case ICMP6_time_exceeded:
155 case ICMP6_parameter_problem:
164 return ((a1->as_u64[0] == a2->as_u64[0])
165 && (a1->as_u64[1] == a2->as_u64[1]));
175 return ((0 != a->as_u64[0]) || (0 != a->as_u64[1]));
182 u16 new_port[VLIB_N_DIR])
209 *sum =
ip_csum_update (*sum, old_port[VLIB_TX], new_port[VLIB_TX],
222 *sum =
ip_csum_update (*sum, old_port[VLIB_RX], new_port[VLIB_RX],
278 u16 new_port[VLIB_N_DIR])
288 sum = icmp->checksum;
298 icmp46_header_t *
icmp,
300 u16 outer_new_port[VLIB_N_DIR],
307 ip_csum_t sum, old_ip_sum, inner_l4_sum, inner_l4_old_sum;
324 sum = icmp->checksum;
332 if (ip4->
protocol == IP_PROTOCOL_TCP)
334 inner_l4_old_sum = inner_l4_sum = tcp->checksum;
338 else if (ip4->
protocol == IP_PROTOCOL_UDP)
340 inner_l4_old_sum = inner_l4_sum = udp->
checksum;
369 if (new_addr[VLIB_TX].as_u32)
371 ip_csum_update (sum, old_addr[VLIB_TX].as_u32, new_addr[VLIB_TX].as_u32,
374 if (new_addr[VLIB_RX].as_u32)
376 ip_csum_update (sum, old_addr[VLIB_RX].as_u32, new_addr[VLIB_RX].as_u32,
395 if (ip4->
protocol == IP_PROTOCOL_TCP)
403 else if (ip4->
protocol == IP_PROTOCOL_UDP)
410 else if (ip4->
protocol == IP_PROTOCOL_ICMP)
412 icmp46_header_t *
icmp = (icmp46_header_t *) udp;
440 u16 new_port[VLIB_N_DIR])
466 if (new_port[VLIB_TX])
469 *sum =
ip_csum_update (*sum, old_port[VLIB_TX], new_port[VLIB_TX],
481 if (new_port[VLIB_RX])
484 *sum =
ip_csum_update (*sum, old_port[VLIB_RX], new_port[VLIB_RX],
493 u16 new_port[VLIB_N_DIR])
503 sum = icmp->checksum;
532 icmp46_header_t *
icmp,
534 u16 outer_new_port[VLIB_N_DIR],
542 ip_csum_t sum, inner_l4_sum, inner_l4_old_sum;
562 sum = icmp->checksum;
586 if (ip6->
protocol == IP_PROTOCOL_TCP)
588 inner_l4_old_sum = inner_l4_sum = tcp->checksum;
592 else if (ip6->
protocol == IP_PROTOCOL_UDP)
594 inner_l4_old_sum = inner_l4_sum = udp->
checksum;
607 if (old_port[VLIB_TX] && new_port[VLIB_TX])
612 if (old_port[VLIB_RX] && new_port[VLIB_RX])
652 if (ip6->
protocol == IP_PROTOCOL_TCP)
660 else if (ip6->
protocol == IP_PROTOCOL_UDP)
667 else if (ip6->
protocol == IP_PROTOCOL_ICMP6)
669 icmp46_header_t *
icmp = (icmp46_header_t *) udp;
694 session->
key.__cs_pad = 0;
697 iph_offset =
vnet_buffer (b)->ip.save_rewrite_length;
706 icmp46_header_t *
icmp = (icmp46_header_t *) (ip4 + 1);
734 else if (ip4->
protocol == IP_PROTOCOL_UDP ||
755 icmp46_header_t *
icmp = (icmp46_header_t *) (ip6 + 1);
783 else if (ip6->
protocol == IP_PROTOCOL_UDP ||
813 u32 hash_c0, bucket0;
903 rsession->
key.
cs_loc = rsession_location;
904 rsession->
key.__cs_pad = 0;
984 next[3] = cnat_sub (vm, node, b[3], &ctx, rv[3], session[3]);
989 next[2] = cnat_sub (vm, node, b[2], &ctx, rv[2], session[2]);
994 next[1] = cnat_sub (vm, node, b[1], &ctx, rv[1], session[1]);
999 next[0] = cnat_sub (vm, node, b[0], &ctx, rv[0], session[0]);
1032 next[0] = cnat_sub (vm, node, b[0], &ctx, rv[0], session[0]);
static_always_inline void cnat_translation_icmp6_echo(ip6_header_t *ip6, icmp46_header_t *icmp, ip6_address_t new_addr[VLIB_N_DIR], u16 new_port[VLIB_N_DIR])
u16 lb_n_buckets
number of buckets in the load-balance.
struct cnat_session_t_::@635 key
this key sits in the same memory location a 'key' in the bihash kvp
#define cnat_bihash_add_del
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
static_always_inline cnat_ep_trk_t * cnat_load_balance(const cnat_translation_t *ct, ip_address_family_t af, ip4_header_t *ip4, ip6_header_t *ip6, u32 *dpoi_index)
This session doesn't have a client, do not attempt to free it.
static_always_inline u8 cmp_ip6_address(const ip6_address_t *a1, const ip6_address_t *a2)
static_always_inline void cnat_session_create(cnat_session_t *session, cnat_node_ctx_t *ctx, cnat_session_location_t rsession_location, u8 rsession_flags)
Create NAT sessions rsession_location is the location the (return) session will be matched at...
static u32 ip4_compute_flow_hash(const ip4_header_t *ip, flow_hash_config_t flow_hash_config)
u16 nexts[VLIB_FRAME_SIZE]
vnet_feature_config_main_t * cm
static f64 vlib_time_now(vlib_main_t *vm)
uword(* cnat_node_sub_t)(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, cnat_node_ctx_t *ctx, int rv, cnat_session_t *session)
struct cnat_trace_element_t_ cnat_trace_element_t
flow_hash_config_t lb_hash_config
the hash config to use when selecting a bucket.
static const dpo_id_t * load_balance_get_fwd_bucket(const load_balance_t *lb, u16 bucket)
u16 cs_port[VLIB_N_DIR]
ports in rx/tx
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
u8 * format_cnat_session(u8 *s, va_list *args)
A Translation represents the translation of a VEP to one of a set of real server addresses.
#define hash_set_mem(h, key, value)
static_always_inline void cnat_translation_icmp4_error(ip4_header_t *outer_ip4, icmp46_header_t *icmp, ip4_address_t outer_new_addr[VLIB_N_DIR], u16 outer_new_port[VLIB_N_DIR], u8 snat_outer_ip)
static u32 cnat_timestamp_new(f64 t)
static_always_inline void ip46_address_set_ip6(ip46_address_t *dst, const ip6_address_t *src)
static_always_inline void cnat_tcp_update_session_lifetime(tcp_header_t *tcp, u32 index)
void cnat_session_free(cnat_session_t *session)
Free a session & update refcounts.
struct _tcp_header tcp_header_t
format_function_t format_vnet_sw_if_index_name
static_always_inline void cnat_ip6_translate_l4(ip6_header_t *ip6, udp_header_t *udp, ip_csum_t *sum, ip6_address_t new_addr[VLIB_N_DIR], u16 new_port[VLIB_N_DIR])
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
#define clib_memcpy(d, s, n)
static void cnat_timestamp_set_lifetime(u32 index, u16 lifetime)
A session represents the memory of a translation.
u8 cs_af
The address family describing the IP addresses.
static_always_inline void cnat_session_make_key(vlib_buffer_t *b, ip_address_family_t af, cnat_session_location_t cs_loc, cnat_bihash_kv_t *bkey)
#define static_always_inline
#define cnat_bihash_prefetch_data
struct cnat_session_t_::@636 value
this value sits in the same memory location a 'value' in the bihash kvp
vlib_get_buffers(vm, from, b, n_left_from)
description fragment has unexpected format
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
vnet_main_t * vnet_get_main(void)
cnat_lb_type_t lb_type
Type of load balancing.
vlib_buffer_enqueue_to_next(vm, node, from,(u16 *) nexts, frame->n_vectors)
static_always_inline void cnat_ip4_translate_l4(ip4_header_t *ip4, udp_header_t *udp, ip_csum_t *sum, ip4_address_t new_addr[VLIB_N_DIR], u16 new_port[VLIB_N_DIR])
#define cnat_bihash_search_i2_hash
ip46_address_t cs_ip[VLIB_N_DIR]
IP 4/6 address in the rx/tx direction.
u32 cs_ts_index
Timestamp index this session was last used.
static_always_inline u32 cnat_client_cnt_session(cnat_client_t *cc)
Add a session refcnt to this client.
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static_always_inline cnat_client_t * cnat_client_ip4_find(const ip4_address_t *ip)
Find a client from an IP4 address.
vl_api_address_union_t src_address
static_always_inline void cnat_translation_ip6(const cnat_session_t *session, ip6_header_t *ip6, udp_header_t *udp)
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
enum cnat_session_location_t_ cnat_session_location_t
static_always_inline u8 icmp6_type_is_error_message(u8 icmp_type)
void cnat_client_learn(const ip_address_t *addr)
Called in the main thread by RPC from the workers to learn a new client.
index_t cs_lbi
The load balance object to use to forward.
#define cnat_bihash_search_i2
static_always_inline u8 icmp6_type_is_echo(u8 icmp_type)
static_always_inline void cnat_ip6_translate_l3(ip6_header_t *ip6, ip6_address_t new_addr[VLIB_N_DIR])
static_always_inline void cnat_ip4_translate_l3(ip4_header_t *ip4, ip4_address_t new_addr[VLIB_N_DIR])
static u8 * format_cnat_trace(u8 *s, va_list *args)
static_always_inline void cnat_translation_ip4(const cnat_session_t *session, ip4_header_t *ip4, udp_header_t *udp)
dpo_id_t ct_lb
The LB used to forward to the backends.
#define CNAT_DEFAULT_TCP_RST_TIMEOUT
static load_balance_t * load_balance_get(index_t lbi)
static ip_csum_t ip_csum_sub_even(ip_csum_t c, ip_csum_t x)
u8 * format_cnat_translation(u8 *s, va_list *args)
ip_address_family_t version
enum cnat_trace_element_flag_t_ cnat_trace_element_flag_t
#define cnat_bihash_prefetch_bucket
static_always_inline u8 icmp_type_is_echo(u8 icmp_type)
static uword cnat_node_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, cnat_node_sub_t cnat_sub, ip_address_family_t af, cnat_session_location_t cs_loc, u8 do_trace)
static_always_inline cnat_client_t * cnat_client_ip6_find(const ip6_address_t *ip)
Find a client from an IP6 address.
enum ip_address_family_t_ ip_address_family_t
static u32 ip6_compute_flow_hash(const ip6_header_t *ip, flow_hash_config_t flow_hash_config)
static_always_inline void cnat_translation_icmp6_error(ip6_header_t *outer_ip6, icmp46_header_t *icmp, ip6_address_t outer_new_addr[VLIB_N_DIR], u16 outer_new_port[VLIB_N_DIR], u8 snat_outer_ip)
cnat_ep_trk_t * ct_active_paths
The vector of active tracked back-ends.
static_always_inline void cnat_translation_icmp4_echo(ip4_header_t *ip4, icmp46_header_t *icmp, ip4_address_t new_addr[VLIB_N_DIR], u16 new_port[VLIB_N_DIR])
static_always_inline void cnat_add_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, cnat_session_t *session, const cnat_translation_t *ct, u8 flags)
ip_protocol_t cs_proto
The IP protocol TCP or UDP only supported.
index_t dpoi_index
the index of objects of that type
u32 sw_if_index[VLIB_N_RX_TX]
vlib_main_t vlib_node_runtime_t * node
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
VLIB buffer representation.
cnat_bihash_t cnat_session_db
The DB of sessions.
u8 cs_loc
input / output / fib session
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 void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
cnat_client_db_t cnat_client_db
cnat_trace_element_flag_t_
#define hash_get_mem(h, key)
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static void hash_set_mem_alloc(uword **h, const void *key, uword v)
Data used to track an EP in the FIB.
clib_spinlock_t throttle_lock
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
static u16 ip_csum_fold(ip_csum_t c)
static void ip46_address_set_ip4(ip46_address_t *ip46, const ip4_address_t *ip)
static ip_csum_t ip_csum_add_even(ip_csum_t c, ip_csum_t x)
A client is a representation of an IP address behind the NAT.
static_always_inline u8 has_ip6_address(ip6_address_t *a)
Inline translation functions.