LCOV - code coverage report
Current view: top level - plugins/cnat - cnat_inline.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 59 68 86.8 %
Date: 2023-10-26 01:39:38 Functions: 10 11 90.9 %

          Line data    Source code
       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        4899 : cnat_ts_is_free_index (u32 index)
      24             : {
      25        4899 :   u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
      26        4899 :   index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
      27        4899 :   return pool_is_free_index (cnat_timestamps.ts_pools[pidx], index);
      28             : }
      29             : 
      30             : always_inline cnat_timestamp_t *
      31        4730 : cnat_timestamp_get (u32 index)
      32             : {
      33             :   /* 6 top bits for choosing pool */
      34        4730 :   u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
      35        4730 :   index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
      36        4730 :   return pool_elt_at_index (cnat_timestamps.ts_pools[pidx], index);
      37             : }
      38             : 
      39             : always_inline cnat_timestamp_t *
      40        5434 : cnat_timestamp_get_if_valid (u32 index)
      41             : {
      42             :   /* 6 top bits for choosing pool */
      43        5434 :   u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
      44        5434 :   index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
      45        5434 :   if (pidx >= cnat_timestamps.next_empty_pool_idx)
      46           0 :     return (NULL);
      47        5434 :   if (pool_is_free_index (cnat_timestamps.ts_pools[pidx], index))
      48           0 :     return (NULL);
      49        5434 :   return pool_elt_at_index (cnat_timestamps.ts_pools[pidx], index);
      50             : }
      51             : 
      52             : always_inline index_t
      53         140 : cnat_timestamp_alloc ()
      54             : {
      55             :   cnat_timestamp_t *ts;
      56             :   u32 index, pool_sz;
      57             :   uword pidx;
      58             : 
      59         140 :   clib_spinlock_lock (&cnat_timestamps.ts_lock);
      60         140 :   pidx = clib_bitmap_first_set (cnat_timestamps.ts_free);
      61         140 :   pool_sz = 1 << (CNAT_TS_BASE_SIZE + pidx);
      62         140 :   ASSERT (pidx <= cnat_timestamps.next_empty_pool_idx);
      63         140 :   if (pidx == cnat_timestamps.next_empty_pool_idx)
      64           2 :     pool_init_fixed (
      65             :       cnat_timestamps.ts_pools[cnat_timestamps.next_empty_pool_idx++],
      66             :       pool_sz);
      67         140 :   pool_get (cnat_timestamps.ts_pools[pidx], ts);
      68         140 :   if (pool_elts (cnat_timestamps.ts_pools[pidx]) == pool_sz)
      69           0 :     clib_bitmap_set (cnat_timestamps.ts_free, pidx, 0);
      70         140 :   clib_spinlock_unlock (&cnat_timestamps.ts_lock);
      71             : 
      72         140 :   index = (u32) pidx << (32 - CNAT_TS_MPOOL_BITS);
      73         140 :   return index | (ts - cnat_timestamps.ts_pools[pidx]);
      74             : }
      75             : 
      76             : always_inline void
      77         122 : cnat_timestamp_destroy (u32 index)
      78             : {
      79         122 :   u32 pidx = index >> (32 - CNAT_TS_MPOOL_BITS);
      80         122 :   index = index & (0xffffffff >> CNAT_TS_MPOOL_BITS);
      81         122 :   clib_spinlock_lock (&cnat_timestamps.ts_lock);
      82         122 :   pool_put_index (cnat_timestamps.ts_pools[pidx], index);
      83         122 :   clib_bitmap_set (cnat_timestamps.ts_free, pidx, 1);
      84         122 :   clib_spinlock_unlock (&cnat_timestamps.ts_lock);
      85         122 : }
      86             : 
      87             : always_inline u32
      88         140 : cnat_timestamp_new (f64 t)
      89             : {
      90         140 :   index_t index = cnat_timestamp_alloc ();
      91         140 :   cnat_timestamp_t *ts = cnat_timestamp_get (index);
      92         140 :   ts->last_seen = t;
      93         140 :   ts->lifetime = cnat_main.session_max_age;
      94         140 :   ts->refcnt = CNAT_TIMESTAMP_INIT_REFCNT;
      95         140 :   return index;
      96             : }
      97             : 
      98             : always_inline void
      99         140 : cnat_timestamp_inc_refcnt (u32 index)
     100             : {
     101         140 :   cnat_timestamp_t *ts = cnat_timestamp_get (index);
     102         140 :   clib_atomic_add_fetch (&ts->refcnt, 1);
     103         140 : }
     104             : 
     105             : always_inline void
     106        4450 : cnat_timestamp_update (u32 index, f64 t)
     107             : {
     108        4450 :   cnat_timestamp_t *ts = cnat_timestamp_get (index);
     109        4450 :   ts->last_seen = t;
     110        4450 : }
     111             : 
     112             : always_inline void
     113           0 : cnat_timestamp_set_lifetime (u32 index, u16 lifetime)
     114             : {
     115           0 :   cnat_timestamp_t *ts = cnat_timestamp_get (index);
     116           0 :   ts->lifetime = lifetime;
     117           0 : }
     118             : 
     119             : always_inline f64
     120        5172 : cnat_timestamp_exp (u32 index)
     121             : {
     122             :   f64 t;
     123        5172 :   cnat_timestamp_t *ts = cnat_timestamp_get_if_valid (index);
     124        5172 :   if (NULL == ts)
     125           0 :     return -1;
     126        5172 :   t = ts->last_seen + (f64) ts->lifetime;
     127        5172 :   return t;
     128             : }
     129             : 
     130             : always_inline void
     131         262 : cnat_timestamp_free (u32 index)
     132             : {
     133         262 :   cnat_timestamp_t *ts = cnat_timestamp_get_if_valid (index);
     134         262 :   if (NULL == ts)
     135           0 :     return;
     136         262 :   if (0 == clib_atomic_sub_fetch (&ts->refcnt, 1))
     137         122 :     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

Generated by: LCOV version 1.14