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