LCOV - code coverage report
Current view: top level - plugins/cnat - cnat_types.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 72 118 61.0 %
Date: 2023-10-26 01:39:38 Functions: 8 12 66.7 %

          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             : #include <cnat/cnat_types.h>
      17             : 
      18             : cnat_main_t cnat_main;
      19             : cnat_timestamp_mpool_t cnat_timestamps;
      20             : 
      21             : char *cnat_error_strings[] = {
      22             : #define cnat_error(n,s) s,
      23             : #include <cnat/cnat_error.def>
      24             : #undef cnat_error
      25             : };
      26             : 
      27             : u8
      28         110 : cnat_resolve_addr (u32 sw_if_index, ip_address_family_t af,
      29             :                    ip_address_t * addr)
      30             : {
      31             :   /* Tries to resolve IP from sw_if_index
      32             :    * returns 1 if we need to schedule DHCP */
      33         110 :   if (INDEX_INVALID == sw_if_index)
      34          74 :     return 0;
      35          36 :   if (af == AF_IP6)
      36             :     {
      37          18 :       ip6_address_t *ip6 = 0;
      38          18 :       ip6 = ip6_interface_first_address (&ip6_main, sw_if_index);
      39          18 :       if (ip6)
      40             :         {
      41           6 :           ip_address_set (addr, ip6, AF_IP6);
      42           6 :           return 0;
      43             :         }
      44             :       else
      45          12 :         return 1;
      46             :     }
      47             :   else
      48             :     {
      49          18 :       ip4_address_t *ip4 = 0;
      50          18 :       ip4 = ip4_interface_first_address (&ip4_main, sw_if_index, 0);
      51          18 :       if (ip4)
      52             :         {
      53           6 :           ip_address_set (addr, ip4, AF_IP4);
      54           6 :           return 0;
      55             :         }
      56             :       else
      57          12 :         return 1;
      58             :     }
      59             : }
      60             : 
      61             : u8
      62          86 : cnat_resolve_ep (cnat_endpoint_t * ep)
      63             : {
      64             :   int rv;
      65          86 :   rv = cnat_resolve_addr (ep->ce_sw_if_index, ep->ce_ip.version, &ep->ce_ip);
      66          86 :   if (0 == rv)
      67          74 :     ep->ce_flags |= CNAT_EP_FLAG_RESOLVED;
      68          86 :   return rv;
      69             : }
      70             : 
      71             : uword
      72           0 : unformat_cnat_ep (unformat_input_t * input, va_list * args)
      73             : {
      74           0 :   cnat_endpoint_t *a = va_arg (*args, cnat_endpoint_t *);
      75           0 :   vnet_main_t *vnm = vnet_get_main ();
      76           0 :   int port = 0;
      77             : 
      78           0 :   clib_memset (a, 0, sizeof (*a));
      79           0 :   a->ce_sw_if_index = INDEX_INVALID;
      80           0 :   if (unformat (input, "%U %d", unformat_ip_address, &a->ce_ip, &port))
      81             :     ;
      82           0 :   else if (unformat_user (input, unformat_ip_address, &a->ce_ip))
      83             :     ;
      84           0 :   else if (unformat (input, "%U v6 %d", unformat_vnet_sw_interface,
      85             :                      vnm, &a->ce_sw_if_index, &port))
      86           0 :     a->ce_ip.version = AF_IP6;
      87           0 :   else if (unformat (input, "%U v6", unformat_vnet_sw_interface,
      88             :                      vnm, &a->ce_sw_if_index))
      89           0 :     a->ce_ip.version = AF_IP6;
      90           0 :   else if (unformat (input, "%U %d", unformat_vnet_sw_interface,
      91             :                      vnm, &a->ce_sw_if_index, &port))
      92           0 :     a->ce_ip.version = AF_IP4;
      93           0 :   else if (unformat_user (input, unformat_vnet_sw_interface,
      94             :                           vnm, &a->ce_sw_if_index))
      95           0 :     a->ce_ip.version = AF_IP4;
      96           0 :   else if (unformat (input, "%d", &port))
      97             :     ;
      98             :   else
      99           0 :     return 0;
     100           0 :   a->ce_port = (u16) port;
     101           0 :   return 1;
     102             : }
     103             : 
     104             : uword
     105           0 : unformat_cnat_ep_flags (unformat_input_t *input, va_list *args)
     106             : {
     107           0 :   int *a = va_arg (*args, int *);
     108           0 :   if (unformat (input, ":nonat"))
     109           0 :     *a = CNAT_TRK_FLAG_NO_NAT;
     110           0 :   return 1;
     111             : }
     112             : 
     113             : uword
     114           0 : unformat_cnat_ep_tuple (unformat_input_t * input, va_list * args)
     115             : {
     116           0 :   cnat_endpoint_tuple_t *a = va_arg (*args, cnat_endpoint_tuple_t *);
     117           0 :   int flgs = 0;
     118           0 :   if (unformat (input, "%U->%U%U", unformat_cnat_ep, &a->src_ep,
     119             :                 unformat_cnat_ep, &a->dst_ep, unformat_cnat_ep_flags, &flgs))
     120           0 :     a->ep_flags = flgs;
     121           0 :   else if (unformat (input, "->%U%U", unformat_cnat_ep, &a->dst_ep,
     122             :                      unformat_cnat_ep_flags, &flgs))
     123           0 :     a->ep_flags = flgs;
     124           0 :   else if (unformat (input, "%U->%U", unformat_cnat_ep, &a->src_ep,
     125             :                      unformat_cnat_ep_flags, &flgs))
     126           0 :     a->ep_flags = flgs;
     127             :   else
     128           0 :     return 0;
     129           0 :   return 1;
     130             : }
     131             : 
     132             : u8 *
     133         447 : format_cnat_endpoint (u8 * s, va_list * args)
     134             : {
     135         447 :   cnat_endpoint_t *cep = va_arg (*args, cnat_endpoint_t *);
     136         447 :   vnet_main_t *vnm = vnet_get_main ();
     137         447 :   if (INDEX_INVALID == cep->ce_sw_if_index)
     138         447 :     s = format (s, "%U;%d", format_ip_address, &cep->ce_ip, cep->ce_port);
     139             :   else
     140             :     {
     141           0 :       if (cep->ce_flags & CNAT_EP_FLAG_RESOLVED)
     142           0 :         s = format (s, "%U (%U);%d", format_vnet_sw_if_index_name, vnm,
     143             :                     cep->ce_sw_if_index, format_ip_address, &cep->ce_ip,
     144           0 :                     cep->ce_port);
     145             :       else
     146             :         s =
     147           0 :           format (s, "%U (%U);%d", format_vnet_sw_if_index_name, vnm,
     148             :                   cep->ce_sw_if_index, format_ip_address_family,
     149           0 :                   cep->ce_ip.version, cep->ce_port);
     150             :     }
     151         447 :   return (s);
     152             : }
     153             : 
     154             : void
     155           7 : cnat_enable_disable_scanner (cnat_scanner_cmd_t event_type)
     156             : {
     157           7 :   vlib_main_t *vm = vlib_get_main ();
     158           7 :   vlib_process_signal_event (vm, cnat_main.scanner_node_index, event_type, 0);
     159           7 : }
     160             : 
     161             : void
     162          28 : cnat_lazy_init ()
     163             : {
     164          28 :   cnat_main_t *cm = &cnat_main;
     165          28 :   if (cm->lazy_init_done)
     166          25 :     return;
     167           3 :   cnat_enable_disable_scanner (cm->default_scanner_state);
     168           3 :   cm->lazy_init_done = 1;
     169             : }
     170             : 
     171             : static clib_error_t *
     172         575 : cnat_config (vlib_main_t * vm, unformat_input_t * input)
     173             : {
     174         575 :   cnat_main_t *cm = &cnat_main;
     175             : 
     176         575 :   cm->session_hash_memory = CNAT_DEFAULT_SESSION_MEMORY;
     177         575 :   cm->session_hash_buckets = CNAT_DEFAULT_SESSION_BUCKETS;
     178         575 :   cm->translation_hash_memory = CNAT_DEFAULT_TRANSLATION_MEMORY;
     179         575 :   cm->translation_hash_buckets = CNAT_DEFAULT_TRANSLATION_BUCKETS;
     180         575 :   cm->client_hash_memory = CNAT_DEFAULT_CLIENT_MEMORY;
     181         575 :   cm->client_hash_buckets = CNAT_DEFAULT_CLIENT_BUCKETS;
     182         575 :   cm->snat_hash_memory = CNAT_DEFAULT_SNAT_MEMORY;
     183         575 :   cm->snat_hash_buckets = CNAT_DEFAULT_SNAT_BUCKETS;
     184         575 :   cm->snat_if_map_length = CNAT_DEFAULT_SNAT_IF_MAP_LEN;
     185         575 :   cm->scanner_timeout = CNAT_DEFAULT_SCANNER_TIMEOUT;
     186         575 :   cm->session_max_age = CNAT_DEFAULT_SESSION_MAX_AGE;
     187         575 :   cm->tcp_max_age = CNAT_DEFAULT_TCP_MAX_AGE;
     188         575 :   cm->default_scanner_state = CNAT_SCANNER_ON;
     189         575 :   cm->maglev_len = CNAT_DEFAULT_MAGLEV_LEN;
     190         575 :   cm->lazy_init_done = 0;
     191             : 
     192         590 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     193             :     {
     194          15 :       if (unformat
     195             :           (input, "session-db-buckets %u", &cm->session_hash_buckets))
     196             :         ;
     197          12 :       else if (unformat (input, "session-db-memory %U",
     198             :                          unformat_memory_size, &cm->session_hash_memory))
     199             :         ;
     200          12 :       else if (unformat (input, "translation-db-buckets %u",
     201             :                          &cm->translation_hash_buckets))
     202             :         ;
     203          12 :       else if (unformat (input, "translation-db-memory %U",
     204             :                          unformat_memory_size, &cm->translation_hash_memory))
     205             :         ;
     206          12 :       else if (unformat (input, "client-db-buckets %u",
     207             :                          &cm->client_hash_buckets))
     208             :         ;
     209          12 :       else if (unformat (input, "client-db-memory %U", unformat_memory_size,
     210             :                          &cm->client_hash_memory))
     211             :         ;
     212          12 :       else if (unformat (input, "snat-db-buckets %u", &cm->snat_hash_buckets))
     213             :         ;
     214          12 :       else if (unformat (input, "snat-if-map-len %u", &cm->snat_if_map_length))
     215             :         ;
     216          12 :       else if (unformat (input, "snat-db-memory %U",
     217             :                          unformat_memory_size, &cm->snat_hash_memory))
     218             :         ;
     219          12 :       else if (unformat (input, "session-cleanup-timeout %f",
     220             :                          &cm->scanner_timeout))
     221             :         ;
     222           9 :       else if (unformat (input, "scanner off"))
     223           3 :         cm->default_scanner_state = CNAT_SCANNER_OFF;
     224           6 :       else if (unformat (input, "scanner on"))
     225           0 :         cm->default_scanner_state = CNAT_SCANNER_ON;
     226           6 :       else if (unformat (input, "session-max-age %u", &cm->session_max_age))
     227             :         ;
     228           3 :       else if (unformat (input, "tcp-max-age %u", &cm->tcp_max_age))
     229             :         ;
     230           0 :       else if (unformat (input, "maglev-len %u", &cm->maglev_len))
     231             :         ;
     232             :       else
     233           0 :         return clib_error_return (0, "unknown input '%U'",
     234             :                                   format_unformat_error, input);
     235             :     }
     236             : 
     237         575 :   return 0;
     238             : }
     239             : 
     240             : cnat_main_t *
     241           0 : cnat_get_main ()
     242             : {
     243           0 :   return &cnat_main;
     244             : }
     245             : 
     246        6362 : VLIB_EARLY_CONFIG_FUNCTION (cnat_config, "cnat");
     247             : 
     248             : /*
     249             :  * fd.io coding-style-patch-verification: ON
     250             :  *
     251             :  * Local Variables:
     252             :  * eval: (c-set-style "gnu")
     253             :  * End:
     254             :  */

Generated by: LCOV version 1.14