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 */
void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log);
-inline void handle_cnat_port_exceeded_logging(
+void handle_cnat_port_exceeded_logging(
cnat_user_db_entry_t *udb,
cnat_key_t * key,
cnat_vrfmap_t *vrfmap);
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 = {
found:
pool_put(cnat_user_db, up);
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
}
cnat_user_db_entry_t*
{
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));
#ifndef NO_BULK_LOGGING
INIT_BULK_CACHE(udb)
#endif /* NO_BULK_LOGGING */
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
return udb;
}
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);
#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;
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
}
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*
* 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,
/*
* 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 {
/*
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 */
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
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
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
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) {
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;
return NULL;
}
+ pthread_spin_lock(cnat_db_v2_main.session_db_lockp);
pool_get(cnat_session_db, db);
memset(db, 0, sizeof(*db));
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;
}
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;
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 */
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)
{
{
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));
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));
}
#endif
-inline void handle_cnat_port_exceeded_logging(
+void handle_cnat_port_exceeded_logging(
cnat_user_db_entry_t *udb,
cnat_key_t * key,
cnat_vrfmap_t *vrfmap)
#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
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;