hs-test: more debug output in http3 test
[vpp.git] / src / plugins / cnat / cnat_inline.h
1 /*
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:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15
16
17 #ifndef __CNAT_INLINE_H__
18 #define __CNAT_INLINE_H__
19
20 #include <cnat/cnat_types.h>
21
22 always_inline int
23 cnat_ts_is_free_index (u32 index)
24 {
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);
28 }
29
30 always_inline cnat_timestamp_t *
31 cnat_timestamp_get (u32 index)
32 {
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);
37 }
38
39 always_inline cnat_timestamp_t *
40 cnat_timestamp_get_if_valid (u32 index)
41 {
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)
46     return (NULL);
47   if (pool_is_free_index (cnat_timestamps.ts_pools[pidx], index))
48     return (NULL);
49   return pool_elt_at_index (cnat_timestamps.ts_pools[pidx], index);
50 }
51
52 always_inline index_t
53 cnat_timestamp_alloc ()
54 {
55   cnat_timestamp_t *ts;
56   u32 index, pool_sz;
57   uword pidx;
58
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)
64     pool_init_fixed (
65       cnat_timestamps.ts_pools[cnat_timestamps.next_empty_pool_idx++],
66       pool_sz);
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);
71
72   index = (u32) pidx << (32 - CNAT_TS_MPOOL_BITS);
73   return index | (ts - cnat_timestamps.ts_pools[pidx]);
74 }
75
76 always_inline void
77 cnat_timestamp_destroy (u32 index)
78 {
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);
85 }
86
87 always_inline u32
88 cnat_timestamp_new (f64 t)
89 {
90   index_t index = cnat_timestamp_alloc ();
91   cnat_timestamp_t *ts = cnat_timestamp_get (index);
92   ts->last_seen = t;
93   ts->lifetime = cnat_main.session_max_age;
94   ts->refcnt = CNAT_TIMESTAMP_INIT_REFCNT;
95   return index;
96 }
97
98 always_inline void
99 cnat_timestamp_inc_refcnt (u32 index)
100 {
101   cnat_timestamp_t *ts = cnat_timestamp_get (index);
102   clib_atomic_add_fetch (&ts->refcnt, 1);
103 }
104
105 always_inline void
106 cnat_timestamp_update (u32 index, f64 t)
107 {
108   cnat_timestamp_t *ts = cnat_timestamp_get (index);
109   ts->last_seen = t;
110 }
111
112 always_inline void
113 cnat_timestamp_set_lifetime (u32 index, u16 lifetime)
114 {
115   cnat_timestamp_t *ts = cnat_timestamp_get (index);
116   ts->lifetime = lifetime;
117 }
118
119 always_inline f64
120 cnat_timestamp_exp (u32 index)
121 {
122   f64 t;
123   cnat_timestamp_t *ts = cnat_timestamp_get_if_valid (index);
124   if (NULL == ts)
125     return -1;
126   t = ts->last_seen + (f64) ts->lifetime;
127   return t;
128 }
129
130 always_inline void
131 cnat_timestamp_free (u32 index)
132 {
133   cnat_timestamp_t *ts = cnat_timestamp_get_if_valid (index);
134   if (NULL == ts)
135     return;
136   if (0 == clib_atomic_sub_fetch (&ts->refcnt, 1))
137     cnat_timestamp_destroy (index);
138 }
139
140 /*
141  * fd.io coding-style-patch-verification: ON
142  *
143  * Local Variables:
144  * eval: (c-set-style "gnu")
145  * End:
146  */
147
148 #endif