LCOV - code coverage report
Current view: top level - plugins/nat/nat44-ei - nat44_ei_inlines.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 94 101 93.1 %
Date: 2023-10-26 01:39:38 Functions: 17 17 100.0 %

          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             : #ifndef __included_nat44_ei_inlines_h__
      17             : #define __included_nat44_ei_inlines_h__
      18             : 
      19             : #include <vppinfra/clib.h>
      20             : 
      21             : #include <nat/nat44-ei/nat44_ei.h>
      22             : #include <nat/nat44-ei/nat44_ei_ha.h>
      23             : #include <nat/lib/nat_proto.h>
      24             : 
      25             : always_inline u64
      26      116046 : calc_nat_key (ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
      27             : {
      28      116046 :   ASSERT (fib_index <= (1 << 14) - 1);
      29      116046 :   ASSERT (proto <= (1 << 3) - 1);
      30      232092 :   return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 |
      31      116046 :          (proto & 0x7);
      32             : }
      33             : 
      34             : always_inline void
      35       20963 : split_nat_key (u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index,
      36             :                nat_protocol_t *proto)
      37             : {
      38       20963 :   if (addr)
      39             :     {
      40       20963 :       addr->as_u32 = key >> 32;
      41             :     }
      42       20963 :   if (port)
      43             :     {
      44       20963 :       *port = (key >> 16) & (u16) ~0;
      45             :     }
      46       20963 :   if (fib_index)
      47             :     {
      48       20963 :       *fib_index = key >> 3 & ((1 << 13) - 1);
      49             :     }
      50       20963 :   if (proto)
      51             :     {
      52       20963 :       *proto = key & 0x7;
      53             :     }
      54       20963 : }
      55             : 
      56             : always_inline void
      57      116046 : init_nat_k (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
      58             :             u32 fib_index, nat_protocol_t proto)
      59             : {
      60      116046 :   kv->key = calc_nat_key (addr, port, fib_index, proto);
      61      116046 :   kv->value = ~0ULL;
      62      116046 : }
      63             : 
      64             : always_inline void
      65          77 : init_nat_kv (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
      66             :              u32 fib_index, nat_protocol_t proto, u32 thread_index,
      67             :              u32 session_index)
      68             : {
      69          77 :   init_nat_k (kv, addr, port, fib_index, proto);
      70          77 :   kv->value = (u64) thread_index << 32 | session_index;
      71          77 : }
      72             : 
      73             : always_inline void
      74       10484 : init_nat_i2o_k (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s)
      75             : {
      76       10484 :   return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
      77             :                      s->nat_proto);
      78             : }
      79             : 
      80             : always_inline void
      81       10487 : init_nat_i2o_kv (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s,
      82             :                  u32 thread_index, u32 session_index)
      83             : {
      84       10487 :   init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
      85             :               s->nat_proto);
      86       10487 :   kv->value = (u64) thread_index << 32 | session_index;
      87       10487 : }
      88             : 
      89             : always_inline void
      90       10484 : init_nat_o2i_k (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s)
      91             : {
      92       10484 :   return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
      93             :                      s->nat_proto);
      94             : }
      95             : 
      96             : always_inline void
      97       10487 : init_nat_o2i_kv (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s,
      98             :                  u32 thread_index, u32 session_index)
      99             : {
     100       10487 :   init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
     101             :               s->nat_proto);
     102       10487 :   kv->value = (u64) thread_index << 32 | session_index;
     103       10487 : }
     104             : 
     105             : always_inline u32
     106       20972 : nat_value_get_thread_index (clib_bihash_kv_8_8_t *value)
     107             : {
     108       20972 :   return value->value >> 32;
     109             : }
     110             : 
     111             : always_inline u32
     112       21155 : nat_value_get_session_index (clib_bihash_kv_8_8_t *value)
     113             : {
     114       21155 :   return value->value & ~(u32) 0;
     115             : }
     116             : 
     117             : always_inline u8
     118       10455 : nat44_ei_is_interface_addr (ip4_main_t *im, vlib_node_runtime_t *node,
     119             :                             u32 sw_if_index0, u32 ip4_addr)
     120             : {
     121       10455 :   nat44_ei_runtime_t *rt = (nat44_ei_runtime_t *) node->runtime_data;
     122             :   u8 ip4_addr_exists;
     123             : 
     124       10455 :   if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
     125             :     {
     126          20 :       ip_lookup_main_t *lm = &im->lookup_main;
     127             :       ip_interface_address_t *ia;
     128             :       ip4_address_t *a;
     129             : 
     130          20 :       rt->cached_sw_if_index = ~0;
     131          20 :       hash_free (rt->cached_presence_by_ip4_address);
     132             : 
     133          38 :       foreach_ip_interface_address (
     134             :         lm, ia, sw_if_index0, 1 /* honor unnumbered */, ({
     135             :           a = ip_interface_address_get_address (lm, ia);
     136             :           hash_set (rt->cached_presence_by_ip4_address, a->as_u32, 1);
     137             :           rt->cached_sw_if_index = sw_if_index0;
     138             :         }));
     139             : 
     140          20 :       if (rt->cached_sw_if_index == ~0)
     141           3 :         return 0;
     142             :     }
     143             : 
     144       10452 :   ip4_addr_exists = !!hash_get (rt->cached_presence_by_ip4_address, ip4_addr);
     145       10452 :   if (PREDICT_FALSE (ip4_addr_exists))
     146           1 :     return 1;
     147             :   else
     148       10451 :     return 0;
     149             : }
     150             : 
     151             : /** \brief Per-user LRU list maintenance */
     152             : always_inline void
     153       10674 : nat44_ei_session_update_lru (nat44_ei_main_t *nm, nat44_ei_session_t *s,
     154             :                              u32 thread_index)
     155             : {
     156             :   /* don't update too often - timeout is in magnitude of seconds anyway */
     157       10674 :   if (s->last_heard > s->last_lru_update + 1)
     158             :     {
     159       10488 :       clib_dlist_remove (nm->per_thread_data[thread_index].list_pool,
     160             :                          s->per_user_index);
     161       10488 :       clib_dlist_addtail (nm->per_thread_data[thread_index].list_pool,
     162             :                           s->per_user_list_head_index, s->per_user_index);
     163       10488 :       s->last_lru_update = s->last_heard;
     164             :     }
     165       10674 : }
     166             : 
     167             : always_inline void
     168       10487 : nat44_ei_user_session_increment (nat44_ei_main_t *nm, nat44_ei_user_t *u,
     169             :                                  u8 is_static)
     170             : {
     171       10487 :   if (u->nsessions + u->nstaticsessions < nm->max_translations_per_user)
     172             :     {
     173       10487 :       if (is_static)
     174          49 :         u->nstaticsessions++;
     175             :       else
     176       10438 :         u->nsessions++;
     177             :     }
     178       10487 : }
     179             : 
     180             : always_inline void
     181       10484 : nat44_ei_delete_user_with_no_session (nat44_ei_main_t *nm, nat44_ei_user_t *u,
     182             :                                       u32 thread_index)
     183             : {
     184             :   clib_bihash_kv_8_8_t kv;
     185             :   nat44_ei_user_key_t u_key;
     186       10484 :   nat44_ei_main_per_thread_data_t *tnm =
     187       10484 :     vec_elt_at_index (nm->per_thread_data, thread_index);
     188             : 
     189       10484 :   if (u->nstaticsessions == 0 && u->nsessions == 0)
     190             :     {
     191       10395 :       u_key.addr.as_u32 = u->addr.as_u32;
     192       10395 :       u_key.fib_index = u->fib_index;
     193       10395 :       kv.key = u_key.as_u64;
     194       10395 :       pool_put_index (tnm->list_pool, u->sessions_per_user_list_head_index);
     195       10395 :       pool_put (tnm->users, u);
     196       10395 :       clib_bihash_add_del_8_8 (&tnm->user_hash, &kv, 0);
     197       10395 :       vlib_set_simple_counter (&nm->total_users, thread_index, 0,
     198       10395 :                                pool_elts (tnm->users));
     199             :     }
     200       10484 : }
     201             : 
     202             : static_always_inline u8
     203       10497 : nat44_ei_maximum_sessions_exceeded (nat44_ei_main_t *nm, u32 thread_index)
     204             : {
     205       10497 :   if (pool_elts (nm->per_thread_data[thread_index].sessions) >=
     206       10497 :       nm->max_translations_per_thread)
     207           3 :     return 1;
     208       10494 :   return 0;
     209             : }
     210             : 
     211             : always_inline void
     212       10674 : nat44_ei_session_update_counters (nat44_ei_session_t *s, f64 now, uword bytes,
     213             :                                   u32 thread_index)
     214             : {
     215       10674 :   s->last_heard = now;
     216       10674 :   s->total_pkts++;
     217       10674 :   s->total_bytes += bytes;
     218       10674 :   nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
     219       10674 :                s->ext_host_port, s->nat_proto, s->out2in.fib_index,
     220             :                s->total_pkts, s->total_bytes, thread_index,
     221             :                &s->ha_last_refreshed, now);
     222       10674 : }
     223             : 
     224             : static_always_inline u32
     225          49 : nat_session_get_timeout (nat_timeouts_t *timeouts, nat_protocol_t proto,
     226             :                          u8 state)
     227             : {
     228          49 :   switch (proto)
     229             :     {
     230           0 :     case NAT_PROTOCOL_ICMP:
     231           0 :       return timeouts->icmp;
     232           0 :     case NAT_PROTOCOL_UDP:
     233           0 :       return timeouts->udp;
     234          49 :     case NAT_PROTOCOL_TCP:
     235             :       {
     236          49 :         if (state)
     237           0 :           return timeouts->tcp.transitory;
     238             :         else
     239          49 :           return timeouts->tcp.established;
     240             :       }
     241           0 :     default:
     242           0 :       return timeouts->udp;
     243             :     }
     244             :   return 0;
     245             : }
     246             : 
     247             : #endif /* __included_nat44_ei_inlines_h__ */
     248             : 
     249             : /*
     250             :  * fd.io coding-style-patch-verification: ON
     251             :  *
     252             :  * Local Variables:
     253             :  * eval: (c-set-style "gnu")
     254             :  * End:
     255             :  */

Generated by: LCOV version 1.14