diff options
author | Matus Fabian <matfabia@cisco.com> | 2017-07-06 05:37:49 -0700 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2017-07-07 07:04:42 +0000 |
commit | 7968e6cad5fac28568162945e2e57556740013fd (patch) | |
tree | e379568214b125982ff3348d4943c1ac5cab8832 /src/plugins/snat/snat.c | |
parent | 7b749fe890a4acb23431148859c25643a3597d2a (diff) |
SNAT: Fallback to 3-tuple key for non TCP/UDP sessions (VPP-884)
Change-Id: I4868ff6e81c579b29d3ea066976ae145f8b83e9e
Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src/plugins/snat/snat.c')
-rw-r--r-- | src/plugins/snat/snat.c | 102 |
1 files changed, 87 insertions, 15 deletions
diff --git a/src/plugins/snat/snat.c b/src/plugins/snat/snat.c index df0a5a07294..97eb061c16b 100644 --- a/src/plugins/snat/snat.c +++ b/src/plugins/snat/snat.c @@ -468,6 +468,31 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, continue; } + if (snat_is_unk_proto_session (s)) + { + clib_bihash_kv_16_8_t up_kv; + snat_unk_proto_ses_key_t up_key; + up_key.l_addr = s->in2out.addr; + up_key.r_addr = s->ext_host_addr; + up_key.fib_index = s->in2out.fib_index; + up_key.proto = s->in2out.port; + up_key.rsvd[0] = up_key.rsvd[1] = up_key.rsvd[2] = 0; + up_kv.key[0] = up_key.as_u64[0]; + up_kv.key[1] = up_key.as_u64[1]; + if (clib_bihash_add_del_16_8 (&sm->in2out_unk_proto, + &up_kv, 0)) + clib_warning ("in2out key del failed"); + + up_key.l_addr = s->out2in.addr; + up_key.fib_index = s->out2in.fib_index; + up_kv.key[0] = up_key.as_u64[0]; + up_kv.key[1] = up_key.as_u64[1]; + if (clib_bihash_add_del_16_8 (&sm->out2in_unk_proto, + &up_kv, 0)) + clib_warning ("out2in key del failed"); + + goto delete; + } /* log NAT event */ snat_ipfix_logging_nat44_ses_delete(s->in2out.addr.as_u32, s->out2in.addr.as_u32, @@ -477,9 +502,12 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, s->in2out.fib_index); value.key = s->in2out.as_u64; - clib_bihash_add_del_8_8 (&sm->in2out, &value, 0); + if (clib_bihash_add_del_8_8 (&sm->in2out, &value, 0)) + clib_warning ("in2out key del failed"); value.key = s->out2in.as_u64; - clib_bihash_add_del_8_8 (&sm->out2in, &value, 0); + if (clib_bihash_add_del_8_8 (&sm->out2in, &value, 0)) + clib_warning ("out2in key del failed"); +delete: pool_put (tsm->sessions, s); clib_dlist_remove (tsm->list_pool, del_elt_index); @@ -572,18 +600,44 @@ int snat_del_address (snat_main_t *sm, ip4_address_t addr, u8 delete_sm) pool_foreach (ses, tsm->sessions, ({ if (ses->out2in.addr.as_u32 == addr.as_u32) { - /* log NAT event */ - snat_ipfix_logging_nat44_ses_delete(ses->in2out.addr.as_u32, - ses->out2in.addr.as_u32, - ses->in2out.protocol, - ses->in2out.port, - ses->out2in.port, - ses->in2out.fib_index); + if (snat_is_unk_proto_session (ses)) + { + clib_bihash_kv_16_8_t up_kv; + snat_unk_proto_ses_key_t up_key; + up_key.l_addr = ses->in2out.addr; + up_key.r_addr = ses->ext_host_addr; + up_key.fib_index = ses->in2out.fib_index; + up_key.proto = ses->in2out.port; + up_key.rsvd[0] = up_key.rsvd[1] = up_key.rsvd[2] = 0; + up_kv.key[0] = up_key.as_u64[0]; + up_kv.key[1] = up_key.as_u64[1]; + if (clib_bihash_add_del_16_8 (&sm->in2out_unk_proto, + &up_kv, 0)) + clib_warning ("in2out key del failed"); + + up_key.l_addr = ses->out2in.addr; + up_key.fib_index = ses->out2in.fib_index; + up_kv.key[0] = up_key.as_u64[0]; + up_kv.key[1] = up_key.as_u64[1]; + if (clib_bihash_add_del_16_8 (&sm->out2in_unk_proto, + &up_kv, 0)) + clib_warning ("out2in key del failed"); + } + else + { + /* log NAT event */ + snat_ipfix_logging_nat44_ses_delete(ses->in2out.addr.as_u32, + ses->out2in.addr.as_u32, + ses->in2out.protocol, + ses->in2out.port, + ses->out2in.port, + ses->in2out.fib_index); + kv.key = ses->in2out.as_u64; + clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0); + kv.key = ses->out2in.as_u64; + clib_bihash_add_del_8_8 (&sm->out2in, &kv, 0); + } vec_add1 (ses_to_be_removed, ses - tsm->sessions); - kv.key = ses->in2out.as_u64; - clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0); - kv.key = ses->out2in.as_u64; - clib_bihash_add_del_8_8 (&sm->out2in, &kv, 0); clib_dlist_remove (tsm->list_pool, ses->per_user_index); user_key.addr = ses->in2out.addr; user_key.fib_index = ses->in2out.fib_index; @@ -1575,6 +1629,12 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) clib_bihash_init_8_8 (&sm->user_hash, "users", user_buckets, user_memory_size); + + clib_bihash_init_16_8 (&sm->in2out_unk_proto, "in2out-unk-proto", + translation_buckets, translation_memory_size); + + clib_bihash_init_16_8 (&sm->out2in_unk_proto, "out2in-unk-proto", + translation_buckets, translation_memory_size); } else { @@ -1636,8 +1696,20 @@ u8 * format_snat_session (u8 * s, va_list * args) snat_main_t * sm __attribute__((unused)) = va_arg (*args, snat_main_t *); snat_session_t * sess = va_arg (*args, snat_session_t *); - s = format (s, " i2o %U\n", format_snat_key, &sess->in2out); - s = format (s, " o2i %U\n", format_snat_key, &sess->out2in); + if (snat_is_unk_proto_session (sess)) + { + s = format (s, " i2o %U proto %u fib %u\n", + format_ip4_address, &sess->in2out.addr, sess->in2out.port, + sess->in2out.fib_index); + s = format (s, " o2i %U proto %u fib %u\n", + format_ip4_address, &sess->out2in.addr, sess->out2in.port, + sess->out2in.fib_index); + } + else + { + s = format (s, " i2o %U\n", format_snat_key, &sess->in2out); + s = format (s, " o2i %U\n", format_snat_key, &sess->out2in); + } s = format (s, " last heard %.2f\n", sess->last_heard); s = format (s, " total pkts %d, total bytes %lld\n", sess->total_pkts, sess->total_bytes); |