LCOV - code coverage report
Current view: top level - plugins/cnat - cnat_types.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 73 119 61.3 %
Date: 2023-07-05 22:20:52 Functions: 11 15 73.3 %

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

Generated by: LCOV version 1.14