aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat_affinity.c
diff options
context:
space:
mode:
authorFilip Varga <fivarga@cisco.com>2021-02-17 14:34:54 +0100
committerOle Tr�an <otroan@employees.org>2021-02-24 19:25:25 +0000
commit0eaf4e6784efb2d058fe2f031578251b6bcc0aa8 (patch)
treecc0c2b485bfee51068fa4970acc9f95ec595e8e5 /src/plugins/nat/nat_affinity.c
parent5db2f4a4312112ab57043ce88f10edc4acc141ec (diff)
nat: Final NAT44 EI/ED split patch
This patch achieves complete separation of endpoint-dependent and endpoint-independent IPv4 NAT features. Some common stuff is also moved to NAT library. Type: refactor Change-Id: I52468b7e2b5ac28958a2baf8e2ea01787322e801 Signed-off-by: Filip Varga <fivarga@cisco.com>
Diffstat (limited to 'src/plugins/nat/nat_affinity.c')
-rw-r--r--src/plugins/nat/nat_affinity.c282
1 files changed, 0 insertions, 282 deletions
diff --git a/src/plugins/nat/nat_affinity.c b/src/plugins/nat/nat_affinity.c
deleted file mode 100644
index e7a7354c18d..00000000000
--- a/src/plugins/nat/nat_affinity.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 2018 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
- * @brief NAT plugin client-IP based session affinity for load-balancing
- */
-
-#include <nat/nat_affinity.h>
-#include <nat/nat.h>
-
-nat_affinity_main_t nat_affinity_main;
-
-#define AFFINITY_HASH_BUCKETS 65536
-#define AFFINITY_HASH_MEMORY (2 << 25)
-
-u8 *
-format_affinity_kvp (u8 * s, va_list * args)
-{
- clib_bihash_kv_16_8_t *v = va_arg (*args, clib_bihash_kv_16_8_t *);
- nat_affinity_key_t k;
-
- k.as_u64[0] = v->key[0];
- k.as_u64[1] = v->key[1];
-
- s = format (s, "client %U backend %U:%d proto %U index %llu",
- format_ip4_address, &k.client_addr,
- format_ip4_address, &k.service_addr,
- clib_net_to_host_u16 (k.service_port),
- format_nat_protocol, k.proto);
-
- return s;
-}
-
-void
-nat_affinity_enable ()
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- vlib_thread_main_t *tm = vlib_get_thread_main ();
-
- if (tm->n_vlib_mains > 1)
- clib_spinlock_init (&nam->affinity_lock);
- clib_bihash_init_16_8 (&nam->affinity_hash, "nat-affinity",
- AFFINITY_HASH_BUCKETS, AFFINITY_HASH_MEMORY);
- clib_bihash_set_kvp_format_fn_16_8 (&nam->affinity_hash,
- format_affinity_kvp);
-}
-
-void
-nat_affinity_disable ()
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- vlib_thread_main_t *tm = vlib_get_thread_main ();
-
- if (tm->n_vlib_mains > 1)
- clib_spinlock_free (&nam->affinity_lock);
- clib_bihash_free_16_8 (&nam->affinity_hash);
-}
-
-clib_error_t *
-nat_affinity_init (vlib_main_t * vm)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- nam->vlib_main = vm;
- return 0;
-}
-
-static_always_inline void
-make_affinity_kv (clib_bihash_kv_16_8_t * kv, ip4_address_t client_addr,
- ip4_address_t service_addr, u8 proto, u16 service_port)
-{
- nat_affinity_key_t *key = (nat_affinity_key_t *) kv->key;
-
- key->client_addr = client_addr;
- key->service_addr = service_addr;
- key->proto = proto;
- key->service_port = service_port;
-
- kv->value = ~0ULL;
-}
-
-u32
-nat_affinity_get_per_service_list_head_index (void)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- dlist_elt_t *head_elt;
-
- clib_spinlock_lock_if_init (&nam->affinity_lock);
-
- pool_get (nam->list_pool, head_elt);
- clib_dlist_init (nam->list_pool, head_elt - nam->list_pool);
-
- clib_spinlock_unlock_if_init (&nam->affinity_lock);
-
- return head_elt - nam->list_pool;
-}
-
-void
-nat_affinity_flush_service (u32 affinity_per_service_list_head_index)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- u32 elt_index;
- dlist_elt_t *elt;
- nat_affinity_t *a;
- clib_bihash_kv_16_8_t kv;
-
- clib_spinlock_lock_if_init (&nam->affinity_lock);
-
- while ((elt_index =
- clib_dlist_remove_head (nam->list_pool,
- affinity_per_service_list_head_index)) !=
- ~0)
- {
- elt = pool_elt_at_index (nam->list_pool, elt_index);
- a = pool_elt_at_index (nam->affinity_pool, elt->value);
- kv.key[0] = a->key.as_u64[0];
- kv.key[1] = a->key.as_u64[1];
- pool_put_index (nam->affinity_pool, elt->value);
- if (clib_bihash_add_del_16_8 (&nam->affinity_hash, &kv, 0))
- nat_elog_warn ("affinity key del failed");
- pool_put_index (nam->list_pool, elt_index);
- }
- pool_put_index (nam->list_pool, affinity_per_service_list_head_index);
-
- clib_spinlock_unlock_if_init (&nam->affinity_lock);
-}
-
-int
-nat_affinity_find_and_lock (ip4_address_t client_addr,
- ip4_address_t service_addr, u8 proto,
- u16 service_port, u8 * backend_index)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- clib_bihash_kv_16_8_t kv, value;
- nat_affinity_t *a;
- int rv = 0;
-
- make_affinity_kv (&kv, client_addr, service_addr, proto, service_port);
- clib_spinlock_lock_if_init (&nam->affinity_lock);
- if (clib_bihash_search_16_8 (&nam->affinity_hash, &kv, &value))
- {
- rv = 1;
- goto unlock;
- }
-
- a = pool_elt_at_index (nam->affinity_pool, value.value);
- /* if already expired delete */
- if (a->ref_cnt == 0)
- {
- if (a->expire < vlib_time_now (nam->vlib_main))
- {
- clib_dlist_remove (nam->list_pool, a->per_service_index);
- pool_put_index (nam->list_pool, a->per_service_index);
- pool_put_index (nam->affinity_pool, value.value);
- if (clib_bihash_add_del_16_8 (&nam->affinity_hash, &kv, 0))
- nat_elog_warn ("affinity key del failed");
- rv = 1;
- goto unlock;
- }
- }
- a->ref_cnt++;
- *backend_index = a->backend_index;
-
-unlock:
- clib_spinlock_unlock_if_init (&nam->affinity_lock);
- return rv;
-}
-
-static int
-affinity_is_expired_cb (clib_bihash_kv_16_8_t * kv, void *arg)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- nat_affinity_t *a;
-
- a = pool_elt_at_index (nam->affinity_pool, kv->value);
- if (a->ref_cnt == 0)
- {
- if (a->expire < vlib_time_now (nam->vlib_main))
- {
- clib_dlist_remove (nam->list_pool, a->per_service_index);
- pool_put_index (nam->list_pool, a->per_service_index);
- pool_put_index (nam->affinity_pool, kv->value);
- if (clib_bihash_add_del_16_8 (&nam->affinity_hash, kv, 0))
- nat_elog_warn ("affinity key del failed");
- return 1;
- }
- }
-
- return 0;
-}
-
-int
-nat_affinity_create_and_lock (ip4_address_t client_addr,
- ip4_address_t service_addr, u8 proto,
- u16 service_port, u8 backend_index,
- u32 sticky_time,
- u32 affinity_per_service_list_head_index)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- clib_bihash_kv_16_8_t kv, value;
- nat_affinity_t *a;
- dlist_elt_t *list_elt;
- int rv = 0;
-
- make_affinity_kv (&kv, client_addr, service_addr, proto, service_port);
- clib_spinlock_lock_if_init (&nam->affinity_lock);
- if (!clib_bihash_search_16_8 (&nam->affinity_hash, &kv, &value))
- {
- rv = 1;
- nat_elog_notice ("affinity key already exist");
- goto unlock;
- }
-
- pool_get (nam->affinity_pool, a);
- kv.value = a - nam->affinity_pool;
- rv =
- clib_bihash_add_or_overwrite_stale_16_8 (&nam->affinity_hash, &kv,
- affinity_is_expired_cb, NULL);
- if (rv)
- {
- nat_elog_notice ("affinity key add failed");
- pool_put (nam->affinity_pool, a);
- goto unlock;
- }
-
- pool_get (nam->list_pool, list_elt);
- clib_dlist_init (nam->list_pool, list_elt - nam->list_pool);
- list_elt->value = a - nam->affinity_pool;
- a->per_service_index = list_elt - nam->list_pool;
- a->backend_index = backend_index;
- a->ref_cnt = 1;
- a->sticky_time = sticky_time;
- a->key.as_u64[0] = kv.key[0];
- a->key.as_u64[1] = kv.key[1];
- clib_dlist_addtail (nam->list_pool, affinity_per_service_list_head_index,
- a->per_service_index);
-
-unlock:
- clib_spinlock_unlock_if_init (&nam->affinity_lock);
- return rv;
-}
-
-void
-nat_affinity_unlock (ip4_address_t client_addr, ip4_address_t service_addr,
- u8 proto, u16 service_port)
-{
- nat_affinity_main_t *nam = &nat_affinity_main;
- clib_bihash_kv_16_8_t kv, value;
- nat_affinity_t *a;
-
- make_affinity_kv (&kv, client_addr, service_addr, proto, service_port);
- clib_spinlock_lock_if_init (&nam->affinity_lock);
- if (clib_bihash_search_16_8 (&nam->affinity_hash, &kv, &value))
- goto unlock;
-
- a = pool_elt_at_index (nam->affinity_pool, value.value);
- a->ref_cnt--;
- if (a->ref_cnt == 0)
- a->expire = (u64) a->sticky_time + vlib_time_now (nam->vlib_main);
-
-unlock:
- clib_spinlock_unlock_if_init (&nam->affinity_lock);
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */