LCOV - code coverage report
Current view: top level - plugins/nat/nat44-ei - nat44_ei_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 411 659 62.4 %
Date: 2023-10-26 01:39:38 Functions: 35 55 63.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020 Cisco and/or its affiliates.
       3             :  *
       4             :  * Licensed under the Apache License, Version 2.0 (the "License");
       5             :  * you may not use this file except in compliance with the License.
       6             :  * You may obtain a copy of the License at:
       7             :  *
       8             :  *     http://www.apache.org/licenses/LICENSE-2.0
       9             :  *
      10             :  * Unless required by applicable law or agreed to in writing, software
      11             :  * distributed under the License is distributed on an "AS IS" BASIS,
      12             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13             :  * See the License for the specific language governing permissions and
      14             :  * limitations under the License.
      15             :  */
      16             : 
      17             : #include <vnet/ip/ip_types_api.h>
      18             : #include <vlibmemory/api.h>
      19             : 
      20             : #include <vnet/fib/fib_table.h>
      21             : 
      22             : #include <nat/lib/nat_inlines.h>
      23             : #include <nat/lib/ipfix_logging.h>
      24             : 
      25             : #include <nat/nat44-ei/nat44_ei.api_enum.h>
      26             : #include <nat/nat44-ei/nat44_ei.api_types.h>
      27             : 
      28             : #include <nat/nat44-ei/nat44_ei_ha.h>
      29             : #include <nat/nat44-ei/nat44_ei.h>
      30             : 
      31             : #define REPLY_MSG_ID_BASE nm->msg_id_base
      32             : #include <vlibapi/api_helper_macros.h>
      33             : 
      34             : static void
      35           1 : vl_api_nat44_ei_show_running_config_t_handler (
      36             :   vl_api_nat44_ei_show_running_config_t *mp)
      37             : {
      38             :   vl_api_nat44_ei_show_running_config_reply_t *rmp;
      39           1 :   nat44_ei_main_t *nm = &nat44_ei_main;
      40           1 :   nat44_ei_config_t *rc = &nm->rconfig;
      41           1 :   int rv = 0;
      42             : 
      43           1 :   REPLY_MACRO2_ZERO (
      44             :     VL_API_NAT44_EI_SHOW_RUNNING_CONFIG_REPLY, ({
      45             :       rmp->inside_vrf = htonl (rc->inside_vrf);
      46             :       rmp->outside_vrf = htonl (rc->outside_vrf);
      47             :       rmp->users = htonl (rc->users);
      48             :       rmp->sessions = htonl (rc->sessions);
      49             :       rmp->user_sessions = htonl (rc->user_sessions);
      50             : 
      51             :       rmp->user_buckets = htonl (nm->user_buckets);
      52             :       rmp->translation_buckets = htonl (nm->translation_buckets);
      53             : 
      54             :       rmp->timeouts.udp = htonl (nm->timeouts.udp);
      55             :       rmp->timeouts.tcp_established = htonl (nm->timeouts.tcp.established);
      56             :       rmp->timeouts.tcp_transitory = htonl (nm->timeouts.tcp.transitory);
      57             :       rmp->timeouts.icmp = htonl (nm->timeouts.icmp);
      58             : 
      59             :       rmp->forwarding_enabled = nm->forwarding_enabled == 1;
      60             :       // consider how to split functionality between subplugins
      61             :       rmp->ipfix_logging_enabled = nat_ipfix_logging_enabled ();
      62             : 
      63             :       if (rc->static_mapping_only)
      64             :         rmp->flags |= NAT44_EI_STATIC_MAPPING_ONLY;
      65             :       if (rc->connection_tracking)
      66             :         rmp->flags |= NAT44_EI_CONNECTION_TRACKING;
      67             :       if (rc->out2in_dpo)
      68             :         rmp->flags |= NAT44_EI_OUT2IN_DPO;
      69             :     }));
      70             : }
      71             : 
      72             : static void
      73           0 : vl_api_nat44_ei_set_workers_t_handler (vl_api_nat44_ei_set_workers_t *mp)
      74             : {
      75           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
      76             :   vl_api_nat44_ei_set_workers_reply_t *rmp;
      77           0 :   int rv = 0;
      78           0 :   uword *bitmap = 0;
      79             :   u64 mask;
      80             : 
      81           0 :   mask = clib_net_to_host_u64 (mp->worker_mask);
      82             : 
      83           0 :   if (nm->num_workers < 2)
      84             :     {
      85           0 :       rv = VNET_API_ERROR_FEATURE_DISABLED;
      86           0 :       goto send_reply;
      87             :     }
      88             : 
      89           0 :   bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
      90           0 :   rv = nat44_ei_set_workers (bitmap);
      91           0 :   clib_bitmap_free (bitmap);
      92             : 
      93           0 : send_reply:
      94           0 :   REPLY_MACRO (VL_API_NAT44_EI_SET_WORKERS_REPLY);
      95             : }
      96             : 
      97             : static void
      98           0 : send_nat_worker_details (u32 worker_index, vl_api_registration_t *reg,
      99             :                          u32 context)
     100             : {
     101             :   vl_api_nat44_ei_worker_details_t *rmp;
     102           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     103           0 :   vlib_worker_thread_t *w =
     104           0 :     vlib_worker_threads + worker_index + nm->first_worker_index;
     105             : 
     106           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     107           0 :   clib_memset (rmp, 0, sizeof (*rmp));
     108           0 :   rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_WORKER_DETAILS + nm->msg_id_base);
     109           0 :   rmp->context = context;
     110           0 :   rmp->worker_index = htonl (worker_index);
     111           0 :   rmp->lcore_id = htonl (w->cpu_id);
     112           0 :   strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
     113             : 
     114           0 :   vl_api_send_msg (reg, (u8 *) rmp);
     115           0 : }
     116             : 
     117             : static void
     118           0 : vl_api_nat44_ei_worker_dump_t_handler (vl_api_nat44_ei_worker_dump_t *mp)
     119             : {
     120             :   vl_api_registration_t *reg;
     121           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     122             :   u32 *worker_index;
     123             : 
     124           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     125           0 :   if (!reg)
     126           0 :     return;
     127             : 
     128           0 :   vec_foreach (worker_index, nm->workers)
     129             :     {
     130           0 :       send_nat_worker_details (*worker_index, reg, mp->context);
     131             :     }
     132             : }
     133             : 
     134             : static void
     135           0 : vl_api_nat44_ei_set_log_level_t_handler (vl_api_nat44_ei_set_log_level_t *mp)
     136             : {
     137           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     138             :   vl_api_nat44_ei_set_log_level_reply_t *rmp;
     139           0 :   int rv = 0;
     140             : 
     141           0 :   if (nm->log_level > NAT_LOG_DEBUG)
     142           0 :     rv = VNET_API_ERROR_UNSUPPORTED;
     143             :   else
     144           0 :     nm->log_level = mp->log_level;
     145             : 
     146           0 :   REPLY_MACRO (VL_API_NAT44_EI_SET_LOG_LEVEL_REPLY);
     147             : }
     148             : 
     149             : static void
     150         116 : vl_api_nat44_ei_plugin_enable_disable_t_handler (
     151             :   vl_api_nat44_ei_plugin_enable_disable_t *mp)
     152             : {
     153         116 :   nat44_ei_main_t *nm = &nat44_ei_main;
     154         116 :   nat44_ei_config_t c = { 0 };
     155             :   vl_api_nat44_ei_plugin_enable_disable_reply_t *rmp;
     156         116 :   int rv = 0;
     157             : 
     158         116 :   if (mp->enable)
     159             :     {
     160          58 :       c.static_mapping_only = mp->flags & NAT44_EI_STATIC_MAPPING_ONLY;
     161          58 :       c.connection_tracking = mp->flags & NAT44_EI_CONNECTION_TRACKING;
     162          58 :       c.out2in_dpo = mp->flags & NAT44_EI_OUT2IN_DPO;
     163             : 
     164          58 :       c.inside_vrf = ntohl (mp->inside_vrf);
     165          58 :       c.outside_vrf = ntohl (mp->outside_vrf);
     166             : 
     167          58 :       c.users = ntohl (mp->users);
     168             : 
     169          58 :       c.sessions = ntohl (mp->sessions);
     170             : 
     171          58 :       c.user_sessions = ntohl (mp->user_sessions);
     172             : 
     173          58 :       rv = nat44_ei_plugin_enable (c);
     174             :     }
     175             :   else
     176             :     {
     177          58 :       rv = nat44_ei_plugin_disable ();
     178             :     }
     179             : 
     180         116 :   REPLY_MACRO (VL_API_NAT44_EI_PLUGIN_ENABLE_DISABLE_REPLY);
     181             : }
     182             : 
     183             : static void
     184          60 : vl_api_nat44_ei_ipfix_enable_disable_t_handler (
     185             :   vl_api_nat44_ei_ipfix_enable_disable_t *mp)
     186             : {
     187          60 :   nat44_ei_main_t *nm = &nat44_ei_main;
     188             :   vl_api_nat44_ei_ipfix_enable_disable_reply_t *rmp;
     189          60 :   int rv = 0;
     190             : 
     191          60 :   rv = nat_ipfix_logging_enable_disable (mp->enable,
     192             :                                          clib_host_to_net_u32 (mp->domain_id),
     193          60 :                                          clib_host_to_net_u16 (mp->src_port));
     194             : 
     195          60 :   REPLY_MACRO (VL_API_NAT44_EI_IPFIX_ENABLE_DISABLE_REPLY);
     196             : }
     197             : 
     198             : static void
     199           0 : vl_api_nat44_ei_set_timeouts_t_handler (vl_api_nat44_ei_set_timeouts_t *mp)
     200             : {
     201           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     202             :   vl_api_nat44_ei_set_timeouts_reply_t *rmp;
     203           0 :   int rv = 0;
     204             : 
     205           0 :   nm->timeouts.udp = ntohl (mp->udp);
     206           0 :   nm->timeouts.tcp.established = ntohl (mp->tcp_established);
     207           0 :   nm->timeouts.tcp.transitory = ntohl (mp->tcp_transitory);
     208           0 :   nm->timeouts.icmp = ntohl (mp->icmp);
     209             : 
     210           0 :   REPLY_MACRO (VL_API_NAT44_EI_SET_TIMEOUTS_REPLY);
     211             : }
     212             : 
     213             : static void
     214           2 : vl_api_nat44_ei_set_addr_and_port_alloc_alg_t_handler (
     215             :   vl_api_nat44_ei_set_addr_and_port_alloc_alg_t *mp)
     216             : {
     217           2 :   nat44_ei_main_t *nm = &nat44_ei_main;
     218             :   vl_api_nat44_ei_set_addr_and_port_alloc_alg_reply_t *rmp;
     219           2 :   int rv = 0;
     220             :   u16 port_start, port_end;
     221             : 
     222           2 :   switch (mp->alg)
     223             :     {
     224           0 :     case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_DEFAULT:
     225           0 :       nat44_ei_set_alloc_default ();
     226           0 :       break;
     227           1 :     case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_MAPE:
     228           1 :       nat44_ei_set_alloc_mape (ntohs (mp->psid), mp->psid_offset,
     229           1 :                                mp->psid_length);
     230           1 :       break;
     231           1 :     case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_RANGE:
     232           1 :       port_start = ntohs (mp->start_port);
     233           1 :       port_end = ntohs (mp->end_port);
     234           1 :       if (port_end <= port_start)
     235             :         {
     236           0 :           rv = VNET_API_ERROR_INVALID_VALUE;
     237           0 :           goto send_reply;
     238             :         }
     239           1 :       nat44_ei_set_alloc_range (port_start, port_end);
     240           1 :       break;
     241           0 :     default:
     242           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
     243           0 :       break;
     244             :     }
     245             : 
     246           2 : send_reply:
     247           2 :   REPLY_MACRO (VL_API_NAT44_EI_SET_ADDR_AND_PORT_ALLOC_ALG_REPLY);
     248             : }
     249             : 
     250             : static void
     251           0 : vl_api_nat44_ei_get_addr_and_port_alloc_alg_t_handler (
     252             :   vl_api_nat44_ei_get_addr_and_port_alloc_alg_t *mp)
     253             : {
     254           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     255             :   vl_api_nat44_ei_get_addr_and_port_alloc_alg_reply_t *rmp;
     256           0 :   int rv = 0;
     257             : 
     258           0 :   REPLY_MACRO2 (VL_API_NAT44_EI_GET_ADDR_AND_PORT_ALLOC_ALG_REPLY, ({
     259             :                   rmp->alg = nm->addr_and_port_alloc_alg;
     260             :                   rmp->psid_offset = nm->psid_offset;
     261             :                   rmp->psid_length = nm->psid_length;
     262             :                   rmp->psid = htons (nm->psid);
     263             :                   rmp->start_port = htons (nm->start_port);
     264             :                   rmp->end_port = htons (nm->end_port);
     265             :                 }))
     266             : }
     267             : 
     268             : static void
     269           3 : vl_api_nat44_ei_set_mss_clamping_t_handler (
     270             :   vl_api_nat44_ei_set_mss_clamping_t *mp)
     271             : {
     272           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
     273             :   vl_api_nat44_ei_set_mss_clamping_reply_t *rmp;
     274           3 :   int rv = 0;
     275             : 
     276           3 :   if (mp->enable)
     277           2 :     nm->mss_clamping = ntohs (mp->mss_value);
     278             :   else
     279           1 :     nm->mss_clamping = 0;
     280             : 
     281           3 :   REPLY_MACRO (VL_API_NAT44_EI_SET_MSS_CLAMPING_REPLY);
     282             : }
     283             : 
     284             : static void
     285           0 : vl_api_nat44_ei_get_mss_clamping_t_handler (
     286             :   vl_api_nat44_ei_get_mss_clamping_t *mp)
     287             : {
     288           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     289             :   vl_api_nat44_ei_get_mss_clamping_reply_t *rmp;
     290           0 :   int rv = 0;
     291             : 
     292           0 :   REPLY_MACRO2 (VL_API_NAT44_EI_GET_MSS_CLAMPING_REPLY, ({
     293             :                   rmp->enable = nm->mss_clamping ? 1 : 0;
     294             :                   rmp->mss_value = htons (nm->mss_clamping);
     295             :                 }))
     296             : }
     297             : 
     298             : static void
     299           2 : vl_api_nat44_ei_ha_set_listener_t_handler (
     300             :   vl_api_nat44_ei_ha_set_listener_t *mp)
     301             : {
     302           2 :   nat44_ei_main_t *nm = &nat44_ei_main;
     303             :   vl_api_nat44_ei_ha_set_listener_reply_t *rmp;
     304             :   ip4_address_t addr;
     305             :   int rv;
     306             : 
     307           2 :   memcpy (&addr, &mp->ip_address, sizeof (addr));
     308           4 :   rv = nat_ha_set_listener (vlib_get_main (), &addr,
     309           2 :                             clib_net_to_host_u16 (mp->port),
     310             :                             clib_net_to_host_u32 (mp->path_mtu));
     311             : 
     312           2 :   REPLY_MACRO (VL_API_NAT44_EI_HA_SET_LISTENER_REPLY);
     313             : }
     314             : 
     315             : static void
     316           0 : vl_api_nat44_ei_ha_get_listener_t_handler (
     317             :   vl_api_nat44_ei_ha_get_listener_t *mp)
     318             : {
     319           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     320             :   vl_api_nat44_ei_ha_get_listener_reply_t *rmp;
     321           0 :   int rv = 0;
     322             :   ip4_address_t addr;
     323             :   u16 port;
     324             :   u32 path_mtu;
     325             : 
     326           0 :   nat_ha_get_listener (&addr, &port, &path_mtu);
     327             : 
     328           0 :   REPLY_MACRO2 (VL_API_NAT44_EI_HA_GET_LISTENER_REPLY, ({
     329             :                   clib_memcpy (rmp->ip_address, &addr, sizeof (ip4_address_t));
     330             :                   rmp->port = clib_host_to_net_u16 (port);
     331             :                   rmp->path_mtu = clib_host_to_net_u32 (path_mtu);
     332             :                 }))
     333             : }
     334             : 
     335             : static void
     336           1 : vl_api_nat44_ei_ha_set_failover_t_handler (
     337             :   vl_api_nat44_ei_ha_set_failover_t *mp)
     338             : {
     339           1 :   nat44_ei_main_t *nm = &nat44_ei_main;
     340             :   vl_api_nat44_ei_ha_set_failover_reply_t *rmp;
     341             :   ip4_address_t addr;
     342             :   int rv;
     343             : 
     344           1 :   memcpy (&addr, &mp->ip_address, sizeof (addr));
     345           2 :   rv = nat_ha_set_failover (
     346           1 :     vlib_get_main (), &addr, clib_net_to_host_u16 (mp->port),
     347             :     clib_net_to_host_u32 (mp->session_refresh_interval));
     348             : 
     349           1 :   REPLY_MACRO (VL_API_NAT44_EI_HA_SET_FAILOVER_REPLY);
     350             : }
     351             : 
     352             : static void
     353           0 : vl_api_nat44_ei_ha_get_failover_t_handler (
     354             :   vl_api_nat44_ei_ha_get_failover_t *mp)
     355             : {
     356           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     357             :   vl_api_nat44_ei_ha_get_failover_reply_t *rmp;
     358           0 :   int rv = 0;
     359             :   ip4_address_t addr;
     360             :   u16 port;
     361             :   u32 session_refresh_interval;
     362             : 
     363           0 :   nat_ha_get_failover (&addr, &port, &session_refresh_interval);
     364             : 
     365           0 :   REPLY_MACRO2 (VL_API_NAT44_EI_HA_GET_FAILOVER_REPLY, ({
     366             :                   clib_memcpy (rmp->ip_address, &addr, sizeof (ip4_address_t));
     367             :                   rmp->port = clib_host_to_net_u16 (port);
     368             :                   rmp->session_refresh_interval =
     369             :                     clib_host_to_net_u32 (session_refresh_interval);
     370             :                 }))
     371             : }
     372             : 
     373             : static void
     374           3 : vl_api_nat44_ei_ha_flush_t_handler (vl_api_nat44_ei_ha_flush_t *mp)
     375             : {
     376           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
     377             :   vl_api_nat44_ei_ha_flush_reply_t *rmp;
     378           3 :   int rv = 0;
     379             : 
     380           3 :   nat_ha_flush (0);
     381             : 
     382           3 :   REPLY_MACRO (VL_API_NAT44_EI_HA_FLUSH_REPLY);
     383             : }
     384             : 
     385             : static void
     386           0 : nat_ha_resync_completed_event_cb (u32 client_index, u32 pid, u32 missed_count)
     387             : {
     388           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     389             :   vl_api_registration_t *reg;
     390             :   vl_api_nat44_ei_ha_resync_completed_event_t *mp;
     391             : 
     392           0 :   reg = vl_api_client_index_to_registration (client_index);
     393           0 :   if (!reg)
     394           0 :     return;
     395             : 
     396           0 :   mp = vl_msg_api_alloc (sizeof (*mp));
     397           0 :   clib_memset (mp, 0, sizeof (*mp));
     398           0 :   mp->client_index = client_index;
     399           0 :   mp->pid = pid;
     400           0 :   mp->missed_count = clib_host_to_net_u32 (missed_count);
     401           0 :   mp->_vl_msg_id =
     402           0 :     ntohs (VL_API_NAT44_EI_HA_RESYNC_COMPLETED_EVENT + nm->msg_id_base);
     403             : 
     404           0 :   vl_api_send_msg (reg, (u8 *) mp);
     405             : }
     406             : 
     407             : static void
     408           0 : vl_api_nat44_ei_ha_resync_t_handler (vl_api_nat44_ei_ha_resync_t *mp)
     409             : {
     410           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     411             :   vl_api_nat44_ei_ha_resync_reply_t *rmp;
     412             :   int rv;
     413             : 
     414           0 :   rv = nat_ha_resync (
     415             :     mp->client_index, mp->pid,
     416           0 :     mp->want_resync_event ? nat_ha_resync_completed_event_cb : NULL);
     417             : 
     418           0 :   REPLY_MACRO (VL_API_NAT44_EI_HA_RESYNC_REPLY);
     419             : }
     420             : 
     421             : static void
     422           0 : vl_api_nat44_ei_del_user_t_handler (vl_api_nat44_ei_del_user_t *mp)
     423             : {
     424           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     425             :   vl_api_nat44_ei_del_user_reply_t *rmp;
     426             :   ip4_address_t addr;
     427             :   int rv;
     428           0 :   memcpy (&addr.as_u8, mp->ip_address, 4);
     429           0 :   rv = nat44_ei_user_del (&addr, ntohl (mp->fib_index));
     430           0 :   REPLY_MACRO (VL_API_NAT44_EI_DEL_USER_REPLY);
     431             : }
     432             : 
     433             : static void
     434          48 : vl_api_nat44_ei_add_del_address_range_t_handler (
     435             :   vl_api_nat44_ei_add_del_address_range_t *mp)
     436             : {
     437          48 :   nat44_ei_main_t *nm = &nat44_ei_main;
     438             :   vl_api_nat44_ei_add_del_address_range_reply_t *rmp;
     439             :   ip4_address_t this_addr;
     440             :   u8 is_add;
     441             :   u32 start_host_order, end_host_order;
     442             :   u32 vrf_id;
     443             :   int i, count;
     444          48 :   int rv = 0;
     445             :   u32 *tmp;
     446             : 
     447          48 :   if (nm->static_mapping_only)
     448             :     {
     449           0 :       rv = VNET_API_ERROR_FEATURE_DISABLED;
     450           0 :       goto send_reply;
     451             :     }
     452             : 
     453          48 :   is_add = mp->is_add;
     454             : 
     455          48 :   tmp = (u32 *) mp->first_ip_address;
     456          48 :   start_host_order = clib_host_to_net_u32 (tmp[0]);
     457          48 :   tmp = (u32 *) mp->last_ip_address;
     458          48 :   end_host_order = clib_host_to_net_u32 (tmp[0]);
     459             : 
     460          48 :   count = (end_host_order - start_host_order) + 1;
     461             : 
     462          48 :   vrf_id = clib_host_to_net_u32 (mp->vrf_id);
     463             : 
     464          48 :   if (count > 1024)
     465           0 :     nat44_ei_log_info ("%U - %U, %d addresses...", format_ip4_address,
     466             :                        mp->first_ip_address, format_ip4_address,
     467             :                        mp->last_ip_address, count);
     468             : 
     469          48 :   memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
     470             : 
     471         194 :   for (i = 0; i < count; i++)
     472             :     {
     473         146 :       if (is_add)
     474         142 :         rv = nat44_ei_add_address (&this_addr, vrf_id);
     475             :       else
     476           4 :         rv = nat44_ei_del_address (this_addr, 0);
     477             : 
     478         146 :       if (rv)
     479           0 :         goto send_reply;
     480             : 
     481         146 :       if (nm->out2in_dpo)
     482           0 :         nat44_ei_add_del_address_dpo (this_addr, is_add);
     483             : 
     484         146 :       increment_v4_address (&this_addr);
     485             :     }
     486             : 
     487          48 : send_reply:
     488          48 :   REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_ADDRESS_RANGE_REPLY);
     489             : }
     490             : 
     491             : static void
     492           3 : send_nat44_ei_address_details (nat44_ei_address_t *a,
     493             :                                vl_api_registration_t *reg, u32 context)
     494             : {
     495             :   vl_api_nat44_ei_address_details_t *rmp;
     496           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
     497             : 
     498           3 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     499           3 :   clib_memset (rmp, 0, sizeof (*rmp));
     500           3 :   rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_ADDRESS_DETAILS + nm->msg_id_base);
     501           3 :   clib_memcpy (rmp->ip_address, &(a->addr), 4);
     502           3 :   if (a->fib_index != ~0)
     503             :     {
     504           0 :       fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
     505           0 :       rmp->vrf_id = ntohl (fib->ft_table_id);
     506             :     }
     507             :   else
     508           3 :     rmp->vrf_id = ~0;
     509           3 :   rmp->context = context;
     510             : 
     511           3 :   vl_api_send_msg (reg, (u8 *) rmp);
     512           3 : }
     513             : 
     514             : static void
     515           5 : vl_api_nat44_ei_address_dump_t_handler (vl_api_nat44_ei_address_dump_t *mp)
     516             : {
     517             :   vl_api_registration_t *reg;
     518           5 :   nat44_ei_main_t *nm = &nat44_ei_main;
     519             :   nat44_ei_address_t *a;
     520             : 
     521           5 :   reg = vl_api_client_index_to_registration (mp->client_index);
     522           5 :   if (!reg)
     523           0 :     return;
     524             : 
     525           8 :   vec_foreach (a, nm->addresses)
     526             :     {
     527           3 :       send_nat44_ei_address_details (a, reg, mp->context);
     528             :     }
     529             : }
     530             : 
     531             : static void
     532         106 : vl_api_nat44_ei_interface_add_del_feature_t_handler (
     533             :   vl_api_nat44_ei_interface_add_del_feature_t *mp)
     534             : {
     535         106 :   nat44_ei_main_t *nm = &nat44_ei_main;
     536             :   vl_api_nat44_ei_interface_add_del_feature_reply_t *rmp;
     537         106 :   u32 sw_if_index = ntohl (mp->sw_if_index);
     538         106 :   int rv = 0;
     539             : 
     540         106 :   VALIDATE_SW_IF_INDEX (mp);
     541             : 
     542         106 :   if (mp->is_add)
     543             :     {
     544             :       rv =
     545         106 :         nat44_ei_add_interface (sw_if_index, mp->flags & NAT44_EI_IF_INSIDE);
     546             :     }
     547             :   else
     548             :     {
     549             :       rv =
     550           0 :         nat44_ei_del_interface (sw_if_index, mp->flags & NAT44_EI_IF_INSIDE);
     551             :     }
     552             : 
     553         106 :   BAD_SW_IF_INDEX_LABEL;
     554         106 :   REPLY_MACRO (VL_API_NAT44_EI_INTERFACE_ADD_DEL_FEATURE_REPLY);
     555             : }
     556             : 
     557             : static void
     558           6 : send_nat44_ei_interface_details (nat44_ei_interface_t *i,
     559             :                                  vl_api_registration_t *reg, u32 context)
     560             : {
     561             :   vl_api_nat44_ei_interface_details_t *rmp;
     562           6 :   nat44_ei_main_t *nm = &nat44_ei_main;
     563             : 
     564           6 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     565           6 :   clib_memset (rmp, 0, sizeof (*rmp));
     566           6 :   rmp->_vl_msg_id =
     567           6 :     ntohs (VL_API_NAT44_EI_INTERFACE_DETAILS + nm->msg_id_base);
     568           6 :   rmp->sw_if_index = ntohl (i->sw_if_index);
     569             : 
     570           6 :   if (nat44_ei_interface_is_inside (i))
     571           5 :     rmp->flags |= NAT44_EI_IF_INSIDE;
     572           6 :   if (nat44_ei_interface_is_outside (i))
     573           1 :     rmp->flags |= NAT44_EI_IF_OUTSIDE;
     574             : 
     575           6 :   rmp->context = context;
     576             : 
     577           6 :   vl_api_send_msg (reg, (u8 *) rmp);
     578           6 : }
     579             : 
     580             : static void
     581           5 : vl_api_nat44_ei_interface_dump_t_handler (vl_api_nat44_ei_interface_dump_t *mp)
     582             : {
     583             :   vl_api_registration_t *reg;
     584           5 :   nat44_ei_main_t *nm = &nat44_ei_main;
     585             :   nat44_ei_interface_t *i;
     586             : 
     587           5 :   reg = vl_api_client_index_to_registration (mp->client_index);
     588           5 :   if (!reg)
     589           0 :     return;
     590             : 
     591          11 :   pool_foreach (i, nm->interfaces)
     592             :     {
     593           6 :       send_nat44_ei_interface_details (i, reg, mp->context);
     594             :     }
     595             : }
     596             : 
     597             : static_always_inline int
     598           0 : add_del_dummy_output_interface (u32 sw_if_index, u8 is_inside, u8 is_add)
     599             : {
     600           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     601             :   nat44_ei_interface_t *i;
     602           0 :   int rv = 1;
     603             : 
     604           0 :   pool_foreach (i, nm->output_feature_dummy_interfaces)
     605             :     {
     606           0 :       if (i->sw_if_index == sw_if_index)
     607             :         {
     608           0 :           if (!is_add)
     609             :             {
     610           0 :               pool_put (nm->output_feature_dummy_interfaces, i);
     611           0 :               rv = 0;
     612             :             }
     613           0 :           goto done;
     614             :         }
     615             :     }
     616             : 
     617           0 :   if (is_add)
     618             :     {
     619           0 :       pool_get (nm->output_feature_dummy_interfaces, i);
     620           0 :       i->sw_if_index = sw_if_index;
     621             : 
     622           0 :       if (is_inside)
     623             :         {
     624           0 :           i->flags |= NAT44_EI_INTERFACE_FLAG_IS_INSIDE;
     625             :         }
     626             :       else
     627             :         {
     628           0 :           i->flags |= NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE;
     629             :         }
     630             : 
     631           0 :       rv = 0;
     632             :     }
     633             : 
     634           0 : done:
     635           0 :   return rv;
     636             : }
     637             : 
     638             : static void
     639           0 : vl_api_nat44_ei_interface_add_del_output_feature_t_handler (
     640             :   vl_api_nat44_ei_interface_add_del_output_feature_t *mp)
     641             : {
     642             :   vl_api_nat44_ei_interface_add_del_output_feature_reply_t *rmp;
     643           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     644             :   u32 sw_if_index;
     645           0 :   int rv = 0;
     646             : 
     647           0 :   VALIDATE_SW_IF_INDEX (mp);
     648             : 
     649           0 :   sw_if_index = ntohl (mp->sw_if_index);
     650             : 
     651             :   // register all interfaces in the dummy structure
     652           0 :   rv = add_del_dummy_output_interface (
     653           0 :     sw_if_index, mp->flags & NAT44_EI_IF_INSIDE, mp->is_add);
     654             : 
     655           0 :   if (!(mp->flags & NAT44_EI_IF_INSIDE))
     656             :     {
     657           0 :       if (mp->is_add)
     658             :         {
     659           0 :           rv = nat44_ei_add_output_interface (sw_if_index);
     660             :         }
     661             :       else
     662             :         {
     663           0 :           rv = nat44_ei_del_output_interface (sw_if_index);
     664             :         }
     665             :     }
     666             : 
     667           0 :   BAD_SW_IF_INDEX_LABEL;
     668           0 :   REPLY_MACRO (VL_API_NAT44_EI_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
     669             : }
     670             : 
     671             : static void
     672           0 : send_nat44_ei_interface_output_feature_details (nat44_ei_interface_t *i,
     673             :                                                 vl_api_registration_t *reg,
     674             :                                                 u32 context)
     675             : {
     676             :   vl_api_nat44_ei_interface_output_feature_details_t *rmp;
     677           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     678             : 
     679           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     680           0 :   clib_memset (rmp, 0, sizeof (*rmp));
     681           0 :   rmp->_vl_msg_id =
     682           0 :     ntohs (VL_API_NAT44_EI_INTERFACE_OUTPUT_FEATURE_DETAILS + nm->msg_id_base);
     683           0 :   rmp->sw_if_index = ntohl (i->sw_if_index);
     684           0 :   rmp->context = context;
     685             : 
     686           0 :   if (nat44_ei_interface_is_inside (i))
     687             :     {
     688           0 :       rmp->flags |= NAT44_EI_IF_INSIDE;
     689             :     }
     690             : 
     691           0 :   vl_api_send_msg (reg, (u8 *) rmp);
     692           0 : }
     693             : 
     694             : static void
     695           0 : vl_api_nat44_ei_interface_output_feature_dump_t_handler (
     696             :   vl_api_nat44_ei_interface_output_feature_dump_t *mp)
     697             : {
     698             :   vl_api_registration_t *reg;
     699           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     700             :   nat44_ei_interface_t *i;
     701             : 
     702           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     703           0 :   if (!reg)
     704           0 :     return;
     705             : 
     706           0 :   pool_foreach (i, nm->output_feature_dummy_interfaces)
     707             :     {
     708           0 :       send_nat44_ei_interface_output_feature_details (i, reg, mp->context);
     709             :     }
     710             : }
     711             : 
     712             : static void
     713           5 : vl_api_nat44_ei_add_del_output_interface_t_handler (
     714             :   vl_api_nat44_ei_add_del_output_interface_t *mp)
     715             : {
     716             :   vl_api_nat44_ei_add_del_output_interface_reply_t *rmp;
     717           5 :   nat44_ei_main_t *nm = &nat44_ei_main;
     718           5 :   int rv = 0;
     719             : 
     720           5 :   VALIDATE_SW_IF_INDEX_END (mp);
     721             : 
     722           5 :   if (mp->is_add)
     723             :     {
     724           5 :       rv = nat44_ei_add_output_interface (mp->sw_if_index);
     725             :     }
     726             :   else
     727             :     {
     728           0 :       rv = nat44_ei_del_output_interface (mp->sw_if_index);
     729             :     }
     730             : 
     731           5 : bad_sw_if_index:
     732           5 :   REPLY_MACRO_END (VL_API_NAT44_EI_ADD_DEL_OUTPUT_INTERFACE_REPLY);
     733             : }
     734             : 
     735             : #define vl_endianfun
     736             : #include <nat/nat44-ei/nat44_ei.api.h>
     737             : #undef vl_endianfun
     738             : static void
     739           4 : send_nat44_ei_output_interface_details (u32 index, vl_api_registration_t *rp,
     740             :                                         u32 context)
     741             : {
     742           4 :   nat44_ei_main_t *nm = &nat44_ei_main;
     743             :   vl_api_nat44_ei_output_interface_details_t *rmp;
     744           4 :   nat44_ei_interface_t *i =
     745           4 :     pool_elt_at_index (nm->output_feature_interfaces, index);
     746             : 
     747             :   /* Make sure every field is initiated (or don't skip the clib_memset()) */
     748           4 :   REPLY_MACRO_DETAILS4 (
     749             :     VL_API_NAT44_EI_OUTPUT_INTERFACE_DETAILS, rp, context, ({
     750             :       rmp->sw_if_index = i->sw_if_index;
     751             : 
     752             :       /* Endian hack until apigen registers _details
     753             :        * endian functions */
     754             :       vl_api_nat44_ei_output_interface_details_t_endian (rmp);
     755             :       rmp->_vl_msg_id = htons (rmp->_vl_msg_id);
     756             :       rmp->context = htonl (rmp->context);
     757             :     }));
     758           4 : }
     759             : 
     760             : static void
     761           5 : vl_api_nat44_ei_output_interface_get_t_handler (
     762             :   vl_api_nat44_ei_output_interface_get_t *mp)
     763             : {
     764             :   vl_api_nat44_ei_output_interface_get_reply_t *rmp;
     765           5 :   nat44_ei_main_t *nm = &nat44_ei_main;
     766           5 :   i32 rv = 0;
     767             : 
     768           5 :   if (pool_elts (nm->output_feature_interfaces) == 0)
     769             :     {
     770           1 :       REPLY_MACRO (VL_API_NAT44_EI_OUTPUT_INTERFACE_GET_REPLY);
     771           1 :       return;
     772             :     }
     773             : 
     774           8 :   REPLY_AND_DETAILS_MACRO (
     775             :     VL_API_NAT44_EI_OUTPUT_INTERFACE_GET_REPLY, nm->output_feature_interfaces,
     776             :     ({ send_nat44_ei_output_interface_details (cursor, rp, mp->context); }));
     777             : }
     778             : 
     779             : static void
     780          38 : vl_api_nat44_ei_add_del_static_mapping_t_handler (
     781             :   vl_api_nat44_ei_add_del_static_mapping_t *mp)
     782             : {
     783             :   vl_api_nat44_ei_add_del_static_mapping_reply_t *rmp;
     784             : 
     785          38 :   nat44_ei_main_t *nm = &nat44_ei_main;
     786          38 :   int rv = 0;
     787             : 
     788          38 :   ip4_address_t l_addr, e_addr, pool_addr = { 0 };
     789          38 :   u32 sw_if_index, flags = 0, vrf_id;
     790          38 :   u16 l_port = 0, e_port = 0;
     791          38 :   nat_protocol_t proto = 0;
     792          38 :   u8 *tag = 0;
     793             : 
     794          38 :   memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
     795             : 
     796          38 :   if (mp->flags & NAT44_EI_ADDR_ONLY_MAPPING)
     797             :     {
     798          23 :       flags |= NAT44_EI_SM_FLAG_ADDR_ONLY;
     799             :     }
     800             :   else
     801             :     {
     802          15 :       l_port = mp->local_port;
     803          15 :       e_port = mp->external_port;
     804          15 :       proto = ip_proto_to_nat_proto (mp->protocol);
     805             :     }
     806             : 
     807          38 :   sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
     808          38 :   if (sw_if_index != ~0)
     809             :     {
     810           2 :       flags |= NAT44_EI_SM_FLAG_SWITCH_ADDRESS;
     811             :     }
     812             :   else
     813             :     {
     814          36 :       memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
     815             :     }
     816             : 
     817          38 :   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
     818             : 
     819          38 :   if (mp->is_add)
     820             :     {
     821          35 :       mp->tag[sizeof (mp->tag) - 1] = 0;
     822          35 :       tag = format (0, "%s", mp->tag);
     823          35 :       vec_terminate_c_string (tag);
     824             : 
     825          35 :       rv = nat44_ei_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
     826             :                                         vrf_id, sw_if_index, flags, pool_addr,
     827             :                                         tag);
     828          35 :       vec_free (tag);
     829             :     }
     830             :   else
     831             :     {
     832           3 :       rv = nat44_ei_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
     833             :                                         vrf_id, sw_if_index, flags);
     834             :     }
     835          38 :   REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_STATIC_MAPPING_REPLY);
     836             : }
     837             : 
     838             : static void
     839           4 : send_nat44_ei_static_mapping_details (nat44_ei_static_mapping_t *m,
     840             :                                       vl_api_registration_t *reg, u32 context)
     841             : {
     842             :   vl_api_nat44_ei_static_mapping_details_t *rmp;
     843           4 :   nat44_ei_main_t *nm = &nat44_ei_main;
     844           4 :   u32 len = sizeof (*rmp);
     845             : 
     846           4 :   rmp = vl_msg_api_alloc (len);
     847           4 :   clib_memset (rmp, 0, len);
     848           4 :   rmp->_vl_msg_id =
     849           4 :     ntohs (VL_API_NAT44_EI_STATIC_MAPPING_DETAILS + nm->msg_id_base);
     850             : 
     851           4 :   clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
     852           4 :   clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
     853           4 :   rmp->external_sw_if_index = ~0;
     854           4 :   rmp->vrf_id = htonl (m->vrf_id);
     855           4 :   rmp->context = context;
     856             : 
     857           4 :   if (is_sm_addr_only (m->flags))
     858             :     {
     859           4 :       rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING;
     860             :     }
     861             :   else
     862             :     {
     863           0 :       rmp->protocol = nat_proto_to_ip_proto (m->proto);
     864           0 :       rmp->external_port = m->external_port;
     865           0 :       rmp->local_port = m->local_port;
     866             :     }
     867             : 
     868           4 :   if (m->tag)
     869           4 :     strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
     870             : 
     871           4 :   vl_api_send_msg (reg, (u8 *) rmp);
     872           4 : }
     873             : 
     874             : static void
     875           4 : send_nat44_ei_static_map_resolve_details (nat44_ei_static_map_resolve_t *m,
     876             :                                           vl_api_registration_t *reg,
     877             :                                           u32 context)
     878             : {
     879             :   vl_api_nat44_ei_static_mapping_details_t *rmp;
     880           4 :   nat44_ei_main_t *nm = &nat44_ei_main;
     881             : 
     882           4 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     883           4 :   clib_memset (rmp, 0, sizeof (*rmp));
     884           4 :   rmp->_vl_msg_id =
     885           4 :     ntohs (VL_API_NAT44_EI_STATIC_MAPPING_DETAILS + nm->msg_id_base);
     886           4 :   clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
     887           4 :   rmp->external_sw_if_index = htonl (m->sw_if_index);
     888           4 :   rmp->vrf_id = htonl (m->vrf_id);
     889           4 :   rmp->context = context;
     890             : 
     891           4 :   if (is_sm_addr_only (m->flags))
     892             :     {
     893           4 :       rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING;
     894             :     }
     895             :   else
     896             :     {
     897           0 :       rmp->protocol = nat_proto_to_ip_proto (m->proto);
     898           0 :       rmp->external_port = m->e_port;
     899           0 :       rmp->local_port = m->l_port;
     900             :     }
     901           4 :   if (m->tag)
     902           4 :     strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
     903             : 
     904           4 :   vl_api_send_msg (reg, (u8 *) rmp);
     905           4 : }
     906             : 
     907             : static void
     908           7 : vl_api_nat44_ei_static_mapping_dump_t_handler (
     909             :   vl_api_nat44_ei_static_mapping_dump_t *mp)
     910             : {
     911             :   vl_api_registration_t *reg;
     912           7 :   nat44_ei_main_t *nm = &nat44_ei_main;
     913             :   nat44_ei_static_mapping_t *m;
     914             :   nat44_ei_static_map_resolve_t *rp;
     915             :   int j;
     916             : 
     917           7 :   reg = vl_api_client_index_to_registration (mp->client_index);
     918           7 :   if (!reg)
     919           0 :     return;
     920             : 
     921          11 :   pool_foreach (m, nm->static_mappings)
     922             :     {
     923           4 :       if (!is_sm_identity_nat (m->flags))
     924           4 :         send_nat44_ei_static_mapping_details (m, reg, mp->context);
     925             :     }
     926             : 
     927          11 :   for (j = 0; j < vec_len (nm->to_resolve); j++)
     928             :     {
     929           4 :       rp = nm->to_resolve + j;
     930           4 :       if (!is_sm_identity_nat (rp->flags))
     931           4 :         send_nat44_ei_static_map_resolve_details (rp, reg, mp->context);
     932             :     }
     933             : }
     934             : 
     935             : static void
     936           3 : vl_api_nat44_ei_add_del_identity_mapping_t_handler (
     937             :   vl_api_nat44_ei_add_del_identity_mapping_t *mp)
     938             : {
     939             :   vl_api_nat44_ei_add_del_identity_mapping_reply_t *rmp;
     940             : 
     941           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
     942           3 :   int rv = 0;
     943             : 
     944           3 :   ip4_address_t addr, pool_addr = { 0 };
     945             :   u32 sw_if_index, flags, vrf_id;
     946           3 :   nat_protocol_t proto = 0;
     947           3 :   u16 port = 0;
     948           3 :   u8 *tag = 0;
     949             : 
     950           3 :   flags = NAT44_EI_SM_FLAG_IDENTITY_NAT;
     951             : 
     952           3 :   if (mp->flags & NAT44_EI_ADDR_ONLY_MAPPING)
     953             :     {
     954           2 :       flags |= NAT44_EI_SM_FLAG_ADDR_ONLY;
     955             :     }
     956             :   else
     957             :     {
     958           1 :       port = mp->port;
     959           1 :       proto = ip_proto_to_nat_proto (mp->protocol);
     960             :     }
     961             : 
     962           3 :   sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
     963           3 :   if (sw_if_index != ~0)
     964             :     {
     965           1 :       flags |= NAT44_EI_SM_FLAG_SWITCH_ADDRESS;
     966             :     }
     967             :   else
     968             :     {
     969           2 :       memcpy (&addr.as_u8, mp->ip_address, 4);
     970             :     }
     971             : 
     972           3 :   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
     973             : 
     974           3 :   if (mp->is_add)
     975             :     {
     976           3 :       mp->tag[sizeof (mp->tag) - 1] = 0;
     977           3 :       tag = format (0, "%s", mp->tag);
     978           3 :       vec_terminate_c_string (tag);
     979             : 
     980           3 :       rv = nat44_ei_add_static_mapping (addr, addr, port, port, proto, vrf_id,
     981             :                                         sw_if_index, flags, pool_addr, tag);
     982           3 :       vec_free (tag);
     983             :     }
     984             :   else
     985             :     {
     986           0 :       rv = nat44_ei_del_static_mapping (addr, addr, port, port, proto, vrf_id,
     987             :                                         sw_if_index, flags);
     988             :     }
     989             : 
     990           3 :   REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_IDENTITY_MAPPING_REPLY);
     991             : }
     992             : 
     993             : static void
     994           3 : send_nat44_ei_identity_mapping_details (nat44_ei_static_mapping_t *m,
     995             :                                         int index, vl_api_registration_t *reg,
     996             :                                         u32 context)
     997             : {
     998             :   vl_api_nat44_ei_identity_mapping_details_t *rmp;
     999           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1000           3 :   nat44_ei_lb_addr_port_t *local = pool_elt_at_index (m->locals, index);
    1001             : 
    1002           3 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
    1003           3 :   clib_memset (rmp, 0, sizeof (*rmp));
    1004           3 :   rmp->_vl_msg_id =
    1005           3 :     ntohs (VL_API_NAT44_EI_IDENTITY_MAPPING_DETAILS + nm->msg_id_base);
    1006             : 
    1007           3 :   if (is_sm_addr_only (m->flags))
    1008           2 :     rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING;
    1009             : 
    1010           3 :   clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
    1011           3 :   rmp->port = m->local_port;
    1012           3 :   rmp->sw_if_index = ~0;
    1013           3 :   rmp->vrf_id = htonl (local->vrf_id);
    1014           3 :   rmp->protocol = nat_proto_to_ip_proto (m->proto);
    1015           3 :   rmp->context = context;
    1016           3 :   if (m->tag)
    1017           3 :     strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
    1018             : 
    1019           3 :   vl_api_send_msg (reg, (u8 *) rmp);
    1020           3 : }
    1021             : 
    1022             : static void
    1023           3 : send_nat44_ei_identity_map_resolve_details (nat44_ei_static_map_resolve_t *m,
    1024             :                                             vl_api_registration_t *reg,
    1025             :                                             u32 context)
    1026             : {
    1027             :   vl_api_nat44_ei_identity_mapping_details_t *rmp;
    1028           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1029           3 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
    1030           3 :   clib_memset (rmp, 0, sizeof (*rmp));
    1031           3 :   rmp->_vl_msg_id =
    1032           3 :     ntohs (VL_API_NAT44_EI_IDENTITY_MAPPING_DETAILS + nm->msg_id_base);
    1033             : 
    1034           3 :   if (is_sm_addr_only (m->flags))
    1035           0 :     rmp->flags = (vl_api_nat44_ei_config_flags_t) NAT44_EI_ADDR_ONLY_MAPPING;
    1036             : 
    1037           3 :   rmp->port = m->l_port;
    1038           3 :   rmp->sw_if_index = htonl (m->sw_if_index);
    1039           3 :   rmp->vrf_id = htonl (m->vrf_id);
    1040           3 :   rmp->protocol = nat_proto_to_ip_proto (m->proto);
    1041           3 :   rmp->context = context;
    1042           3 :   if (m->tag)
    1043           3 :     strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
    1044             : 
    1045           3 :   vl_api_send_msg (reg, (u8 *) rmp);
    1046           3 : }
    1047             : 
    1048             : static void
    1049           4 : vl_api_nat44_ei_identity_mapping_dump_t_handler (
    1050             :   vl_api_nat44_ei_identity_mapping_dump_t *mp)
    1051             : {
    1052             :   vl_api_registration_t *reg;
    1053           4 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1054             :   nat44_ei_static_mapping_t *m;
    1055             :   nat44_ei_static_map_resolve_t *rp;
    1056             :   int j;
    1057             : 
    1058           4 :   reg = vl_api_client_index_to_registration (mp->client_index);
    1059           4 :   if (!reg)
    1060           0 :     return;
    1061             : 
    1062           6 :   pool_foreach (m, nm->static_mappings)
    1063             :     {
    1064           2 :       if (is_sm_identity_nat (m->flags))
    1065             :         {
    1066           5 :           pool_foreach_index (j, m->locals)
    1067             :             {
    1068           3 :               send_nat44_ei_identity_mapping_details (m, j, reg, mp->context);
    1069             :             }
    1070             :         }
    1071             :     }
    1072             : 
    1073           7 :   for (j = 0; j < vec_len (nm->to_resolve); j++)
    1074             :     {
    1075           3 :       rp = nm->to_resolve + j;
    1076           3 :       if (is_sm_identity_nat (rp->flags))
    1077           3 :         send_nat44_ei_identity_map_resolve_details (rp, reg, mp->context);
    1078             :     }
    1079             : }
    1080             : 
    1081             : static void
    1082           4 : vl_api_nat44_ei_add_del_interface_addr_t_handler (
    1083             :   vl_api_nat44_ei_add_del_interface_addr_t *mp)
    1084             : {
    1085           4 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1086             :   vl_api_nat44_ei_add_del_interface_addr_reply_t *rmp;
    1087           4 :   u32 sw_if_index = ntohl (mp->sw_if_index);
    1088           4 :   int rv = 0;
    1089             : 
    1090           4 :   VALIDATE_SW_IF_INDEX (mp);
    1091             : 
    1092           4 :   if (mp->is_add)
    1093             :     {
    1094           4 :       rv = nat44_ei_add_interface_address (sw_if_index);
    1095             :     }
    1096             :   else
    1097             :     {
    1098           0 :       rv = nat44_ei_del_interface_address (sw_if_index);
    1099             :     }
    1100             : 
    1101           4 :   BAD_SW_IF_INDEX_LABEL;
    1102           4 :   REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_INTERFACE_ADDR_REPLY);
    1103             : }
    1104             : 
    1105             : static void
    1106           0 : send_nat44_ei_interface_addr_details (u32 sw_if_index,
    1107             :                                       vl_api_registration_t *reg, u32 context)
    1108             : {
    1109             :   vl_api_nat44_ei_interface_addr_details_t *rmp;
    1110           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1111             : 
    1112           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
    1113           0 :   clib_memset (rmp, 0, sizeof (*rmp));
    1114           0 :   rmp->_vl_msg_id =
    1115           0 :     ntohs (VL_API_NAT44_EI_INTERFACE_ADDR_DETAILS + nm->msg_id_base);
    1116           0 :   rmp->sw_if_index = ntohl (sw_if_index);
    1117           0 :   rmp->context = context;
    1118             : 
    1119           0 :   vl_api_send_msg (reg, (u8 *) rmp);
    1120           0 : }
    1121             : 
    1122             : static void
    1123           0 : vl_api_nat44_ei_interface_addr_dump_t_handler (
    1124             :   vl_api_nat44_ei_interface_addr_dump_t *mp)
    1125             : {
    1126             :   vl_api_registration_t *reg;
    1127           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1128             :   u32 *i;
    1129             : 
    1130           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
    1131           0 :   if (!reg)
    1132           0 :     return;
    1133             : 
    1134           0 :   vec_foreach (i, nm->auto_add_sw_if_indices)
    1135           0 :     send_nat44_ei_interface_addr_details (*i, reg, mp->context);
    1136             : }
    1137             : 
    1138             : static void
    1139           6 : send_nat44_ei_user_details (nat44_ei_user_t *u, vl_api_registration_t *reg,
    1140             :                             u32 context)
    1141             : {
    1142             :   vl_api_nat44_ei_user_details_t *rmp;
    1143           6 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1144           6 :   ip4_main_t *im = &ip4_main;
    1145             : 
    1146           6 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
    1147           6 :   clib_memset (rmp, 0, sizeof (*rmp));
    1148           6 :   rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_USER_DETAILS + nm->msg_id_base);
    1149             : 
    1150           6 :   if (!pool_is_free_index (im->fibs, u->fib_index))
    1151             :     {
    1152           6 :       fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
    1153           6 :       rmp->vrf_id = ntohl (fib->ft_table_id);
    1154             :     }
    1155             : 
    1156           6 :   clib_memcpy (rmp->ip_address, &(u->addr), 4);
    1157           6 :   rmp->nsessions = ntohl (u->nsessions);
    1158           6 :   rmp->nstaticsessions = ntohl (u->nstaticsessions);
    1159           6 :   rmp->context = context;
    1160             : 
    1161           6 :   vl_api_send_msg (reg, (u8 *) rmp);
    1162           6 : }
    1163             : 
    1164             : static void
    1165           5 : vl_api_nat44_ei_user_dump_t_handler (vl_api_nat44_ei_user_dump_t *mp)
    1166             : {
    1167             :   vl_api_registration_t *reg;
    1168           5 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1169             :   nat44_ei_main_per_thread_data_t *tnm;
    1170             :   nat44_ei_user_t *u;
    1171             : 
    1172           5 :   reg = vl_api_client_index_to_registration (mp->client_index);
    1173           5 :   if (!reg)
    1174           0 :     return;
    1175             : 
    1176          10 :   vec_foreach (tnm, nm->per_thread_data)
    1177             :     {
    1178          11 :       pool_foreach (u, tnm->users)
    1179             :         {
    1180           6 :           send_nat44_ei_user_details (u, reg, mp->context);
    1181             :         }
    1182             :     }
    1183             : }
    1184             : 
    1185             : static void
    1186          28 : send_nat44_ei_user_session_details (nat44_ei_session_t *s,
    1187             :                                     vl_api_registration_t *reg, u32 context)
    1188             : {
    1189             :   vl_api_nat44_ei_user_session_details_t *rmp;
    1190          28 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1191             : 
    1192          28 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
    1193          28 :   clib_memset (rmp, 0, sizeof (*rmp));
    1194          28 :   rmp->_vl_msg_id =
    1195          28 :     ntohs (VL_API_NAT44_EI_USER_SESSION_DETAILS + nm->msg_id_base);
    1196          28 :   clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
    1197          28 :   clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
    1198             : 
    1199          28 :   if (nat44_ei_is_session_static (s))
    1200           6 :     rmp->flags |= NAT44_EI_STATIC_MAPPING;
    1201             : 
    1202          28 :   rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
    1203          28 :   rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
    1204          28 :   rmp->total_pkts = ntohl (s->total_pkts);
    1205          28 :   rmp->context = context;
    1206          28 :   if (nat44_ei_is_unk_proto_session (s))
    1207             :     {
    1208           0 :       rmp->outside_port = 0;
    1209           0 :       rmp->inside_port = 0;
    1210           0 :       rmp->protocol = ntohs (s->in2out.port);
    1211             :     }
    1212             :   else
    1213             :     {
    1214          28 :       rmp->outside_port = s->out2in.port;
    1215          28 :       rmp->inside_port = s->in2out.port;
    1216          28 :       rmp->protocol = ntohs (nat_proto_to_ip_proto (s->nat_proto));
    1217             :     }
    1218          28 :   vl_api_send_msg (reg, (u8 *) rmp);
    1219          28 : }
    1220             : 
    1221             : static void
    1222           0 : send_nat44_ei_user_session_v2_details (nat44_ei_session_t *s,
    1223             :                                        vl_api_registration_t *reg, u32 context)
    1224             : {
    1225             :   vl_api_nat44_ei_user_session_v2_details_t *rmp;
    1226           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1227             : 
    1228           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
    1229           0 :   clib_memset (rmp, 0, sizeof (*rmp));
    1230           0 :   rmp->_vl_msg_id =
    1231           0 :     ntohs (VL_API_NAT44_EI_USER_SESSION_V2_DETAILS + nm->msg_id_base);
    1232           0 :   clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
    1233           0 :   clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
    1234             : 
    1235           0 :   if (nat44_ei_is_session_static (s))
    1236           0 :     rmp->flags |= NAT44_EI_STATIC_MAPPING;
    1237             : 
    1238           0 :   rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
    1239           0 :   rmp->time_since_last_heard = clib_host_to_net_u64 (
    1240           0 :     (u64) (vlib_time_now (vlib_get_main ()) - s->last_heard));
    1241           0 :   rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
    1242           0 :   rmp->total_pkts = ntohl (s->total_pkts);
    1243           0 :   rmp->context = context;
    1244           0 :   if (nat44_ei_is_unk_proto_session (s))
    1245             :     {
    1246           0 :       rmp->outside_port = 0;
    1247           0 :       rmp->inside_port = 0;
    1248           0 :       rmp->protocol = ntohs (s->in2out.port);
    1249             :     }
    1250             :   else
    1251             :     {
    1252           0 :       rmp->outside_port = s->out2in.port;
    1253           0 :       rmp->inside_port = s->in2out.port;
    1254           0 :       rmp->protocol = ntohs (nat_proto_to_ip_proto (s->nat_proto));
    1255             :     }
    1256           0 :   vl_api_send_msg (reg, (u8 *) rmp);
    1257           0 : }
    1258             : 
    1259             : static void
    1260          13 : vl_api_nat44_ei_user_session_dump_t_handler (
    1261             :   vl_api_nat44_ei_user_session_dump_t *mp)
    1262             : {
    1263             :   vl_api_registration_t *reg;
    1264          13 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1265             :   nat44_ei_main_per_thread_data_t *tnm;
    1266             :   nat44_ei_session_t *s;
    1267             :   clib_bihash_kv_8_8_t key, value;
    1268             :   nat44_ei_user_key_t ukey;
    1269             :   nat44_ei_user_t *u;
    1270             :   u32 session_index, head_index, elt_index;
    1271             :   dlist_elt_t *head, *elt;
    1272             :   ip4_header_t ip;
    1273             : 
    1274          13 :   reg = vl_api_client_index_to_registration (mp->client_index);
    1275          13 :   if (!reg)
    1276           2 :     return;
    1277             : 
    1278          13 :   clib_memcpy (&ukey.addr, mp->ip_address, 4);
    1279          13 :   ip.src_address.as_u32 = ukey.addr.as_u32;
    1280          13 :   ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
    1281          13 :   key.key = ukey.as_u64;
    1282          13 :   if (nm->num_workers > 1)
    1283           0 :     tnm = vec_elt_at_index (
    1284             :       nm->per_thread_data,
    1285             :       nat44_ei_get_in2out_worker_index (&ip, ukey.fib_index, 0));
    1286             :   else
    1287          13 :     tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
    1288             : 
    1289          13 :   if (clib_bihash_search_8_8 (&tnm->user_hash, &key, &value))
    1290           2 :     return;
    1291          11 :   u = pool_elt_at_index (tnm->users, value.value);
    1292          11 :   if (!u->nsessions && !u->nstaticsessions)
    1293           0 :     return;
    1294             : 
    1295          11 :   head_index = u->sessions_per_user_list_head_index;
    1296          11 :   head = pool_elt_at_index (tnm->list_pool, head_index);
    1297          11 :   elt_index = head->next;
    1298          11 :   elt = pool_elt_at_index (tnm->list_pool, elt_index);
    1299          11 :   session_index = elt->value;
    1300          39 :   while (session_index != ~0)
    1301             :     {
    1302          28 :       s = pool_elt_at_index (tnm->sessions, session_index);
    1303             : 
    1304          28 :       send_nat44_ei_user_session_details (s, reg, mp->context);
    1305             : 
    1306          28 :       elt_index = elt->next;
    1307          28 :       elt = pool_elt_at_index (tnm->list_pool, elt_index);
    1308          28 :       session_index = elt->value;
    1309             :     }
    1310             : }
    1311             : 
    1312             : static void
    1313           0 : vl_api_nat44_ei_user_session_v2_dump_t_handler (
    1314             :   vl_api_nat44_ei_user_session_dump_t *mp)
    1315             : {
    1316             :   vl_api_registration_t *reg;
    1317           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1318             :   nat44_ei_main_per_thread_data_t *tnm;
    1319             :   nat44_ei_session_t *s;
    1320             :   clib_bihash_kv_8_8_t key, value;
    1321             :   nat44_ei_user_key_t ukey;
    1322             :   nat44_ei_user_t *u;
    1323             :   u32 session_index, head_index, elt_index;
    1324             :   dlist_elt_t *head, *elt;
    1325             :   ip4_header_t ip;
    1326             : 
    1327           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
    1328           0 :   if (!reg)
    1329           0 :     return;
    1330             : 
    1331           0 :   clib_memcpy (&ukey.addr, mp->ip_address, 4);
    1332           0 :   ip.src_address.as_u32 = ukey.addr.as_u32;
    1333           0 :   ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
    1334           0 :   key.key = ukey.as_u64;
    1335           0 :   if (nm->num_workers > 1)
    1336           0 :     tnm = vec_elt_at_index (
    1337             :       nm->per_thread_data,
    1338             :       nat44_ei_get_in2out_worker_index (&ip, ukey.fib_index, 0));
    1339             :   else
    1340           0 :     tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
    1341             : 
    1342           0 :   if (clib_bihash_search_8_8 (&tnm->user_hash, &key, &value))
    1343           0 :     return;
    1344           0 :   u = pool_elt_at_index (tnm->users, value.value);
    1345           0 :   if (!u->nsessions && !u->nstaticsessions)
    1346           0 :     return;
    1347             : 
    1348           0 :   head_index = u->sessions_per_user_list_head_index;
    1349           0 :   head = pool_elt_at_index (tnm->list_pool, head_index);
    1350           0 :   elt_index = head->next;
    1351           0 :   elt = pool_elt_at_index (tnm->list_pool, elt_index);
    1352           0 :   session_index = elt->value;
    1353           0 :   while (session_index != ~0)
    1354             :     {
    1355           0 :       s = pool_elt_at_index (tnm->sessions, session_index);
    1356             : 
    1357           0 :       send_nat44_ei_user_session_v2_details (s, reg, mp->context);
    1358             : 
    1359           0 :       elt_index = elt->next;
    1360           0 :       elt = pool_elt_at_index (tnm->list_pool, elt_index);
    1361           0 :       session_index = elt->value;
    1362             :     }
    1363             : }
    1364             : 
    1365             : static void
    1366           4 : vl_api_nat44_ei_del_session_t_handler (vl_api_nat44_ei_del_session_t *mp)
    1367             : {
    1368           4 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1369             :   vl_api_nat44_ei_del_session_reply_t *rmp;
    1370             :   ip4_address_t addr, eh_addr;
    1371             :   u16 port;
    1372             :   u32 vrf_id;
    1373           4 :   int rv = 0;
    1374             :   u8 is_in;
    1375             :   nat_protocol_t proto;
    1376             : 
    1377           4 :   memcpy (&addr.as_u8, mp->address, 4);
    1378           4 :   port = mp->port;
    1379           4 :   vrf_id = clib_net_to_host_u32 (mp->vrf_id);
    1380           4 :   proto = ip_proto_to_nat_proto (mp->protocol);
    1381           4 :   memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
    1382             : 
    1383             :   // is session inside ?
    1384           4 :   is_in = mp->flags & NAT44_EI_IF_INSIDE;
    1385             : 
    1386           4 :   rv = nat44_ei_del_session (nm, &addr, port, proto, vrf_id, is_in);
    1387             : 
    1388           4 :   REPLY_MACRO (VL_API_NAT44_EI_DEL_SESSION_REPLY);
    1389             : }
    1390             : 
    1391             : static void
    1392           3 : vl_api_nat44_ei_forwarding_enable_disable_t_handler (
    1393             :   vl_api_nat44_ei_forwarding_enable_disable_t *mp)
    1394             : {
    1395           3 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1396             :   vl_api_nat44_ei_forwarding_enable_disable_reply_t *rmp;
    1397           3 :   int rv = 0;
    1398           3 :   u32 *ses_to_be_removed = 0, *ses_index;
    1399             :   nat44_ei_main_per_thread_data_t *tnm;
    1400             :   nat44_ei_session_t *s;
    1401             : 
    1402           3 :   nm->forwarding_enabled = mp->enable != 0;
    1403             : 
    1404           3 :   if (mp->enable == 0)
    1405             :     {
    1406           2 :       vec_foreach (tnm, nm->per_thread_data)
    1407             :         {
    1408           1 :           vec_foreach (ses_index, ses_to_be_removed)
    1409             :             {
    1410           0 :               s = pool_elt_at_index (tnm->sessions, ses_index[0]);
    1411           0 :               nat44_ei_free_session_data (nm, s, tnm - nm->per_thread_data, 0);
    1412           0 :               nat44_ei_delete_session (nm, s, tnm - nm->per_thread_data);
    1413             :             }
    1414             : 
    1415           1 :           vec_free (ses_to_be_removed);
    1416             :         }
    1417             :     }
    1418             : 
    1419           3 :   REPLY_MACRO (VL_API_NAT44_EI_FORWARDING_ENABLE_DISABLE_REPLY);
    1420             : }
    1421             : 
    1422             : static void
    1423           1 : vl_api_nat44_ei_set_fq_options_t_handler (vl_api_nat44_ei_set_fq_options_t *mp)
    1424             : {
    1425           1 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1426             :   vl_api_nat44_ei_set_fq_options_reply_t *rmp;
    1427           1 :   int rv = 0;
    1428           1 :   u32 frame_queue_nelts = ntohl (mp->frame_queue_nelts);
    1429           1 :   rv = nat44_ei_set_frame_queue_nelts (frame_queue_nelts);
    1430           1 :   REPLY_MACRO (VL_API_NAT44_EI_SET_FQ_OPTIONS_REPLY);
    1431             : }
    1432             : 
    1433             : static void
    1434           1 : vl_api_nat44_ei_show_fq_options_t_handler (
    1435             :   vl_api_nat44_ei_show_fq_options_t *mp)
    1436             : {
    1437           1 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1438             :   vl_api_nat44_ei_show_fq_options_reply_t *rmp;
    1439           1 :   int rv = 0;
    1440             :   /* clang-format off */
    1441           1 :   REPLY_MACRO2_ZERO (VL_API_NAT44_EI_SHOW_FQ_OPTIONS_REPLY,
    1442             :   ({
    1443             :     rmp->frame_queue_nelts = htonl (nm->frame_queue_nelts);
    1444             :   }));
    1445             :   /* clang-format on */
    1446             : }
    1447             : 
    1448             : /* API definitions */
    1449             : #include <vnet/format_fns.h>
    1450             : #include <nat/nat44-ei/nat44_ei.api.c>
    1451             : 
    1452             : /* Set up the API message handling tables */
    1453             : clib_error_t *
    1454         575 : nat44_ei_api_hookup (vlib_main_t *vm)
    1455             : {
    1456         575 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1457         575 :   nm->msg_id_base = setup_message_id_table ();
    1458         575 :   return 0;
    1459             : }
    1460             : 
    1461             : /*
    1462             :  * fd.io coding-style-patch-verification: ON
    1463             :  *
    1464             :  * Local Variables:
    1465             :  * eval: (c-set-style "gnu")
    1466             :  * End:
    1467             :  */

Generated by: LCOV version 1.14