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