diff options
Diffstat (limited to 'src/plugins/cnat/cnat_session.c')
-rw-r--r-- | src/plugins/cnat/cnat_session.c | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/src/plugins/cnat/cnat_session.c b/src/plugins/cnat/cnat_session.c index 216d2575c37..0f1cd43f501 100644 --- a/src/plugins/cnat/cnat_session.c +++ b/src/plugins/cnat/cnat_session.c @@ -94,7 +94,8 @@ format_cnat_session (u8 * s, va_list * args) cnat_session_t *sess = va_arg (*args, cnat_session_t *); CLIB_UNUSED (int verbose) = va_arg (*args, int); f64 ts = 0; - if (!pool_is_free_index (cnat_timestamps, sess->value.cs_ts_index)) + + if (!cnat_ts_is_free_index (sess->value.cs_ts_index)) ts = cnat_timestamp_exp (sess->value.cs_ts_index); s = format ( @@ -172,15 +173,43 @@ cnat_session_purge (void) return (0); } +void +cnat_reverse_session_free (cnat_session_t *session) +{ + cnat_bihash_kv_t bkey, bvalue; + cnat_session_t *rsession = (cnat_session_t *) &bkey; + int rv; + + ip46_address_copy (&rsession->key.cs_ip[VLIB_RX], + &session->value.cs_ip[VLIB_TX]); + ip46_address_copy (&rsession->key.cs_ip[VLIB_TX], + &session->value.cs_ip[VLIB_RX]); + rsession->key.cs_proto = session->key.cs_proto; + rsession->key.cs_loc = session->key.cs_loc == CNAT_LOCATION_OUTPUT ? + CNAT_LOCATION_INPUT : + CNAT_LOCATION_OUTPUT; + rsession->key.__cs_pad = 0; + rsession->key.cs_af = session->key.cs_af; + rsession->key.cs_port[VLIB_RX] = session->value.cs_port[VLIB_TX]; + rsession->key.cs_port[VLIB_TX] = session->value.cs_port[VLIB_RX]; + + rv = cnat_bihash_search_i2 (&cnat_session_db, &bkey, &bvalue); + if (!rv) + { + /* other session is in bihash */ + cnat_session_t *rsession = (cnat_session_t *) &bvalue; + cnat_session_free (rsession); + } +} + u64 cnat_session_scan (vlib_main_t * vm, f64 start_time, int i) { BVT (clib_bihash) * h = &cnat_session_db; int j, k; - /* Don't scan the l2 fib if it hasn't been instantiated yet */ if (alloc_arena (h) == 0) - return 0.0; + return 0; for ( /* caller saves starting point */ ; i < h->nbuckets; i++) { @@ -210,7 +239,7 @@ cnat_session_scan (vlib_main_t * vm, f64 start_time, int i) { for (k = 0; k < BIHASH_KVP_PER_PAGE; k++) { - if (v->kvp[k].key[0] == ~0ULL && v->kvp[k].value[0] == ~0ULL) + if (BV (clib_bihash_is_free) (&v->kvp[k])) continue; cnat_session_t *session = (cnat_session_t *) & v->kvp[k]; @@ -219,6 +248,9 @@ cnat_session_scan (vlib_main_t * vm, f64 start_time, int i) cnat_timestamp_exp (session->value.cs_ts_index)) { /* age it */ + cnat_reverse_session_free (session); + /* this should be last as deleting the session memset it to + * 0xff */ cnat_session_free (session); /* @@ -248,6 +280,12 @@ cnat_session_init (vlib_main_t * vm) cm->session_hash_memory); BV (clib_bihash_set_kvp_format_fn) (&cnat_session_db, format_cnat_session); + cnat_timestamps.next_empty_pool_idx = 0; + clib_bitmap_alloc (cnat_timestamps.ts_free, 1 << CNAT_TS_MPOOL_BITS); + clib_bitmap_set_region (cnat_timestamps.ts_free, 0, 1, + 1 << CNAT_TS_MPOOL_BITS); + clib_spinlock_init (&cnat_timestamps.ts_lock); + return (NULL); } @@ -258,21 +296,38 @@ cnat_timestamp_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { cnat_timestamp_t *ts; - clib_rwlock_reader_lock (&cnat_main.ts_lock); - pool_foreach (ts, cnat_timestamps) + int ts_cnt = 0, cnt; + u8 verbose = 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - vlib_cli_output (vm, "[%d] last_seen:%f lifetime:%u ref:%u", - ts - cnat_timestamps, ts->last_seen, ts->lifetime, - ts->refcnt); + if (unformat (input, "verbose")) + verbose = 1; + else + return (clib_error_return (0, "unknown input '%U'", + format_unformat_error, input)); + } + + for (int i = 0; i < cnat_timestamps.next_empty_pool_idx; i++) + { + cnt = pool_elts (cnat_timestamps.ts_pools[i]); + ts_cnt += cnt; + vlib_cli_output (vm, "-- Pool %d [%d/%d]", i, cnt, + pool_header (cnat_timestamps.ts_pools[i])->max_elts); + if (!verbose) + continue; + pool_foreach (ts, cnat_timestamps.ts_pools[i]) + vlib_cli_output (vm, "[%d] last_seen:%f lifetime:%u ref:%u", + ts - cnat_timestamps.ts_pools[i], ts->last_seen, + ts->lifetime, ts->refcnt); } - clib_rwlock_reader_unlock (&cnat_main.ts_lock); + vlib_cli_output (vm, "Total timestamps %d", ts_cnt); return (NULL); } VLIB_CLI_COMMAND (cnat_timestamp_show_cmd, static) = { .path = "show cnat timestamp", .function = cnat_timestamp_show, - .short_help = "show cnat timestamp", + .short_help = "show cnat timestamp [verbose]", .is_mp_safe = 1, }; |