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

Generated by: LCOV version 1.14