Initial commit of vpp code.
[vpp.git] / vpp / api / test_client.c
1 /*
2  *------------------------------------------------------------------
3  * api.c - message handler registration
4  * 
5  * Copyright (c) 2010 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License. 
17  *------------------------------------------------------------------
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <sys/mman.h>
24 #include <sys/stat.h>
25 #include <netinet/in.h>
26 #include <signal.h>
27 #include <pthread.h>
28 #include <unistd.h>
29 #include <time.h>
30 #include <fcntl.h>
31 #include <string.h>
32 #include <vppinfra/clib.h>
33 #include <vppinfra/vec.h>
34 #include <vppinfra/hash.h>
35 #include <vppinfra/bitmap.h>
36 #include <vppinfra/fifo.h>
37 #include <vppinfra/time.h>
38 #include <vppinfra/mheap.h>
39 #include <vppinfra/heap.h>
40 #include <vppinfra/pool.h>
41 #include <vppinfra/format.h>
42 #include <vppinfra/error.h>
43
44 #include <vnet/vnet.h>
45 #include <vnet/sr/sr.h>
46 #include <vlib/vlib.h>
47 #include <vlib/unix/unix.h>
48 #include <vlibapi/api.h>
49 #include <vlibmemory/api.h>
50
51 #include <api/vpe_msg_enum.h>
52
53 #include <vnet/ip/ip.h>
54 #include <vnet/interface.h>
55
56 #define f64_endian(a)
57 #define f64_print(a,b)
58
59 #define vl_typedefs             /* define message structures */
60 #include <api/vpe_all_api_h.h> 
61 #undef vl_typedefs
62
63 #define vl_endianfun             /* define message structures */
64 #include <api/vpe_all_api_h.h> 
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...) 
69 #define vl_printfun
70 #include <api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 vl_shmem_hdr_t *shmem_hdr;
74
75 typedef struct {
76     int link_events_on;
77     int stats_on;
78     int oam_events_on;
79
80     /* convenience */
81     unix_shared_memory_queue_t * vl_input_queue;
82     u32 my_client_index;
83 } test_main_t;
84
85 test_main_t test_main;
86
87 /* 
88  * Satisfy external references when -lvlib is not available.
89  */
90 void vlib_cli_output (struct vlib_main_t * vm, char * fmt, ...)
91 {
92     clib_warning ("vlib_cli_output callled...");
93 }
94
95 u8 * format_ethernet_address (u8 * s, va_list * args)
96 {
97   u8 * a = va_arg (*args, u8 *);
98
99   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
100                  a[0], a[1], a[2], a[3], a[4], a[5]);
101 }
102
103 static void vl_api_sw_interface_details_t_handler (
104     vl_api_sw_interface_details_t * mp)
105 {
106     char * duplex, * speed;
107
108     switch (mp->link_duplex << VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT)
109       {
110       case VNET_HW_INTERFACE_FLAG_HALF_DUPLEX:
111         duplex = "half";
112         break;
113       case VNET_HW_INTERFACE_FLAG_FULL_DUPLEX:
114         duplex = "full";
115         break;
116       default:
117         duplex = "bogus";
118         break;
119       }
120     switch (mp->link_speed << VNET_HW_INTERFACE_FLAG_SPEED_SHIFT)
121       {
122       case VNET_HW_INTERFACE_FLAG_SPEED_10M:
123         speed = "10Mbps";
124         break;
125       case VNET_HW_INTERFACE_FLAG_SPEED_100M:
126         speed = "100Mbps";
127         break;
128       case VNET_HW_INTERFACE_FLAG_SPEED_1G:
129         speed = "1Gbps";
130         break;
131       case VNET_HW_INTERFACE_FLAG_SPEED_10G:
132         speed = "10Gbps";
133         break;
134       case VNET_HW_INTERFACE_FLAG_SPEED_40G:
135         speed = "40Gbps";
136         break;
137       case VNET_HW_INTERFACE_FLAG_SPEED_100G:
138         speed = "100Gbps";
139         break;
140       default:
141         speed = "bogus";
142         break;
143       }
144     fformat(stdout, "details: %s sw_if_index %d sup_sw_if_index %d "
145             "link_duplex %s link_speed %s",
146             mp->interface_name, ntohl(mp->sw_if_index),
147             ntohl(mp->sup_sw_if_index), duplex, speed);
148
149     if (mp->l2_address_length)
150         fformat(stdout, "  l2 address: %U\n", 
151                 format_ethernet_address, mp->l2_address);
152     else
153         fformat(stdout, "\n");
154 }
155
156 static void vl_api_sw_interface_set_flags_t_handler (
157     vl_api_sw_interface_set_flags_t * mp)
158 {
159     fformat (stdout, "set flags: sw_if_index %d, admin %s link %s\n",
160              ntohl(mp->sw_if_index), 
161              mp->admin_up_down ? "up" : "down",
162              mp->link_up_down ? "up" : "down");
163 }
164
165 static void vl_api_sw_interface_set_flags_reply_t_handler (
166     vl_api_sw_interface_set_flags_reply_t * mp)
167 {
168     fformat (stdout, "set flags reply: reply %d\n", ntohl(mp->retval));
169 }
170
171 static void vl_api_want_interface_events_reply_t_handler (
172     vl_api_want_interface_events_reply_t *mp)
173 {
174 }
175
176 static void vl_api_want_stats_reply_t_handler (
177     vl_api_want_stats_reply_t *mp)
178 {
179     fformat (stdout, "want stats reply %d\n", ntohl(mp->retval));
180 }
181
182 static void vl_api_want_oam_events_reply_t_handler (
183     vl_api_want_oam_events_reply_t *mp)
184 {
185     fformat (stdout, "want oam reply %d\n", ntohl(mp->retval));
186 }
187 static void vl_api_ip_add_del_route_reply_t_handler (
188     vl_api_ip_add_del_route_reply_t *mp)
189 {
190     fformat (stdout, "add_route reply %d\n", ntohl(mp->retval));
191 }
192
193 static void vl_api_sw_interface_add_del_address_reply_t_handler (
194     vl_api_sw_interface_add_del_address_reply_t *mp)
195 {
196     fformat (stdout, "add_del_address reply %d\n", ntohl(mp->retval));
197 }
198
199 static void vl_api_sw_interface_set_table_reply_t_handler (
200     vl_api_sw_interface_set_table_reply_t *mp)
201 {
202     fformat (stdout, "set_table reply %d\n", ntohl(mp->retval));
203 }
204
205 static void vl_api_tap_connect_reply_t_handler (
206     vl_api_tap_connect_reply_t * mp)
207 {
208     fformat (stdout, "tap connect reply %d, sw_if_index %d\n", 
209              ntohl(mp->retval), ntohl(mp->sw_if_index));
210 }
211
212 static void vl_api_create_vlan_subif_reply_t_handler (
213     vl_api_create_vlan_subif_reply_t * mp)
214 {
215     fformat (stdout, "create vlan subif reply %d, sw_if_index %d\n", 
216              ntohl(mp->retval), ntohl(mp->sw_if_index));
217 }
218
219 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler (
220     vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
221 {
222     fformat (stdout, "add_del mpls gre tunnel reply %d\n", ntohl(mp->retval));
223 }
224
225 static void vl_api_mpls_add_del_encap_reply_t_handler (
226     vl_api_mpls_add_del_encap_reply_t *mp)
227 {
228     fformat (stdout, "add del mpls label reply %d\n", ntohl(mp->retval));
229 }
230
231 static void vl_api_mpls_add_del_decap_reply_t_handler (
232     vl_api_mpls_add_del_decap_reply_t *mp)
233 {
234     fformat (stdout, "add del mpls decap label reply %d\n", ntohl(mp->retval));
235 }
236
237 static void vl_api_proxy_arp_add_del_reply_t_handler 
238 (vl_api_proxy_arp_add_del_reply_t *mp)
239 {
240     fformat (stdout, "add del proxy arp reply %d\n", ntohl(mp->retval));
241 }
242
243 static void vl_api_proxy_arp_intfc_enable_disable_reply_t_handler
244 (vl_api_proxy_arp_intfc_enable_disable_reply_t *mp)
245 {
246     fformat (stdout, "proxy arp intfc ena/dis reply %d\n", ntohl(mp->retval));
247 }
248
249 static void vl_api_ip_neighbor_add_del_reply_t_handler
250 (vl_api_ip_neighbor_add_del_reply_t *mp)
251
252 {
253     fformat (stdout, "ip neighbor add del reply %d\n", ntohl(mp->retval));
254 }
255
256 static void vl_api_vnet_interface_counters_t_handler (
257     vl_api_vnet_interface_counters_t *mp)
258 {
259     char *counter_name;
260     u32 count, sw_if_index;
261     int i;
262
263     count = ntohl (mp->count);
264     sw_if_index = ntohl (mp->first_sw_if_index);
265     if (mp->is_combined == 0) {
266         u64 * vp, v;
267         vp = (u64 *) mp->data;
268
269         switch (mp->vnet_counter_type) {
270         case  VNET_INTERFACE_COUNTER_DROP:
271             counter_name = "drop";
272             break;
273         case  VNET_INTERFACE_COUNTER_PUNT:
274             counter_name = "punt";
275             break;
276         case  VNET_INTERFACE_COUNTER_IP4:
277             counter_name = "ip4";
278             break;
279         case  VNET_INTERFACE_COUNTER_IP6:
280             counter_name = "ip6";
281             break;
282         case  VNET_INTERFACE_COUNTER_RX_NO_BUF:
283             counter_name = "rx-no-buf";
284             break;
285         case  VNET_INTERFACE_COUNTER_RX_MISS:
286             counter_name = "rx-miss";
287             break;
288         case  VNET_INTERFACE_COUNTER_RX_ERROR:
289             counter_name = "rx-error";
290             break;
291         case  VNET_INTERFACE_COUNTER_TX_ERROR:
292             counter_name = "tx-error (fifo-full)";
293             break;
294         default:
295             counter_name = "bogus";
296             break;
297         }
298         for (i = 0; i < count; i++) {
299             v = clib_mem_unaligned (vp, u64);
300             v = clib_net_to_host_u64 (v);
301             vp++;
302             fformat (stdout, "%d.%s %lld\n", sw_if_index, counter_name, v);
303             sw_if_index++;
304         }
305     } else {
306         vlib_counter_t *vp;
307         u64 packets, bytes;
308         vp = (vlib_counter_t *) mp->data;
309
310         switch (mp->vnet_counter_type) {
311         case  VNET_INTERFACE_COUNTER_RX:
312             counter_name = "rx";
313             break;
314         case  VNET_INTERFACE_COUNTER_TX:
315             counter_name = "tx";
316             break;
317         default:
318             counter_name = "bogus";
319             break;
320         }
321         for (i = 0; i < count; i++) {
322             packets = clib_mem_unaligned (&vp->packets, u64);
323             packets = clib_net_to_host_u64 (packets);
324             bytes = clib_mem_unaligned (&vp->bytes, u64);
325             bytes = clib_net_to_host_u64 (bytes);
326             vp++;
327             fformat (stdout, "%d.%s.packets %lld\n", 
328                      sw_if_index, counter_name, packets);
329             fformat (stdout, "%d.%s.bytes %lld\n", 
330                      sw_if_index, counter_name, bytes);
331             sw_if_index++;
332         }
333     }
334 }
335
336 /* Format an IP4 address. */
337 u8 * format_ip4_address (u8 * s, va_list * args)
338 {
339   u8 * a = va_arg (*args, u8 *);
340   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
341 }
342
343 /* Format an IP4 route destination and length. */
344 u8 * format_ip4_address_and_length (u8 * s, va_list * args)
345 {
346   u8 * a = va_arg (*args, u8 *);
347   u8 l = va_arg (*args, u32);
348   return format (s, "%U/%d", format_ip4_address, a, l);
349 }
350
351 static void vl_api_vnet_ip4_fib_counters_t_handler (
352     vl_api_vnet_ip4_fib_counters_t *mp)
353 {
354     int i;
355     vl_api_ip4_fib_counter_t * ctrp;
356     u32 count;
357
358     count = ntohl(mp->count);
359
360     fformat (stdout, "fib id %d, count this msg %d\n",
361              ntohl(mp->vrf_id), count);
362
363     ctrp = mp->c;
364     for (i = 0; i < count; i++) {
365         fformat(stdout, "%U: %lld packets, %lld bytes\n",
366                 format_ip4_address_and_length, &ctrp->address, 
367                 (u32)ctrp->address_length,
368                 clib_net_to_host_u64 (ctrp->packets),
369                 clib_net_to_host_u64 (ctrp->bytes));
370         ctrp++;
371     }
372 }
373
374 /* Format an IP6 address. */
375 u8 * format_ip6_address (u8 * s, va_list * args)
376 {
377   ip6_address_t * a = va_arg (*args, ip6_address_t *);
378   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
379
380   i_max_n_zero = ARRAY_LEN (a->as_u16);
381   max_n_zeros = 0;
382   i_first_zero = i_max_n_zero;
383   n_zeros = 0;
384   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
385     {
386       u32 is_zero = a->as_u16[i] == 0;
387       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
388         {
389           i_first_zero = i;
390           n_zeros = 0;
391         }
392       n_zeros += is_zero;
393       if ((! is_zero && n_zeros > max_n_zeros)
394           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
395         {
396           i_max_n_zero = i_first_zero;
397           max_n_zeros = n_zeros;
398           i_first_zero = ARRAY_LEN (a->as_u16);
399           n_zeros = 0;
400         }
401     }
402
403   last_double_colon = 0;
404   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
405     {
406       if (i == i_max_n_zero && max_n_zeros > 1)
407         {
408           s = format (s, "::");
409           i += max_n_zeros - 1;
410           last_double_colon = 1;
411         }
412       else
413         {
414           s = format (s, "%s%x",
415                       (last_double_colon || i == 0) ? "" : ":",
416                       clib_net_to_host_u16 (a->as_u16[i]));
417           last_double_colon = 0;
418         }
419     }
420
421   return s;
422 }
423
424 /* Format an IP6 route destination and length. */
425 u8 * format_ip6_address_and_length (u8 * s, va_list * args)
426 {
427   ip6_address_t * a = va_arg (*args, ip6_address_t *);
428   u8 l = va_arg (*args, u32);
429   return format (s, "%U/%d", format_ip6_address, a, l);
430 }
431
432 static void vl_api_vnet_ip6_fib_counters_t_handler (
433     vl_api_vnet_ip6_fib_counters_t *mp)
434 {
435     int i;
436     vl_api_ip6_fib_counter_t * ctrp;
437     u32 count;
438
439     count = ntohl(mp->count);
440
441     fformat (stdout, "fib id %d, count this msg %d\n",
442              ntohl(mp->vrf_id), count);
443
444     ctrp = mp->c;
445     for (i = 0; i < count; i++) {
446         fformat(stdout, "%U: %lld packets, %lld bytes\n",
447                 format_ip6_address_and_length, &ctrp->address, 
448                 (u32)ctrp->address_length,
449                 clib_net_to_host_u64 (ctrp->packets),
450                 clib_net_to_host_u64 (ctrp->bytes));
451         ctrp++;
452     }
453 }
454
455 static void vl_api_oam_event_t_handler (
456     vl_api_oam_event_t *mp)
457 {
458     fformat(stdout, "OAM: %U now %s\n",
459             format_ip4_address, &mp->dst_address, 
460             mp->state == 1 ? "alive" : "dead");
461 }
462
463 static void vl_api_oam_add_del_reply_t_handler (
464     vl_api_oam_add_del_reply_t *mp)
465 {
466     fformat(stdout, "oam add del reply %d\n", ntohl(mp->retval));
467 }
468
469 static void vl_api_reset_fib_reply_t_handler (
470     vl_api_reset_fib_reply_t *mp)
471 {
472     fformat(stdout, "fib reset reply %d\n", ntohl(mp->retval));
473 }
474 static void vl_api_dhcp_proxy_set_vss_reply_t_handler (
475     vl_api_dhcp_proxy_set_vss_reply_t *mp)
476 {
477     fformat(stdout, "dhcp proxy set vss reply %d\n", ntohl(mp->retval));
478 }
479
480 static void vl_api_dhcp_proxy_config_reply_t_handler (
481     vl_api_dhcp_proxy_config_reply_t *mp)
482 {
483     fformat(stdout, "dhcp proxy config reply %d\n", ntohl(mp->retval));
484 }
485
486 static void vl_api_set_ip_flow_hash_reply_t_handler (
487     vl_api_set_ip_flow_hash_reply_t *mp)
488 {
489     fformat(stdout, "set ip flow hash reply %d\n", ntohl(mp->retval));
490 }
491
492 static void vl_api_sw_interface_ip6nd_ra_config_reply_t_handler (
493     vl_api_sw_interface_ip6nd_ra_config_reply_t *mp)
494 {
495     fformat (stdout, "ip6 nd ra-config  reply %d\n", ntohl(mp->retval));
496 }
497
498 static void vl_api_sw_interface_ip6nd_ra_prefix_reply_t_handler (
499     vl_api_sw_interface_ip6nd_ra_prefix_reply_t *mp)
500 {
501     fformat (stdout, "ip6 nd ra-prefix  reply %d\n", ntohl(mp->retval));
502 }
503
504 static void vl_api_sw_interface_ip6_enable_disable_reply_t_handler (
505     vl_api_sw_interface_ip6_enable_disable_reply_t *mp)
506 {
507     fformat (stdout, "ip6 enable/disable reply %d\n", ntohl(mp->retval));
508 }
509
510 static void vl_api_sw_interface_ip6_set_link_local_address_reply_t_handler (
511     vl_api_sw_interface_ip6_set_link_local_address_reply_t *mp)
512 {
513     fformat (stdout, "ip6 set link-local address reply %d\n", ntohl(mp->retval));
514 }
515
516 static void vl_api_create_loopback_reply_t_handler 
517 (vl_api_create_loopback_reply_t *mp)
518 {
519     fformat (stdout, "create loopback status %d, sw_if_index %d\n", 
520              ntohl(mp->retval), ntohl (mp->sw_if_index));
521 }
522
523 static void vl_api_sr_tunnel_add_del_reply_t_handler (
524     vl_api_sr_tunnel_add_del_reply_t *mp)
525 {
526     fformat(stdout, "sr tunnel add/del reply %d\n", ntohl(mp->retval));
527 }
528
529 static void vl_api_l2_patch_add_del_reply_t_handler
530 (vl_api_l2_patch_add_del_reply_t *mp)
531 {
532     fformat (stdout, "l2 patch reply %d\n", ntohl(mp->retval));
533 }
534
535 static void vl_api_sw_interface_set_l2_xconnect_reply_t_handler
536 (vl_api_sw_interface_set_l2_xconnect_reply_t *mp)
537 {
538     fformat (stdout, "l2_xconnect reply %d\n", ntohl(mp->retval));
539 }
540
541 static void vl_api_sw_interface_set_l2_bridge_reply_t_handler
542 (vl_api_sw_interface_set_l2_bridge_reply_t *mp)
543 {
544     fformat (stdout, "l2_bridge reply %d\n", ntohl(mp->retval));
545 }
546
547 static void noop_handler (void *notused) { }
548
549 #define vl_api_vnet_ip4_fib_counters_t_endian noop_handler
550 #define vl_api_vnet_ip4_fib_counters_t_print noop_handler
551 #define vl_api_vnet_ip6_fib_counters_t_endian noop_handler
552 #define vl_api_vnet_ip6_fib_counters_t_print noop_handler
553
554 #define foreach_api_msg                                                 \
555 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
556 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
557 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
558 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
559 _(WANT_STATS_REPLY, want_stats_reply)                                   \
560 _(WANT_OAM_EVENTS_REPLY, want_oam_events_reply)                         \
561 _(OAM_EVENT, oam_event)                                                 \
562 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
563 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
564 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
565 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
566 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
567 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, sw_interface_add_del_address_reply) \
568 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
569 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
570 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
571 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
572 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
573 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
574 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
575 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, proxy_arp_intfc_enable_disable_reply) \
576 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
577 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
578 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
579 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
580 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
581 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, sw_interface_ip6nd_ra_config_reply) \
582 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, sw_interface_ip6nd_ra_prefix_reply) \
583 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, sw_interface_ip6_enable_disable_reply) \
584 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, sw_interface_ip6_set_link_local_address_reply) \
585  _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                        \
586 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
587 _(SR_TUNNEL_ADD_DEL_REPLY,sr_tunnel_add_del_reply)          \
588 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY, sw_interface_set_l2_xconnect_reply) \
589 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY, sw_interface_set_l2_bridge_reply)
590
591 int connect_to_vpe(char *name)
592 {
593     int rv=0;
594
595     rv = vl_client_connect_to_vlib("/vpe-api", name, 32);
596
597 #define _(N,n)                                                  \
598     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
599                            vl_api_##n##_t_handler,              \
600                            noop_handler,                        \
601                            vl_api_##n##_t_endian,               \
602                            vl_api_##n##_t_print,                \
603                            sizeof(vl_api_##n##_t), 1); 
604     foreach_api_msg;
605 #undef _
606
607     shmem_hdr = api_main.shmem_hdr;
608
609     return rv;
610 }
611
612 int disconnect_from_vpe(void)
613 {
614     vl_client_disconnect_from_vlib();
615     return 0;
616 }
617
618 void link_up_down_enable_disable (test_main_t * tm, int enable)
619 {
620     vl_api_want_interface_events_t * mp;
621
622     /* Request admin / link up down messages */
623     mp = vl_msg_api_alloc (sizeof (*mp));
624     memset(mp, 0, sizeof (*mp));
625     mp->_vl_msg_id = ntohs (VL_API_WANT_INTERFACE_EVENTS);
626     mp->client_index = tm->my_client_index;
627     mp->context = 0xdeadbeef;
628     mp->enable_disable = enable;
629     mp->pid = getpid();
630     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
631     tm->link_events_on = enable;
632 }
633
634 void stats_enable_disable (test_main_t *tm, int enable)
635 {
636     vl_api_want_stats_t * mp;
637
638     mp = vl_msg_api_alloc (sizeof (*mp));
639     memset(mp, 0, sizeof (*mp));
640     mp->_vl_msg_id = ntohs (VL_API_WANT_STATS);
641     mp->client_index = tm->my_client_index;
642     mp->context = 0xdeadbeef;
643     mp->enable_disable = enable;
644     mp->pid = getpid();
645     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
646     tm->stats_on = enable;
647 }
648
649 void oam_events_enable_disable (test_main_t *tm, int enable)
650 {
651     vl_api_want_oam_events_t * mp;
652
653     mp = vl_msg_api_alloc (sizeof (*mp));
654     memset(mp, 0, sizeof (*mp));
655     mp->_vl_msg_id = ntohs (VL_API_WANT_OAM_EVENTS);
656     mp->client_index = tm->my_client_index;
657     mp->context = 0xdeadbeef;
658     mp->enable_disable = enable;
659     mp->pid = getpid();
660     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
661     tm->oam_events_on = enable;
662 }
663
664 void oam_add_del (test_main_t *tm, int is_add)
665 {
666     vl_api_oam_add_del_t *mp;
667     ip4_address_t tmp;
668
669     mp = vl_msg_api_alloc (sizeof (*mp));
670     memset(mp, 0, sizeof (*mp));
671     mp->_vl_msg_id = ntohs (VL_API_OAM_ADD_DEL);
672     mp->client_index = tm->my_client_index;
673     mp->context = 0xdeadbeef;
674     mp->is_add = is_add;
675
676     tmp.as_u32 = ntohl (0xc0a80101); /* 192.168.1.1 */
677     memcpy (mp->src_address, tmp.as_u8, 4);
678
679     tmp.as_u32 = ntohl (0xc0a80103); /* 192.168.1.3 */
680     memcpy (mp->dst_address, tmp.as_u8, 4);
681     
682     mp->vrf_id = 0;
683     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
684 }
685
686 void dump (test_main_t *tm)
687 {
688     vl_api_sw_interface_dump_t * mp;
689
690     mp = vl_msg_api_alloc (sizeof (*mp));
691     memset(mp, 0, sizeof (*mp));
692     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DUMP);
693     mp->client_index = tm->my_client_index;
694     mp->name_filter_valid = 1;
695     strncpy ((char *) mp->name_filter, "eth", sizeof (mp->name_filter)-1);
696     
697     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
698 }
699
700 void add_del_ip4_route (test_main_t *tm, int enable_disable)
701 {
702     vl_api_ip_add_del_route_t *mp;
703     u32 tmp;
704
705     mp = vl_msg_api_alloc (sizeof (*mp));
706     memset(mp, 0, sizeof (*mp));
707     mp->_vl_msg_id = ntohs (VL_API_IP_ADD_DEL_ROUTE);
708     mp->client_index = tm->my_client_index;
709     mp->context = 0xdeadbeef;
710     mp->vrf_id = ntohl(0);
711     mp->create_vrf_if_needed = 1;
712     /* Arp, please, if needed */
713     mp->resolve_if_needed = 1;
714     mp->resolve_attempts = ntohl(10);
715
716     mp->next_hop_sw_if_index = ntohl(5);
717     mp->is_add = enable_disable;
718     mp->next_hop_weight = 1;
719
720     /* Next hop: 6.0.0.1 */
721     tmp = ntohl(0x06000001);
722     memcpy (mp->next_hop_address, &tmp, sizeof (tmp));
723
724     /* Destination: 10.0.0.1/32 */
725     tmp = ntohl(0x0);
726     memcpy (mp->dst_address, &tmp, sizeof (tmp));
727     mp->dst_address_length = 0;
728
729     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
730 }
731
732 void add_del_ip6_route (test_main_t *tm, int enable_disable)
733 {
734     vl_api_ip_add_del_route_t *mp;
735     u64 tmp[2];
736
737     mp = vl_msg_api_alloc (sizeof (*mp));
738     memset(mp, 0, sizeof (*mp));
739     mp->_vl_msg_id = ntohs (VL_API_IP_ADD_DEL_ROUTE);
740     mp->client_index = tm->my_client_index;
741     mp->context = 0xdeadbeef;
742     mp->next_hop_sw_if_index = ntohl(5);
743     mp->is_add = enable_disable;
744     mp->is_ipv6 = 1;
745     mp->next_hop_weight = 1;
746     mp->dst_address_length = 64;
747
748     /* add/del dabe::/64 via db01::11 */
749
750     tmp[0] = clib_host_to_net_u64 (0xdabe000000000000ULL);
751     tmp[1] = clib_host_to_net_u64 (0x0ULL);
752     memcpy (mp->dst_address, &tmp[0], 8);
753     memcpy (&mp->dst_address[8], &tmp[1], 8);
754
755     tmp[0] = clib_host_to_net_u64(0xdb01000000000000ULL);
756     tmp[1] = clib_host_to_net_u64 (0x11ULL);
757     memcpy (mp->next_hop_address, &tmp[0], 8);
758     memcpy (&mp->next_hop_address[8], &tmp[1], 8);
759
760     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
761 }
762
763 void add_del_interface_address (test_main_t *tm, int enable_disable)
764 {
765     vl_api_sw_interface_add_del_address_t *mp;
766     u32 tmp;
767
768     mp = vl_msg_api_alloc (sizeof (*mp));
769     memset(mp, 0, sizeof (*mp));
770     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS);
771     mp->client_index = tm->my_client_index;
772     mp->context = 0xdeadbeef;
773     mp->sw_if_index = ntohl(5);
774     mp->is_add = enable_disable;
775     mp->address_length = 8;
776     
777     tmp = ntohl (0x01020304);
778     memcpy (mp->address, &tmp, 4);
779
780     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
781 }
782 void add_del_v6_interface_address (test_main_t *tm, int enable_disable)
783 {
784     vl_api_sw_interface_add_del_address_t *mp;
785     u64 tmp[2];
786
787     mp = vl_msg_api_alloc (sizeof (*mp));
788     memset(mp, 0, sizeof (*mp));
789     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS);
790     mp->client_index = tm->my_client_index;
791     mp->context = 0xdeadbeef;
792     mp->is_ipv6 = 1;
793     mp->sw_if_index = ntohl(5);
794     mp->is_add = enable_disable;
795     mp->address_length = 64;
796     
797     tmp[0] = clib_host_to_net_u64(0xdb01000000000000ULL);
798     tmp[1] = clib_host_to_net_u64 (0x11ULL);
799
800     memcpy (mp->address, &tmp[0], 8);
801     memcpy (&mp->address[8], &tmp[1], 8);
802
803     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
804 }
805
806 void del_all_interface_addresses (test_main_t *tm)
807 {
808     vl_api_sw_interface_add_del_address_t *mp;
809
810     mp = vl_msg_api_alloc (sizeof (*mp));
811     memset(mp, 0, sizeof (*mp));
812     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS);
813     mp->client_index = tm->my_client_index;
814     mp->context = 0xdeadbeef;
815     mp->sw_if_index = ntohl(5);
816     mp->del_all = 1;
817
818     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
819 }
820
821 void set_interface_table (test_main_t *tm, int is_ipv6, u32 vrf_id)
822 {
823     vl_api_sw_interface_set_table_t *mp;
824
825     mp = vl_msg_api_alloc (sizeof (*mp));
826     memset(mp, 0, sizeof (*mp));
827     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_TABLE);
828     mp->client_index = tm->my_client_index;
829     mp->context = 0xdeadbeef;
830     mp->sw_if_index = ntohl(5);
831     mp->is_ipv6 = is_ipv6;
832     mp->vrf_id = ntohl(vrf_id);
833
834     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
835 }
836
837 void connect_unix_tap (test_main_t *tm, char *name)
838 {
839     vl_api_tap_connect_t *mp;
840
841     mp = vl_msg_api_alloc (sizeof (*mp));
842     memset(mp, 0, sizeof (*mp));
843     mp->_vl_msg_id = ntohs (VL_API_TAP_CONNECT);
844     mp->client_index = tm->my_client_index;
845     mp->context = 0xdeadbeef;
846     memcpy (mp->tap_name, name, strlen(name));
847     mp->use_random_mac = 1;
848     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
849 }
850
851 void create_vlan_subif (test_main_t *tm, u32 vlan_id)
852 {
853     vl_api_create_vlan_subif_t *mp;
854
855     mp = vl_msg_api_alloc (sizeof (*mp));
856     memset(mp, 0, sizeof (*mp));
857     mp->_vl_msg_id = ntohs (VL_API_CREATE_VLAN_SUBIF);
858     mp->client_index = tm->my_client_index;
859     mp->context = 0xdeadbeef;
860     mp->sw_if_index = ntohl (5);
861     mp->vlan_id = ntohl(vlan_id);
862
863     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
864 }
865
866 void create_mpls_gre_tunnel (test_main_t *tm, u32 vrf_id, u32 label, 
867                              u8 is_add)
868 {
869     vl_api_mpls_add_del_encap_t *lp;
870     vl_api_mpls_add_del_decap_t *dlp;
871     vl_api_mpls_gre_add_del_tunnel_t *mp;
872     u32 tmp;
873
874     dlp = vl_msg_api_alloc (sizeof (*dlp));
875     memset(dlp, 0, sizeof (*dlp));
876     dlp->_vl_msg_id = ntohs (VL_API_MPLS_ADD_DEL_DECAP);
877     dlp->client_index = tm->my_client_index;
878     dlp->context = 0xdeadbeef;
879     dlp->tx_vrf_id = ntohl(vrf_id);
880     dlp->label = ntohl(label);
881     dlp->s_bit = 1;
882     dlp->is_add = is_add;
883     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&dlp);
884
885     lp = vl_msg_api_alloc (sizeof (*lp) + sizeof (u32));
886     memset(lp, 0, sizeof (*lp) + sizeof (u32));
887     lp->_vl_msg_id = ntohs (VL_API_MPLS_ADD_DEL_ENCAP);
888     lp->client_index = tm->my_client_index;
889     lp->context = 0xdeadbeef;
890     lp->vrf_id = ntohl(vrf_id);
891     lp->labels[0] = ntohl(label);
892     lp->nlabels = 1;
893     lp->is_add = is_add;
894     /* dst: 5.0.0.1 */
895     tmp = ntohl (0x05000001);
896     memcpy (lp->dst_address, &tmp, 4);
897
898     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&lp);
899
900     mp = vl_msg_api_alloc (sizeof (*mp));
901     memset(mp, 0, sizeof (*mp));
902     mp->_vl_msg_id = ntohs (VL_API_MPLS_GRE_ADD_DEL_TUNNEL);
903     mp->client_index = tm->my_client_index;
904     mp->context = 0xdeadbeef;
905     mp->inner_vrf_id = ntohl(vrf_id);
906     mp->outer_vrf_id = 0;
907     mp->is_add = is_add;
908
909     /* src: 6.0.0.1 */
910     tmp = ntohl (0x06000001);
911     memcpy (mp->src_address, &tmp, 4);
912     /* dst: 5.0.0.1 */
913     tmp = ntohl (0x05000001);
914     memcpy (mp->dst_address, &tmp, 4);
915     /* intfc: 5.0.0.1/24 */
916     tmp = ntohl (0x05000001);
917     memcpy (mp->intfc_address, &tmp, 4);
918     mp->intfc_address_length = 24;
919
920     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
921 }
922
923 void add_del_proxy_arp (test_main_t *tm, int is_add)
924 {
925     vl_api_proxy_arp_add_del_t *mp;
926     u32 tmp;
927
928     mp = vl_msg_api_alloc (sizeof (*mp));
929     memset(mp, 0, sizeof (*mp));
930     mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_ADD_DEL);
931     mp->client_index = tm->my_client_index;
932     mp->context = 0xdeadbeef;
933     mp->vrf_id = ntohl(11);
934     mp->is_add = is_add;
935
936     /* proxy fib 11, 1.1.1.1 -> 1.1.1.10 */
937     tmp = ntohl (0x01010101);
938     memcpy (mp->low_address, &tmp, 4);
939
940     tmp = ntohl (0x0101010a);
941     memcpy (mp->hi_address, &tmp, 4);
942
943     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
944 }
945
946 void proxy_arp_intfc_enable_disable (test_main_t *tm, int enable_disable)
947 {
948     vl_api_proxy_arp_intfc_enable_disable_t *mp;
949
950     mp = vl_msg_api_alloc (sizeof (*mp));
951     memset(mp, 0, sizeof (*mp));
952     mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE);
953     mp->client_index = tm->my_client_index;
954     mp->context = 0xdeadbeef;
955     mp->sw_if_index = ntohl(6);
956     mp->enable_disable = enable_disable;
957
958     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
959 }
960
961 void add_ip4_neighbor (test_main_t *tm, int add_del)
962 {
963     vl_api_ip_neighbor_add_del_t *mp;
964     u32 tmp;
965
966     mp = vl_msg_api_alloc (sizeof (*mp));
967     memset(mp, 0, sizeof (*mp));
968     mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_ADD_DEL);
969     mp->client_index = tm->my_client_index;
970     mp->context = 0xdeadbeef;
971     mp->vrf_id = ntohl(11);
972     mp->sw_if_index = ntohl(6);
973     mp->is_add = add_del;
974
975     memset (mp->mac_address, 0xbe, sizeof (mp->mac_address));
976     
977     tmp = ntohl (0x0101010a);
978     memcpy (mp->dst_address, &tmp, 4);
979
980     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
981 }
982
983 void add_ip6_neighbor (test_main_t *tm, int add_del)
984 {
985     vl_api_ip_neighbor_add_del_t *mp;
986     u64 tmp[2];
987
988     mp = vl_msg_api_alloc (sizeof (*mp));
989     memset(mp, 0, sizeof (*mp));
990     mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_ADD_DEL);
991     mp->client_index = tm->my_client_index;
992     mp->context = 0xdeadbeef;
993     mp->vrf_id = ntohl(11);
994     mp->sw_if_index = ntohl(6);
995     mp->is_add = add_del;
996     mp->is_ipv6 = 1;
997
998     memset (mp->mac_address, 0xbe, sizeof (mp->mac_address));
999     
1000     tmp[0] = clib_host_to_net_u64(0xdb01000000000000ULL);
1001     tmp[1] = clib_host_to_net_u64 (0x11ULL);
1002
1003     memcpy (mp->dst_address, &tmp[0], 8);
1004     memcpy (&mp->dst_address[8], &tmp[1], 8);
1005
1006     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1007 }
1008
1009 void reset_fib (test_main_t *tm, u8 is_ip6)
1010 {
1011     vl_api_reset_fib_t *mp;
1012     
1013     mp = vl_msg_api_alloc (sizeof (*mp));
1014     memset(mp, 0, sizeof (*mp));
1015     mp->_vl_msg_id = ntohs (VL_API_RESET_FIB);
1016     mp->client_index = tm->my_client_index;
1017     mp->context = 0xdeadbeef;
1018     mp->vrf_id = ntohl(11);
1019     mp->is_ipv6 = is_ip6;
1020
1021     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1022 }
1023
1024 void dhcpv6_set_vss (test_main_t *tm)
1025 {
1026     vl_api_dhcp_proxy_set_vss_t *mp;
1027     
1028     mp = vl_msg_api_alloc (sizeof (*mp));
1029     memset(mp, 0, sizeof (*mp));
1030     mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_SET_VSS);
1031     mp->client_index = tm->my_client_index;
1032     mp->context = 0xdeadbeef;
1033     mp->oui = ntohl(6);
1034     mp->fib_id = ntohl(60);
1035     mp->is_add = 1;
1036     mp->is_ipv6 = 1;
1037     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1038 }
1039 void dhcpv4_set_vss (test_main_t *tm)
1040 {
1041     vl_api_dhcp_proxy_set_vss_t *mp;
1042     
1043     mp = vl_msg_api_alloc (sizeof (*mp));
1044     memset(mp, 0, sizeof (*mp));
1045     mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_SET_VSS);
1046     mp->client_index = tm->my_client_index;
1047     mp->context = 0xdeadbeef;
1048     mp->oui = ntohl(4);
1049     mp->fib_id = ntohl(40);
1050     mp->is_add = 1;
1051     mp->is_ipv6 = 0;
1052     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1053 }
1054
1055 void dhcp_set_vss(test_main_t *tm)
1056 {
1057     dhcpv4_set_vss(tm);
1058     dhcpv6_set_vss(tm);    
1059 }
1060
1061 void dhcp_set_proxy (test_main_t *tm, int ipv6)
1062 {
1063     vl_api_dhcp_proxy_config_t *mp; 
1064     
1065     mp = vl_msg_api_alloc (sizeof (*mp));
1066     memset(mp, 0, sizeof (*mp));
1067     mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_CONFIG);
1068     mp->client_index = tm->my_client_index;
1069     mp->context = 0xdeadbeef;
1070     mp->vrf_id = ntohl(0);
1071     mp->is_ipv6  = ipv6;
1072     mp->insert_circuit_id = 1;
1073     mp->is_add = 1;
1074     mp->dhcp_server[0] = 0x20;
1075     mp->dhcp_server[1] = 0x01;
1076     mp->dhcp_server[2] = 0xab;
1077     mp->dhcp_server[3] = 0xcd;
1078     mp->dhcp_server[4] = 0x12;
1079     mp->dhcp_server[5] = 0x34;
1080     mp->dhcp_server[6] = 0xfe;
1081     mp->dhcp_server[7] = 0xdc;
1082     mp->dhcp_server[14] = 0;
1083     mp->dhcp_server[15] = 0x2;
1084     
1085     mp->dhcp_src_address[0] = 0x20;
1086     mp->dhcp_src_address[1] = 0x01;
1087     mp->dhcp_src_address[2] = 0xab;
1088     mp->dhcp_src_address[3] = 0xcd;
1089     mp->dhcp_src_address[4] = 0x12;
1090     mp->dhcp_src_address[5] = 0x34;
1091     mp->dhcp_src_address[6] = 0x56;
1092     mp->dhcp_src_address[7] = 0x78;
1093     mp->dhcp_src_address[14] = 0;
1094     mp->dhcp_src_address[15] = 0x2;
1095
1096     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1097 }
1098
1099 void set_ip_flow_hash (test_main_t *tm, u8 is_ip6)
1100 {
1101     vl_api_set_ip_flow_hash_t *mp;
1102     
1103     mp = vl_msg_api_alloc (sizeof (*mp));
1104     memset(mp, 0, sizeof (*mp));
1105     mp->_vl_msg_id = ntohs (VL_API_SET_IP_FLOW_HASH);
1106     mp->client_index = tm->my_client_index;
1107     mp->context = 0xdeadbeef;
1108     mp->vrf_id = 0;
1109     mp->is_ipv6 = is_ip6;
1110     mp->dst = 1;
1111     mp->reverse = 1;
1112
1113    vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1114 }
1115
1116 void ip6nd_ra_config(test_main_t *tm, int is_no)
1117 {
1118     vl_api_sw_interface_ip6nd_ra_config_t *mp;
1119    
1120     mp = vl_msg_api_alloc (sizeof (*mp));
1121     memset(mp, 0, sizeof (*mp));
1122     
1123     mp->client_index = tm->my_client_index;
1124     mp->context = 0xdeadbeef;
1125     mp->sw_if_index = ntohl(5);
1126     mp->is_no = is_no;
1127    
1128     mp->surpress = 1; 
1129
1130
1131     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG);
1132     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1133 }
1134
1135 void ip6nd_ra_prefix(test_main_t *tm, int is_no)
1136 {
1137     vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
1138     u64 tmp[2];
1139
1140     mp = vl_msg_api_alloc (sizeof (*mp));
1141     memset(mp, 0, sizeof (*mp));
1142     
1143     mp->client_index = tm->my_client_index;
1144     mp->context = 0xdeadbeef;
1145     mp->sw_if_index = ntohl(5);
1146     mp->is_no = is_no;
1147
1148     mp->use_default = 1;
1149
1150
1151     tmp[0] = clib_host_to_net_u64(0xdb01000000000000ULL);
1152     tmp[1] = clib_host_to_net_u64 (0x11ULL);
1153
1154
1155     memcpy (mp->address, &tmp[0], 8);
1156     memcpy (&mp->address[8], &tmp[1], 8);
1157
1158     mp->address_length = 64;
1159
1160
1161     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX);
1162     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1163 }
1164
1165 void ip6_enable_disable(test_main_t *tm, int enable)
1166 {
1167     vl_api_sw_interface_ip6_enable_disable_t *mp;
1168    
1169     mp = vl_msg_api_alloc (sizeof (*mp));
1170     memset(mp, 0, sizeof (*mp));
1171     
1172     mp->client_index = tm->my_client_index;
1173     mp->context = 0xdeadbeef;
1174     mp->sw_if_index = ntohl(5);
1175     mp->enable = (enable == 1);;
1176   
1177     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE);
1178     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1179 }
1180
1181 void loop_create (test_main_t *tm)
1182 {
1183     vl_api_create_loopback_t * mp;
1184
1185     mp = vl_msg_api_alloc (sizeof(*mp));
1186     memset(mp, 0, sizeof (*mp));
1187     
1188     mp->_vl_msg_id = ntohs (VL_API_CREATE_LOOPBACK);
1189     mp->client_index = tm->my_client_index;
1190     mp->context = 0xdeadbeef;
1191     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1192 }
1193
1194 void ip6_set_link_local_address(test_main_t *tm)
1195 {
1196     vl_api_sw_interface_ip6_set_link_local_address_t *mp;
1197     u64 tmp[2];
1198
1199     mp = vl_msg_api_alloc (sizeof (*mp));
1200     memset(mp, 0, sizeof (*mp));
1201     
1202     mp->client_index = tm->my_client_index;
1203     mp->context = 0xdeadbeef;
1204     mp->sw_if_index = ntohl(5);
1205
1206     tmp[0] = clib_host_to_net_u64(0xfe80000000000000ULL);
1207     tmp[1] = clib_host_to_net_u64 (0x11ULL);
1208
1209     memcpy (mp->address, &tmp[0], 8);
1210     memcpy (&mp->address[8], &tmp[1], 8);
1211
1212     mp->address_length = 64;
1213
1214     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS);
1215
1216     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1217 }
1218
1219
1220 void set_flags (test_main_t *tm, int up_down)
1221 {
1222     vl_api_sw_interface_set_flags_t * mp;
1223
1224     mp = vl_msg_api_alloc (sizeof (*mp));
1225     memset(mp, 0, sizeof (*mp));
1226
1227     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
1228     mp->client_index = tm->my_client_index;
1229     mp->context = 0xdeadbeef;
1230     mp->sw_if_index = ntohl (5);
1231     mp->admin_up_down = up_down;
1232     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1233
1234 }
1235
1236 void l2_patch_add_del (test_main_t *tm, int is_add)
1237 {
1238     vl_api_l2_patch_add_del_t *mp;
1239
1240     mp = vl_msg_api_alloc (sizeof (*mp));
1241     memset(mp, 0, sizeof (*mp));
1242     mp->_vl_msg_id = ntohs (VL_API_L2_PATCH_ADD_DEL);
1243     mp->client_index = tm->my_client_index;
1244     mp->context = 0xdeadbeef;
1245     mp->is_add = is_add;
1246     mp->rx_sw_if_index = ntohl (1);
1247     mp->tx_sw_if_index = ntohl (2);
1248     
1249     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1250 }
1251
1252 void l2_xconnect (test_main_t *tm)
1253 {
1254     vl_api_sw_interface_set_l2_xconnect_t *mp;
1255
1256     mp = vl_msg_api_alloc (sizeof (*mp));
1257     memset(mp, 0, sizeof (*mp));
1258     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_L2_XCONNECT);
1259         mp->client_index = tm->my_client_index;
1260     mp->context = 0xdeadbeef;
1261     mp->rx_sw_if_index = ntohl(5);
1262     mp->tx_sw_if_index = ntohl(6);
1263         mp->enable = 1;
1264     
1265     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1266 }
1267
1268 void l2_bridge (test_main_t *tm)
1269 {
1270     vl_api_sw_interface_set_l2_bridge_t *mp;
1271
1272     mp = vl_msg_api_alloc (sizeof (*mp));
1273     memset(mp, 0, sizeof (*mp));
1274     mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_L2_BRIDGE);
1275         mp->client_index = tm->my_client_index;
1276     mp->context = 0xdeadbeef;
1277     mp->rx_sw_if_index = ntohl(5);
1278     mp->bd_id = ntohl(6);
1279     mp->bvi = ntohl(1);
1280     mp->shg = ntohl(0);
1281     mp->enable = 1;
1282     
1283     vl_msg_api_send_shmem (tm->vl_input_queue, (u8 *)&mp);
1284 }
1285
1286 int main (int argc, char ** argv)
1287 {
1288     api_main_t * am = &api_main;
1289     test_main_t * tm = &test_main;
1290     int ch;
1291     
1292     connect_to_vpe("test_client");
1293     
1294     tm->vl_input_queue = shmem_hdr->vl_input_queue;
1295     tm->my_client_index = am->my_client_index;
1296     
1297     fformat(stdout, "Type 'h' for help, 'q' to quit...\n");
1298     
1299     while (1) {
1300         ch = getchar();
1301         switch (ch) {
1302         case 'q':
1303             goto done;
1304         case 'd':
1305             dump (tm);
1306             break;
1307         case 'L':
1308             link_up_down_enable_disable (tm, 1 /* enable_disable */);
1309             break;
1310         case 'l':
1311             link_up_down_enable_disable (tm, 0 /* enable_disable */);
1312             break;
1313         case 'S':
1314             stats_enable_disable (tm, 1 /* enable_disable */);
1315             break;
1316         case 's':
1317             stats_enable_disable (tm, 0 /* enable_disable */);
1318             break;
1319         case '3':
1320             add_del_ip4_route (tm, 0 /* add */);
1321             break;
1322         case '4':
1323             add_del_ip4_route (tm, 1 /* add */);
1324             break;
1325         case '5':
1326             add_del_ip6_route (tm, 0 /* add */);
1327             break;
1328         case '6':
1329             add_del_ip6_route (tm, 1 /* add */);
1330             break;
1331         case 'A':
1332             add_del_interface_address (tm, 1 /* add */);
1333             break;
1334         case 'a':
1335             add_del_interface_address (tm, 0 /* add */);
1336             break;
1337         case 'B':
1338             add_del_v6_interface_address (tm, 1 /* add */);
1339             break;
1340         case 'b':
1341             add_del_v6_interface_address (tm, 0 /* add */);
1342             break;
1343         case 'E':
1344             l2_patch_add_del(tm, 1 /* is_add */);
1345             break;
1346         case 'e':
1347             l2_patch_add_del(tm, 0 /* is_add */);
1348             break;
1349         case 'z':
1350             del_all_interface_addresses (tm);
1351             break;
1352         case 't':
1353             set_interface_table (tm, 0 /* is_ipv6 */, 
1354                                  11 /* my amp goes to 11 */);
1355             break;
1356         case 'T':
1357             set_interface_table (tm, 1 /* is_ipv6 */, 
1358                                  12 /* my amp goes to 12 */);
1359             break;
1360
1361         case 'u':
1362             create_vlan_subif (tm, 123);
1363             break;
1364
1365         case 'c':
1366             connect_unix_tap (tm, "foo");
1367             break;
1368
1369         case 'M':
1370             create_mpls_gre_tunnel (tm, 11 /* fib */, 123 /* label */, 
1371                                     1 /* is_add */);
1372             break;
1373
1374         case 'm':
1375             create_mpls_gre_tunnel (tm, 11 /* fib */, 123 /* label */,
1376                                     0 /* is_add */);
1377             break;
1378
1379         case 'n':
1380             add_ip4_neighbor (tm, 1 /* is_add */);
1381             add_ip6_neighbor (tm, 1 /* is_add */);
1382             break;
1383
1384         case 'N':
1385             add_ip4_neighbor (tm, 0 /* is_add */);
1386             add_ip6_neighbor (tm, 0 /* is_add */);
1387             break;
1388             
1389         case 'p':
1390             add_del_proxy_arp (tm, 1 /* add */);
1391             break;
1392             
1393         case 'i':
1394             proxy_arp_intfc_enable_disable (tm, 1 /* enable */);
1395             break;
1396
1397         case 'O':
1398             oam_events_enable_disable (tm, 0 /* enable */);
1399             break;
1400
1401         case 'o':
1402             oam_events_enable_disable (tm, 1 /* enable */);
1403             break;
1404
1405         case '0':
1406             oam_add_del (tm, 0 /* is_add */);
1407             break;
1408
1409         case '1':
1410             oam_add_del (tm, 1 /* is_add */);
1411             break;
1412
1413         case 'r':
1414             reset_fib (tm, 0 /* is_ip6 */);
1415             break;
1416
1417         case 'R':
1418             reset_fib (tm, 1 /* is_ip6 */);
1419             break;
1420             
1421         case 'j':
1422             dhcp_set_vss(tm);
1423             break;
1424
1425         case 'k':
1426             dhcp_set_proxy(tm, 0);
1427             break;
1428
1429         case 'K':
1430             dhcp_set_proxy(tm, 1 /*ipv6*/);
1431             break;
1432        
1433         case 'v':
1434             set_ip_flow_hash (tm, 0 /* is_ip6 */);
1435             break;
1436
1437         case 'V':
1438             ip6_set_link_local_address(tm);
1439             break;
1440
1441         case 'w':
1442             ip6_enable_disable(tm, 1 /* enable */);
1443             break;
1444
1445         case 'W':
1446             ip6_enable_disable(tm, 0 /* disable */);
1447             break;
1448
1449         case 'x':
1450             ip6nd_ra_config(tm, 0 /* is_no */);
1451             break;
1452         case 'X':
1453             ip6nd_ra_config(tm, 1 /* is_no */);
1454             break;
1455         case 'y':
1456             ip6nd_ra_prefix(tm, 0 /* is_no */);
1457             break;
1458         case 'Y':
1459             ip6nd_ra_prefix(tm, 1 /* is_no */);
1460             break;
1461
1462         case '7':
1463             loop_create (tm);
1464             break;
1465
1466         case 'F':
1467             set_flags (tm, 1 /* up_down */);
1468             break;
1469
1470         case 'f':
1471             set_flags (tm, 0 /* up_down */);
1472             break;
1473                 
1474         case '@':
1475                         l2_xconnect (tm);
1476             break;
1477                 
1478         case '#':
1479                         l2_bridge(tm);
1480             break;
1481                 
1482         case 'h':
1483             fformat (stdout, "q=quit,d=dump,L=link evts on,l=link evts off\n");
1484             fformat (stdout, "S=stats on,s=stats off\n");
1485             fformat (stdout, "4=add v4 route, 3=del v4 route\n");
1486             fformat (stdout, "6=add v6 route, 5=del v6 route\n");
1487             fformat (stdout, "A=add v4 intfc route, a=del v4 intfc route\n");
1488             fformat (stdout, "B=add v6 intfc route, b=del v6 intfc route\n");
1489             fformat (stdout, "z=del all intfc routes\n");
1490             fformat (stdout, "t=set v4 intfc table, T=set v6 intfc table\n");
1491             fformat (stdout, "c=connect unix tap\n");
1492             fformat (stdout, "j=set dhcpv4 and v6 link-address/option-82 params\n");
1493             fformat (stdout, "k=set dhcpv4 relay agent params\n");
1494             fformat (stdout, "K=set dhcpv6 relay agent params\n");
1495             fformat (stdout, "E=add l2 patch, e=del l2 patch\n");
1496             fformat (stdout, "V=ip6 set link-local address \n");
1497             fformat (stdout, "w=ip6 enable \n");
1498             fformat (stdout, "W=ip6 disable \n");
1499             fformat (stdout, "x=ip6 nd config \n");
1500             fformat (stdout, "X=no ip6 nd config\n");
1501             fformat (stdout, "y=ip6 nd prefix \n");
1502             fformat (stdout, "Y=no ip6 nd prefix\n");
1503             fformat (stdout, "@=l2 xconnect\n");
1504             fformat (stdout, "#=l2 bridge\n");
1505             
1506         default:
1507             break;
1508         }
1509
1510     }
1511
1512  done:
1513
1514     if (tm->link_events_on)
1515         link_up_down_enable_disable (tm, 0 /* enable */);
1516     if (tm->stats_on)
1517         stats_enable_disable (tm, 0 /* enable */);
1518     if (tm->oam_events_on)
1519         oam_events_enable_disable (tm, 0 /* enable */);
1520
1521     disconnect_from_vpe();
1522     exit (0);
1523 }
1524
1525 #undef vl_api_version
1526 #define vl_api_version(n,v) static u32 vpe_api_version = v;
1527 #include <api/vpe.api.h>
1528 #undef vl_api_version
1529
1530 void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp) 
1531 {
1532     /* 
1533      * Send the main API signature in slot 0. This bit of code must
1534      * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
1535      */
1536     mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
1537 }