interface: add api test file
[vpp.git] / src / vnet / interface_test.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2021 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #include <vat/vat.h>
19 #include <vlibapi/api.h>
20 #include <vlibmemory/api.h>
21 #include <vppinfra/error.h>
22 #include <vpp/api/types.h>
23
24 #include <vnet/ip/ip_types_api.h>
25
26 #define __plugin_msg_base interface_test_main.msg_id_base
27 #include <vlibapi/vat_helper_macros.h>
28
29 /* Declare message IDs */
30 #include <vnet/format_fns.h>
31 #include <vnet/interface.api_enum.h>
32 #include <vnet/interface.api_types.h>
33 #include <vlibmemory/vlib.api_types.h>
34 #include <vlibmemory/memclnt.api_enum.h>
35
36 #define vl_endianfun /* define message structures */
37 #include <vnet/interface.api.h>
38 #undef vl_endianfun
39
40 typedef struct
41 {
42   /* API message ID base */
43   u16 msg_id_base;
44   vat_main_t *vat_main;
45 } interface_test_main_t;
46
47 static interface_test_main_t interface_test_main;
48
49 static int
50 api_sw_interface_set_flags (vat_main_t *vam)
51 {
52   unformat_input_t *i = vam->input;
53   vl_api_sw_interface_set_flags_t *mp;
54   u32 sw_if_index;
55   u8 sw_if_index_set = 0;
56   u8 admin_up = 0;
57   int ret;
58
59   /* Parse args required to build the message */
60   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
61     {
62       if (unformat (i, "admin-up"))
63         admin_up = 1;
64       else if (unformat (i, "admin-down"))
65         admin_up = 0;
66       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
67         sw_if_index_set = 1;
68       else if (unformat (i, "sw_if_index %d", &sw_if_index))
69         sw_if_index_set = 1;
70       else
71         break;
72     }
73
74   if (sw_if_index_set == 0)
75     {
76       errmsg ("missing interface name or sw_if_index");
77       return -99;
78     }
79
80   /* Construct the API message */
81   M (SW_INTERFACE_SET_FLAGS, mp);
82   mp->sw_if_index = ntohl (sw_if_index);
83   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
84
85   /* send it... */
86   S (mp);
87
88   /* Wait for a reply, return the good/bad news... */
89   W (ret);
90   return ret;
91 }
92
93 static int
94 api_hw_interface_set_mtu (vat_main_t *vam)
95 {
96   unformat_input_t *i = vam->input;
97   vl_api_hw_interface_set_mtu_t *mp;
98   u32 sw_if_index = ~0;
99   u32 mtu = 0;
100   int ret;
101
102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
103     {
104       if (unformat (i, "mtu %d", &mtu))
105         ;
106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
107         ;
108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
109         ;
110       else
111         break;
112     }
113
114   if (sw_if_index == ~0)
115     {
116       errmsg ("missing interface name or sw_if_index");
117       return -99;
118     }
119
120   if (mtu == 0)
121     {
122       errmsg ("no mtu specified");
123       return -99;
124     }
125
126   /* Construct the API message */
127   M (HW_INTERFACE_SET_MTU, mp);
128   mp->sw_if_index = ntohl (sw_if_index);
129   mp->mtu = ntohs ((u16) mtu);
130
131   S (mp);
132   W (ret);
133   return ret;
134 }
135
136 static int
137 api_sw_interface_tag_add_del (vat_main_t *vam)
138 {
139   unformat_input_t *i = vam->input;
140   vl_api_sw_interface_tag_add_del_t *mp;
141   u32 sw_if_index = ~0;
142   u8 *tag = 0;
143   u8 enable = 1;
144   int ret;
145
146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
147     {
148       if (unformat (i, "tag %s", &tag))
149         ;
150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
151         ;
152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
153         ;
154       else if (unformat (i, "del"))
155         enable = 0;
156       else
157         break;
158     }
159
160   if (sw_if_index == ~0)
161     {
162       errmsg ("missing interface name or sw_if_index");
163       return -99;
164     }
165
166   if (enable && (tag == 0))
167     {
168       errmsg ("no tag specified");
169       return -99;
170     }
171
172   /* Construct the API message */
173   M (SW_INTERFACE_TAG_ADD_DEL, mp);
174   mp->sw_if_index = ntohl (sw_if_index);
175   mp->is_add = enable;
176   if (enable)
177     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
178   vec_free (tag);
179
180   S (mp);
181   W (ret);
182   return ret;
183 }
184
185 static int
186 api_sw_interface_add_del_mac_address (vat_main_t *vam)
187 {
188   unformat_input_t *i = vam->input;
189   vl_api_mac_address_t mac = { 0 };
190   vl_api_sw_interface_add_del_mac_address_t *mp;
191   u32 sw_if_index = ~0;
192   u8 is_add = 1;
193   u8 mac_set = 0;
194   int ret;
195
196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
197     {
198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
199         ;
200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
201         ;
202       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
203         mac_set++;
204       else if (unformat (i, "del"))
205         is_add = 0;
206       else
207         break;
208     }
209
210   if (sw_if_index == ~0)
211     {
212       errmsg ("missing interface name or sw_if_index");
213       return -99;
214     }
215
216   if (!mac_set)
217     {
218       errmsg ("missing MAC address");
219       return -99;
220     }
221
222   /* Construct the API message */
223   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
224   mp->sw_if_index = ntohl (sw_if_index);
225   mp->is_add = is_add;
226   clib_memcpy (&mp->addr, &mac, sizeof (mac));
227
228   S (mp);
229   W (ret);
230   return ret;
231 }
232
233 static void
234 vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t *mp)
235 {
236   vat_main_t *vam = &vat_main;
237   u8 *s = format (0, "%s%c", mp->interface_name, 0);
238
239   hash_set_mem (vam->sw_if_index_by_interface_name, s,
240                 ntohl (mp->sw_if_index));
241
242   /* In sub interface case, fill the sub interface table entry */
243   if (mp->sw_if_index != mp->sup_sw_if_index)
244     {
245       sw_interface_subif_t *sub = NULL;
246
247       vec_add2 (vam->sw_if_subif_table, sub, 1);
248
249       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
250       strncpy ((char *) sub->interface_name, (char *) s,
251                vec_len (sub->interface_name));
252       sub->sw_if_index = ntohl (mp->sw_if_index);
253       sub->sub_id = ntohl (mp->sub_id);
254
255       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
256
257       sub->sub_number_of_tags = mp->sub_number_of_tags;
258       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
259       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
260
261       /* vlan tag rewrite */
262       sub->vtr_op = ntohl (mp->vtr_op);
263       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
264       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
265       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
266     }
267 }
268
269 static int
270 api_sw_interface_get_mac_address (vat_main_t *vat)
271 {
272   return -1;
273 }
274
275 static void
276 vl_api_sw_interface_get_mac_address_reply_t_handler (
277   vl_api_sw_interface_get_mac_address_reply_t *mp)
278 {
279 }
280
281 static int
282 api_sw_interface_add_del_address (vat_main_t *vam)
283 {
284   unformat_input_t *i = vam->input;
285   vl_api_sw_interface_add_del_address_t *mp;
286   u32 sw_if_index;
287   u8 sw_if_index_set = 0;
288   u8 is_add = 1, del_all = 0;
289   u32 address_length = 0;
290   u8 v4_address_set = 0;
291   u8 v6_address_set = 0;
292   ip4_address_t v4address;
293   ip6_address_t v6address;
294   int ret;
295
296   /* Parse args required to build the message */
297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
298     {
299       if (unformat (i, "del-all"))
300         del_all = 1;
301       else if (unformat (i, "del"))
302         is_add = 0;
303       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
304         sw_if_index_set = 1;
305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
306         sw_if_index_set = 1;
307       else if (unformat (i, "%U/%d", unformat_ip4_address, &v4address,
308                          &address_length))
309         v4_address_set = 1;
310       else if (unformat (i, "%U/%d", unformat_ip6_address, &v6address,
311                          &address_length))
312         v6_address_set = 1;
313       else
314         break;
315     }
316
317   if (sw_if_index_set == 0)
318     {
319       errmsg ("missing interface name or sw_if_index");
320       return -99;
321     }
322   if (v4_address_set && v6_address_set)
323     {
324       errmsg ("both v4 and v6 addresses set");
325       return -99;
326     }
327   if (!v4_address_set && !v6_address_set && !del_all)
328     {
329       errmsg ("no addresses set");
330       return -99;
331     }
332
333   /* Construct the API message */
334   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
335
336   mp->sw_if_index = ntohl (sw_if_index);
337   mp->is_add = is_add;
338   mp->del_all = del_all;
339   if (v6_address_set)
340     {
341       mp->prefix.address.af = ADDRESS_IP6;
342       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
343     }
344   else
345     {
346       mp->prefix.address.af = ADDRESS_IP4;
347       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
348     }
349   mp->prefix.len = address_length;
350
351   /* send it... */
352   S (mp);
353
354   /* Wait for a reply, return good/bad news  */
355   W (ret);
356   return ret;
357 }
358
359 static int
360 api_sw_interface_get_table (vat_main_t *vam)
361 {
362   unformat_input_t *i = vam->input;
363   vl_api_sw_interface_get_table_t *mp;
364   u32 sw_if_index;
365   u8 sw_if_index_set = 0;
366   u8 is_ipv6 = 0;
367   int ret;
368
369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
370     {
371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
372         sw_if_index_set = 1;
373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
374         sw_if_index_set = 1;
375       else if (unformat (i, "ipv6"))
376         is_ipv6 = 1;
377       else
378         break;
379     }
380
381   if (sw_if_index_set == 0)
382     {
383       errmsg ("missing interface name or sw_if_index");
384       return -99;
385     }
386
387   M (SW_INTERFACE_GET_TABLE, mp);
388   mp->sw_if_index = htonl (sw_if_index);
389   mp->is_ipv6 = is_ipv6;
390
391   S (mp);
392   W (ret);
393   return ret;
394 }
395
396 static int
397 api_sw_interface_set_rx_mode (vat_main_t *vam)
398 {
399   unformat_input_t *i = vam->input;
400   vl_api_sw_interface_set_rx_mode_t *mp;
401   u32 sw_if_index;
402   u8 sw_if_index_set = 0;
403   int ret;
404   u8 queue_id_valid = 0;
405   u32 queue_id;
406   vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
407
408   /* Parse args required to build the message */
409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
410     {
411       if (unformat (i, "queue %d", &queue_id))
412         queue_id_valid = 1;
413       else if (unformat (i, "polling"))
414         mode = VNET_HW_IF_RX_MODE_POLLING;
415       else if (unformat (i, "interrupt"))
416         mode = VNET_HW_IF_RX_MODE_INTERRUPT;
417       else if (unformat (i, "adaptive"))
418         mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
419       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
420         sw_if_index_set = 1;
421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
422         sw_if_index_set = 1;
423       else
424         break;
425     }
426
427   if (sw_if_index_set == 0)
428     {
429       errmsg ("missing interface name or sw_if_index");
430       return -99;
431     }
432   if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
433     {
434       errmsg ("missing rx-mode");
435       return -99;
436     }
437
438   /* Construct the API message */
439   M (SW_INTERFACE_SET_RX_MODE, mp);
440   mp->sw_if_index = ntohl (sw_if_index);
441   mp->mode = (vl_api_rx_mode_t) mode;
442   mp->queue_id_valid = queue_id_valid;
443   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
444
445   /* send it... */
446   S (mp);
447
448   /* Wait for a reply, return the good/bad news... */
449   W (ret);
450   return ret;
451 }
452
453 static int
454 api_sw_interface_set_unnumbered (vat_main_t *vam)
455 {
456   unformat_input_t *i = vam->input;
457   vl_api_sw_interface_set_unnumbered_t *mp;
458   u32 sw_if_index;
459   u32 unnum_sw_index = ~0;
460   u8 is_add = 1;
461   u8 sw_if_index_set = 0;
462   int ret;
463
464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
465     {
466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
467         sw_if_index_set = 1;
468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
469         sw_if_index_set = 1;
470       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
471         ;
472       else if (unformat (i, "del"))
473         is_add = 0;
474       else
475         {
476           clib_warning ("parse error '%U'", format_unformat_error, i);
477           return -99;
478         }
479     }
480
481   if (sw_if_index_set == 0)
482     {
483       errmsg ("missing interface name or sw_if_index");
484       return -99;
485     }
486
487   M (SW_INTERFACE_SET_UNNUMBERED, mp);
488
489   mp->sw_if_index = ntohl (sw_if_index);
490   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
491   mp->is_add = is_add;
492
493   S (mp);
494   W (ret);
495   return ret;
496 }
497
498 static void
499 vl_api_sw_interface_get_table_reply_t_handler (
500   vl_api_sw_interface_get_table_reply_t *mp)
501 {
502   vat_main_t *vam = interface_test_main.vat_main;
503
504   fformat (vam->ofp, "%d", ntohl (mp->vrf_id));
505
506   vam->retval = ntohl (mp->retval);
507   vam->result_ready = 1;
508 }
509
510 static int
511 api_sw_interface_address_replace_begin (vat_main_t *vam)
512 {
513   return -1;
514 }
515
516 static int
517 api_sw_interface_set_mac_address (vat_main_t *vam)
518 {
519   return -1;
520 }
521
522 static int
523 api_sw_interface_set_rx_placement (vat_main_t *vam)
524 {
525   unformat_input_t *i = vam->input;
526   vl_api_sw_interface_set_rx_placement_t *mp;
527   u32 sw_if_index;
528   u8 sw_if_index_set = 0;
529   int ret;
530   u8 is_main = 0;
531   u32 queue_id, thread_index;
532
533   /* Parse args required to build the message */
534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
535     {
536       if (unformat (i, "queue %d", &queue_id))
537         ;
538       else if (unformat (i, "main"))
539         is_main = 1;
540       else if (unformat (i, "worker %d", &thread_index))
541         ;
542       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
543         sw_if_index_set = 1;
544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
545         sw_if_index_set = 1;
546       else
547         break;
548     }
549
550   if (sw_if_index_set == 0)
551     {
552       errmsg ("missing interface name or sw_if_index");
553       return -99;
554     }
555
556   if (is_main)
557     thread_index = 0;
558   /* Construct the API message */
559   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
560   mp->sw_if_index = ntohl (sw_if_index);
561   mp->worker_id = ntohl (thread_index);
562   mp->queue_id = ntohl (queue_id);
563   mp->is_main = is_main;
564
565   /* send it... */
566   S (mp);
567   /* Wait for a reply, return the good/bad news... */
568   W (ret);
569   return ret;
570 }
571
572 static int
573 api_interface_name_renumber (vat_main_t *vam)
574 {
575   unformat_input_t *line_input = vam->input;
576   vl_api_interface_name_renumber_t *mp;
577   u32 sw_if_index = ~0;
578   u32 new_show_dev_instance = ~0;
579   int ret;
580
581   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
582     {
583       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
584                     &sw_if_index))
585         ;
586       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
587         ;
588       else if (unformat (line_input, "new_show_dev_instance %d",
589                          &new_show_dev_instance))
590         ;
591       else
592         break;
593     }
594
595   if (sw_if_index == ~0)
596     {
597       errmsg ("missing interface name or sw_if_index");
598       return -99;
599     }
600
601   if (new_show_dev_instance == ~0)
602     {
603       errmsg ("missing new_show_dev_instance");
604       return -99;
605     }
606
607   M (INTERFACE_NAME_RENUMBER, mp);
608
609   mp->sw_if_index = ntohl (sw_if_index);
610   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
611
612   S (mp);
613   W (ret);
614   return ret;
615 }
616
617 static int
618 api_delete_subif (vat_main_t *vam)
619 {
620   unformat_input_t *i = vam->input;
621   vl_api_delete_subif_t *mp;
622   u32 sw_if_index = ~0;
623   int ret;
624
625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
626     {
627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
628         ;
629       if (unformat (i, "sw_if_index %d", &sw_if_index))
630         ;
631       else
632         break;
633     }
634
635   if (sw_if_index == ~0)
636     {
637       errmsg ("missing sw_if_index");
638       return -99;
639     }
640
641   /* Construct the API message */
642   M (DELETE_SUBIF, mp);
643   mp->sw_if_index = ntohl (sw_if_index);
644
645   S (mp);
646   W (ret);
647   return ret;
648 }
649
650 static int
651 api_delete_loopback (vat_main_t *vam)
652 {
653   unformat_input_t *i = vam->input;
654   vl_api_delete_loopback_t *mp;
655   u32 sw_if_index = ~0;
656   int ret;
657
658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
659     {
660       if (unformat (i, "sw_if_index %d", &sw_if_index))
661         ;
662       else
663         break;
664     }
665
666   if (sw_if_index == ~0)
667     {
668       errmsg ("missing sw_if_index");
669       return -99;
670     }
671
672   /* Construct the API message */
673   M (DELETE_LOOPBACK, mp);
674   mp->sw_if_index = ntohl (sw_if_index);
675
676   S (mp);
677   W (ret);
678   return ret;
679 }
680
681 static int
682 api_create_loopback_instance (vat_main_t *vat)
683 {
684   return -1;
685 }
686
687 static int
688 api_create_loopback (vat_main_t *vam)
689 {
690   unformat_input_t *i = vam->input;
691   vl_api_create_loopback_t *mp;
692   vl_api_create_loopback_instance_t *mp_lbi;
693   u8 mac_address[6];
694   u8 mac_set = 0;
695   u8 is_specified = 0;
696   u32 user_instance = 0;
697   int ret;
698
699   clib_memset (mac_address, 0, sizeof (mac_address));
700
701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
702     {
703       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
704         mac_set = 1;
705       if (unformat (i, "instance %d", &user_instance))
706         is_specified = 1;
707       else
708         break;
709     }
710
711   if (is_specified)
712     {
713       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
714       mp_lbi->is_specified = is_specified;
715       if (is_specified)
716         mp_lbi->user_instance = htonl (user_instance);
717       if (mac_set)
718         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
719       S (mp_lbi);
720     }
721   else
722     {
723       /* Construct the API message */
724       M (CREATE_LOOPBACK, mp);
725       if (mac_set)
726         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
727       S (mp);
728     }
729
730   W (ret);
731   return ret;
732 }
733
734 static void
735 vl_api_create_subif_reply_t_handler (vl_api_create_subif_reply_t *mp)
736 {
737   vat_main_t *vam = interface_test_main.vat_main;
738   vam->result_ready = 1;
739 }
740
741 #define foreach_create_subif_bit                                              \
742   _ (no_tags)                                                                 \
743   _ (one_tag)                                                                 \
744   _ (two_tags)                                                                \
745   _ (dot1ad)                                                                  \
746   _ (exact_match)                                                             \
747   _ (default_sub)                                                             \
748   _ (outer_vlan_id_any)                                                       \
749   _ (inner_vlan_id_any)
750
751 #define foreach_create_subif_flag                                             \
752   _ (0, "no_tags")                                                            \
753   _ (1, "one_tag")                                                            \
754   _ (2, "two_tags")                                                           \
755   _ (3, "dot1ad")                                                             \
756   _ (4, "exact_match")                                                        \
757   _ (5, "default_sub")                                                        \
758   _ (6, "outer_vlan_id_any")                                                  \
759   _ (7, "inner_vlan_id_any")
760
761 static int
762 api_create_subif (vat_main_t *vam)
763 {
764   unformat_input_t *i = vam->input;
765   vl_api_create_subif_t *mp;
766   u32 sw_if_index;
767   u8 sw_if_index_set = 0;
768   u32 sub_id;
769   u8 sub_id_set = 0;
770   u32 __attribute__ ((unused)) no_tags = 0;
771   u32 __attribute__ ((unused)) one_tag = 0;
772   u32 __attribute__ ((unused)) two_tags = 0;
773   u32 __attribute__ ((unused)) dot1ad = 0;
774   u32 __attribute__ ((unused)) exact_match = 0;
775   u32 __attribute__ ((unused)) default_sub = 0;
776   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
777   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
778   u32 tmp;
779   u16 outer_vlan_id = 0;
780   u16 inner_vlan_id = 0;
781   int ret;
782
783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
784     {
785       if (unformat (i, "sw_if_index %d", &sw_if_index))
786         sw_if_index_set = 1;
787       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
788         sw_if_index_set = 1;
789       else if (unformat (i, "sub_id %d", &sub_id))
790         sub_id_set = 1;
791       else if (unformat (i, "outer_vlan_id %d", &tmp))
792         outer_vlan_id = tmp;
793       else if (unformat (i, "inner_vlan_id %d", &tmp))
794         inner_vlan_id = tmp;
795
796 #define _(a) else if (unformat (i, #a)) a = 1;
797       foreach_create_subif_bit
798 #undef _
799         else
800       {
801         clib_warning ("parse error '%U'", format_unformat_error, i);
802         return -99;
803       }
804     }
805
806   if (sw_if_index_set == 0)
807     {
808       errmsg ("missing interface name or sw_if_index");
809       return -99;
810     }
811
812   if (sub_id_set == 0)
813     {
814       errmsg ("missing sub_id");
815       return -99;
816     }
817   M (CREATE_SUBIF, mp);
818
819   mp->sw_if_index = ntohl (sw_if_index);
820   mp->sub_id = ntohl (sub_id);
821
822 #define _(a, b) mp->sub_if_flags |= (1 << a);
823   foreach_create_subif_flag;
824 #undef _
825
826   mp->outer_vlan_id = ntohs (outer_vlan_id);
827   mp->inner_vlan_id = ntohs (inner_vlan_id);
828
829   S (mp);
830   W (ret);
831   return ret;
832 }
833
834 static void
835 vl_api_sw_interface_rx_placement_details_t_handler (
836   vl_api_sw_interface_rx_placement_details_t *mp)
837 {
838   vat_main_t *vam = interface_test_main.vat_main;
839   u32 worker_id = ntohl (mp->worker_id);
840
841   print (vam->ofp, "\n%-11d %-11s %-6d %-5d %-9s", ntohl (mp->sw_if_index),
842          (worker_id == 0) ? "main" : "worker", worker_id, ntohl (mp->queue_id),
843          (mp->mode == 1) ? "polling" :
844                            ((mp->mode == 2) ? "interrupt" : "adaptive"));
845 }
846
847 static void
848 vl_api_create_vlan_subif_reply_t_handler (vl_api_create_vlan_subif_reply_t *mp)
849 {
850   vat_main_t *vam = interface_test_main.vat_main;
851   vam->result_ready = 1;
852 }
853
854 static void
855 vl_api_create_loopback_reply_t_handler (vl_api_create_loopback_reply_t *mp)
856 {
857   vat_main_t *vam = interface_test_main.vat_main;
858   vam->result_ready = 1;
859 }
860
861 static void
862 vl_api_create_loopback_instance_reply_t_handler (
863   vl_api_create_loopback_instance_reply_t *mp)
864 {
865   vat_main_t *vam = interface_test_main.vat_main;
866   vam->result_ready = 1;
867 }
868
869 static int
870 api_create_vlan_subif (vat_main_t *vam)
871 {
872   unformat_input_t *i = vam->input;
873   vl_api_create_vlan_subif_t *mp;
874   u32 sw_if_index;
875   u8 sw_if_index_set = 0;
876   u32 vlan_id;
877   u8 vlan_id_set = 0;
878   int ret;
879
880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
881     {
882       if (unformat (i, "sw_if_index %d", &sw_if_index))
883         sw_if_index_set = 1;
884       else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
885         sw_if_index_set = 1;
886       else if (unformat (i, "vlan %d", &vlan_id))
887         vlan_id_set = 1;
888       else
889         {
890           clib_warning ("parse error '%U'", format_unformat_error, i);
891           return -99;
892         }
893     }
894
895   if (sw_if_index_set == 0)
896     {
897       errmsg ("missing interface name or sw_if_index");
898       return -99;
899     }
900
901   if (vlan_id_set == 0)
902     {
903       errmsg ("missing vlan_id");
904       return -99;
905     }
906   M (CREATE_VLAN_SUBIF, mp);
907
908   mp->sw_if_index = ntohl (sw_if_index);
909   mp->vlan_id = ntohl (vlan_id);
910
911   S (mp);
912   W (ret);
913   return ret;
914 }
915
916 static int
917 api_collect_detailed_interface_stats (vat_main_t *vam)
918 {
919   return -1;
920 }
921
922 static int
923 api_sw_interface_rx_placement_dump (vat_main_t *vam)
924 {
925   unformat_input_t *i = vam->input;
926   vl_api_sw_interface_rx_placement_dump_t *mp;
927   vl_api_control_ping_t *mp_ping;
928   int ret;
929   u32 sw_if_index;
930   u8 sw_if_index_set = 0;
931
932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
933     {
934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
935         sw_if_index_set++;
936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
937         sw_if_index_set++;
938       else
939         break;
940     }
941
942   fformat (vam->ofp, "\n%-11s %-11s %-6s %-5s %-4s", "sw_if_index",
943            "main/worker", "thread", "queue", "mode");
944
945   /* Dump Interface rx placement */
946   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
947
948   if (sw_if_index_set)
949     mp->sw_if_index = htonl (sw_if_index);
950   else
951     mp->sw_if_index = ~0;
952
953   S (mp);
954
955   /* Use a control ping for synchronization */
956   PING (&interface_test_main, mp_ping);
957   S (mp_ping);
958
959   W (ret);
960   return ret;
961 }
962
963 static int
964 api_sw_interface_clear_stats (vat_main_t *vam)
965 {
966   unformat_input_t *i = vam->input;
967   vl_api_sw_interface_clear_stats_t *mp;
968   u32 sw_if_index;
969   u8 sw_if_index_set = 0;
970   int ret;
971
972   /* Parse args required to build the message */
973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
974     {
975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
976         sw_if_index_set = 1;
977       else if (unformat (i, "sw_if_index %d", &sw_if_index))
978         sw_if_index_set = 1;
979       else
980         break;
981     }
982
983   /* Construct the API message */
984   M (SW_INTERFACE_CLEAR_STATS, mp);
985
986   if (sw_if_index_set == 1)
987     mp->sw_if_index = ntohl (sw_if_index);
988   else
989     mp->sw_if_index = ~0;
990
991   /* send it... */
992   S (mp);
993
994   /* Wait for a reply, return the good/bad news... */
995   W (ret);
996   return ret;
997 }
998
999 static int
1000 api_sw_interface_set_table (vat_main_t *vam)
1001 {
1002   unformat_input_t *i = vam->input;
1003   vl_api_sw_interface_set_table_t *mp;
1004   u32 sw_if_index, vrf_id = 0;
1005   u8 sw_if_index_set = 0;
1006   u8 is_ipv6 = 0;
1007   int ret;
1008
1009   /* Parse args required to build the message */
1010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1011     {
1012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1013         sw_if_index_set = 1;
1014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
1015         sw_if_index_set = 1;
1016       else if (unformat (i, "vrf %d", &vrf_id))
1017         ;
1018       else if (unformat (i, "ipv6"))
1019         is_ipv6 = 1;
1020       else
1021         break;
1022     }
1023
1024   if (sw_if_index_set == 0)
1025     {
1026       errmsg ("missing interface name or sw_if_index");
1027       return -99;
1028     }
1029
1030   /* Construct the API message */
1031   M (SW_INTERFACE_SET_TABLE, mp);
1032
1033   mp->sw_if_index = ntohl (sw_if_index);
1034   mp->is_ipv6 = is_ipv6;
1035   mp->vrf_id = ntohl (vrf_id);
1036
1037   /* send it... */
1038   S (mp);
1039
1040   /* Wait for a reply... */
1041   W (ret);
1042   return ret;
1043 }
1044
1045 static int
1046 api_sw_interface_address_replace_end (vat_main_t *vam)
1047 {
1048   return -1;
1049 }
1050
1051 static int
1052 api_sw_interface_set_ip_directed_broadcast (vat_main_t *vam)
1053 {
1054   return -1;
1055 }
1056
1057 static int
1058 api_sw_interface_set_mtu (vat_main_t *vam)
1059 {
1060   return -1;
1061 }
1062
1063 static int
1064 api_sw_interface_set_promisc (vat_main_t *vam)
1065 {
1066   return -1;
1067 }
1068
1069 static int
1070 api_want_interface_events (vat_main_t *vam)
1071 {
1072   unformat_input_t *i = vam->input;
1073   vl_api_want_interface_events_t *mp;
1074   int enable = -1;
1075   int ret;
1076
1077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1078     {
1079       if (unformat (i, "enable"))
1080         enable = 1;
1081       else if (unformat (i, "disable"))
1082         enable = 0;
1083       else
1084         break;
1085     }
1086
1087   if (enable == -1)
1088     {
1089       errmsg ("missing enable|disable");
1090       return -99;
1091     }
1092
1093   M (WANT_INTERFACE_EVENTS, mp);
1094   mp->enable_disable = enable;
1095
1096   vam->interface_event_display = enable;
1097
1098   S (mp);
1099   W (ret);
1100   return ret;
1101 }
1102
1103 typedef struct
1104 {
1105   u8 *name;
1106   u32 value;
1107 } name_sort_t;
1108
1109 int
1110 api_sw_interface_dump (vat_main_t *vam)
1111 {
1112   vl_api_sw_interface_dump_t *mp;
1113   vl_api_control_ping_t *mp_ping;
1114   hash_pair_t *p;
1115   name_sort_t *nses = 0, *ns;
1116   sw_interface_subif_t *sub = NULL;
1117   int ret;
1118
1119   /* Toss the old name table */
1120   hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({
1121                        vec_add2 (nses, ns, 1);
1122                        ns->name = (u8 *) (p->key);
1123                        ns->value = (u32) p->value[0];
1124                      }));
1125
1126   hash_free (vam->sw_if_index_by_interface_name);
1127
1128   vec_foreach (ns, nses)
1129     vec_free (ns->name);
1130
1131   vec_free (nses);
1132
1133   vec_foreach (sub, vam->sw_if_subif_table)
1134     {
1135       vec_free (sub->interface_name);
1136     }
1137   vec_free (vam->sw_if_subif_table);
1138
1139   /* recreate the interface name hash table */
1140   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
1141
1142   /*
1143    * Ask for all interface names. Otherwise, the epic catalog of
1144    * name filters becomes ridiculously long, and vat ends up needing
1145    * to be taught about new interface types.
1146    */
1147   M (SW_INTERFACE_DUMP, mp);
1148   S (mp);
1149
1150   /* Use a control ping for synchronization */
1151   PING (&interface_test_main, mp_ping);
1152   S (mp_ping);
1153
1154   W (ret);
1155   return ret;
1156 }
1157
1158 static int
1159 api_sw_interface_set_interface_name (vat_main_t *vam)
1160 {
1161   return -1;
1162 }
1163
1164 #include <vnet/interface.api_test.c>
1165
1166 /*
1167  * Local Variables:
1168  * eval: (c-set-style "gnu")
1169  * End:
1170  */