/* * Copyright (c) 2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file NAT plugin global declarations */ #ifndef __included_nat_h__ #define __included_nat_h__ #include #include #include #include #include #include #include #include #include #include #include /* default session timeouts */ #define SNAT_UDP_TIMEOUT 300 #define SNAT_TCP_TRANSITORY_TIMEOUT 240 #define SNAT_TCP_ESTABLISHED_TIMEOUT 7440 #define SNAT_ICMP_TIMEOUT 60 /* number of worker handoff frame queue elements */ #define NAT_FQ_NELTS 64 /* NAT buffer flags */ #define SNAT_FLAG_HAIRPINNING (1 << 0) /* session key (4-tuple) */ typedef struct { union { struct { ip4_address_t addr; u16 port; u16 protocol:3, fib_index:13; }; u64 as_u64; }; } snat_session_key_t; /* endpoint-dependent session key (6-tuple) */ typedef struct { union { struct { ip4_address_t l_addr; ip4_address_t r_addr; u32 proto:8, fib_index:24; u16 l_port; u16 r_port; }; u64 as_u64[2]; }; } nat_ed_ses_key_t; /* deterministic session outside key */ 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; /* user (internal host) key */ typedef struct { union { struct { ip4_address_t addr; u32 fib_index; }; u64 as_u64; }; } snat_user_key_t; typedef struct { u32 sw_if_index; u32 next_index; u8 cached; } nat44_reass_trace_t; /* External address and port allocation modes */ #define foreach_nat_addr_and_port_alloc_alg \ _(0, DEFAULT, "default") \ _(1, MAPE, "map-e") \ _(2, RANGE, "port-range") typedef enum { #define _(v, N, s) NAT_ADDR_AND_PORT_ALLOC_ALG_##N = v, foreach_nat_addr_and_port_alloc_alg #undef _ } nat_addr_and_port_alloc_alg_t; /* Supported L4 protocols */ #define foreach_snat_protocol \ _(UDP, 0, udp, "udp") \ _(TCP, 1, tcp, "tcp") \ _(ICMP, 2, icmp, "icmp") typedef enum { #define _(N, i, n, s) SNAT_PROTOCOL_##N = i, foreach_snat_protocol #undef _ } snat_protocol_t; /* Session state */ #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_CLOSING, "tcp-closing") \ _(7, TCP_LAST_ACK, "tcp-last-ack") \ _(8, TCP_CLOSED, "tcp-closed") \ _(9, ICMP_ACTIVE, "icmp-active") typedef enum { #define _(v, N, s) SNAT_SESSION_##N = v, foreach_snat_session_state #undef _ } snat_session_state_t; /* Endpoint dependent TCP session state */ #define NAT44_SES_I2O_FIN 1 #define NAT44_SES_O2I_FIN 2 #define NAT44_SES_I2O_FIN_ACK 4 #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_UNKNOWN_PROTO 2 #define SNAT_SESSION_FLAG_LOAD_BALANCING 4 #define SNAT_SESSION_FLAG_TWICE_NAT 8 #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 { /* Outside network key */ snat_session_key_t out2in; /* Inside network key */ snat_session_key_t in2out; /* Flags */ u32 flags; /* Per-user translations */ u32 per_user_index; u32 per_user_list_head_index; /* Last heard timer */ f64 last_heard; /* Last HA refresh */ f64 ha_last_refreshed; /* Counters */ u64 total_bytes; u32 total_pkts; /* External host address and port */ ip4_address_t ext_host_addr; u16 ext_host_port; /* External host address and port after translation */ ip4_address_t ext_host_nat_addr; u16 ext_host_nat_port; /* TCP session state */ u8 state; u32 i2o_fin_seq; u32 o2i_fin_seq; /* user index */ u32 user_index; }) snat_session_t; /* *INDENT-ON* */ typedef struct { ip4_address_t addr; u32 fib_index; u32 sessions_per_user_list_head_index; u32 nsessions; u32 nstaticsessions; } snat_user_t; typedef struct { ip4_address_t addr; u32 fib_index; /* *INDENT-OFF* */ #define _(N, i, n, s) \ u16 busy_##n##_ports; \ u16 * busy_##n##_ports_per_thread; \ uword * busy_##n##_port_bitmap; foreach_snat_protocol #undef _ /* *INDENT-ON* */ } snat_address_t; typedef struct { u32 fib_index; u32 refcount; } nat_outside_fib_t; typedef struct { /* Inside network port */ u16 in_port; /* Outside network address and port */ snat_det_out_key_t out; /* Session state */ u8 state; /* Expire timeout */ u32 expire; } snat_det_session_t; typedef struct { /* inside IP address range */ ip4_address_t in_addr; u8 in_plen; /* outside IP address range */ ip4_address_t out_addr; u8 out_plen; /* inside IP addresses / outside IP addresses */ u32 sharing_ratio; /* number of ports available to internal host */ u16 ports_per_host; /* session counter */ u32 ses_num; /* vector of sessions */ snat_det_session_t *sessions; } snat_det_map_t; typedef struct { /* backend IP address */ ip4_address_t addr; /* backend port number */ u16 port; /* probability of the backend to be randomly matched */ u8 probability; u8 prefix; /* backend FIB table */ u32 vrf_id; u32 fib_index; } nat44_lb_addr_port_t; typedef enum { /* twice-nat disabled */ TWICE_NAT_DISABLED, /* twice-nat enabled */ TWICE_NAT, /* twice-nat only when src IP equals dst IP after translation */ TWICE_NAT_SELF, } twice_nat_type_t; typedef enum { /* no load-balancing */ NO_LB_NAT, /* load-balancing */ LB_NAT, /* load-balancing with affinity */ AFFINITY_LB_NAT, } lb_nat_type_t; typedef struct { /* local IP address */ ip4_address_t local_addr; /* external IP address */ ip4_address_t external_addr; /* local port */ u16 local_port; /* external port */ u16 external_port; /* is twice-nat */ twice_nat_type_t twice_nat; /* local FIB table */ u32 vrf_id; u32 fib_index; /* protocol */ snat_protocol_t proto; /* 0 = disabled, otherwise client IP affinity sticky time in seconds */ u32 affinity; /* worker threads used by backends/local host */ u32 *workers; /* opaque string tag */ u8 *tag; /* backends for load-balancing mode */ 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; u8 flags; } snat_interface_t; typedef struct { ip4_address_t l_addr; u16 l_port; u16 e_port; 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; typedef struct { /* Main lookup tables */ clib_bihash_8_8_t out2in; clib_bihash_8_8_t in2out; /* Endpoint dependent sessions lookup tables */ clib_bihash_16_8_t out2in_ed; clib_bihash_16_8_t in2out_ed; /* Find-a-user => src address lookup */ clib_bihash_8_8_t user_hash; /* User pool */ snat_user_t *users; /* Session pool */ snat_session_t *sessions; /* Pool of doubly-linked list elements */ dlist_elt_t *list_pool; /* NAT thread index */ u32 snat_thread_index; } snat_main_per_thread_data_t; struct snat_main_s; /* ICMP session match function */ typedef u32 (snat_icmp_match_function_t) (struct snat_main_s * sm, vlib_node_runtime_t * node, u32 thread_index, vlib_buffer_t * b0,
/*
 *------------------------------------------------------------------
 * svmdb.h - shared VM database
 *
 * Copyright (c) 2009 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

#ifndef __included_svmdb_h__
#define __included_svmdb_h__

#include "svm.h"

typedef enum
{
  SVMDB_ACTION_ILLEGAL = 0,
  SVMDB_ACTION_GET,		/* not clear why anyone would care */
  SVMDB_ACTION_SET,
  SVMDB_ACTION_UNSET,
} svmdb_action_t;

typedef struct
{
  int pid;
  int signum;
  u32 action:4;
  u32 opaque:28;
} svmdb_notify_t;

typedef struct
{
  u8 *value;
  svmdb_notify_t *notifications;
  u32 elsize;
} svmdb_value_t;

typedef enum
{
  SVMDB_NAMESPACE_STRING = 0,
  SVMDB_NAMESPACE_VEC,
  SVMDB_N_NAMESPACES,
} svmdb_namespace_t;

typedef struct
{
  uword version;
  /* pool of values */
  svmdb_value_t *values;
  uword *namespaces[SVMDB_N_NAMESPACES];
} svmdb_shm_hdr_t;

#define SVMDB_SHM_VERSION 2

typedef struct
{
  int flags;
  int pid;
  svm_region_t *db_rp;
  svmdb_shm_hdr_t *shm;
} svmdb_client_t;

typedef struct
{
  int add_del;
  svmdb_namespace_t nspace;
  char *var;
  u32 elsize;
  int signum;
  u32 action:4;
  u32 opaque:28;
} svmdb_notification_args_t;

typedef struct
{
  const char *root_path;
  uword size;
  u32 uid;
  u32 gid;
} svmdb_map_args_t;

/*
 * Must be a reasonable number, several mb smaller than
 * SVM_GLOBAL_REGION_SIZE, or no donut for you...
 */
#define SVMDB_DEFAULT_SIZE (4<<20)

svmdb_client_t *svmdb_map (svmdb_map_args_t *);

void svmdb_unmap (svmdb_client_t * client);
void svmdb_local_unset_string_variable (svmdb_client_t * client, char *var);
void svmdb_local_set_string_variable (svmdb_client_t * client,
				      char *var, char *val);
char *svmdb_local_get_string_variable (svmdb_client_t * client, char *var);
void *svmdb_local_get_variable_reference (svmdb_client_t * client,
					  svmdb_namespace_t ns, char *var);

void svmdb_local_dump_strings (svmdb_client_t * client);

void svmdb_local_unset_vec_variable (svmdb_client_t * client, char *var);
void svmdb_local_set_vec_variable (svmdb_client_t * client,
				   char *var, void *val, u32 elsize);
void *svmdb_local_get_vec_variable (svmdb_client_t * client, char *var,
				    u32 elsize);
void svmdb_local_dump_vecs (svmdb_client_t * client);

int svmdb_local_add_del_notification (svmdb_client_t * client,
				      svmdb_notification_args_t * args);

void *svmdb_local_find_or_add_vec_variable (svmdb_client_t * client,
					    char *var, u32 nbytes);

int svmdb_local_serialize_strings (svmdb_client_t * client, char *filename);
int svmdb_local_unserialize_strings (svmdb_client_t * client, char *filename);


#endif /* __included_svmdb_h__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
1 if matched mapping is address only * @param twice_nat matched mapping is twice NAT type * @param lb 1 if matched mapping is load-balanced * @param ext_host_addr external host address * * @returns 0 if match found otherwise 1. */ int snat_static_mapping_match (snat_main_t * sm, snat_session_key_t match, snat_session_key_t * mapping, u8 by_external, u8 * is_addr_only, twice_nat_type_t * twice_nat, lb_nat_type_t * lb, ip4_address_t * ext_host_addr, u8 * is_identity_nat); /** * @brief Add/del NAT address to FIB. * * Add the external NAT address to the FIB as receive entries. This ensures * that VPP will reply to ARP for this address and we don't need to enable * proxy ARP on the outside interface. * * @param addr IPv4 address * @param plen address prefix length * @param sw_if_index software index of the outside interface * @param is_add 0 = delete, 1 = add. */ 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 * value to NAT an echo request/reply. */ typedef struct { u16 identifier; u16 sequence; } icmp_echo_header_t; typedef struct { u16 src_port, dst_port; } tcp_udp_header_t; #endif /* __included_nat_h__ */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */