2 * Copyright (c) 2017 Intel and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include <vlibapi/api.h>
19 #include <vlibmemory/api.h>
20 #include <vppinfra/error.h>
21 #include <gtpu/gtpu.h>
22 #include <vnet/ip/ip_types_api.h>
24 #define __plugin_msg_base gtpu_test_main.msg_id_base
25 #include <vlibapi/vat_helper_macros.h>
27 #include <vnet/format_fns.h>
28 #include <gtpu/gtpu.api_enum.h>
29 #include <gtpu/gtpu.api_types.h>
31 uword unformat_ip46_address (unformat_input_t * input, va_list * args)
33 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
34 ip46_type_t type = va_arg (*args, ip46_type_t);
35 if ((type != IP46_TYPE_IP6) &&
36 unformat(input, "%U", unformat_ip4_address, &ip46->ip4)) {
37 ip46_address_mask_ip4(ip46);
39 } else if ((type != IP46_TYPE_IP4) &&
40 unformat(input, "%U", unformat_ip6_address, &ip46->ip6)) {
45 uword unformat_ip46_prefix (unformat_input_t * input, va_list * args)
47 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
48 u8 *len = va_arg (*args, u8 *);
49 ip46_type_t type = va_arg (*args, ip46_type_t);
52 if ((type != IP46_TYPE_IP6) && unformat(input, "%U/%u", unformat_ip4_address, &ip46->ip4, &l)) {
56 ip46->pad[0] = ip46->pad[1] = ip46->pad[2] = 0;
57 } else if ((type != IP46_TYPE_IP4) && unformat(input, "%U/%u", unformat_ip6_address, &ip46->ip6, &l)) {
66 /////////////////////////
69 /* API message ID base */
74 gtpu_test_main_t gtpu_test_main;
76 static void vl_api_gtpu_add_del_tunnel_reply_t_handler
77 (vl_api_gtpu_add_del_tunnel_reply_t * mp)
79 vat_main_t *vam = &vat_main;
80 i32 retval = ntohl (mp->retval);
83 vam->async_errors += (retval < 0);
88 vam->sw_if_index = ntohl (mp->sw_if_index);
89 vam->result_ready = 1;
94 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
100 api_sw_interface_set_gtpu_bypass (vat_main_t * vam)
102 unformat_input_t *i = vam->input;
103 vl_api_sw_interface_set_gtpu_bypass_t *mp;
105 u8 sw_if_index_set = 0;
110 /* Parse args required to build the message */
111 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
113 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
115 else if (unformat (i, "sw_if_index %d", &sw_if_index))
117 else if (unformat (i, "enable"))
119 else if (unformat (i, "disable"))
121 else if (unformat (i, "ip4"))
123 else if (unformat (i, "ip6"))
129 if (sw_if_index_set == 0)
131 errmsg ("missing interface name or sw_if_index");
135 /* Construct the API message */
136 M (SW_INTERFACE_SET_GTPU_BYPASS, mp);
138 mp->sw_if_index = ntohl (sw_if_index);
139 mp->enable = is_enable;
140 mp->is_ipv6 = is_ipv6;
145 /* Wait for a reply... */
150 static uword unformat_gtpu_decap_next
151 (unformat_input_t * input, va_list * args)
153 u32 *result = va_arg (*args, u32 *);
156 if (unformat (input, "l2"))
157 *result = GTPU_INPUT_NEXT_L2_INPUT;
158 else if (unformat (input, "%d", &tmp))
166 api_gtpu_offload_rx (vat_main_t * vam)
168 unformat_input_t *line_input = vam->input;
169 vl_api_gtpu_offload_rx_t *mp;
170 u32 rx_sw_if_index = ~0;
171 u32 hw_if_index = ~0;
175 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
177 if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam, &hw_if_index))
180 if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
183 if (unformat (line_input, "del"))
190 errmsg ("parse error '%U'", format_unformat_error, line_input);
195 if (rx_sw_if_index == ~0)
197 errmsg ("missing rx interface");
201 if (hw_if_index == ~0)
203 errmsg ("missing hw interface");
207 M (GTPU_OFFLOAD_RX, mp);
208 mp->hw_if_index = ntohl (hw_if_index);
209 mp->sw_if_index = ntohl (rx_sw_if_index);
218 api_gtpu_add_del_tunnel (vat_main_t * vam)
220 unformat_input_t *line_input = vam->input;
221 vl_api_gtpu_add_del_tunnel_t *mp;
222 ip46_address_t src, dst;
224 u8 ipv4_set = 0, ipv6_set = 0;
228 u32 mcast_sw_if_index = ~0;
229 u32 encap_vrf_id = 0;
230 u32 decap_next_index = ~0;
231 u32 teid = 0, tteid = 0;
234 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
235 clib_memset (&src, 0, sizeof src);
236 clib_memset (&dst, 0, sizeof dst);
238 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
240 if (unformat (line_input, "del"))
243 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
249 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
255 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
261 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
266 else if (unformat (line_input, "group %U %U",
267 unformat_ip4_address, &dst.ip4,
268 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
270 grp_set = dst_set = 1;
273 else if (unformat (line_input, "group %U",
274 unformat_ip4_address, &dst.ip4))
276 grp_set = dst_set = 1;
279 else if (unformat (line_input, "group %U %U",
280 unformat_ip6_address, &dst.ip6,
281 api_unformat_sw_if_index, vam, &mcast_sw_if_index))
283 grp_set = dst_set = 1;
286 else if (unformat (line_input, "group %U",
287 unformat_ip6_address, &dst.ip6))
289 grp_set = dst_set = 1;
293 if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
295 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
297 else if (unformat (line_input, "decap-next %U",
298 unformat_gtpu_decap_next, &decap_next_index))
300 else if (unformat (line_input, "teid %d", &teid))
302 else if (unformat (line_input, "tteid %d", &tteid))
306 errmsg ("parse error '%U'", format_unformat_error, line_input);
311 if (is_add && src_set == 0)
313 errmsg ("tunnel src address not specified");
318 errmsg ("tunnel dst address not specified");
322 if (grp_set && !ip46_address_is_multicast (&dst))
324 errmsg ("tunnel group address not multicast");
327 if (grp_set && mcast_sw_if_index == ~0)
329 errmsg ("tunnel nonexistent multicast device");
332 if (grp_set == 0 && ip46_address_is_multicast (&dst))
334 errmsg ("tunnel dst address must be unicast");
339 if (ipv4_set && ipv6_set)
341 errmsg ("both IPv4 and IPv6 addresses specified");
345 M (GTPU_ADD_DEL_TUNNEL, mp);
347 ip_address_encode(&src, ipv6_set ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
349 ip_address_encode(&dst, ipv6_set ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
351 mp->encap_vrf_id = ntohl (encap_vrf_id);
352 mp->decap_next_index = ntohl (decap_next_index);
353 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
354 mp->teid = ntohl (teid);
355 mp->tteid = ntohl (tteid);
364 vl_api_gtpu_add_del_tunnel_v2_reply_t_handler (
365 vl_api_gtpu_add_del_tunnel_v2_reply_t *mp)
367 vat_main_t *vam = &vat_main;
368 i32 retval = ntohl (mp->retval);
371 vam->async_errors += (retval < 0);
375 vam->retval = retval;
376 vam->sw_if_index = ntohl (mp->sw_if_index);
377 vam->result_ready = 1;
382 api_gtpu_add_del_tunnel_v2 (vat_main_t *vam)
384 unformat_input_t *line_input = vam->input;
385 vl_api_gtpu_add_del_tunnel_v2_t *mp;
386 ip46_address_t src, dst;
388 u8 ipv4_set = 0, ipv6_set = 0;
392 u32 mcast_sw_if_index = ~0;
393 u32 encap_vrf_id = 0;
394 u32 decap_next_index = ~0;
395 u32 teid = 0, tteid = 0;
396 u8 pdu_extension = 0;
400 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
401 clib_memset (&src, 0, sizeof src);
402 clib_memset (&dst, 0, sizeof dst);
404 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
406 if (unformat (line_input, "del"))
408 else if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
413 else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
418 else if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
423 else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
428 else if (unformat (line_input, "group %U %U", unformat_ip4_address,
429 &dst.ip4, api_unformat_sw_if_index, vam,
432 grp_set = dst_set = 1;
435 else if (unformat (line_input, "group %U", unformat_ip4_address,
438 grp_set = dst_set = 1;
441 else if (unformat (line_input, "group %U %U", unformat_ip6_address,
442 &dst.ip6, api_unformat_sw_if_index, vam,
445 grp_set = dst_set = 1;
448 else if (unformat (line_input, "group %U", unformat_ip6_address,
451 grp_set = dst_set = 1;
454 else if (unformat (line_input, "mcast_sw_if_index %u",
457 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
459 else if (unformat (line_input, "decap-next %U", unformat_gtpu_decap_next,
462 else if (unformat (line_input, "teid %d", &teid)) /* Change to %u ? */
464 else if (unformat (line_input, "tteid %d", &tteid)) /* Change to %u ? */
466 else if (unformat (line_input, "qfi %u", &qfi))
470 errmsg ("parse error '%U'", format_unformat_error, line_input);
475 if (is_add && src_set == 0)
477 errmsg ("tunnel src address not specified");
482 errmsg ("tunnel dst address not specified");
486 if (grp_set && !ip46_address_is_multicast (&dst))
488 errmsg ("tunnel group address not multicast");
491 if (grp_set && mcast_sw_if_index == ~0)
493 errmsg ("tunnel nonexistent multicast device");
496 if (grp_set == 0 && ip46_address_is_multicast (&dst))
498 errmsg ("tunnel dst address must be unicast");
502 if (ipv4_set && ipv6_set)
504 errmsg ("both IPv4 and IPv6 addresses specified");
509 errmsg ("qfi max value is 31");
513 M (GTPU_ADD_DEL_TUNNEL_V2, mp);
515 ip_address_encode (&src, ipv6_set ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
517 ip_address_encode (&dst, ipv6_set ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
519 mp->encap_vrf_id = ntohl (encap_vrf_id);
520 mp->decap_next_index = ntohl (decap_next_index);
521 mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
522 mp->teid = ntohl (teid);
523 mp->tteid = ntohl (tteid);
525 mp->pdu_extension = pdu_extension;
526 mp->qfi = ntohl (qfi);
533 api_gtpu_tunnel_update_tteid (vat_main_t * vam)
535 unformat_input_t *line_input = vam->input;
536 vl_api_gtpu_tunnel_update_tteid_t *mp;
540 u32 encap_vrf_id = 0;
541 u32 teid = 0, tteid = 0;
544 /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
545 clib_memset (&dst, 0, sizeof dst);
547 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
549 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
553 else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
558 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
560 else if (unformat (line_input, "teid %d", &teid))
562 else if (unformat (line_input, "tteid %d", &tteid))
566 errmsg ("parse error '%U'", format_unformat_error, line_input);
573 errmsg ("tunnel dst address not specified");
577 M (GTPU_TUNNEL_UPDATE_TTEID, mp);
579 ip_address_encode(&dst, ipv6_set ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
581 mp->encap_vrf_id = ntohl (encap_vrf_id);
582 mp->teid = ntohl (teid);
583 mp->tteid = ntohl (tteid);
590 static void vl_api_gtpu_tunnel_details_t_handler
591 (vl_api_gtpu_tunnel_details_t * mp)
593 vat_main_t *vam = &vat_main;
596 ip_address_decode(&mp->dst_address, &dst);
597 ip_address_decode(&mp->src_address, &src);
598 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%13d%19d",
599 ntohl (mp->sw_if_index),
600 format_ip46_address, &src, IP46_TYPE_ANY,
601 format_ip46_address, &dst, IP46_TYPE_ANY,
602 ntohl (mp->encap_vrf_id),
603 ntohl (mp->decap_next_index),
604 ntohl (mp->teid), ntohl (mp->tteid),
605 ntohl (mp->mcast_sw_if_index));
609 vl_api_gtpu_tunnel_v2_details_t_handler (vl_api_gtpu_tunnel_v2_details_t *mp)
611 vat_main_t *vam = &vat_main;
614 ip_address_decode (&mp->dst_address, &dst);
615 ip_address_decode (&mp->src_address, &src);
616 print (vam->ofp, "%11d%24U%24U%14d%18d%13d%13d%19d%15d%5d%15d%17d",
617 ntohl (mp->sw_if_index), format_ip46_address, &src, IP46_TYPE_ANY,
618 format_ip46_address, &dst, IP46_TYPE_ANY, ntohl (mp->encap_vrf_id),
619 ntohl (mp->decap_next_index), ntohl (mp->teid), ntohl (mp->tteid),
620 ntohl (mp->mcast_sw_if_index), mp->pdu_extension, mp->qfi,
621 mp->is_forwarding, ntohl (mp->forwarding_type));
625 vl_api_gtpu_add_del_forward_reply_t_handler (
626 vl_api_gtpu_add_del_forward_reply_t *mp)
628 vat_main_t *vam = &vat_main;
629 i32 retval = ntohl (mp->retval);
632 vam->async_errors += (retval < 0);
636 vam->retval = retval;
637 vam->sw_if_index = ntohl (mp->sw_if_index);
638 vam->result_ready = 1;
643 api_gtpu_tunnel_dump (vat_main_t * vam)
645 unformat_input_t *i = vam->input;
646 vl_api_gtpu_tunnel_dump_t *mp;
648 u8 sw_if_index_set = 0;
650 /* Parse args required to build the message */
651 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
653 if (unformat (i, "sw_if_index %d", &sw_if_index))
659 if (sw_if_index_set == 0)
664 if (!vam->json_output)
666 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%13s%19s",
667 "sw_if_index", "src_address", "dst_address",
668 "encap_vrf_id", "decap_next_index", "teid", "tteid",
669 "mcast_sw_if_index");
672 /* Get list of gtpu-tunnel interfaces */
673 M (GTPU_TUNNEL_DUMP, mp);
675 mp->sw_if_index = htonl (sw_if_index);
679 /* No status response for this API call.
680 * Wait 1 sec for any dump output before return to vat# */
687 api_gtpu_tunnel_v2_dump (vat_main_t *vam)
689 unformat_input_t *i = vam->input;
690 vl_api_gtpu_tunnel_dump_t *mp;
692 u8 sw_if_index_set = 0;
694 /* Parse args required to build the message */
695 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
697 if (unformat (i, "sw_if_index %d", &sw_if_index))
703 if (sw_if_index_set == 0)
708 if (!vam->json_output)
710 print (vam->ofp, "%11s%24s%24s%14s%18s%13s%13s%19s%12s%5s%15s%17s",
711 "sw_if_index", "src_address", "dst_address", "encap_vrf_id",
712 "decap_next_index", "teid", "tteid", "mcast_sw_if_index",
713 "pdu_extension", "qfi", "is_forwarding", "forwarding_type");
716 /* Get list of gtpu-tunnel interfaces */
717 M (GTPU_TUNNEL_DUMP, mp);
719 mp->sw_if_index = htonl (sw_if_index);
723 /* No status response for this API call.
724 * Wait 1 sec for any dump output before return to vat# */
731 api_gtpu_add_del_forward (vat_main_t *vam)
733 unformat_input_t *line_input = vam->input;
734 vl_api_gtpu_add_del_forward_t *mp;
736 u32 decap_next_index = GTPU_INPUT_NEXT_L2_INPUT;
744 /* Cant "universally zero init" (={0}) due to GCC bug 53119 */
745 clib_memset (&dst, 0, sizeof dst);
747 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
749 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
751 else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
756 else if (unformat (line_input, "decap-next %U", unformat_gtpu_decap_next,
759 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
761 else if (unformat (line_input, "del"))
763 else if (unformat (line_input, "bad-header"))
764 type |= GTPU_FORWARD_BAD_HEADER;
765 else if (unformat (line_input, "unknown-teid"))
766 type |= GTPU_FORWARD_UNKNOWN_TEID;
767 else if (unformat (line_input, "unknown-type"))
768 type |= GTPU_FORWARD_UNKNOWN_TYPE;
771 errmsg ("parse error '%U'", format_unformat_error, line_input);
778 errmsg ("dst must be set to a valid IP address");
782 M (GTPU_ADD_DEL_FORWARD, mp);
785 ip_address_encode (&dst, ipv6_set ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
787 mp->forwarding_type = type;
788 mp->encap_vrf_id = ntohl (encap_vrf_id);
789 mp->decap_next_index = ntohl (decap_next_index);
797 api_gtpu_get_transfer_counts (vat_main_t *vam)
799 unformat_input_t *line_input = vam->input;
800 vl_api_gtpu_get_transfer_counts_t *mp;
805 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
807 if (unformat (line_input, "start_index %u", &start_index))
809 else if (unformat (line_input, "capacity %u", &capacity))
813 errmsg ("parse error '%U'", format_unformat_error, line_input);
818 M (GTPU_GET_TRANSFER_COUNTS, mp);
819 mp->sw_if_index_start = start_index;
820 mp->capacity = capacity;
822 S (mp); // TODO: Handle the prints somehow. But how is it done??
828 vl_api_gtpu_get_transfer_counts_reply_t_handler (
829 vl_api_gtpu_get_transfer_counts_reply_t *mp)
831 vat_main_t *vam = &vat_main;
832 i32 retval = ntohl (mp->retval);
835 vam->async_errors += (retval < 0);
839 vam->retval = retval;
840 // TODO: Add reply here?
841 vam->result_ready = 1;
845 #include <gtpu/gtpu.api_test.c>