X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fsnat%2Fsnat.h;h=f4e1c5c0007d1599492206af240d4db1e3a75b62;hb=586afd762bfa149f5ca167bd5fd5a0cd59ce94fe;hp=fc379dfa3ed29026d894215c75f30220bdbd626a;hpb=8b275371d1487958d9469d2be8f5330ee8197d04;p=vpp.git diff --git a/src/plugins/snat/snat.h b/src/plugins/snat/snat.h index fc379dfa3ed..f4e1c5c0007 100644 --- a/src/plugins/snat/snat.h +++ b/src/plugins/snat/snat.h @@ -28,6 +28,11 @@ #include #include + +#define SNAT_UDP_TIMEOUT 300 +#define SNAT_TCP_TRANSITORY_TIMEOUT 240 +#define SNAT_TCP_ESTABLISHED_TIMEOUT 7440 + /* Key */ typedef struct { union @@ -43,6 +48,19 @@ typedef struct { }; } snat_session_key_t; +typedef struct { + union + { + struct + { + ip4_address_t ext_host_addr; + u16 ext_host_port; + u16 out_port; + }; + u64 as_u64; + }; +} snat_det_out_key_t; + typedef struct { union { @@ -66,16 +84,37 @@ typedef struct { }; u64 as_u64; }; -} snat_static_mapping_key_t; +} snat_worker_key_t; + +#define foreach_snat_protocol \ + _(UDP, 0, udp, "udp") \ + _(TCP, 1, tcp, "tcp") \ + _(ICMP, 2, icmp, "icmp") typedef enum { - SNAT_PROTOCOL_UDP = 0, - SNAT_PROTOCOL_TCP, - SNAT_PROTOCOL_ICMP, +#define _(N, i, n, s) SNAT_PROTOCOL_##N = i, + foreach_snat_protocol +#undef _ } snat_protocol_t; +#define foreach_snat_session_state \ + _(0, UNKNOWN, "unknown") \ + _(1, UDP_ACTIVE, "udp-active") \ + _(2, TCP_SYN_SENT, "tcp-syn-sent") \ + _(3, TCP_ESTABLISHED, "tcp-established") \ + _(4, TCP_FIN_WAIT, "tcp-fin-wait") \ + _(5, TCP_CLOSE_WAIT, "tcp-close-wait") \ + _(6, TCP_LAST_ACK, "tcp-last-ack") + +typedef enum { +#define _(v, N, s) SNAT_SESSION_##N = v, + foreach_snat_session_state +#undef _ +} snat_session_state_t; + + #define SNAT_SESSION_FLAG_STATIC_MAPPING 1 typedef CLIB_PACKED(struct { @@ -105,6 +144,7 @@ typedef CLIB_PACKED(struct { typedef struct { ip4_address_t addr; + u32 fib_index; u32 sessions_per_user_list_head_index; u32 nsessions; u32 nstaticsessions; @@ -112,10 +152,33 @@ typedef struct { typedef struct { ip4_address_t addr; - u32 busy_ports; - uword * busy_port_bitmap; + u32 fib_index; +#define _(N, i, n, s) \ + u32 busy_##n##_ports; \ + uword * busy_##n##_port_bitmap; + foreach_snat_protocol +#undef _ } snat_address_t; +typedef struct { + u16 in_port; + snat_det_out_key_t out; + u8 state; + u32 expire; +} snat_det_session_t; + +typedef struct { + ip4_address_t in_addr; + u8 in_plen; + ip4_address_t out_addr; + u8 out_plen; + u32 sharing_ratio; + u16 ports_per_host; + u32 ses_num; + /* vector of sessions */ + snat_det_session_t * sessions; +} snat_det_map_t; + typedef struct { ip4_address_t local_addr; ip4_address_t external_addr; @@ -124,6 +187,7 @@ typedef struct { u8 addr_only; u32 vrf_id; u32 fib_index; + snat_protocol_t proto; } snat_static_mapping_t; typedef struct { @@ -137,6 +201,7 @@ typedef struct { u16 e_port; u32 sw_if_index; u32 vrf_id; + snat_protocol_t proto; int addr_only; int is_add; } snat_static_map_resolve_t; @@ -152,7 +217,20 @@ typedef struct { dlist_elt_t * list_pool; } snat_main_per_thread_data_t; -typedef struct { +struct snat_main_s; + +typedef u32 snat_icmp_match_function_t (struct snat_main_s *sm, + vlib_node_runtime_t *node, + u32 thread_index, + vlib_buffer_t *b0, + snat_session_key_t *p_key, + snat_session_key_t *p_value, + u8 *p_dont_translate, + void *d); + +typedef u32 (snat_get_worker_function_t) (ip4_header_t * ip, u32 rx_fib_index); + +typedef struct snat_main_s { /* Main lookup tables */ clib_bihash_8_8_t out2in; clib_bihash_8_8_t in2out; @@ -166,10 +244,15 @@ typedef struct { /* Translated packets worker lookup => IP address + port number */ clib_bihash_8_8_t worker_by_out; + snat_icmp_match_function_t * icmp_match_in2out_cb; + snat_icmp_match_function_t * icmp_match_out2in_cb; + u32 num_workers; u32 first_worker_index; u32 next_worker; u32 * workers; + snat_get_worker_function_t * worker_in2out_cb; + snat_get_worker_function_t * worker_out2in_cb; /* Per thread data */ snat_main_per_thread_data_t * per_thread_data; @@ -202,9 +285,17 @@ typedef struct { u32 fq_in2out_index; u32 fq_out2in_index; + /* in2out and out2in node index */ + u32 in2out_node_index; + u32 out2in_node_index; + + /* Deterministic NAT */ + snat_det_map_t * det_maps; + /* Config parameters */ u8 static_mapping_only; u8 static_mapping_connection_tracking; + u8 deterministic; u32 translation_buckets; u32 translation_memory_size; u32 user_buckets; @@ -215,6 +306,9 @@ typedef struct { u32 inside_vrf_id; u32 inside_fib_index; + /* tenant VRF aware address pool activation flag */ + u8 vrf_mode; + /* API message ID base */ u16 msg_id_base; @@ -223,7 +317,6 @@ typedef struct { vnet_main_t * vnet_main; ip4_main_t * ip4_main; ip_lookup_main_t * ip4_lookup_main; - ethernet_main_t * ethernet_main; api_main_t * api_main; } snat_main_t; @@ -234,12 +327,15 @@ extern vlib_node_registration_t snat_in2out_fast_node; extern vlib_node_registration_t snat_out2in_fast_node; extern vlib_node_registration_t snat_in2out_worker_handoff_node; extern vlib_node_registration_t snat_out2in_worker_handoff_node; +extern vlib_node_registration_t snat_det_in2out_node; +extern vlib_node_registration_t snat_det_out2in_node; void snat_free_outside_address_and_port (snat_main_t * sm, snat_session_key_t * k, u32 address_index); int snat_alloc_outside_address_and_port (snat_main_t * sm, + u32 fib_index, snat_session_key_t * k, u32 * address_indexp); @@ -248,6 +344,11 @@ int snat_static_mapping_match (snat_main_t * sm, snat_session_key_t * mapping, u8 by_external); +void snat_add_del_addr_to_fib (ip4_address_t * addr, + u8 p_len, + u32 sw_if_index, + int is_add); + format_function_t format_snat_user; typedef struct { @@ -272,4 +373,69 @@ typedef struct { u16 sequence; } icmp_echo_header_t; +always_inline snat_protocol_t +ip_proto_to_snat_proto (u8 ip_proto) +{ + snat_protocol_t snat_proto = ~0; + + snat_proto = (ip_proto == IP_PROTOCOL_UDP) ? SNAT_PROTOCOL_UDP : snat_proto; + snat_proto = (ip_proto == IP_PROTOCOL_TCP) ? SNAT_PROTOCOL_TCP : snat_proto; + snat_proto = (ip_proto == IP_PROTOCOL_ICMP) ? SNAT_PROTOCOL_ICMP : snat_proto; + + return snat_proto; +} + +always_inline u8 +snat_proto_to_ip_proto (snat_protocol_t snat_proto) +{ + u8 ip_proto = ~0; + + ip_proto = (snat_proto == SNAT_PROTOCOL_UDP) ? IP_PROTOCOL_UDP : ip_proto; + ip_proto = (snat_proto == SNAT_PROTOCOL_TCP) ? IP_PROTOCOL_TCP : ip_proto; + ip_proto = (snat_proto == SNAT_PROTOCOL_ICMP) ? IP_PROTOCOL_ICMP : ip_proto; + + return ip_proto; +} + +typedef struct { + u16 src_port, dst_port; +} tcp_udp_header_t; + +u32 icmp_match_in2out_fast(snat_main_t *sm, vlib_node_runtime_t *node, + u32 thread_index, vlib_buffer_t *b0, + snat_session_key_t *p_key, + snat_session_key_t *p_value, + u8 *p_dont_translate, void *d); +u32 icmp_match_in2out_slow(snat_main_t *sm, vlib_node_runtime_t *node, + u32 thread_index, vlib_buffer_t *b0, + snat_session_key_t *p_key, + snat_session_key_t *p_value, + u8 *p_dont_translate, void *d); +u32 icmp_match_out2in_fast(snat_main_t *sm, vlib_node_runtime_t *node, + u32 thread_index, vlib_buffer_t *b0, + snat_session_key_t *p_key, + snat_session_key_t *p_value, + u8 *p_dont_translate, void *d); +u32 icmp_match_out2in_slow(snat_main_t *sm, vlib_node_runtime_t *node, + u32 thread_index, vlib_buffer_t *b0, + snat_session_key_t *p_key, + snat_session_key_t *p_value, + u8 *p_dont_translate, void *d); + +static_always_inline u8 +icmp_is_error_message (icmp46_header_t * icmp) +{ + switch(icmp->type) + { + case ICMP4_destination_unreachable: + case ICMP4_time_exceeded: + case ICMP4_parameter_problem: + case ICMP4_source_quench: + case ICMP4_redirect: + case ICMP4_alternate_host_address: + return 1; + } + return 0; +} + #endif /* __included_snat_h__ */