u8 cached;
} nat44_reass_trace_t;
+/* NAT API Configuration flags */
+#define foreach_nat_config_flag \
+ _(0x01, IS_TWICE_NAT) \
+ _(0x02, IS_SELF_TWICE_NAT) \
+ _(0x04, IS_OUT2IN_ONLY) \
+ _(0x08, IS_ADDR_ONLY) \
+ _(0x10, IS_OUTSIDE) \
+ _(0x20, IS_INSIDE) \
+ _(0x40, IS_STATIC) \
+ _(0x80, IS_EXT_HOST_VALID) \
+
+typedef enum nat_config_flags_t_
+{
+#define _(n,f) NAT_API_##f = n,
+ foreach_nat_config_flag
+#undef _
+} nat_config_flags_t;
+
/* External address and port allocation modes */
#define foreach_nat_addr_and_port_alloc_alg \
_(0, DEFAULT, "default") \
#define NAT44_SES_O2I_FIN_ACK 8
#define NAT44_SES_I2O_SYN 16
#define NAT44_SES_O2I_SYN 32
+#define NAT44_SES_RST 64
/* Session flags */
#define SNAT_SESSION_FLAG_STATIC_MAPPING 1
#define SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT 16
#define SNAT_SESSION_FLAG_FWD_BYPASS 32
#define SNAT_SESSION_FLAG_AFFINITY 64
+#define SNAT_SESSION_FLAG_OUTPUT_FEATURE 128
/* NAT interface flags */
#define NAT_INTERFACE_FLAG_IS_INSIDE 1
#define NAT_INTERFACE_FLAG_IS_OUTSIDE 2
+/* Static mapping flags */
+#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY 1
+#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY 2
+#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT 4
+#define NAT_STATIC_MAPPING_FLAG_LB 8
+
/* *INDENT-OFF* */
typedef CLIB_PACKED(struct
{
/* Last heard timer */
f64 last_heard;
+ /* Last HA refresh */
+ f64 ha_last_refreshed;
+
/* Counters */
u64 total_bytes;
u32 total_pkts;
u8 state;
u32 i2o_fin_seq;
u32 o2i_fin_seq;
+
+ /* user index */
+ u32 user_index;
}) snat_session_t;
/* *INDENT-ON* */
u16 local_port;
/* external port */
u16 external_port;
- /* 1 = 1:1NAT, 0 = 1:1NAPT */
- u8 addr_only;
/* is twice-nat */
twice_nat_type_t twice_nat;
- /* 1 = rule match only out2in direction */
- u8 out2in_only;
/* local FIB table */
u32 vrf_id;
u32 fib_index;
nat44_lb_addr_port_t *locals;
/* affinity per service lis */
u32 affinity_per_service_list_head_index;
+ /* flags */
+ u32 flags;
} snat_static_mapping_t;
typedef struct
u32 sw_if_index;
u32 vrf_id;
snat_protocol_t proto;
+ u32 flags;
int addr_only;
int twice_nat;
int is_add;
+ int out2in_only;
+ int identity_nat;
u8 *tag;
} snat_static_map_resolve_t;
u32 fq_in2out_output_index;
u32 fq_out2in_index;
- /* in2out and out2in node index */
+ /* node indexes */
+ u32 error_node_index;
+
u32 in2out_node_index;
u32 in2out_output_node_index;
+ u32 in2out_fast_node_index;
+ u32 in2out_slowpath_node_index;
+ u32 in2out_slowpath_output_node_index;
+ u32 in2out_reass_node_index;
+ u32 ed_in2out_node_index;
+ u32 ed_in2out_slowpath_node_index;
+ u32 ed_in2out_reass_node_index;
u32 out2in_node_index;
- u32 error_node_index;
+ u32 out2in_fast_node_index;
+ u32 out2in_reass_node_index;
+ u32 ed_out2in_node_index;
+ u32 ed_out2in_slowpath_node_index;
+ u32 ed_out2in_reass_node_index;
+ u32 det_in2out_node_index;
+ u32 det_out2in_node_index;
+
+ u32 hairpinning_node_index;
+ u32 hairpin_dst_node_index;
+ u32 hairpin_src_node_index;
+ u32 ed_hairpinning_node_index;
+ u32 ed_hairpin_dst_node_index;
+ u32 ed_hairpin_src_node_index;
+
/* Deterministic NAT mappings */
snat_det_map_t *det_maps;
u16 mss_clamping;
u16 mss_value_net;
+ /* counters/gauges */
+ vlib_simple_counter_main_t total_users;
+ vlib_simple_counter_main_t total_sessions;
+
/* API message ID base */
u16 msg_id_base;
*/
#define nat44_is_ses_closed(s) s->state == 0xf
+/** \brief Check if NAT static mapping is address only (1:1NAT).
+ @param sm NAT static mapping
+ @return 1 if 1:1NAT, 0 if 1:1NAPT
+*/
+#define is_addr_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_ADDR_ONLY)
+
+/** \brief Check if NAT static mapping match only out2in direction.
+ @param sm NAT static mapping
+ @return 1 if rule match only out2in direction
+*/
+#define is_out2in_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY)
+
+/** \brief Check if NAT static mapping is identity NAT.
+ @param sm NAT static mapping
+ @return 1 if identity NAT
+*/
+#define is_identity_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT)
+
+/** \brief Check if NAT static mapping is load-balancing.
+ @param sm NAT static mapping
+ @return 1 if load-balancing
+*/
+#define is_lb_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_LB)
+
+/** \brief Check if client initiating TCP connection (received SYN from client)
+ @param t TCP header
+ @return 1 if client initiating TCP connection
+*/
+#define tcp_is_init(t) ((t->flags & TCP_FLAG_SYN) && !(t->flags & TCP_FLAG_ACK))
+
/* logging */
#define nat_log_err(...) \
vlib_log(VLIB_LOG_LEVEL_ERR, snat_main.log_class, __VA_ARGS__)
/**
* @brief Add/delete NAT44 static mapping
*
- * @param l_addr local IPv4 address
- * @param e_addr external IPv4 address
- * @param l_port local port number
- * @param e_port external port number
- * @param vrf_id local VRF ID
- * @param addr_only 1 = 1:1NAT, 0 = 1:1NAPT
- * @param sw_if_index use interface address as external IPv4 address
- * @param proto L4 protocol
- * @param is_add 1 = add, 0 = delete
- * @param twice_nat twice-nat mode
- * @param out2in_only if 1 rule match only out2in direction
- * @param tagi opaque string tag
+ * @param l_addr local IPv4 address
+ * @param e_addr external IPv4 address
+ * @param l_port local port number
+ * @param e_port external port number
+ * @param vrf_id local VRF ID
+ * @param addr_only 1 = 1:1NAT, 0 = 1:1NAPT
+ * @param sw_if_index use interface address as external IPv4 address
+ * @param proto L4 protocol
+ * @param is_add 1 = add, 0 = delete
+ * @param twice_nat twice-nat mode
+ * @param out2in_only if 1 rule match only out2in direction
+ * @param tag opaque string tag
+ * @param identity_nat identity NAT
*
* @return 0 on success, non-zero value otherwise
*/
int addr_only, u32 sw_if_index,
snat_protocol_t proto, int is_add,
twice_nat_type_t twice_nat, u8 out2in_only,
- u8 * tag);
+ u8 * tag, u8 identity_nat);
/**
* @brief Add/delete static mapping with load-balancing (multiple backends)
twice_nat_type_t twice_nat,
u8 out2in_only, u8 * tag, u32 affinity);
+int nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
+ ip4_address_t l_addr, u16 l_port,
+ snat_protocol_t proto, u32 vrf_id,
+ u8 probability, u8 is_add);
+
clib_error_t *snat_api_init (vlib_main_t * vm, snat_main_t * sm);
/**
* @param port L4 port number
* @param proto L4 protocol
* @param vrf_id VRF ID
- * @param is_in 1 = inside network addres and por pair, 0 = outside
+ * @param is_in 1 = inside network address and port pair, 0 = outside
*
* @return 0 on success, non-zero value otherwise
*/
* @param port L4 port number
* @param proto L4 protocol
* @param vrf_id VRF ID
- * @param is_in 1 = inside network addres and por pair, 0 = outside
+ * @param is_in 1 = inside network address and port pair, 0 = outside
*
* @return 0 on success, non-zero value otherwise
*/
*
* @param s NAT session
* @param thread_index thread index
+ * @param is_ha is HA event
*/
void nat_free_session_data (snat_main_t * sm, snat_session_t * s,
- u32 thread_index);
+ u32 thread_index, u8 is_ha);
/**
* @brief Find or create NAT user
*/
snat_session_t *nat_session_alloc_or_recycle (snat_main_t * sm,
snat_user_t * u,
- u32 thread_index);
+ u32 thread_index, f64 now);
/**
* @brief Allocate NAT endpoint-dependent session
* @return session data structure on success otherwise zero value
*/
snat_session_t *nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u,
- u32 thread_index);
+ u32 thread_index, f64 now);
/**
* @brief Set address and port assignment algorithm for MAP-E CE
*
* @param addresses vector of outside addresses
* @param thread_index thread index
- * @param k adddress, port and protocol
+ * @param k address, port and protocol
*/
void snat_free_outside_address_and_port (snat_address_t * addresses,
u32 thread_index,
u8 * is_addr_only,
twice_nat_type_t * twice_nat,
lb_nat_type_t * lb,
- ip4_address_t * ext_host_addr);
+ ip4_address_t * ext_host_addr,
+ u8 * is_identity_nat);
/**
* @brief Add/del NAT address to FIB.
void snat_add_del_addr_to_fib (ip4_address_t * addr,
u8 p_len, u32 sw_if_index, int is_add);
-
/*
* 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