aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat.h
diff options
context:
space:
mode:
authorKlement Sekera <ksekera@cisco.com>2020-12-15 18:47:05 +0100
committerOle Tr�an <otroan@employees.org>2021-01-18 08:36:26 +0000
commit4881cb4c6f0d9c6276eb7a45ed355f9fc3d729b3 (patch)
tree07959eb6fc99b88b30e6f81f4620d8d6c70110e2 /src/plugins/nat/nat.h
parent4a58e49cfe03150034a65e147a2ffe8d24391b86 (diff)
nat: deal with flows instead of sessions
This change introduces flow concept to endpoint-dependent NAT. Instead of having a session and a plethora of special cases in code for e.g. hairpinning, twice-nat and others, figure all this out and store it in flow logic. Every flow has a match and a rewrite part. This unifies all the NAT packet processing cases into one - match a flow and rewrite the packet based on that flow. It also provides a cure for hairpinning dilemma where one part of the flow is on one worker and another on a different one. These cases are also sped up by not requiring destination adress lookup every single time to be able to rewrite source nat as this is now part of flow rewrite logic. Type: improvement Change-Id: Ib60c992e16792ea4d4129bc10202ebb99a73b5be Signed-off-by: Klement Sekera <ksekera@cisco.com>
Diffstat (limited to 'src/plugins/nat/nat.h')
-rw-r--r--src/plugins/nat/nat.h178
1 files changed, 115 insertions, 63 deletions
diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h
index 58883d491aa..7fa1ef79c3d 100644
--- a/src/plugins/nat/nat.h
+++ b/src/plugins/nat/nat.h
@@ -88,7 +88,6 @@ typedef enum
NAT_NEXT_IN2OUT_ED_OUTPUT_SLOW_PATH,
NAT_NEXT_OUT2IN_ED_FAST_PATH,
NAT_NEXT_OUT2IN_ED_SLOW_PATH,
- NAT_NEXT_OUT2IN_ED_HANDOFF,
NAT_NEXT_IN2OUT_CLASSIFY,
NAT_NEXT_OUT2IN_CLASSIFY,
NAT_N_NEXT,
@@ -163,29 +162,17 @@ typedef enum
NAT_IN2OUT_ED_N_ERROR,
} nat_in2out_ed_error_t;
-#define foreach_nat44_handoff_error \
-_(CONGESTION_DROP, "congestion drop") \
-_(SAME_WORKER, "same worker") \
-_(DO_HANDOFF, "do handoff")
-
-typedef enum
-{
-#define _(sym,str) NAT44_HANDOFF_ERROR_##sym,
- foreach_nat44_handoff_error
-#undef _
- NAT44_HANDOFF_N_ERROR,
-} nat44_handoff_error_t;
-
-#define foreach_nat_out2in_ed_error \
-_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
-_(OUT_OF_PORTS, "out of ports") \
-_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "no translation") \
-_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
-_(MAX_USER_SESS_EXCEEDED, "max user sessions exceeded") \
-_(CANNOT_CREATE_USER, "cannot create NAT user") \
-_(NON_SYN, "non-SYN packet try to create session") \
-_(TCP_CLOSED, "drops due to TCP in transitory timeout")
+#define foreach_nat_out2in_ed_error \
+ _ (UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+ _ (OUT_OF_PORTS, "out of ports") \
+ _ (BAD_ICMP_TYPE, "unsupported ICMP type") \
+ _ (NO_TRANSLATION, "no translation") \
+ _ (MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+ _ (MAX_USER_SESS_EXCEEDED, "max user sessions exceeded") \
+ _ (CANNOT_CREATE_USER, "cannot create NAT user") \
+ _ (NON_SYN, "non-SYN packet try to create session") \
+ _ (TCP_CLOSED, "drops due to TCP in transitory timeout") \
+ _ (HASH_ADD_FAILED, "hash table add failed")
typedef enum
{
@@ -206,14 +193,15 @@ typedef enum
#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_EXACT_ADDRESS 128
+#define SNAT_SESSION_FLAG_STATIC_MAPPING (1 << 0)
+#define SNAT_SESSION_FLAG_UNKNOWN_PROTO (1 << 1)
+#define SNAT_SESSION_FLAG_LOAD_BALANCING (1 << 2)
+#define SNAT_SESSION_FLAG_TWICE_NAT (1 << 3)
+#define SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT (1 << 4)
+#define SNAT_SESSION_FLAG_FWD_BYPASS (1 << 5)
+#define SNAT_SESSION_FLAG_AFFINITY (1 << 6)
+#define SNAT_SESSION_FLAG_EXACT_ADDRESS (1 << 7)
+#define SNAT_SESSION_FLAG_HAIRPINNING (1 << 8)
/* NAT interface flags */
#define NAT_INTERFACE_FLAG_IS_INSIDE 1
@@ -240,6 +228,72 @@ typedef CLIB_PACKED(struct
}) per_vrf_sessions_t;
/* *INDENT-ON* */
+typedef struct
+{
+ ip4_address_t saddr, daddr;
+ u32 fib_index;
+ u16 sport, dport;
+ u16 icmp_id;
+ u8 proto;
+} nat_6t_t;
+
+typedef struct
+{
+#define NAT_FLOW_OP_SADDR_REWRITE (1 << 1)
+#define NAT_FLOW_OP_SPORT_REWRITE (1 << 2)
+#define NAT_FLOW_OP_DADDR_REWRITE (1 << 3)
+#define NAT_FLOW_OP_DPORT_REWRITE (1 << 4)
+#define NAT_FLOW_OP_ICMP_ID_REWRITE (1 << 5)
+#define NAT_FLOW_OP_TXFIB_REWRITE (1 << 6)
+ int ops;
+ nat_6t_t match;
+ nat_6t_t rewrite;
+ uword l3_csum_delta;
+ uword l4_csum_delta;
+} nat_6t_flow_t;
+
+always_inline void
+nat_6t_flow_saddr_rewrite_set (nat_6t_flow_t *f, u32 saddr)
+{
+ f->ops |= NAT_FLOW_OP_SADDR_REWRITE;
+ f->rewrite.saddr.as_u32 = saddr;
+}
+
+always_inline void
+nat_6t_flow_daddr_rewrite_set (nat_6t_flow_t *f, u32 daddr)
+{
+ f->ops |= NAT_FLOW_OP_DADDR_REWRITE;
+ f->rewrite.daddr.as_u32 = daddr;
+}
+
+always_inline void
+nat_6t_flow_sport_rewrite_set (nat_6t_flow_t *f, u32 sport)
+{
+ f->ops |= NAT_FLOW_OP_SPORT_REWRITE;
+ f->rewrite.sport = sport;
+}
+
+always_inline void
+nat_6t_flow_dport_rewrite_set (nat_6t_flow_t *f, u32 dport)
+{
+ f->ops |= NAT_FLOW_OP_DPORT_REWRITE;
+ f->rewrite.dport = dport;
+}
+
+always_inline void
+nat_6t_flow_txfib_rewrite_set (nat_6t_flow_t *f, u32 tx_fib_index)
+{
+ f->ops |= NAT_FLOW_OP_TXFIB_REWRITE;
+ f->rewrite.fib_index = tx_fib_index;
+}
+
+always_inline void
+nat_6t_flow_icmp_id_rewrite_set (nat_6t_flow_t *f, u16 id)
+{
+ f->ops |= NAT_FLOW_OP_ICMP_ID_REWRITE;
+ f->rewrite.icmp_id = id;
+}
+
/* *INDENT-OFF* */
typedef CLIB_PACKED(struct
{
@@ -261,6 +315,9 @@ typedef CLIB_PACKED(struct
nat_protocol_t nat_proto;
+ nat_6t_flow_t i2o;
+ nat_6t_flow_t o2i;
+
/* Flags */
u32 flags;
@@ -439,9 +496,6 @@ typedef struct
clib_bihash_8_8_t out2in;
clib_bihash_8_8_t in2out;
- /* Endpoint dependent sessions lookup tables */
- clib_bihash_16_8_t in2out_ed;
-
/* Find-a-user => src address lookup */
clib_bihash_8_8_t user_hash;
@@ -536,8 +590,8 @@ typedef struct snat_main_s
/* Static mapping pool */
snat_static_mapping_t *static_mappings;
- /* Endpoint-dependent out2in mappings */
- clib_bihash_16_8_t out2in_ed;
+ /* Endpoint dependent lookup table */
+ clib_bihash_16_8_t flow_hash;
/* Interface pool */
snat_interface_t *interfaces;
@@ -616,9 +670,6 @@ typedef struct snat_main_s
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;
nat44_config_t rconfig;
//nat44_config_t cconfig;
@@ -1103,18 +1154,6 @@ u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
nat_protocol_t * proto, void *d, void *e,
u8 * dont_translate);
-/* ICMP endpoint-dependent session match functions */
-u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
- u32 thread_index, vlib_buffer_t * b0,
- ip4_header_t * ip0, ip4_address_t * addr,
- u16 * port, u32 * fib_index, nat_protocol_t * proto,
- void *d, void *e, u8 * dont_translate);
-u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
- u32 thread_index, vlib_buffer_t * b0,
- ip4_header_t * ip0, ip4_address_t * addr,
- u16 * port, u32 * fib_index, nat_protocol_t * proto,
- void *d, void *e, u8 * dont_translate);
-
u32 icmp_in2out (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
vlib_node_runtime_t * node, u32 next0, u32 thread_index,
@@ -1126,22 +1165,17 @@ u32 icmp_out2in (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
void *d, void *e);
/* hairpinning functions */
-u32 snat_icmp_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
- ip4_header_t * ip0, icmp46_header_t * icmp0,
- int is_ed);
+u32 snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0,
+ ip4_header_t *ip0, icmp46_header_t *icmp0);
+
void nat_hairpinning_sm_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
ip4_header_t * ip);
-void nat44_ed_hairpinning_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
- ip4_header_t * ip);
-int snat_hairpinning (vlib_main_t * vm, vlib_node_runtime_t * node,
- snat_main_t * sm, vlib_buffer_t * b0,
- ip4_header_t * ip0, udp_header_t * udp0,
- tcp_header_t * tcp0, u32 proto0, int is_ed,
+int snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node,
+ snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
+ udp_header_t *udp0, tcp_header_t *tcp0, u32 proto0,
int do_trace);
/* Call back functions for clib_bihash_add_or_overwrite_stale */
-int nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg);
-int nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg);
int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
@@ -1496,6 +1530,24 @@ u32 nat_calc_bihash_buckets (u32 n_elts);
void nat44_addresses_free (snat_address_t **addresses);
+typedef enum
+{
+ NAT_ED_TRNSL_ERR_SUCCESS = 0,
+ NAT_ED_TRNSL_ERR_TRANSLATION_FAILED = 1,
+ NAT_ED_TRNSL_ERR_FLOW_MISMATCH = 2,
+} nat_translation_error_e;
+
+nat_translation_error_e
+nat_6t_flow_buf_translate (snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip,
+ nat_6t_flow_t *f, nat_protocol_t proto,
+ int is_output_feature);
+
+void nat_6t_l3_l4_csum_calc (nat_6t_flow_t *f);
+
+format_function_t format_nat_ed_translation_error;
+format_function_t format_nat_6t_flow;
+format_function_t format_ed_session_kvp;
+
#endif /* __included_nat_h__ */
/*
* fd.io coding-style-patch-verification: ON