Move vcgn as plugin
[vpp.git] / vnet / vnet / vcgn / cnat_bulk_port.c
diff --git a/vnet/vnet/vcgn/cnat_bulk_port.c b/vnet/vnet/vcgn/cnat_bulk_port.c
deleted file mode 100644 (file)
index d8894eb..0000000
+++ /dev/null
@@ -1,964 +0,0 @@
-/* 
- *------------------------------------------------------------------
- * cnat_bulk_ports.c - wrappers for bulk port allocation
- *
- * Copyright (c) 2011-2013 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.
- *------------------------------------------------------------------
- */
-
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include <vppinfra/error.h>
-#include <vnet/buffer.h>
-#include <vppinfra/vec.h>
-#include <vppinfra/hash.h>
-#include <vppinfra/pool.h>
-#include <vppinfra/bitmap.h>
-
-#include "cnat_db.h"
-#include "cnat_config.h"
-#include "cnat_global.h"
-#include "cnat_logging.h"
-#include "spp_timers.h"
-#include "platform_common.h"
-#include "cgn_bitmap.h"
-#include "spp_platform_trace_log.h"
-#include "cnat_ports.h"
-
-#ifndef NO_BULK_LOGGING
-
-#define PORT_TO_CACHE(y, z)   ((y)/(z))
-/* The last bit (MSB) is used to indicate whether the cache entry is full */
-#define CACHE_TO_PORT(x, z)   (((x)& 0x7FFF) * (z))
-#define IS_CACHE_ENTRY_FULL(x) ((x) & 0x8000)
-#define MARK_CACHE_ENTRY_AS_FULL(x) ((x) = ((x) | 0x8000))
-#define UNMARK_CACHE_ENTRY_AS_FULL(x) ((x) = ((x) & 0x7FFF))
-#define CACHE_ENTRY_WITHOUT_FULL_STAT(x) ((x) & 0x7FFF) 
-
-
-#define NUM_BULK_CHECK  128 /* max number of previous chache to check.
-    * somewhat orbirtrary.. assume 64 as bulk size.. can handle up 
-    * to 128*64 ports allocated by a single subscriber */
-
-/* #define DEBUG_BULK_PORT 1 */
-/* #define DEBUG_BULK_PORT_DETAIL   1   */
-#define HAVE_BULK_PORT_STATS    1 
-
-#ifdef HAVE_BULK_PORT_STATS
-static uword bulk_cache_hit_count;
-static uword bulk_port_use_count;
-static uword bulk_port_alloc_count;
-static uword mapped_port_alloc_count;
-#endif /* HAVE_BULK_PORT_STATS */
-
-static u32 bulk_port_rand_across;
-
-void show_bulk_port_allocation(u16 in_vrfid, u32 inside_ip)
-{
-    cnat_db_key_bucket_t u_ki;
-    cnat_user_db_entry_t *udb;
-    int i;
-    u32 head;
-    cnat_main_db_entry_t *db = NULL;
-    i16 printed_so_far = 0; /* entries printed so far */
-    u16 prev_bulks[NUM_BULK_CHECK]; 
-    cnat_vrfmap_t *my_vrfmap = 0;
-    cnat_vrfmap_t *vrfmap = 0;
-    bulk_alloc_size_t bulk_size;
-
-    u_ki.k.k.vrf = in_vrfid;
-    u_ki.k.k.ipv4 = inside_ip; 
-    u_ki.k.k.port = 0;
-
-    PLATFORM_DEBUG_PRINT("Searching for user %x in invrf %d\n",
-        inside_ip, in_vrfid);
-    udb = cnat_user_db_lookup_entry(&u_ki);
-    if(!udb) {
-        PLATFORM_DEBUG_PRINT("No such user\n"); return; 
-    }
-
-    pool_foreach (vrfmap, cnat_map_by_vrf, ({
-        if(vrfmap->i_vrf == in_vrfid) {
-            my_vrfmap = vrfmap;
-            break;
-        }}));
-
-    if(!my_vrfmap) {
-        PLATFORM_DEBUG_PRINT("Vrf map not found\n");
-        return;
-    }
-    bulk_size = BULKSIZE_FROM_VRFMAP(my_vrfmap);
-
-    if(bulk_size == BULK_ALLOC_SIZE_NONE) {  
-        PLATFORM_DEBUG_PRINT("Bulk allocation not enabled\n"); 
-        return;
-    }
-    
-    PLATFORM_DEBUG_PRINT("\nBulk cache for subscriber 0x%x: ", inside_ip);
-    for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-        PLATFORM_DEBUG_PRINT("%d , ", 
-            CACHE_TO_PORT(udb->bulk_port_range_cache[i], bulk_size));
-    }
-    PLATFORM_DEBUG_PRINT("\nNon cached bulk allocation for subscriber 0x%x:\n", 
-            inside_ip);
-    ASSERT(udb);
-    memset(prev_bulks, 0,sizeof(prev_bulks));
-
-    head = udb->translation_list_head_index;
-    if(PREDICT_FALSE(head == EMPTY)) {
-        return;
-    }
-    db = cnat_main_db + head;
-    while (1) { 
-        /* skip static ports - static ports may not belong to bulk pool*/
-        if(db->out2in_key.k.port < cnat_static_port_range) goto next_entry;
-
-        u16 bm_index = PORT_TO_CACHE(db->out2in_key.k.port, bulk_size);
-
-        /*Check if we have already tested this bulk */
-        for(i=0; i < printed_so_far; i++) {
-            if(prev_bulks[i] == bm_index) goto next_entry;
-        }
-
-        /*Check if this base port is already part of cache */
-        for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(CACHE_ENTRY_WITHOUT_FULL_STAT(udb->bulk_port_range_cache[i])
-                == bm_index) {
-                goto next_entry;
-            }
-        }
-        /* this is not in chache already */
-        PLATFORM_DEBUG_PRINT("%d ", CACHE_TO_PORT(bm_index, bulk_size));
-        if(printed_so_far <  NUM_BULK_CHECK) {
-            prev_bulks[printed_so_far] = bm_index;
-            printed_so_far++;
-        }
-
-next_entry:
-        db = cnat_main_db + db->user_ports.next;
-        /*
-         * its a circular list, so if we have reached the head again
-         * all the entries for that user have been read
-         */
-        if (db == (cnat_main_db + head)) {
-            break;
-        }
-    } /* while loop for db entries */
-
-    PLATFORM_DEBUG_PRINT("\n");
-    return;
-}
-
-void show_bulk_port_stats()
-{
-
-    cnat_vrfmap_t *my_vrfmap = 0;
-    PLATFORM_DEBUG_PRINT("Bulk size settings of each inside vrf ...\n");
-    pool_foreach (my_vrfmap, cnat_map_by_vrf, ({
-        PLATFORM_DEBUG_PRINT("vrf id %d, bulk size %d\n", my_vrfmap->i_vrf,
-                BULKSIZE_FROM_VRFMAP(my_vrfmap));
-        }));
-
-#ifdef HAVE_BULK_PORT_STATS
-    PLATFORM_DEBUG_PRINT("\nBulk port allocation, use and cache hit statistics\n");
-    PLATFORM_DEBUG_PRINT("Number of times bulk ports allocated %lld\n", 
-            bulk_port_alloc_count);
-    PLATFORM_DEBUG_PRINT("Number of times pre-allocated ports used %lld\n",
-            bulk_port_use_count);
-    PLATFORM_DEBUG_PRINT(
-        "Number of times pre-allocated bulk port found from cache %lld\n",
-        bulk_cache_hit_count);
-    PLATFORM_DEBUG_PRINT(
-        "Number of times mapped port (static) allocations made %lld\n", 
-         mapped_port_alloc_count);
-#else 
-    PLATFORM_DEBUG_PRINT("\nNat44 bulk port statistics not turned on\n");
-#endif /* HAVE_BULK_PORT_STATS */
-}
-
-void clear_bulk_port_stats()
-{
-#ifdef HAVE_BULK_PORT_STATS
-    bulk_port_alloc_count = 0;
-    bulk_port_use_count = 0;
-    bulk_cache_hit_count = 0;
-    mapped_port_alloc_count = 0;
-#endif /* HAVE_BULK_PORT_STATS */
-    return;
-}
-
-void cnat_update_bulk_range_cache(cnat_user_db_entry_t *udb, u16 o_port, 
-        bulk_alloc_size_t bulk_size)
-{
-    i16 i;
-    if(!udb) {
-#ifdef DEBUG_BULK_PORT    
-        PLATFORM_DEBUG_PRINT("%s, null udb!\n", __func__);
-#endif
-        return;        
-     }
-    if(BULK_ALLOC_SIZE_NONE == bulk_size) { /* no bulk logging */
-        return;
-    }
-
-    /* Take care of caching */
-    if(o_port & 0x1) {
-        o_port--;
-    }
-    if(PREDICT_FALSE(o_port <= 0)) {
-#ifdef DEBUG_BULK_PORT
-        PLATFORM_DEBUG_PRINT("%s invalid port: %d\n", __func__, o_port);
-#endif 
-        return;
-    }
-
-    /* First preference is for the cache entry's that are not used yet */
-    for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-        if(PREDICT_FALSE(
-            udb->bulk_port_range_cache[i] == (i16)BULK_RANGE_INVALID)) {
-            udb->bulk_port_range_cache[i] = PORT_TO_CACHE(o_port, bulk_size); 
-            return;
-        }
-    }
-
-    /* Now check if any cache entry is full and if it can be replaced */
-    for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-        if(PREDICT_FALSE(IS_CACHE_ENTRY_FULL(udb->bulk_port_range_cache[i]))) {
-            udb->bulk_port_range_cache[i] = PORT_TO_CACHE(o_port, bulk_size); 
-            return;
-        }
-    }
-
-    return;
-}
-
-
-void cnat_port_free_v2_bulk (
-            cnat_portmap_v2_t    *pm,
-            int                index,
-            port_pair_t        ptype,
-            u16                base_port,
-            cnat_user_db_entry_t *udb,
-            u16               static_port_range,
-            bulk_alloc_size_t    bulk_size,
-            int                *nfv9_log_req)
-{
-    cnat_portmap_v2_t *my_pm;
-    i16 bm_index;
-    i16 i;
-    int unmark_full_status = 0;
-
-    *nfv9_log_req = BULK_ALLOC_NOT_ATTEMPTED;
-    
-    /* First free up the port */
-    cnat_port_free_v2(pm, index, ptype, base_port, static_port_range);
-    if(BULK_ALLOC_SIZE_NONE == bulk_size) /* no bulk logging */
-        return;
-    if(PREDICT_FALSE(!udb)) {
-#ifdef DEBUG_BULK_PORT
-        PLATFORM_DEBUG_PRINT("%s udb is null\n", __func__);
-#endif
-    }
-
-    if(PREDICT_FALSE(base_port < static_port_range)) {
-        return;
-    }
-    /* Now check if cache needs to be removed */
-    my_pm = pm + index;
-    base_port = base_port/bulk_size;
-    base_port = base_port * bulk_size; /*Align it to multiples of bulk_size */
-    if(PREDICT_TRUE(!cgn_clib_bitmap_check_if_all(
-        my_pm->bm, base_port, bulk_size))) {
-        *nfv9_log_req = CACHE_ALLOC_NO_LOG_REQUIRED;
-        unmark_full_status = 1;
-        /* One or more ports are still in use */
-    } else {
-        *nfv9_log_req = base_port; /* logging required now. indicate base port*/
-    }
-    bm_index = PORT_TO_CACHE(base_port, bulk_size);
-    /* Now check if this is in the cache */
-    for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-        if(PREDICT_FALSE(
-            CACHE_ENTRY_WITHOUT_FULL_STAT(udb->bulk_port_range_cache[i]))
-            == bm_index) {
-            if(unmark_full_status) {
-                /* Unmark full stat.. if it was marked so..*/
-                UNMARK_CACHE_ENTRY_AS_FULL(udb->bulk_port_range_cache[i]);
-            } else {
-                udb->bulk_port_range_cache[i] = (i16)BULK_RANGE_INVALID; 
-#ifdef DEBUG_BULK_PORT
-                PLATFORM_DEBUG_PRINT(
-                    "Clearing cache for client 0x%x, bulk port %d\n", 
-                    my_pm->ipv4_address, base_port);
-#endif
-            }
-            break; 
-        }
-    }
-    return;
-}
-
-
-/* Get suitable port from range */
-static i16 get_suiting_port_pos_from_range(cnat_portmap_v2_t *my_pm, 
-    u16 bulk_start, i16 bulk_size, port_pair_t pair_type)
-{
-    i16 num_pos = 0, num_bits, iterations;
-    uword bulk_ports;
-    i16 inc = 0;
-    i16 num_uwords = bulk_size/BITS(my_pm->bm[0]);
-
-    if(PREDICT_FALSE(!num_uwords)) {
-        iterations = 0;
-        num_bits = bulk_size;
-        bulk_size = 0;
-    } else {
-        bulk_port_rand_across = randq1(bulk_port_rand_across);    
-        iterations = bulk_port_rand_across % num_uwords;
-        num_bits = BITS(my_pm->bm[0]);
-    }
-
-    do {
-        bulk_ports = cgn_clib_bitmap_get_bits(my_pm->bm, 
-            (bulk_start + iterations * BITS(my_pm->bm[0])), num_bits);
-#ifdef DEBUG_BULK_PORT_DETAIL
-        PLATFORM_DEBUG_PRINT("%s %d, bulk start %d, num_bits %d, ports %lld \n",
-            __func__, __LINE__, bulk_start, num_bits, bulk_ports);
-#endif /* DEBUG_BULK_PORT_DETAIL */
-        if(PREDICT_FALSE(!bulk_ports)) goto next_uword;
-        if(PREDICT_TRUE((pair_type == PORT_SINGLE)
-            || (pair_type == PORT_PAIR))) {
-            num_pos =0;
-            inc = 1;
-        } else if(pair_type == PORT_S_ODD) {
-            num_pos = 1;
-            inc = 2;
-        } else if(pair_type == PORT_S_EVEN) {
-            num_pos =0;
-            inc = 2;
-        }    
-
-        for(; num_pos < num_bits; num_pos = num_pos + inc) {
-            if(!((bulk_ports >> num_pos) & 1))
-                continue; /* In use */
-            /* Check if the available port meets our
-             * criteria such as add, even, pair etc */
-            else if(PREDICT_FALSE(
-                (pair_type == PORT_PAIR) && ((num_pos & 0x1) ||
-                (!((bulk_ports >> (num_pos + 1)) & 1)))))
-                    continue;
-            else break; /* Found one that meets the criteria */
-        }
-        if(num_pos < num_bits) 
-            return (num_pos + iterations * BITS(my_pm->bm[0]));
-next_uword:        
-        num_bits = BITS(my_pm->bm[0]);
-        bulk_size -= BITS(my_pm->bm[0]);
-        iterations++;
-        if(iterations >= num_uwords) iterations = 0;
-    } while (bulk_size >  0);
-
-    return -2; /* nothing found */
-}
-
-static cnat_errno_t try_bulk_port_from_non_cache(
-            cnat_user_db_entry_t *udb,
-            cnat_portmap_v2_t *my_pm,
-            port_pair_t pair_type,
-            bulk_alloc_size_t bulk_size,
-            u16 *port_available,
-            u16  static_port_range
-    )
-{
-    /****
-    1. user should have existing translations.. otherwise, we wouldn't get here.
-    2. For each, get the outside port. get the base port. 
-       check if it is already in cache
-    3. if not, we stand chance.
-    4. Check for availability from this non cached pool.
-    5. if found, repalce this with one of the cache that is invalid or full??
-    6. if we are replacing the cache.. it has to be governed by user 
-        preference on prefer oldest pool or prefer newest pool
-    ********/
-    u32 head;
-    cnat_main_db_entry_t *db = NULL;
-    u16 bulk_start; /* start point in 64 bitmap array to search for port */
-    i16 port_pos; /* indicates the position of available port in bulk */
-    i16 i; /* just a counter */
-    i16 attempts_so_far = 0; /* (futile-;) attemps so far..*/
-    u16 prev_bulks[NUM_BULK_CHECK]; 
-    ASSERT(udb);
-    memset(prev_bulks, 0,sizeof(prev_bulks));
-
-    head = udb->translation_list_head_index;
-    if(PREDICT_FALSE(head == EMPTY)) return CNAT_NO_PRE_ALLOCATED_BULK_PORTS;
-
-    db = cnat_main_db + head;
-    while (1) { //what should be the limit??
-
-        /* skip static ports - static ports may not belong to bulk pool*/
-        if(db->out2in_key.k.port < static_port_range) goto next_entry;
-
-        u16 bm_index = PORT_TO_CACHE(db->out2in_key.k.port, bulk_size);
-
-        /*Check if we have already tested this bulk */
-        for(i=0; i < attempts_so_far; i++) {
-            if(prev_bulks[i] == bm_index) { 
-                goto next_entry;
-            }
-        }
-
-        /*Check if this base port is already part of cache */
-        for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(CACHE_ENTRY_WITHOUT_FULL_STAT(udb->bulk_port_range_cache[i])
-                == bm_index)
-                goto next_entry;
-        }
-
-        /* this is not in chache already */
-        bulk_start = CACHE_TO_PORT(bm_index, bulk_size);
-        port_pos = get_suiting_port_pos_from_range(my_pm, 
-                bulk_start, bulk_size, pair_type);
-
-        if(port_pos < 0) { /* no port available in this range */
-            /* Mark this bulk so that we don't have to try this again */
-            if(attempts_so_far <  NUM_BULK_CHECK) {
-                prev_bulks[attempts_so_far] = bm_index;
-                attempts_so_far++;
-            }
-            goto next_entry;
-        }
-
-        /* Got one...Get the port number */
-        *port_available = bulk_start + port_pos;
-
-        /* Check to see if we shoud replace one of the cache */
-        for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(PREDICT_FALSE((udb->bulk_port_range_cache[i] 
-                == (i16)BULK_RANGE_INVALID) || (
-                IS_CACHE_ENTRY_FULL(udb->bulk_port_range_cache[i])))) {
-                udb->bulk_port_range_cache[i] = bm_index;
-                return CNAT_SUCCESS;
-            }
-        }
-        /* Check to replace an existing (in use) entry */
-        /* TODO: enforce policy */
-        /* order of looping should depend on policy */
-
-        return CNAT_SUCCESS;
-
-next_entry:
-        db = cnat_main_db + db->user_ports.next;
-        /*
-         * its a circular list, so if we have reached the head again
-         * all the entries for that user have been read
-         */
-        if (db == (cnat_main_db + head)) {
-            break;
-        }
-    } /* while loop for db entries */
-    /* no ports available from pre allocated bulk pool */
-    return CNAT_NO_PORT_FROM_BULK;
-}
-
-cnat_errno_t
-cnat_dynamic_port_alloc_v2_bulk (
-                 cnat_portmap_v2_t    *pm,
-                 port_alloc_t         atype,
-                 port_pair_t          pair_type,
-                 u32                  *index,
-                 u32                  *o_ipv4_address,
-                 u16                  *o_port,
-                 u16                  static_port_range,
-                 cnat_user_db_entry_t *udb,
-                 bulk_alloc_size_t    bulk_size,
-                 int                  *nfv9_log_req,
-                 u16                  ip_n_to_1,
-                 u32                  *rseed_ip
-                 )
-{
-
-    cnat_errno_t rv;
-    u16 port_available = 0;
-    i16  i;
-    cnat_portmap_v2_t *my_pm;
-
-    if((BULK_ALLOC_SIZE_NONE != bulk_size) /* bulk logging enabled */
-        &&  (udb)) {  /* This user does have translations already */
-        u16 bulk_start;
-        i16 port_pos;
-
-        my_pm = pm + *index;
-        /* We have a case to check if bulk allocated ports can be used */
-        /* TODO: order of looping to be based on policy
-         * like prefer older or prefer newer ?? 
-         * For now, start with most recent cache entry
-         * so that we stand a better chance of 
-         * finding a port
-         */
-        for(i= 0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(PREDICT_TRUE((udb->bulk_port_range_cache[i] == 
-                (i16)BULK_RANGE_INVALID) || 
-                IS_CACHE_ENTRY_FULL(udb->bulk_port_range_cache[i]))) {
-                continue; /* This range is not initialized yet or it is full */
-            }
-            bulk_start = CACHE_TO_PORT(udb->bulk_port_range_cache[i], 
-                    bulk_size);
-            port_pos = get_suiting_port_pos_from_range(my_pm, 
-                bulk_start, bulk_size, pair_type);
-            if(PREDICT_FALSE(port_pos < 0)) { 
-                /* Mark this cache entry as full so that we do not 
-                 * waste time on this entry again */
-                MARK_CACHE_ENTRY_AS_FULL(udb->bulk_port_range_cache[i]);
-#ifdef DEBUG_BULK_PORT 
-                PLATFORM_DEBUG_PRINT("Marked bulk cache entry %d as full for %x \n",
-                i, my_pm->ipv4_address);
-#endif /*  #ifdef DEBUG_BULK_PORT */
-                continue;
-            }
-            /* Get the port number */
-            port_available = bulk_start+ port_pos;
-#ifdef DEBUG_BULK_PORT
-            PLATFORM_DEBUG_PRINT(
-                "Found port from cache : IP 0x%x, port %d %d iterations\n",
-                my_pm->ipv4_address, port_available, i)
-#endif 
-#ifdef HAVE_BULK_PORT_STATS
-            bulk_cache_hit_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-            break;
-        } /* end of for loop for cache check */
-        /* If we have not found a port yet, check if we can have 
-         *   pre allocated bulk port from non-cache */
-        if(PREDICT_FALSE(i == BULK_RANGE_CACHE_SIZE)) { 
-            if( try_bulk_port_from_non_cache(udb, my_pm, pair_type,
-                bulk_size, &port_available, 
-                static_port_range) != CNAT_SUCCESS ) {
-                goto ALLCOATE_NEW_BULK;
-            }
-#ifdef DEBUG_BULK_PORT
-            PLATFORM_DEBUG_PRINT("Found port from non-cache : IP 0x%x, port %d\n",
-                my_pm->ipv4_address, port_available);
-#endif 
-        }
-        /* Assign the port, mark it as in use */
-        cgn_clib_bitmap_clear_no_check(my_pm->bm, port_available);
-        (my_pm->inuse)++;
-        if(PREDICT_FALSE(pair_type == PORT_PAIR)) {/* Mark the next one too */
-            cgn_clib_bitmap_clear_no_check(my_pm->bm, port_available + 1);
-            (my_pm->inuse)++;
-        }
-        *o_ipv4_address = my_pm->ipv4_address;
-        *o_port = port_available;
-        *nfv9_log_req = CACHE_ALLOC_NO_LOG_REQUIRED;
-#ifdef HAVE_BULK_PORT_STATS
-        bulk_port_use_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-        return (CNAT_SUCCESS);
-    } 
-ALLCOATE_NEW_BULK:
-#ifdef DEBUG_BULK_PORT
-    if(BULK_ALLOC_SIZE_NONE != bulk_size) {
-        PLATFORM_DEBUG_PRINT(
-            "No port available from bulk cache, bulk size %d\n", bulk_size);
-    }
-#endif 
-    /* For whatever reason, we have not got a port yet */
-    rv = cnat_dynamic_port_alloc_v2(pm, atype, pair_type, index,
-            o_ipv4_address, o_port, static_port_range, bulk_size, nfv9_log_req,
-            ip_n_to_1, rseed_ip);
-    if (PREDICT_FALSE(rv != CNAT_SUCCESS)) {
-        return rv;
-    }
-    /* Take care of caching */
-    if(PREDICT_FALSE(udb != NULL)) { 
-        /* Predict false because, we usually allocate for new users */
-        cnat_update_bulk_range_cache(udb, *o_port, bulk_size);
-    }
-#ifdef HAVE_BULK_PORT_STATS
-        bulk_port_alloc_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-    return (CNAT_SUCCESS);
-}
-
-
-cnat_errno_t
-cnat_static_port_alloc_v2_bulk (
-                 cnat_portmap_v2_t    *pm,
-                 port_alloc_t         atype,
-                 port_pair_t          pair_type,
-                 u32                  i_ipv4_address,
-                 u16                  i_port,
-                 u32                  *index,
-                 u32                  *o_ipv4_address,
-                 u16                  *o_port,
-                 u16                  static_port_range,
-                 cnat_user_db_entry_t *udb,
-                 bulk_alloc_size_t    bulk_size,
-                 int                  *nfv9_log_req,
-                u16                  ip_n_to_1
-                )
-{
-
-    /***
-     * Requirements - 
-     * 1. If the port allocated is below dyn start, it should be individual 
-     * port (not bulk)
-     * 2.  If NOT, it should be bulk allocated
-     * 3.  Try and keep the inside port same as outside port in both the 
-     * cases (best effort)
-
-     * Algorithm
-     * 1.  Check if it is below stat port start or user is new or bulk is 
-     * disabled. If yes, call existing function
-     * 2.  If not, see if we can pick from bulk and yet try to keep the port 
-     * same - difficult thing - check if the port is free - then check if the 
-     * entire bulk is free - if not check if bulk is owned by the user already.
-     * If all of these fail, call existing function to allocate a new bulk
-     * 3.  Update cache, etc return log requirements
-     *****/
-
-    cnat_errno_t rv;
-    i16  i;
-    u32 head;
-    cnat_portmap_v2_t *my_pm;
-    uword bit_test_result, start_bit;
-    cnat_main_db_entry_t *db = NULL;
-
-    if((BULK_ALLOC_SIZE_NONE != bulk_size) /* bulk logging enabled */
-        &&  (udb) && /* This user does have translations already */
-        i_port >= static_port_range ) { /* It is outside stat port range*/
-
-        my_pm = pm + *index;
-        /* We have a case to check if bulk allocated ports can be used */
-
-        /* First check if the required port is available. */
-        if(PREDICT_FALSE(clib_bitmap_get_no_check(my_pm->bm, i_port) == 0)) {
-            goto ALLOCATE_NEW_BULK_STATIC;
-        }
-
-        /* Port is free.. check if the bulk is also free */
-        start_bit= ((i_port/bulk_size) * bulk_size);
-        bit_test_result = cgn_clib_bitmap_check_if_all(my_pm->bm,
-                            start_bit, bulk_size);
-        if(PREDICT_TRUE(bit_test_result)) { /* bulk is available, grab it */
-            goto ALLOCATE_NEW_BULK_STATIC;
-        }
-
-        /* else, bulk is taken by someone. check if it is me */
-        /* Check if we own the bulk by any chance */
-        for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(udb->bulk_port_range_cache[i] == start_bit) break;
-        }
-        if(i == BULK_RANGE_CACHE_SIZE) { /* no luck with cache */        
-            head = udb->translation_list_head_index;
-            if(PREDICT_FALSE(head == EMPTY)) 
-                goto ALLOCATE_NEW_BULK_STATIC;
-            db = cnat_main_db + head;
-            i = 0;
-            while(1) {
-                if((db->out2in_key.k.port/bulk_size) * bulk_size ==                                             start_bit) {    
-                        i = 1; /* Just to indicate it is found */
-                        break;
-                }
-                db = cnat_main_db + db->user_ports.next;
-                /*
-                 * its a circular list, so if we have reached the head again
-                 * all the entries for that user have been read
-                 */
-                if (db == (cnat_main_db + head)) break;
-            } /* while loop for db entries */
-            if(!i) {
-                goto ALLOCATE_NEW_BULK_STATIC;    
-            }
-        }        
-        /* Assign the port, mark it as in use */
-        cgn_clib_bitmap_clear_no_check(my_pm->bm, i_port);
-        (my_pm->inuse)++;
-        *o_ipv4_address = my_pm->ipv4_address;
-        *o_port = i_port;
-        *nfv9_log_req = CACHE_ALLOC_NO_LOG_REQUIRED;
-#ifdef HAVE_BULK_PORT_STATS
-        bulk_port_use_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-
-#ifdef DEBUG_BULK_PORT
-        PLATFORM_DEBUG_PRINT("%s, %d, found stat port from bulk: %x, %d\n", 
-            __func__, 
-            __LINE__, *o_ipv4_address, *o_port);
-#endif /* DEBUG_BULK_PORT */
-        return (CNAT_SUCCESS);
-    } 
-
-ALLOCATE_NEW_BULK_STATIC:
-#ifdef DEBUG_BULK_PORT
-    PLATFORM_DEBUG_PRINT("%s No port available from bulk cache, bulk size %d\n", 
-            __func__,bulk_size);
-#endif 
-    /* For whatever reason, we have not got a port yet */
-    rv = cnat_static_port_alloc_v2(pm, atype, pair_type, i_ipv4_address,
-            i_port, index, o_ipv4_address, o_port, static_port_range,
-            bulk_size, nfv9_log_req,ip_n_to_1);
-    if (PREDICT_FALSE(rv != CNAT_SUCCESS)) {
-        return rv;
-    }
-    /* Take care of caching only if it was a bulk alloc */
-    if(PREDICT_FALSE(udb && (BULK_ALLOC_NOT_ATTEMPTED != *nfv9_log_req))) {
-        cnat_update_bulk_range_cache(udb, *o_port, bulk_size);
-    }
-#ifdef HAVE_BULK_PORT_STATS
-    bulk_port_alloc_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-    return (CNAT_SUCCESS);
-
-}
-
-cnat_errno_t
-cnat_mapped_static_port_alloc_v2_bulk (
-            cnat_portmap_v2_t    *pm,
-            port_alloc_t         atype,
-            u32                  *index,
-            u32                   ipv4_address,
-            u16                   port,
-            cnat_user_db_entry_t *udb,
-            bulk_alloc_size_t    bulk_size,
-            int                  *nfv9_log_req,
-           u16                  ip_n_to_1
-           )
-{
-    /* Requirements : 
-     * 1. Check if bulk allocation is required.
-     * 2. Call cnat_mapped_static_port_alloc_v2 to allocate
-     * 3. Decide if alloc has to be cached
-     * 4. Update nfv9_log_req
-     */
-    cnat_errno_t rv; 
-    rv = cnat_mapped_static_port_alloc_v2 (pm,
-        atype, index, ipv4_address, port, nfv9_log_req, bulk_size, ip_n_to_1);
-    if (PREDICT_FALSE(rv != CNAT_SUCCESS)) {
-        return rv;
-    }
-    /* Take care of caching only if it was a bulk alloc */
-    if(PREDICT_FALSE(udb && (BULK_ALLOC_NOT_ATTEMPTED != *nfv9_log_req))) {
-        int i;
-        port = port*bulk_size;
-        port = port/bulk_size; /* align it to bulk size boundary */
-        for(i=0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(CACHE_ENTRY_WITHOUT_FULL_STAT(udb->bulk_port_range_cache[i])
-                == PORT_TO_CACHE(port, bulk_size))
-                break; 
-        }
-        if( i == BULK_RANGE_CACHE_SIZE) { /* else, it is alredy in cache */
-            cnat_update_bulk_range_cache(udb, port, bulk_size);
-        }
-    }
-#ifdef HAVE_BULK_PORT_STATS
-    mapped_port_alloc_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-    return (CNAT_SUCCESS);
-}
-
-
-cnat_errno_t
-cnat_dynamic_port_alloc_rtsp_bulk (
-                 cnat_portmap_v2_t    *pm,
-                 port_alloc_t         atype,
-                 port_pair_t          pair_type,
-                 u16                  i_port,
-                 u32                  *index,
-                 u32                  *o_ipv4_address,
-                 u16                  *o_port,
-                 u16                  static_port_range,
-                 cnat_user_db_entry_t *udb,
-                 bulk_alloc_size_t    bulk_size,
-                 int                  *nfv9_log_req,
-                 u32                  *rseed_ip)
-{
-
-    /***
-     * Algorithm
-     * 1. Compute the range of ports required based on the number of digits
-     * in the port request made by the client.
-     * 2. Check if bulk logging is enabled. If not, use the existing method.
-     * 3. Check if there are 2 adjacent ports available that meet the above
-     * criteria in any of the bulk allocations made already.
-     * 4. If yes, mark them in use and return.
-     * 5. If not allocate a new bulk and pick 2 ports in it
-     ***/
-
-    i16  i;
-    cnat_portmap_v2_t *my_pm = 0;
-    u32 start_port1, end_port1, start_port2, end_port2;
-    int range_loop;
-    u16 bulk_start;
-    i16 port_pos;
-    u16 port_available = 0;
-    
-    ASSERT(index);
-    ASSERT(o_ipv4_address);
-    ASSERT(o_port);
-    
-    /*
-     * Check if the port is 4 digit or 5 digit.   I am assuming we are
-     * not getting 3 (or 2 or 1) digit ports, which we cannot anyway
-     * allocate same sized outside ports - as outside ports start from 1024
-     *
-     * Static Port has its own reserved range.  Ensure that the range is
-     * such that atleast few 4 digit ports are available for RTSP.  If
-     * not it does not make sense to do special allocation for RTSP.
-     */
-    if (PREDICT_TRUE(static_port_range < MIN_STATIC_PORT_RANGE_FOR_RTSP)) {
-        /*
-         * 4 digit port or less
-         */
-        if (i_port <= 9999) {
-            start_port1  = static_port_range;
-            end_port1    = 9999;
-            
-            start_port2 = 10000;
-            end_port2   = PORTS_PER_ADDR - 1;
-        } else { /* 5 digit port */
-            start_port1 = 10000;
-            end_port1   = PORTS_PER_ADDR - 1;
-            
-            start_port2 = static_port_range;
-            end_port2   = 9999;
-        }
-    } else { /* Static port range is too big */
-        start_port1 = static_port_range;
-        end_port1   = PORTS_PER_ADDR - 1;
-        
-        /*
-         * PORTS_PER_ADDR is just a placeholder for
-         * INVALID_PORT, valid ports are b/w 1 and PORTS_PER_ADDR
-         */
-        start_port2 = PORTS_PER_ADDR;
-        end_port2   = PORTS_PER_ADDR;
-    }
-
-
-    if(PREDICT_TRUE(udb != NULL)) {
-        my_pm = pm + *index;
-    }
-
-    /* Now check if this user already owns a bulk range that is 
-     * within start range 1 
-     */
-
-    u32 start_range = start_port1;
-    u32 end_range = end_port1;
-    for(range_loop = 0; range_loop < 2; range_loop++) {
-        if((BULK_ALLOC_SIZE_NONE == bulk_size) || (!udb)) {
-            goto ALLOCATE_NEW_RTSP_PORTS;
-        }
-        for(i= 0; i < BULK_RANGE_CACHE_SIZE; i++) {
-            if(PREDICT_TRUE((udb->bulk_port_range_cache[i] == 
-                (i16)BULK_RANGE_INVALID) || 
-                IS_CACHE_ENTRY_FULL(udb->bulk_port_range_cache[i]))) {
-                continue; /* This range is not initialized yet or it is full */ 
-            }
-
-            bulk_start = CACHE_TO_PORT(udb->bulk_port_range_cache[i], 
-                        bulk_size);
-            if(bulk_start < start_port1 || bulk_start >= end_port1) {
-                continue; /* Not in the range */
-            }
-
-            port_pos = get_suiting_port_pos_from_range(my_pm, 
-                bulk_start, bulk_size, pair_type);
-            if(PREDICT_FALSE(port_pos < 0)) { 
-                /*  Not Marking  this cache entry as full as it failed 
-                 * for pair type. It might have individual entries
-                 */
-                continue;
-            }
-            /* Get the port number */
-            port_available = bulk_start+ port_pos;
-#ifdef DEBUG_BULK_PORT
-            PLATFORM_DEBUG_PRINT(
-                "Found port from cache : IP 0x%x, port %d %d iterations\n",
-                my_pm->ipv4_address, port_available, i)
-#endif 
-#ifdef HAVE_BULK_PORT_STATS
-            bulk_cache_hit_count += 2;
-#endif /* HAVE_BULK_PORT_STATS */
-            break;
-        } /* end of for loop for cache check */
-
-        if(PREDICT_FALSE(i == BULK_RANGE_CACHE_SIZE)) { 
-            /* we have not found a port yet, but to do not want to try 
-             * non-cache bulks.. because, it is a very low probability and 
-             * do not want to tweak that code for this special case
-             * The impact of non checking the non-cache is, we give this 
-             * user few  extra ports .. which is OK
-             */
-            goto ALLOCATE_NEW_RTSP_PORTS;
-        }
-#ifdef DEBUG_BULK_PORT
-        PLATFORM_DEBUG_PRINT("RTSP: Found port from non-cache : IP 0x%x, port %d\n",
-                my_pm->ipv4_address, port_available);
-#endif 
-
-        /* Assign the port, mark it as in use */
-        cgn_clib_bitmap_clear_no_check(my_pm->bm, port_available);
-        (my_pm->inuse)++;
-        cgn_clib_bitmap_clear_no_check(my_pm->bm, port_available + 1);
-        (my_pm->inuse)++;
-
-        *o_ipv4_address = my_pm->ipv4_address;
-        *o_port = port_available;
-        *nfv9_log_req = CACHE_ALLOC_NO_LOG_REQUIRED;
-#ifdef HAVE_BULK_PORT_STATS
-        bulk_port_use_count += 2;
-#endif /* HAVE_BULK_PORT_STATS */
-        return (CNAT_SUCCESS);
-
-ALLOCATE_NEW_RTSP_PORTS:
-        /* No luck. Let's try allocating new bulk.. */
-        if(PREDICT_TRUE(CNAT_SUCCESS == cnat_dynamic_port_alloc_rtsp 
-            (pm, atype, pair_type,
-                start_range, end_range,index, o_ipv4_address, 
-                o_port, bulk_size, nfv9_log_req,rseed_ip))) {
-            if(PREDICT_FALSE(udb && 
-                (BULK_ALLOC_NOT_ATTEMPTED != *nfv9_log_req))) {
-                cnat_update_bulk_range_cache(udb, *o_port, bulk_size);
-            }
-#ifdef HAVE_BULK_PORT_STATS
-            bulk_port_alloc_count++;
-#endif /* HAVE_BULK_PORT_STATS */
-            return CNAT_SUCCESS; 
-        }
-
-        /* Could not allocate in range 1.. so move to range 2. */
-        start_range = start_port2;
-        end_range = end_port2;
-
-    }
-
-    return (CNAT_NOT_FOUND_DIRECT); /* if we are here, we could not get any ports */
-
-}
-
-#else /* Dummy definitions */
-void show_bulk_port_stats()
-{
-    PLATFORM_DEBUG_PRINT("\nBulk logging feature not included\n");
-}
-
- void clear_bulk_port_stats()
-{
-    PLATFORM_DEBUG_PRINT("\nBulk logging feature not included\n");
-}
-#endif /* NO_BULK_LOGGING */