summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vnet/vnet/vcgn/cnat_db_v2.c96
1 files changed, 91 insertions, 5 deletions
diff --git a/vnet/vnet/vcgn/cnat_db_v2.c b/vnet/vnet/vcgn/cnat_db_v2.c
index 5a26fd99d6c..2b43849dca3 100644
--- a/vnet/vnet/vcgn/cnat_db_v2.c
+++ b/vnet/vnet/vcgn/cnat_db_v2.c
@@ -43,6 +43,12 @@
u8 cnat_db_init_done = 0;
typedef struct {
+ /* Locks for multi thread support */
+ CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
+ pthread_spinlock_t *main_db_lockp;
+ pthread_spinlock_t *user_db_lockp;
+ pthread_spinlock_t *session_db_lockp;
+
u32 cached_next_index;
/* $$$$ add data here */
@@ -543,6 +549,7 @@ void cnat_user_db_delete (cnat_user_db_entry_t *up)
return;
}
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
#if 1
if(PREDICT_FALSE(up->flags & CNAT_USER_DB_DSLITE_FLAG)) {
dslite_key_t dk = {
@@ -589,6 +596,7 @@ void cnat_user_db_delete (cnat_user_db_entry_t *up)
found:
pool_put(cnat_user_db, up);
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
}
cnat_user_db_entry_t*
@@ -622,6 +630,7 @@ cnat_user_db_create_entry(cnat_db_key_bucket_t *uki,
{
cnat_user_db_entry_t *udb = NULL;
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
pool_get(cnat_user_db, udb);
memset(udb, 0, sizeof(*udb));
@@ -636,6 +645,7 @@ cnat_user_db_create_entry(cnat_db_key_bucket_t *uki,
#ifndef NO_BULK_LOGGING
INIT_BULK_CACHE(udb)
#endif /* NO_BULK_LOGGING */
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
return udb;
}
@@ -773,6 +783,7 @@ void cnat_delete_main_db_entry_v2 (cnat_main_db_entry_t *ep)
return;
}
+ pthread_spin_lock(cnat_db_v2_main.main_db_lockp);
if(PREDICT_FALSE(ep->flags &
CNAT_DB_FLAG_PPTP_TUNNEL_ACTIVE)) {
pptp_clear_all_channels(ep);
@@ -815,7 +826,7 @@ void cnat_delete_main_db_entry_v2 (cnat_main_db_entry_t *ep)
#endif
spp_printf(CNAT_INV_UNUSED_USR_INDEX, 1, (u32 *) &(ep->user_index));
cnat_main_db_entry_dump(ep);
- return;
+ goto unlock;
}
up = cnat_user_db + ep->user_index;
@@ -922,7 +933,9 @@ delete_entry:
main_db_index = ep - cnat_main_db;
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
up->ntranslations--;
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
/*
* when user reaches max allowed port limit
@@ -975,6 +988,8 @@ delete_entry:
}
nat44_dslite_common_stats[instance].active_translations--;
nat44_dslite_global_stats[!!(instance - 1)].translation_delete_count ++;
+unlock:
+ pthread_spin_unlock(cnat_db_v2_main.main_db_lockp);
}
cnat_main_db_entry_t*
@@ -1098,8 +1113,8 @@ void cnat_add_dest_n_log(
* if reash per user port limit,
* set user_db_entry pointer, and error == CNAT_OUT_LIMIT
*/
-cnat_main_db_entry_t*
-cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
+static cnat_main_db_entry_t*
+_cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
port_pair_t port_pair_type,
port_type_t port_type,
cnat_gen_icmp_info *info,
@@ -1368,7 +1383,9 @@ cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
/*
* increment port in use for this user
*/
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
udb->ntranslations += 1;
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
} else {
/*
@@ -1592,7 +1609,9 @@ cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
db2->vrfmap_index = my_vrfmap - cnat_map_by_vrf;
db2->entry_expires = cnat_current_time;
db2->flags |= CNAT_DB_FLAG_ALG_ENTRY;
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
udb->ntranslations += 1;
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
db2->dst_ipv4 = dest_info->k.ipv4;
db2->dst_port = dest_info->k.port;
db2->nsessions = 0; /* For ALG db, set sessions to 0 - CSCuf78420 */
@@ -1624,6 +1643,22 @@ cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
return db;
}
+cnat_main_db_entry_t*
+cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
+ port_pair_t port_pair_type,
+ port_type_t port_type,
+ cnat_gen_icmp_info *info,
+ cnat_key_t *dest_info)
+{
+
+ cnat_main_db_entry_t *db;
+ pthread_spin_lock(cnat_db_v2_main.main_db_lockp);
+ db = _cnat_get_main_db_entry_v2(ki, port_pair_type,
+ port_type, info, dest_info);
+ pthread_spin_unlock(cnat_db_v2_main.main_db_lockp);
+ return db;
+}
+
/*
* this function is called from config handler only
* to allocate a static port based db entry
@@ -1650,6 +1685,9 @@ cnat_create_static_main_db_entry_v2 (cnat_db_key_bucket_t *ki,
int nfv9_log_req = BULK_ALLOC_NOT_ATTEMPTED;
#endif
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
/*
* need to try lookup again because
* second pkt may come here before the entry is created
@@ -1984,6 +2022,8 @@ dslite_create_static_main_db_entry_v2 (dslite_db_key_bucket_t *ki,
cnat_vrfmap_t *my_vrfmap =0;
u16 my_vrfmap_index;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
/*
* need to try lookup again because
* second pkt may come here before the entry is created
@@ -2416,6 +2456,9 @@ cnat_timeout_db_create (cnat_timeout_t t_entry)
pool_header_t *h;
u32 free;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
db_index = cnat_timeout_db_hash_lookup(t_key);
if(db_index != EMPTY) {
@@ -2457,6 +2500,9 @@ void cnat_timeout_db_delete(cnat_key_t t_key)
u32 index, bucket;
cnat_timeout_db_entry_t *this, *prev;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
key.k.ipv4 = t_key.k.ipv4;
key.k.port = t_key.k.port;
key.k.vrf = t_key.k.vrf;
@@ -2629,6 +2675,7 @@ cnat_create_session_db_entry(cnat_key_t *ko,
return NULL;
}
+ pthread_spin_lock(cnat_db_v2_main.session_db_lockp);
pool_get(cnat_session_db, db);
memset(db, 0, sizeof(*db));
@@ -2688,6 +2735,7 @@ cnat_create_session_db_entry(cnat_key_t *ko,
newly established sessions */
db->entry_expires = cnat_current_time;
nat44_dslite_common_stats[instance].sessions++;
+ pthread_spin_unlock(cnat_db_v2_main.session_db_lockp);
return db;
}
@@ -2739,7 +2787,8 @@ cnat_dest_update_session2main(cnat_main_db_entry_t *mdb,
mdb->dst_port = sdb->v4_dest_key.k.port;
}
-void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
+static void
+_cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
{
u32 session_db_index;
u32 bdb_len;
@@ -2807,7 +2856,7 @@ void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
ASSERT(sdb_last != NULL);
cnat_dest_update_session2main(be, sdb_last);
- cnat_delete_session_db_entry(sdb_last, FALSE);
+ _cnat_delete_session_db_entry(sdb_last, FALSE);
}
/* Remove from session DB hashes */
@@ -2817,6 +2866,13 @@ void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
pool_put(cnat_session_db, ep);
}
+void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
+{
+ pthread_spin_lock(cnat_db_v2_main.session_db_lockp);
+ _cnat_delete_session_db_entry (ep, log);
+ pthread_spin_unlock(cnat_db_v2_main.session_db_lockp);
+}
+
cnat_main_db_entry_t*
dslite_main_db_lookup_entry(dslite_db_key_bucket_t *ki)
{
@@ -2899,6 +2955,9 @@ dslite_user_db_create_entry(dslite_db_key_bucket_t *uki,
{
cnat_user_db_entry_t *udb = NULL;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
pool_get(cnat_user_db, udb);
memset(udb, 0, sizeof(*udb));
@@ -2943,6 +3002,9 @@ dslite_create_main_db_entry_and_hash(dslite_db_key_bucket_t *ki,
u32 db_index;
cnat_main_db_entry_t *db = NULL;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
pool_get(cnat_main_db, db);
memset(db, 0, sizeof(*db));
@@ -3086,6 +3148,10 @@ dslite_get_main_db_entry_v2(dslite_db_key_bucket_t *ki,
#ifndef NO_BULK_LOGGING
int nfv9_log_req = BULK_ALLOC_NOT_ATTEMPTED;
#endif
+
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
/*
* need to try lookup again because
* second pkt may come here before the entry is created
@@ -3709,6 +3775,26 @@ void cnat_db_v2_init (void)
svi_params_array[i].svi_type = CGSE_SVI_TYPE_INFRA;
}
#endif
+
+ cnat_db_v2_main.main_db_lockp =
+ clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
+ CLIB_CACHE_LINE_BYTES);
+
+ cnat_db_v2_main.user_db_lockp =
+ clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
+ CLIB_CACHE_LINE_BYTES);
+
+ cnat_db_v2_main.session_db_lockp =
+ clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
+ CLIB_CACHE_LINE_BYTES);
+
+ ASSERT (pthread_spin_init(cnat_db_v2_main.main_db_lockp,
+ PTHREAD_PROCESS_PRIVATE) == 0);
+ ASSERT (pthread_spin_init(cnat_db_v2_main.user_db_lockp,
+ PTHREAD_PROCESS_PRIVATE) == 0);
+ ASSERT (pthread_spin_init(cnat_db_v2_main.session_db_lockp,
+ PTHREAD_PROCESS_PRIVATE) == 0);
+
cnat_db_init_done = 1;
printf("CNAT DB init is successful\n");
return;