#include <vnet/ip/icmp46_packet.h>
#include <vnet/api_errno.h>
#include <vppinfra/bihash_8_8.h>
+#include <vppinfra/bihash_16_8.h>
#include <vppinfra/dlist.h>
#include <vppinfra/error.h>
#include <vlibapi/api.h>
#define SNAT_UDP_TIMEOUT 300
+#define SNAT_UDP_TIMEOUT_MIN 120
#define SNAT_TCP_TRANSITORY_TIMEOUT 240
#define SNAT_TCP_ESTABLISHED_TIMEOUT 7440
+#define SNAT_TCP_INCOMING_SYN 6
#define SNAT_ICMP_TIMEOUT 60
/* Key */
};
} snat_session_key_t;
+typedef struct {
+ union
+ {
+ struct
+ {
+ ip4_address_t l_addr;
+ ip4_address_t r_addr;
+ u32 fib_index;
+ u8 proto;
+ u8 rsvd[3];
+ };
+ u64 as_u64[2];
+ };
+} snat_unk_proto_ses_key_t;
+
typedef struct {
union
{
#define SNAT_SESSION_FLAG_STATIC_MAPPING 1
+#define SNAT_SESSION_FLAG_UNKNOWN_PROTO 2
typedef CLIB_PACKED(struct {
snat_session_key_t out2in; /* 0-15 */
/* Outside address */
u32 outside_address_index; /* 64-67 */
+ /* External host address */
+ ip4_address_t ext_host_addr; /* 68-71 */
+
}) snat_session_t;
clib_bihash_8_8_t out2in;
clib_bihash_8_8_t in2out;
+ /* Unknown protocol sessions lookup tables */
+ clib_bihash_16_8_t out2in_unk_proto;
+ clib_bihash_16_8_t in2out_unk_proto;
+
/* Find-a-user => src address lookup */
clib_bihash_8_8_t user_hash;
/* tenant VRF aware address pool activation flag */
u8 vrf_mode;
+ /* values of various timeouts */
+ u32 udp_timeout;
+ u32 tcp_established_timeout;
+ u32 tcp_transitory_timeout;
+ u32 icmp_timeout;
+
/* API message ID base */
u16 msg_id_base;
int snat_static_mapping_match (snat_main_t * sm,
snat_session_key_t match,
snat_session_key_t * mapping,
- u8 by_external);
+ u8 by_external,
+ u8 *is_addr_only);
void snat_add_del_addr_to_fib (ip4_address_t * addr,
u8 p_len,
*/
#define snat_is_session_static(s) s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING
+/** \brief Check if SNAT session for unknown protocol.
+ @param s SNAT session
+ @return 1 if SNAT session for unknown protocol otherwise 0
+*/
+#define snat_is_unk_proto_session(s) s->flags & SNAT_SESSION_FLAG_UNKNOWN_PROTO
+
/*
* Why is this here? Because we don't need to touch this layer to
* simply reply to an icmp. We need to change id to a unique
u16 sequence;
} icmp_echo_header_t;
-always_inline snat_protocol_t
+always_inline u32
ip_proto_to_snat_proto (u8 ip_proto)
{
- snat_protocol_t snat_proto = ~0;
+ u32 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;
+ snat_proto = (ip_proto == IP_PROTOCOL_ICMP6) ? SNAT_PROTOCOL_ICMP : snat_proto;
return snat_proto;
}
u32 thread_index, vlib_buffer_t *b0, u8 *p_proto,
snat_session_key_t *p_value,
u8 *p_dont_translate, void *d, void *e);
+void increment_v4_address(ip4_address_t * a);
+void snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id);
+int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm);
+int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
+ u16 l_port, u16 e_port, u32 vrf_id, int addr_only,
+ u32 sw_if_index, snat_protocol_t proto, int is_add);
+clib_error_t * snat_api_init(vlib_main_t * vm, snat_main_t * sm);
+int snat_set_workers (uword * bitmap);
+int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del);
+int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del);
+uword unformat_snat_protocol(unformat_input_t * input, va_list * args);
+u8 * format_snat_protocol(u8 * s, va_list * args);
static_always_inline u8
icmp_is_error_message (icmp46_header_t * icmp)