cnat: Disable default scanner process
[vpp.git] / src / plugins / cnat / cnat_api.c
1 /*
2  * Copyright (c) 2016 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 <stddef.h>
17
18 #include <vnet/vnet.h>
19 #include <vnet/plugin/plugin.h>
20 #include <cnat/cnat_translation.h>
21 #include <cnat/cnat_session.h>
22 #include <cnat/cnat_client.h>
23 #include <cnat/cnat_snat.h>
24
25 #include <vnet/ip/ip_types_api.h>
26
27 #include <vpp/app/version.h>
28
29 #include <vlibapi/api.h>
30 #include <vlibmemory/api.h>
31
32 /* define message IDs */
33 #include <vnet/format_fns.h>
34 #include <cnat/cnat.api_enum.h>
35 #include <cnat/cnat.api_types.h>
36
37 /**
38  * Base message ID fot the plugin
39  */
40 static u32 cnat_base_msg_id;
41
42 #define REPLY_MSG_ID_BASE cnat_base_msg_id
43
44 #include <vlibapi/api_helper_macros.h>
45
46 static void
47 cnat_endpoint_decode (const vl_api_cnat_endpoint_t * in,
48                       cnat_endpoint_t * out)
49 {
50   ip_address_decode2 (&in->addr, &out->ce_ip);
51   out->ce_port = clib_net_to_host_u16 (in->port);
52 }
53
54 static void
55 cnat_endpoint_tuple_decode (const vl_api_cnat_endpoint_tuple_t * in,
56                             cnat_endpoint_tuple_t * out)
57 {
58   cnat_endpoint_decode (&in->src_ep, &out->src_ep);
59   cnat_endpoint_decode (&in->dst_ep, &out->dst_ep);
60 }
61
62 static void
63 cnat_endpoint_encode (const cnat_endpoint_t * in,
64                       vl_api_cnat_endpoint_t * out)
65 {
66   ip_address_encode2 (&in->ce_ip, &out->addr);
67   out->port = clib_net_to_host_u16 (in->ce_port);
68 }
69
70 static void
71 vl_api_cnat_translation_update_t_handler (vl_api_cnat_translation_update_t
72                                           * mp)
73 {
74   vl_api_cnat_translation_update_reply_t *rmp;
75   cnat_endpoint_t vip;
76   cnat_endpoint_tuple_t *paths = NULL, *path;
77   ip_protocol_t ip_proto;
78   u32 id = ~0;
79   u8 flags;
80   int rv = 0;
81   u8 pi;
82
83   rv = ip_proto_decode (mp->translation.ip_proto, &ip_proto);
84
85   if (rv)
86     goto done;
87
88   vec_validate (paths, mp->translation.n_paths - 1);
89
90   for (pi = 0; pi < mp->translation.n_paths; pi++)
91     {
92       path = &paths[pi];
93       cnat_endpoint_tuple_decode (&mp->translation.paths[pi], path);
94     }
95   cnat_endpoint_decode (&mp->translation.vip, &vip);
96
97   flags = mp->translation.flags;
98   if (!mp->translation.is_real_ip)
99     flags |= CNAT_FLAG_EXCLUSIVE;
100   id = cnat_translation_update (&vip, ip_proto, paths, flags);
101
102   vec_free (paths);
103
104 done:
105   /* *INDENT-OFF* */
106   REPLY_MACRO2 (VL_API_CNAT_TRANSLATION_UPDATE_REPLY,
107   ({
108     rmp->id = htonl (id);
109   }));
110   /* *INDENT-ON* */
111 }
112
113 static void
114 vl_api_cnat_translation_del_t_handler (vl_api_cnat_translation_del_t * mp)
115 {
116   vl_api_cnat_translation_del_reply_t *rmp;
117   int rv;
118
119   rv = cnat_translation_delete (ntohl (mp->id));
120
121   REPLY_MACRO (VL_API_CNAT_TRANSLATION_DEL_REPLY);
122 }
123
124 typedef struct cnat_dump_walk_ctx_t_
125 {
126   vl_api_registration_t *rp;
127   u32 context;
128 } cnat_dump_walk_ctx_t;
129
130 static walk_rc_t
131 cnat_translation_send_details (u32 cti, void *args)
132 {
133   vl_api_cnat_translation_details_t *mp;
134   cnat_dump_walk_ctx_t *ctx;
135   cnat_ep_trk_t *trk;
136   vl_api_cnat_endpoint_tuple_t *path;
137   size_t msg_size;
138   cnat_translation_t *ct;
139   u8 n_paths;
140
141   ctx = args;
142   ct = cnat_translation_get (cti);
143   n_paths = vec_len (ct->ct_paths);
144   msg_size = sizeof (*mp) + sizeof (mp->translation.paths[0]) * n_paths;
145
146   mp = vl_msg_api_alloc_zero (msg_size);
147   mp->_vl_msg_id = ntohs (VL_API_CNAT_TRANSLATION_DETAILS + cnat_base_msg_id);
148
149   /* fill in the message */
150   mp->context = ctx->context;
151   mp->translation.n_paths = n_paths;
152   mp->translation.id = htonl (cti);
153   cnat_endpoint_encode (&ct->ct_vip, &mp->translation.vip);
154   mp->translation.ip_proto = ip_proto_encode (ct->ct_proto);
155
156   path = mp->translation.paths;
157   vec_foreach (trk, ct->ct_paths)
158   {
159     cnat_endpoint_encode (&trk->ct_ep[VLIB_TX], &path->dst_ep);
160     cnat_endpoint_encode (&trk->ct_ep[VLIB_RX], &path->src_ep);
161     path++;
162   }
163
164   vl_api_send_msg (ctx->rp, (u8 *) mp);
165
166   return (WALK_CONTINUE);
167 }
168
169 static void
170 vl_api_cnat_translation_dump_t_handler (vl_api_cnat_translation_dump_t * mp)
171 {
172   vl_api_registration_t *rp;
173
174   rp = vl_api_client_index_to_registration (mp->client_index);
175   if (rp == 0)
176     return;
177
178   cnat_dump_walk_ctx_t ctx = {
179     .rp = rp,
180     .context = mp->context,
181   };
182
183   cnat_translation_walk (cnat_translation_send_details, &ctx);
184 }
185
186 static void
187 ip_address2_from_46 (const ip46_address_t * nh,
188                      ip_address_family_t af, ip_address_t * ip)
189 {
190   ip_addr_46 (ip) = *nh;
191   ip_addr_version (ip) = af;
192 }
193
194 static walk_rc_t
195 cnat_session_send_details (const cnat_session_t * session, void *args)
196 {
197   vl_api_cnat_session_details_t *mp;
198   cnat_dump_walk_ctx_t *ctx;
199   cnat_endpoint_t ep;
200
201   ctx = args;
202
203   mp = vl_msg_api_alloc_zero (sizeof (*mp));
204   mp->_vl_msg_id = ntohs (VL_API_CNAT_SESSION_DETAILS + cnat_base_msg_id);
205
206   /* fill in the message */
207   mp->context = ctx->context;
208
209   ip_address2_from_46 (&session->value.cs_ip[VLIB_TX], session->key.cs_af,
210                        &ep.ce_ip);
211   ep.ce_port = clib_host_to_net_u16 (session->value.cs_port[VLIB_TX]);
212   cnat_endpoint_encode (&ep, &mp->session.new);
213
214   ip_address2_from_46 (&session->key.cs_ip[VLIB_RX], session->key.cs_af,
215                        &ep.ce_ip);
216   ep.ce_port = clib_host_to_net_u16 (session->key.cs_port[VLIB_RX]);
217   cnat_endpoint_encode (&ep, &mp->session.src);
218
219   ip_address2_from_46 (&session->key.cs_ip[VLIB_TX], session->key.cs_af,
220                        &ep.ce_ip);
221   ep.ce_port = clib_host_to_net_u16 (session->key.cs_port[VLIB_TX]);
222   cnat_endpoint_encode (&ep, &mp->session.dst);
223
224   mp->session.ip_proto = ip_proto_encode (session->key.cs_proto);
225
226   vl_api_send_msg (ctx->rp, (u8 *) mp);
227
228   return (WALK_CONTINUE);
229 }
230
231 static void
232 vl_api_cnat_session_dump_t_handler (vl_api_cnat_session_dump_t * mp)
233 {
234   vl_api_registration_t *rp;
235
236   rp = vl_api_client_index_to_registration (mp->client_index);
237   if (rp == 0)
238     return;
239
240   cnat_dump_walk_ctx_t ctx = {
241     .rp = rp,
242     .context = mp->context,
243   };
244
245   cnat_session_walk (cnat_session_send_details, &ctx);
246 }
247
248 static void
249 vl_api_cnat_session_purge_t_handler (vl_api_cnat_session_purge_t * mp)
250 {
251   vl_api_cnat_session_purge_reply_t *rmp;
252   int rv;
253
254   cnat_client_throttle_pool_process ();
255   rv = cnat_session_purge ();
256   rv |= cnat_translation_purge ();
257
258   REPLY_MACRO (VL_API_CNAT_SESSION_PURGE_REPLY);
259 }
260
261 static void
262 vl_api_cnat_set_snat_addresses_t_handler (vl_api_cnat_set_snat_addresses_t
263                                           * mp)
264 {
265   vl_api_cnat_set_snat_addresses_reply_t *rmp;
266   int rv = 0;
267
268   cnat_lazy_init ();
269
270   ip4_address_decode (mp->snat_ip4, &cnat_main.snat_ip4);
271   ip6_address_decode (mp->snat_ip6, &cnat_main.snat_ip6);
272
273   REPLY_MACRO (VL_API_CNAT_SET_SNAT_ADDRESSES_REPLY);
274 }
275
276 static void
277   vl_api_cnat_add_del_snat_prefix_t_handler
278   (vl_api_cnat_add_del_snat_prefix_t * mp)
279 {
280   vl_api_cnat_add_del_snat_prefix_reply_t *rmp;
281   ip_prefix_t pfx;
282   int rv;
283
284   ip_prefix_decode2 (&mp->prefix, &pfx);
285   if (mp->is_add)
286     rv = cnat_add_snat_prefix (&pfx);
287   else
288     rv = cnat_del_snat_prefix (&pfx);
289
290   REPLY_MACRO (VL_API_CNAT_ADD_DEL_SNAT_PREFIX_REPLY);
291 }
292
293 #include <cnat/cnat.api.c>
294
295 static clib_error_t *
296 cnat_api_init (vlib_main_t * vm)
297 {
298   /* Ask for a correctly-sized block of API message decode slots */
299   cnat_base_msg_id = setup_message_id_table ();
300
301   return 0;
302 }
303
304 VLIB_INIT_FUNCTION (cnat_api_init);
305
306 /* *INDENT-OFF* */
307 VLIB_PLUGIN_REGISTER () = {
308     .version = VPP_BUILD_VER,
309     .description = "CNat Translate",
310 };
311 /* *INDENT-ON* */
312
313 /*
314  * fd.io coding-style-patch-verification: ON
315  *
316  * Local Variables:
317  * eval: (c-set-style "gnu")
318  * End:
319  */