dhcp: Move to plugin
[vpp.git] / src / plugins / dhcp / dhcp_test.c
1 /*
2  * Copyright (c) 2015 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 <vat/vat.h>
17 #include <vlibapi/api.h>
18 #include <vlibmemory/api.h>
19 #include <vppinfra/error.h>
20
21 #include <dhcp/client.h>
22 #include <dhcp/dhcp_proxy.h>
23 #include <vnet/ip/ip_format_fns.h>
24 #include <vnet/ethernet/ethernet_format_fns.h>
25
26 /* define message IDs */
27 #include <dhcp/dhcp.api_enum.h>
28 #include <dhcp/dhcp.api_types.h>
29
30 typedef struct {
31     /* API message ID base */
32     u16 msg_id_base;
33     vat_main_t *vat_main;
34 } dhcp_test_main_t;
35
36 dhcp_test_main_t dhcp_test_main;
37
38 #define __plugin_msg_base dhcp_test_main.msg_id_base
39 #include <vlibapi/vat_helper_macros.h>
40
41 /* Macro to finish up custom dump fns */
42 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
43 #define FINISH                                  \
44     vec_add1 (s, 0);                            \
45     vl_print (handle, (char *)s);               \
46     vec_free (s);                               \
47     return handle;
48
49 static int
50 api_dhcp_proxy_config (vat_main_t * vam)
51 {
52   unformat_input_t *i = vam->input;
53   vl_api_dhcp_proxy_config_t *mp;
54   u32 rx_vrf_id = 0;
55   u32 server_vrf_id = 0;
56   u8 is_add = 1;
57   u8 v4_address_set = 0;
58   u8 v6_address_set = 0;
59   ip4_address_t v4address;
60   ip6_address_t v6address;
61   u8 v4_src_address_set = 0;
62   u8 v6_src_address_set = 0;
63   ip4_address_t v4srcaddress;
64   ip6_address_t v6srcaddress;
65   int ret;
66
67   /* Parse args required to build the message */
68   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
69     {
70       if (unformat (i, "del"))
71         is_add = 0;
72       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
73         ;
74       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
75         ;
76       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
77         v4_address_set = 1;
78       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
79         v6_address_set = 1;
80       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
81         v4_src_address_set = 1;
82       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
83         v6_src_address_set = 1;
84       else
85         break;
86     }
87
88   if (v4_address_set && v6_address_set)
89     {
90       errmsg ("both v4 and v6 server addresses set");
91       return -99;
92     }
93   if (!v4_address_set && !v6_address_set)
94     {
95       errmsg ("no server addresses set");
96       return -99;
97     }
98
99   if (v4_src_address_set && v6_src_address_set)
100     {
101       errmsg ("both v4 and v6  src addresses set");
102       return -99;
103     }
104   if (!v4_src_address_set && !v6_src_address_set)
105     {
106       errmsg ("no src addresses set");
107       return -99;
108     }
109
110   if (!(v4_src_address_set && v4_address_set) &&
111       !(v6_src_address_set && v6_address_set))
112     {
113       errmsg ("no matching server and src addresses set");
114       return -99;
115     }
116
117   /* Construct the API message */
118   M (DHCP_PROXY_CONFIG, mp);
119
120   mp->is_add = is_add;
121   mp->rx_vrf_id = ntohl (rx_vrf_id);
122   mp->server_vrf_id = ntohl (server_vrf_id);
123   if (v6_address_set)
124     {
125       clib_memcpy (&mp->dhcp_server.un, &v6address, sizeof (v6address));
126       clib_memcpy (&mp->dhcp_src_address.un, &v6srcaddress,
127                    sizeof (v6address));
128     }
129   else
130     {
131       clib_memcpy (&mp->dhcp_server.un, &v4address, sizeof (v4address));
132       clib_memcpy (&mp->dhcp_src_address.un, &v4srcaddress,
133                    sizeof (v4address));
134     }
135
136   /* send it... */
137   S (mp);
138
139   /* Wait for a reply, return good/bad news  */
140   W (ret);
141   return ret;
142 }
143
144 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
145 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
146
147 static void
148 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
149 {
150   vat_main_t *vam = &vat_main;
151   u32 i, count = mp->count;
152   vl_api_dhcp_server_t *s;
153
154   if (mp->is_ipv6)
155     print (vam->ofp,
156            "RX Table-ID %d, Source Address %U, VSS Type %d, "
157            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
158            ntohl (mp->rx_vrf_id),
159            format_ip6_address, mp->dhcp_src_address,
160            mp->vss_type, mp->vss_vpn_ascii_id,
161            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
162   else
163     print (vam->ofp,
164            "RX Table-ID %d, Source Address %U, VSS Type %d, "
165            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
166            ntohl (mp->rx_vrf_id),
167            format_ip4_address, mp->dhcp_src_address,
168            mp->vss_type, mp->vss_vpn_ascii_id,
169            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
170
171   for (i = 0; i < count; i++)
172     {
173       s = &mp->servers[i];
174
175       if (mp->is_ipv6)
176         print (vam->ofp,
177                " Server Table-ID %d, Server Address %U",
178                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
179       else
180         print (vam->ofp,
181                " Server Table-ID %d, Server Address %U",
182                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
183     }
184 }
185
186 static int
187 api_dhcp_proxy_dump (vat_main_t * vam)
188 {
189   unformat_input_t *i = vam->input;
190   vl_api_dhcp_plugin_control_ping_t *mp_ping;
191   vl_api_dhcp_proxy_dump_t *mp;
192   u8 is_ipv6 = 0;
193   int ret;
194
195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
196     {
197       if (unformat (i, "ipv6"))
198         is_ipv6 = 1;
199       else
200         {
201           clib_warning ("parse error '%U'", format_unformat_error, i);
202           return -99;
203         }
204     }
205
206   M (DHCP_PROXY_DUMP, mp);
207
208   mp->is_ip6 = is_ipv6;
209   S (mp);
210
211   /* Use a control ping for synchronization */
212   MPING (DHCP_PLUGIN_CONTROL_PING, mp_ping);
213   S (mp_ping);
214
215   W (ret);
216   return ret;
217 }
218
219 static int
220 api_dhcp_proxy_set_vss (vat_main_t * vam)
221 {
222   unformat_input_t *i = vam->input;
223   vl_api_dhcp_proxy_set_vss_t *mp;
224   u8 is_ipv6 = 0;
225   u8 is_add = 1;
226   u32 tbl_id = ~0;
227   u8 vss_type = VSS_TYPE_DEFAULT;
228   u8 *vpn_ascii_id = 0;
229   u32 oui = 0;
230   u32 fib_id = 0;
231   int ret;
232
233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
234     {
235       if (unformat (i, "tbl_id %d", &tbl_id))
236         ;
237       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
238         vss_type = VSS_TYPE_ASCII;
239       else if (unformat (i, "fib_id %d", &fib_id))
240         vss_type = VSS_TYPE_VPN_ID;
241       else if (unformat (i, "oui %d", &oui))
242         vss_type = VSS_TYPE_VPN_ID;
243       else if (unformat (i, "ipv6"))
244         is_ipv6 = 1;
245       else if (unformat (i, "del"))
246         is_add = 0;
247       else
248         break;
249     }
250
251   if (tbl_id == ~0)
252     {
253       errmsg ("missing tbl_id ");
254       vec_free (vpn_ascii_id);
255       return -99;
256     }
257
258   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
259     {
260       errmsg ("vpn_ascii_id cannot be longer than 128 ");
261       vec_free (vpn_ascii_id);
262       return -99;
263     }
264
265   M (DHCP_PROXY_SET_VSS, mp);
266   mp->tbl_id = ntohl (tbl_id);
267   mp->vss_type = vss_type;
268   if (vpn_ascii_id)
269     {
270       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
271       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
272     }
273   mp->vpn_index = ntohl (fib_id);
274   mp->oui = ntohl (oui);
275   mp->is_ipv6 = is_ipv6;
276   mp->is_add = is_add;
277
278   S (mp);
279   W (ret);
280
281   vec_free (vpn_ascii_id);
282   return ret;
283 }
284
285 static int
286 api_dhcp_client_config (vat_main_t * vam)
287 {
288   unformat_input_t *i = vam->input;
289   vl_api_dhcp_client_config_t *mp;
290   u32 sw_if_index;
291   u8 sw_if_index_set = 0;
292   u8 is_add = 1;
293   u8 *hostname = 0;
294   u8 disable_event = 0;
295   int ret;
296
297   /* Parse args required to build the message */
298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
299     {
300       if (unformat (i, "del"))
301         is_add = 0;
302       else
303         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
304         sw_if_index_set = 1;
305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
306         sw_if_index_set = 1;
307       else if (unformat (i, "hostname %s", &hostname))
308         ;
309       else if (unformat (i, "disable_event"))
310         disable_event = 1;
311       else
312         break;
313     }
314
315   if (sw_if_index_set == 0)
316     {
317       errmsg ("missing interface name or sw_if_index");
318       return -99;
319     }
320
321   if (vec_len (hostname) > 63)
322     {
323       errmsg ("hostname too long");
324     }
325   vec_add1 (hostname, 0);
326
327   /* Construct the API message */
328   M (DHCP_CLIENT_CONFIG, mp);
329
330   mp->is_add = is_add;
331   mp->client.sw_if_index = htonl (sw_if_index);
332   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
333   vec_free (hostname);
334   mp->client.want_dhcp_event = disable_event ? 0 : 1;
335   mp->client.pid = htonl (getpid ());
336
337   /* send it... */
338   S (mp);
339
340   /* Wait for a reply, return good/bad news  */
341   W (ret);
342   return ret;
343 }
344
345 /* static void *vl_api_dhcp_proxy_config_t_print */
346 /*   (vl_api_dhcp_proxy_config_t * mp, void *handle) */
347 /* { */
348 /*   u8 *s; */
349
350 /*   s = format (0, "SCRIPT: dhcp_proxy_config_2 "); */
351
352 /*   s = format (s, "rx_vrf_id %d ", (mp->rx_vrf_id)); */
353 /*   s = format (s, "server_vrf_id %d ", (mp->server_vrf_id)); */
354
355 /*   s = format (s, "svr %U ", format_ip46_address, */
356 /*            (ip46_address_t *) & mp->dhcp_server.un); */
357 /*   s = format (s, "src %U ", format_ip46_address, */
358 /*            (ip46_address_t *) & mp->dhcp_src_address.un); */
359
360 /*   if (mp->is_add == 0) */
361 /*     s = format (s, "del "); */
362
363 /*   FINISH; */
364 /* } */
365
366 /* static void *vl_api_dhcp_proxy_set_vss_t_print */
367 /*   (vl_api_dhcp_proxy_set_vss_t * mp, void *handle) */
368 /* { */
369 /*   u8 *s; */
370
371 /*   s = format (0, "SCRIPT: dhcp_proxy_set_vss "); */
372
373 /*   s = format (s, "tbl_id %d ", (mp->tbl_id)); */
374
375 /*   if (mp->vss_type == VSS_TYPE_VPN_ID) */
376 /*     { */
377 /*       s = format (s, "fib_id %d ", (mp->vpn_index)); */
378 /*       s = format (s, "oui %d ", (mp->oui)); */
379 /*     } */
380 /*   else if (mp->vss_type == VSS_TYPE_ASCII) */
381 /*     s = format (s, "vpn_ascii_id %s", mp->vpn_ascii_id); */
382
383 /*   if (mp->is_ipv6 != 0) */
384 /*     s = format (s, "ipv6 "); */
385
386 /*   if (mp->is_add == 0) */
387 /*     s = format (s, "del "); */
388
389 /*   FINISH; */
390 /* } */
391
392 /* static void *vl_api_dhcp_client_config_t_print */
393 /*   (vl_api_dhcp_client_config_t * mp, void *handle) */
394 /* { */
395 /*   u8 *s; */
396
397 /*   s = format (0, "SCRIPT: dhcp_client_config "); */
398
399 /*   s = format (s, "sw_if_index %d ", (mp->client.sw_if_index)); */
400
401 /*   s = format (s, "hostname %s ", mp->client.hostname); */
402
403 /*   s = format (s, "want_dhcp_event %d ", mp->client.want_dhcp_event); */
404
405 /*   s = format (s, "pid %d ", (mp->client.pid)); */
406
407 /*   if (mp->is_add == 0) */
408 /*     s = format (s, "del "); */
409
410 /*   FINISH; */
411 /* } */
412
413 static int
414 api_want_dhcp6_reply_events (vat_main_t * vam)
415 {
416     return -1;
417 }
418 static int
419 api_want_dhcp6_pd_reply_events (vat_main_t * vam)
420 {
421     return -1;
422 }
423 static int
424 api_dhcp6_send_client_message (vat_main_t * vam)
425 {
426     return -1;
427 }
428 static int
429 api_dhcp6_pd_send_client_message (vat_main_t * vam)
430 {
431     return -1;
432 }
433 static int
434 api_dhcp_client_dump (vat_main_t * vam)
435 {
436     return -1;
437 }
438 static int
439 api_dhcp6_duid_ll_set (vat_main_t * vam)
440 {
441     return -1;
442 }
443 static int
444 api_dhcp6_clients_enable_disable (vat_main_t * vam)
445 {
446     return -1;
447 }
448 static int
449 api_dhcp_plugin_control_ping (vat_main_t * vam)
450 {
451     return -1;
452 }
453 static int
454 api_dhcp_plugin_get_version (vat_main_t * vam)
455 {
456     return -1;
457 }
458
459 #define vl_api_dhcp_client_details_t_handler vl_noop_handler
460
461 static void
462 vl_api_dhcp_plugin_get_version_reply_t_handler (vl_api_dhcp_plugin_get_version_reply_t * mp)
463 {
464 }
465
466 static void
467 vl_api_dhcp_plugin_control_ping_reply_t_handler (vl_api_dhcp_plugin_get_version_reply_t * mp)
468 {
469 }
470
471 /* static void */
472 /* vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp) */
473 /* { */
474 /*   u8 *s, i; */
475
476 /*   s = format (0, "DHCP compl event: pid %d hostname %s host_addr %U " */
477 /*            "host_mac %U router_addr %U", */
478 /*            ntohl (mp->pid), mp->lease.hostname, */
479 /*            format_ip4_address, mp->lease.host_address, */
480 /*            format_ethernet_address, mp->lease.host_mac, */
481 /*            format_ip4_address, mp->lease.router_address); */
482
483 /*   for (i = 0; i < mp->lease.count; i++) */
484 /*     s = */
485 /*       format (s, " domain_server_addr %U", format_ip4_address, */
486 /*            mp->lease.domain_server[i].address); */
487
488 /*   errmsg ((char *) s); */
489 /*   vec_free (s); */
490 /* } */
491
492 #include <dhcp/dhcp.api_test.c>