LCOV - code coverage report
Current view: top level - plugins/cnat - cnat_client.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 20 20 100.0 %
Date: 2023-10-26 01:39:38 Functions: 5 5 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 __CNAT_CLIENT_H__
      17             : #define __CNAT_CLIENT_H__
      18             : 
      19             : #include <cnat/cnat_types.h>
      20             : #include <vppinfra/bihash_16_8.h>
      21             : 
      22             : /**
      23             :  * A client is a representation of an IP address behind the NAT.
      24             :  * A client thus sends packet to a VIP.
      25             :  * Clients are learned in the Data-plane when they send packets,
      26             :  * but, since they make additions to the FIB they must be programmed
      27             :  * in the main thread. They are aged out when they become idle.
      28             :  *
      29             :  * A client interposes in the FIB graph for the prefix corresponding
      30             :  * to the client (e.g. client's-IP/32). As a result this client object
      31             :  * is cloned as the interpose DPO. The clones are removed when the lock
      32             :  * count drops to zero. The originals are removed when the client ages.
      33             :  * At forwarding time the client preforms the reverse translation and
      34             :  * then ships the packet to where the FIB would send it.
      35             :  */
      36             : typedef struct cnat_client_t_
      37             : {
      38             :   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
      39             : 
      40             :   /**
      41             :    * the client's IP address
      42             :    */
      43             :   ip_address_t cc_ip;
      44             : 
      45             :   /**
      46             :    * How to send packets to this client post translation
      47             :    */
      48             :   dpo_id_t cc_parent;
      49             : 
      50             :   /**
      51             :    * the FIB entry this client sources
      52             :    */
      53             :   fib_node_index_t cc_fei;
      54             : 
      55             :   /**
      56             :    * number of DPO locks
      57             :    */
      58             :   u32 cc_locks;
      59             : 
      60             :   /**
      61             :    * Translations refcount for cleanup
      62             :    */
      63             :   u32 tr_refcnt;
      64             : 
      65             :   /**
      66             :    * Session refcount for cleanup
      67             :    */
      68             :   u32 session_refcnt;
      69             : 
      70             :   /**
      71             :    * Parent cnat_client index if cloned via interpose
      72             :    * or own index if vanilla client.
      73             :    * Used to get translations & update session_refcnt
      74             :    */
      75             :   index_t parent_cci;
      76             : 
      77             :   /**
      78             :    * Client flags
      79             :    */
      80             :   u8 flags;
      81             : } cnat_client_t;
      82             : 
      83             : extern u8 *format_cnat_client (u8 * s, va_list * args);
      84             : extern void cnat_client_free_by_ip (ip46_address_t * addr, u8 af);
      85             : 
      86             : extern cnat_client_t *cnat_client_pool;
      87             : extern dpo_type_t cnat_client_dpo;
      88             : 
      89             : static_always_inline cnat_client_t *
      90        6297 : cnat_client_get (index_t i)
      91             : {
      92        6297 :   return (pool_elt_at_index (cnat_client_pool, i));
      93             : }
      94             : 
      95             : /**
      96             :  * A translation that references this VIP was deleted
      97             :  */
      98             : extern void cnat_client_translation_deleted (index_t cci);
      99             : 
     100             : /**
     101             :  * A translation that references this VIP was added
     102             :  */
     103             : extern void cnat_client_translation_added (index_t cci);
     104             : /**
     105             :  * Called in the main thread by RPC from the workers to learn a
     106             :  * new client
     107             :  */
     108             : extern void cnat_client_learn (const ip_address_t *addr);
     109             : 
     110             : extern index_t cnat_client_add (const ip_address_t * ip, u8 flags);
     111             : 
     112             : /**
     113             :  * Check all the clients were purged by translation & session purge
     114             :  */
     115             : extern int cnat_client_purge (void);
     116             : 
     117             : /**
     118             :  * CNat Client (dpo) flags
     119             :  */
     120             : typedef enum
     121             : {
     122             :   /* IP already present in the FIB, need to interpose dpo */
     123             :   CNAT_FLAG_EXCLUSIVE = (1 << 1),
     124             : } cnat_entry_flag_t;
     125             : 
     126             : 
     127             : extern void cnat_client_throttle_pool_process ();
     128             : 
     129             : /**
     130             :  * DB of clients
     131             :  */
     132             : typedef struct cnat_client_db_t_
     133             : {
     134             :   clib_bihash_16_8_t cc_ip_id_hash;
     135             :   /* Pool of addresses that have been throttled
     136             :      and need to be refcounted before calling
     137             :      cnat_client_free_by_ip */
     138             :   clib_spinlock_t throttle_lock;
     139             :   uword *throttle_mem;
     140             : } cnat_client_db_t;
     141             : 
     142             : extern cnat_client_db_t cnat_client_db;
     143             : 
     144             : /**
     145             :  * Find a client from an IP4 address
     146             :  */
     147             : static_always_inline cnat_client_t *
     148         251 : cnat_client_ip4_find (const ip4_address_t * ip)
     149             : {
     150             :   clib_bihash_kv_16_8_t bkey, bval;
     151             : 
     152         251 :   bkey.key[0] = ip->as_u32;
     153         251 :   bkey.key[1] = 0;
     154             : 
     155         251 :   if (clib_bihash_search_16_8 (&cnat_client_db.cc_ip_id_hash, &bkey, &bval))
     156          38 :     return (NULL);
     157             : 
     158         213 :   return (pool_elt_at_index (cnat_client_pool, bval.value));
     159             : }
     160             : 
     161             : /**
     162             :  * Find a client from an IP6 address
     163             :  */
     164             : static_always_inline cnat_client_t *
     165         191 : cnat_client_ip6_find (const ip6_address_t * ip)
     166             : {
     167             :   clib_bihash_kv_16_8_t bkey, bval;
     168             : 
     169         191 :   bkey.key[0] = ip->as_u64[0];
     170         191 :   bkey.key[1] = ip->as_u64[1];
     171             : 
     172         191 :   if (clib_bihash_search_16_8 (&cnat_client_db.cc_ip_id_hash, &bkey, &bval))
     173          30 :     return (NULL);
     174             : 
     175         161 :   return (pool_elt_at_index (cnat_client_pool, bval.value));
     176             : }
     177             : 
     178             : /**
     179             :  * Add a session refcnt to this client
     180             :  */
     181             : static_always_inline u32
     182         242 : cnat_client_cnt_session (cnat_client_t * cc)
     183             : {
     184         242 :   cnat_client_t *ccp = cnat_client_get (cc->parent_cci);
     185         242 :   return clib_atomic_add_fetch (&ccp->session_refcnt, 1);
     186             : }
     187             : 
     188             : /**
     189             :  * Del a session refcnt to this client
     190             :  */
     191             : static_always_inline u32
     192         242 : cnat_client_uncnt_session (cnat_client_t * cc)
     193             : {
     194         242 :   cnat_client_t *ccp = cnat_client_get (cc->parent_cci);
     195         242 :   return clib_atomic_sub_fetch (&ccp->session_refcnt, 1);
     196             : }
     197             : 
     198             : /*
     199             :  * fd.io coding-style-patch-verification: ON
     200             :  *
     201             :  * Local Variables:
     202             :  * eval: (c-set-style "gnu")
     203             :  * End:
     204             :  */
     205             : 
     206             : #endif

Generated by: LCOV version 1.14