2 * Copyright (c) 2020 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
17 #ifndef __CNAT_INLINE_H__
18 #define __CNAT_INLINE_H__
20 #include <cnat/cnat_types.h>
23 cnat_ts_is_free_index (u32 index)
25 u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
26 index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
27 return pool_is_free_index (cnat_timestamps.ts_pools[pidx], index);
30 always_inline cnat_timestamp_t *
31 cnat_timestamp_get (u32 index)
33 /* 6 top bits for choosing pool */
34 u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
35 index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
36 return pool_elt_at_index (cnat_timestamps.ts_pools[pidx], index);
39 always_inline cnat_timestamp_t *
40 cnat_timestamp_get_if_valid (u32 index)
42 /* 6 top bits for choosing pool */
43 u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
44 index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
45 if (pidx >= cnat_timestamps.next_empty_pool_idx)
47 if (pool_is_free_index (cnat_timestamps.ts_pools[pidx], index))
49 return pool_elt_at_index (cnat_timestamps.ts_pools[pidx], index);
53 cnat_timestamp_alloc ()
59 clib_spinlock_lock (&cnat_timestamps.ts_lock);
60 pidx = clib_bitmap_first_set (cnat_timestamps.ts_free);
61 pool_sz = 1 << (CNAT_TS_BASE_SIZE + pidx);
62 ASSERT (pidx <= cnat_timestamps.next_empty_pool_idx);
63 if (pidx == cnat_timestamps.next_empty_pool_idx)
65 cnat_timestamps.ts_pools[cnat_timestamps.next_empty_pool_idx++],
67 pool_get (cnat_timestamps.ts_pools[pidx], ts);
68 if (pool_elts (cnat_timestamps.ts_pools[pidx]) == pool_sz)
69 clib_bitmap_set (cnat_timestamps.ts_free, pidx, 0);
70 clib_spinlock_unlock (&cnat_timestamps.ts_lock);
72 index = (u32) pidx << (32 - CNAT_TS_MPOOL_BITS);
73 return index | (ts - cnat_timestamps.ts_pools[pidx]);
77 cnat_timestamp_destroy (u32 index)
79 u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
80 index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
81 clib_spinlock_lock (&cnat_timestamps.ts_lock);
82 pool_put_index (cnat_timestamps.ts_pools[pidx], index);
83 clib_bitmap_set (cnat_timestamps.ts_free, pidx, 1);
84 clib_spinlock_unlock (&cnat_timestamps.ts_lock);
88 cnat_timestamp_new (f64 t)
90 index_t index = cnat_timestamp_alloc ();
91 cnat_timestamp_t *ts = cnat_timestamp_get (index);
93 ts->lifetime = cnat_main.session_max_age;
94 ts->refcnt = CNAT_TIMESTAMP_INIT_REFCNT;
99 cnat_timestamp_inc_refcnt (u32 index)
101 cnat_timestamp_t *ts = cnat_timestamp_get (index);
102 clib_atomic_add_fetch (&ts->refcnt, 1);
106 cnat_timestamp_update (u32 index, f64 t)
108 cnat_timestamp_t *ts = cnat_timestamp_get (index);
113 cnat_timestamp_set_lifetime (u32 index, u16 lifetime)
115 cnat_timestamp_t *ts = cnat_timestamp_get (index);
116 ts->lifetime = lifetime;
120 cnat_timestamp_exp (u32 index)
123 cnat_timestamp_t *ts = cnat_timestamp_get_if_valid (index);
126 t = ts->last_seen + (f64) ts->lifetime;
131 cnat_timestamp_free (u32 index)
133 cnat_timestamp_t *ts = cnat_timestamp_get_if_valid (index);
136 if (0 == clib_atomic_sub_fetch (&ts->refcnt, 1))
137 cnat_timestamp_destroy (index);
141 * fd.io coding-style-patch-verification: ON
144 * eval: (c-set-style "gnu")