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 <vlibmemory/api.h> 18 : #include <nat/nat66/nat66.h> 19 : #include <nat/nat66/nat66.api_enum.h> 20 : #include <nat/nat66/nat66.api_types.h> 21 : #include <vnet/fib/fib_table.h> 22 : 23 : #define REPLY_MSG_ID_BASE nm->msg_id_base 24 : #include <vlibapi/api_helper_macros.h> 25 : 26 : static void 27 4 : vl_api_nat66_plugin_enable_disable_t_handler ( 28 : vl_api_nat66_plugin_enable_disable_t *mp) 29 : { 30 4 : nat66_main_t *nm = &nat66_main; 31 : vl_api_nat66_plugin_enable_disable_reply_t *rmp; 32 4 : int rv = 0; 33 : 34 4 : if (mp->enable) 35 : { 36 2 : rv = nat66_plugin_enable (ntohl (mp->outside_vrf)); 37 : } 38 : else 39 2 : rv = nat66_plugin_disable (); 40 : 41 4 : REPLY_MACRO (VL_API_NAT66_PLUGIN_ENABLE_DISABLE_REPLY); 42 : } 43 : 44 : static void 45 4 : vl_api_nat66_add_del_interface_t_handler (vl_api_nat66_add_del_interface_t * 46 : mp) 47 : { 48 4 : nat66_main_t *nm = &nat66_main; 49 : vl_api_nat66_add_del_interface_reply_t *rmp; 50 4 : int rv = 0; 51 : 52 4 : VALIDATE_SW_IF_INDEX (mp); 53 : 54 : rv = 55 4 : nat66_interface_add_del (ntohl (mp->sw_if_index), 56 4 : mp->flags & NAT_IS_INSIDE, mp->is_add); 57 : 58 4 : BAD_SW_IF_INDEX_LABEL; 59 : 60 4 : REPLY_MACRO (VL_API_NAT66_ADD_DEL_INTERFACE_REPLY); 61 : } 62 : 63 : static void 64 2 : vl_api_nat66_add_del_static_mapping_t_handler 65 : (vl_api_nat66_add_del_static_mapping_t * mp) 66 : { 67 2 : nat66_main_t *nm = &nat66_main; 68 : vl_api_nat66_add_del_static_mapping_reply_t *rmp; 69 : ip6_address_t l_addr, e_addr; 70 2 : int rv = 0; 71 : 72 2 : memcpy (&l_addr.as_u8, mp->local_ip_address, 16); 73 2 : memcpy (&e_addr.as_u8, mp->external_ip_address, 16); 74 : 75 : rv = 76 2 : nat66_static_mapping_add_del (&l_addr, &e_addr, 77 : clib_net_to_host_u32 (mp->vrf_id), 78 2 : mp->is_add); 79 : 80 2 : REPLY_MACRO (VL_API_NAT66_ADD_DEL_STATIC_MAPPING_REPLY); 81 : } 82 : 83 : typedef struct nat66_api_walk_ctx_t_ 84 : { 85 : vl_api_registration_t *rp; 86 : u32 context; 87 : } nat66_api_walk_ctx_t; 88 : 89 : static int 90 0 : nat66_api_interface_walk (nat66_interface_t * i, void *arg) 91 : { 92 : vl_api_nat66_interface_details_t *rmp; 93 0 : nat66_main_t *nm = &nat66_main; 94 0 : nat66_api_walk_ctx_t *ctx = arg; 95 : 96 0 : rmp = vl_msg_api_alloc (sizeof (*rmp)); 97 0 : clib_memset (rmp, 0, sizeof (*rmp)); 98 0 : rmp->_vl_msg_id = ntohs (VL_API_NAT66_INTERFACE_DETAILS + nm->msg_id_base); 99 0 : rmp->sw_if_index = ntohl (i->sw_if_index); 100 0 : if (nat66_interface_is_inside (i)) 101 0 : rmp->flags |= NAT_IS_INSIDE; 102 0 : rmp->context = ctx->context; 103 : 104 0 : vl_api_send_msg (ctx->rp, (u8 *) rmp); 105 : 106 0 : return 0; 107 : } 108 : 109 : static void 110 0 : vl_api_nat66_interface_dump_t_handler (vl_api_nat66_interface_dump_t * mp) 111 : { 112 : vl_api_registration_t *rp; 113 0 : nat66_main_t *nm = &nat66_main; 114 : 115 0 : if (PREDICT_FALSE (!nm->enabled)) 116 0 : return; 117 : 118 0 : rp = vl_api_client_index_to_registration (mp->client_index); 119 0 : if (rp == 0) 120 0 : return; 121 : 122 0 : nat66_api_walk_ctx_t ctx = { 123 : .rp = rp, 124 0 : .context = mp->context, 125 : }; 126 : 127 0 : nat66_interfaces_walk (nat66_api_interface_walk, &ctx); 128 : } 129 : 130 : static int 131 1 : nat66_api_static_mapping_walk (nat66_static_mapping_t * m, void *arg) 132 : { 133 : vl_api_nat66_static_mapping_details_t *rmp; 134 1 : nat66_main_t *nm = &nat66_main; 135 1 : nat66_api_walk_ctx_t *ctx = arg; 136 : fib_table_t *fib; 137 : vlib_counter_t vc; 138 : 139 1 : fib = fib_table_get (m->fib_index, FIB_PROTOCOL_IP6); 140 1 : if (!fib) 141 0 : return -1; 142 : 143 1 : vlib_get_combined_counter (&nm->session_counters, m - nm->sm, &vc); 144 : 145 1 : rmp = vl_msg_api_alloc (sizeof (*rmp)); 146 1 : clib_memset (rmp, 0, sizeof (*rmp)); 147 1 : rmp->_vl_msg_id = 148 1 : ntohs (VL_API_NAT66_STATIC_MAPPING_DETAILS + nm->msg_id_base); 149 1 : clib_memcpy (rmp->local_ip_address, &m->l_addr, 16); 150 1 : clib_memcpy (rmp->external_ip_address, &m->e_addr, 16); 151 1 : rmp->vrf_id = ntohl (fib->ft_table_id); 152 1 : rmp->total_bytes = clib_host_to_net_u64 (vc.bytes); 153 1 : rmp->total_pkts = clib_host_to_net_u64 (vc.packets); 154 1 : rmp->context = ctx->context; 155 : 156 1 : vl_api_send_msg (ctx->rp, (u8 *) rmp); 157 : 158 1 : return 0; 159 : } 160 : 161 : static void 162 1 : vl_api_nat66_static_mapping_dump_t_handler (vl_api_nat66_static_mapping_dump_t 163 : * mp) 164 : { 165 : vl_api_registration_t *rp; 166 1 : nat66_main_t *nm = &nat66_main; 167 : 168 1 : if (PREDICT_FALSE (!nm->enabled)) 169 0 : return; 170 : 171 1 : rp = vl_api_client_index_to_registration (mp->client_index); 172 1 : if (rp == 0) 173 0 : return; 174 : 175 1 : nat66_api_walk_ctx_t ctx = { 176 : .rp = rp, 177 1 : .context = mp->context, 178 : }; 179 : 180 1 : nat66_static_mappings_walk (nat66_api_static_mapping_walk, &ctx); 181 : } 182 : 183 : /* API definitions */ 184 : #include <vnet/format_fns.h> 185 : #include <nat/nat66/nat66.api.c> 186 : 187 : /* Set up the API message handling tables */ 188 : clib_error_t * 189 575 : nat66_plugin_api_hookup (vlib_main_t * vm) 190 : { 191 575 : nat66_main_t *nm = &nat66_main; 192 575 : nm->msg_id_base = setup_message_id_table (); 193 575 : return 0; 194 : }