| /* |
| * Copyright (c) 2020 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 __CNAT_SESSION_H__ |
| #define __CNAT_SESSION_H__ |
| |
| #include <vnet/udp/udp_packet.h> |
| |
| #include <cnat/cnat_types.h> |
| #include <cnat/cnat_client.h> |
| #include <cnat/cnat_bihash.h> |
| |
| /** |
| * A session represents the memory of a translation. |
| * In the tx direction (from behind to in front of the NAT), the |
| * session is preserved so subsequent packets follow the same path |
| * even if the translation has been updated. In the tx direction |
| * the session represents the swap from the VIP to the server address |
| * In the RX direction the swap is from the server address/port to VIP. |
| * |
| * A session exists only as key and value in the bihash, there is no |
| * pool for this object. If there were a pool, one would need to be |
| * concerned about what worker is using it. |
| */ |
| typedef struct cnat_session_t_ |
| { |
| /** |
| * this key sits in the same memory location a 'key' in the bihash kvp |
| */ |
| struct |
| { |
| /** |
| * IP 4/6 address in the rx/tx direction |
| */ |
| ip46_address_t cs_ip[VLIB_N_DIR]; |
| |
| /** |
| * ports in rx/tx |
| */ |
| u16 cs_port[VLIB_N_DIR]; |
| |
| /** |
| * The IP protocol TCP or UDP only supported |
| */ |
| ip_protocol_t cs_proto; |
| |
| /** |
| * The address family describing the IP addresses |
| */ |
| u8 cs_af; |
| |
| /** |
| * input / output / fib session |
| */ |
| u8 cs_loc; |
| |
| u8 __cs_pad; |
| } key; |
| /** |
| * this value sits in the same memory location a 'value' in the bihash kvp |
| */ |
| struct |
| { |
| /** |
| * The IP address to translate to. |
| */ |
| ip46_address_t cs_ip[VLIB_N_DIR]; |
| |
| /** |
| * the port to translate to. |
| */ |
| u16 cs_port[VLIB_N_DIR]; |
| |
| /** |
| * The load balance object to use to forward |
| */ |
| index_t cs_lbi; |
| |
| /** |
| * Persist translation->ct_lb.dpoi_next_node |
| */ |
| u32 dpoi_next_node; |
| |
| /** |
| * Timestamp index this session was last used |
| */ |
| u32 cs_ts_index; |
| |
| /** |
| * session flags |
| */ |
| u32 flags; |
| |
| u32 __pad; |
| } value; |
| } cnat_session_t; |
| |
| typedef enum cnat_session_flag_t_ |
| { |
| /** |
| * Indicates a return path session that was source NATed |
| * on the way in. |
| */ |
| CNAT_SESSION_FLAG_HAS_SNAT = (1 << 0), |
| /** |
| * This session source port was allocated, free it on cleanup |
| */ |
| CNAT_SESSION_FLAG_ALLOC_PORT = (1 << 1), |
| /** |
| * This session doesn't have a client, do not attempt to free it |
| */ |
| CNAT_SESSION_FLAG_NO_CLIENT = (1 << 2), |
| |
| /* Do not actually translate the packet but still forward it |
| * Used for Maglev, with an encap */ |
| CNAT_SESSION_FLAG_NO_NAT = (1 << 3), |
| |
| /* Debug flag marking return sessions */ |
| CNAT_SESSION_IS_RETURN = (1 << 4), |
| |
| /** On conflicts when adding the return session, try to sNAT the |
| * forward session, and dNAT the return session with a random port */ |
| CNAT_SESSION_RETRY_SNAT = (1 << 5), |
| |
| } cnat_session_flag_t; |
| |
| typedef enum cnat_session_location_t_ |
| { |
| CNAT_LOCATION_INPUT = 0, |
| CNAT_LOCATION_OUTPUT = 1, |
| CNAT_LOCATION_FIB = 0xff, |
| } cnat_session_location_t; |
| |
| extern u8 *format_cnat_session (u8 * s, va_list * args); |
| |
| /** |
| * Ensure the session object correctly overlays the bihash key/value pair |
| */ |
| STATIC_ASSERT (STRUCT_OFFSET_OF (cnat_session_t, key) == |
| STRUCT_OFFSET_OF (cnat_bihash_kv_t, key), |
| "key overlaps"); |
| STATIC_ASSERT (STRUCT_OFFSET_OF (cnat_session_t, value) == |
| STRUCT_OFFSET_OF (cnat_bihash_kv_t, value), |
| "value overlaps"); |
| STATIC_ASSERT (sizeof (cnat_session_t) == sizeof (cnat_bihash_kv_t), |
| "session kvp"); |
| |
| /** |
| * The DB of sessions |
| */ |
| extern cnat_bihash_t cnat_session_db; |
| |
| /** |
| * Callback function invoked during a walk of all translations |
| */ |
| typedef walk_rc_t (*cnat_session_walk_cb_t) (const cnat_session_t * |
| session, void *ctx); |
| |
| /** |
| * Walk/visit each of the cnat session |
| */ |
| extern void cnat_session_walk (cnat_session_walk_cb_t cb, void *ctx); |
| |
| /** |
| * Scan the session DB for expired sessions |
| */ |
| extern u64 cnat_session_scan (vlib_main_t * vm, f64 start_time, int i); |
| |
| /** |
| * Purge all the sessions |
| */ |
| extern int cnat_session_purge (void); |
| |
| /** |
| * Free a session & update refcounts |
| */ |
| extern void cnat_session_free (cnat_session_t * session); |
| |
| /** |
| * Port cleanup callback |
| */ |
| extern void (*cnat_free_port_cb) (u16 port, ip_protocol_t iproto); |
| |
| /* |
| * fd.io coding-style-patch-verification: ON |
| * |
| * Local Variables: |
| * eval: (c-set-style "gnu") |
| * End: |
| */ |
| |
| #endif |