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