2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
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.
16 *------------------------------------------------------------------
17 * acl_test.c - test harness plugin
18 *------------------------------------------------------------------
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vppinfra/error.h>
25 #include <vnet/ip/ip.h>
26 #include <arpa/inet.h>
28 #define __plugin_msg_base acl_test_main.msg_id_base
29 #include <vlibapi/vat_helper_macros.h>
31 uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
33 /* Declare message IDs */
34 #include <acl/acl_msg_enum.h>
36 /* define message structures */
38 #include <acl/acl_all_api_h.h>
41 /* define message structures */
43 #include <acl/acl_all_api_h.h>
46 /* instantiate all the print functions we know about */
47 #define vl_print(handle, ...)
49 #include <acl/acl_all_api_h.h>
52 /* Get the API version number. */
53 #define vl_api_version(n,v) static u32 api_version=(v);
54 #include <acl/acl_all_api_h.h>
58 /* API message ID base */
63 acl_test_main_t acl_test_main;
65 #define foreach_standard_reply_retval_handler \
67 _(acl_interface_add_del_reply) \
68 _(macip_acl_interface_add_del_reply) \
69 _(acl_interface_set_acl_list_reply) \
70 _(acl_interface_set_etype_whitelist_reply) \
71 _(macip_acl_del_reply)
73 #define foreach_reply_retval_aclindex_handler \
74 _(acl_add_replace_reply) \
75 _(macip_acl_add_reply) \
76 _(macip_acl_add_replace_reply)
79 static void vl_api_##n##_t_handler \
80 (vl_api_##n##_t * mp) \
82 vat_main_t * vam = acl_test_main.vat_main; \
83 i32 retval = ntohl(mp->retval); \
84 if (vam->async_mode) { \
85 vam->async_errors += (retval < 0); \
87 vam->retval = retval; \
88 vam->result_ready = 1; \
91 foreach_standard_reply_retval_handler;
95 static void vl_api_##n##_t_handler \
96 (vl_api_##n##_t * mp) \
98 vat_main_t * vam = acl_test_main.vat_main; \
99 i32 retval = ntohl(mp->retval); \
100 if (vam->async_mode) { \
101 vam->async_errors += (retval < 0); \
103 clib_warning("ACL index: %d", ntohl(mp->acl_index)); \
104 vam->retval = retval; \
105 vam->result_ready = 1; \
108 foreach_reply_retval_aclindex_handler;
111 /* These two ought to be in a library somewhere but they aren't */
113 my_unformat_mac_address (unformat_input_t * input, va_list * args)
115 u8 *a = va_arg (*args, u8 *);
116 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
121 my_format_mac_address (u8 * s, va_list * args)
123 u8 *a = va_arg (*args, u8 *);
124 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
125 a[0], a[1], a[2], a[3], a[4], a[5]);
130 static void vl_api_acl_plugin_get_version_reply_t_handler
131 (vl_api_acl_plugin_get_version_reply_t * mp)
133 vat_main_t * vam = acl_test_main.vat_main;
134 clib_warning("ACL plugin version: %d.%d", ntohl(mp->major), ntohl(mp->minor));
135 vam->result_ready = 1;
138 static void vl_api_acl_interface_list_details_t_handler
139 (vl_api_acl_interface_list_details_t * mp)
142 vat_main_t * vam = acl_test_main.vat_main;
144 vl_api_acl_interface_list_details_t_endian(mp);
145 out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
146 out = format(out, " input ");
147 for(i=0; i<mp->count; i++) {
148 if (i == mp->n_input)
149 out = format(out, "\n output ");
150 out = format(out, "%d ", ntohl (mp->acls[i]));
152 out = format(out, "\n");
153 clib_warning("%s", out);
155 vam->result_ready = 1;
160 vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a)
162 int af = a->is_ipv6 ? AF_INET6 : AF_INET;
163 u8 src[INET6_ADDRSTRLEN];
164 u8 dst[INET6_ADDRSTRLEN];
165 inet_ntop(af, a->src_ip_addr, (void *)src, sizeof(src));
166 inet_ntop(af, a->dst_ip_addr, (void *)dst, sizeof(dst));
168 out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d mask %d",
169 a->is_ipv6 ? "ipv6" : "ipv4", a->is_permit,
170 src, a->src_ip_prefix_len,
171 dst, a->dst_ip_prefix_len,
173 a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
174 a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
175 a->tcp_flags_value, a->tcp_flags_mask);
181 static void vl_api_acl_details_t_handler
182 (vl_api_acl_details_t * mp)
185 vat_main_t * vam = acl_test_main.vat_main;
186 vl_api_acl_details_t_endian(mp);
188 out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
189 for(i=0; i<mp->count; i++) {
190 out = format(out, " ");
191 out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]);
192 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
194 clib_warning("%s", out);
196 vam->result_ready = 1;
200 vl_api_macip_acl_rule_t_pretty_format (u8 *out, vl_api_macip_acl_rule_t * a)
202 int af = a->is_ipv6 ? AF_INET6 : AF_INET;
203 u8 src[INET6_ADDRSTRLEN];
204 inet_ntop(af, a->src_ip_addr, (void *)src, sizeof(src));
206 out = format(out, "%s action %d ip %s/%d mac %U mask %U",
207 a->is_ipv6 ? "ipv6" : "ipv4", a->is_permit,
208 src, a->src_ip_prefix_len,
209 my_format_mac_address, a->src_mac,
210 my_format_mac_address, a->src_mac_mask);
215 static void vl_api_macip_acl_details_t_handler
216 (vl_api_macip_acl_details_t * mp)
219 vat_main_t * vam = acl_test_main.vat_main;
220 vl_api_macip_acl_details_t_endian(mp);
221 u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
222 for(i=0; i<mp->count; i++) {
223 out = format(out, " ");
224 out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]);
225 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
227 clib_warning("%s", out);
229 vam->result_ready = 1;
232 static void vl_api_macip_acl_interface_get_reply_t_handler
233 (vl_api_macip_acl_interface_get_reply_t * mp)
236 vat_main_t * vam = acl_test_main.vat_main;
237 u8 *out = format(0, "sw_if_index with MACIP ACL count: %d\n", ntohl(mp->count));
238 for(i=0; i<ntohl(mp->count); i++) {
239 out = format(out, " macip_acl_interface_add_del sw_if_index %d add acl %d\n", i, ntohl(mp->acls[i]));
241 out = format(out, "\n");
242 clib_warning("%s", out);
244 vam->result_ready = 1;
247 static void vl_api_acl_plugin_control_ping_reply_t_handler
248 (vl_api_acl_plugin_control_ping_reply_t * mp)
250 vat_main_t *vam = &vat_main;
251 i32 retval = ntohl (mp->retval);
254 vam->async_errors += (retval < 0);
258 vam->retval = retval;
259 vam->result_ready = 1;
265 * Table of message reply handlers, must include boilerplate handlers
268 #define foreach_vpe_api_reply_msg \
269 _(ACL_ADD_REPLACE_REPLY, acl_add_replace_reply) \
270 _(ACL_DEL_REPLY, acl_del_reply) \
271 _(ACL_INTERFACE_ADD_DEL_REPLY, acl_interface_add_del_reply) \
272 _(ACL_INTERFACE_SET_ACL_LIST_REPLY, acl_interface_set_acl_list_reply) \
273 _(ACL_INTERFACE_SET_ETYPE_WHITELIST_REPLY, acl_interface_set_etype_whitelist_reply) \
274 _(ACL_INTERFACE_LIST_DETAILS, acl_interface_list_details) \
275 _(ACL_DETAILS, acl_details) \
276 _(MACIP_ACL_ADD_REPLY, macip_acl_add_reply) \
277 _(MACIP_ACL_ADD_REPLACE_REPLY, macip_acl_add_replace_reply) \
278 _(MACIP_ACL_DEL_REPLY, macip_acl_del_reply) \
279 _(MACIP_ACL_DETAILS, macip_acl_details) \
280 _(MACIP_ACL_INTERFACE_ADD_DEL_REPLY, macip_acl_interface_add_del_reply) \
281 _(MACIP_ACL_INTERFACE_GET_REPLY, macip_acl_interface_get_reply) \
282 _(ACL_PLUGIN_CONTROL_PING_REPLY, acl_plugin_control_ping_reply) \
283 _(ACL_PLUGIN_GET_VERSION_REPLY, acl_plugin_get_version_reply)
285 static int api_acl_plugin_get_version (vat_main_t * vam)
287 acl_test_main_t * sm = &acl_test_main;
288 vl_api_acl_plugin_get_version_t * mp;
289 u32 msg_size = sizeof(*mp);
292 vam->result_ready = 0;
293 mp = vl_msg_api_alloc_as_if_client(msg_size);
294 memset (mp, 0, msg_size);
295 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base);
296 mp->client_index = vam->my_client_index;
301 /* Wait for a reply... */
306 static int api_macip_acl_interface_get (vat_main_t * vam)
308 acl_test_main_t * sm = &acl_test_main;
309 vl_api_acl_plugin_get_version_t * mp;
310 u32 msg_size = sizeof(*mp);
313 vam->result_ready = 0;
314 mp = vl_msg_api_alloc_as_if_client(msg_size);
315 memset (mp, 0, msg_size);
316 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_INTERFACE_GET + sm->msg_id_base);
317 mp->client_index = vam->my_client_index;
322 /* Wait for a reply... */
327 #define vec_validate_acl_rules(v, idx) \
329 if (vec_len(v) < idx+1) { \
330 vec_validate(v, idx); \
331 v[idx].is_permit = 0x1; \
332 v[idx].srcport_or_icmptype_last = 0xffff; \
333 v[idx].dstport_or_icmpcode_last = 0xffff; \
338 static int api_acl_add_replace (vat_main_t * vam)
340 acl_test_main_t * sm = &acl_test_main;
341 unformat_input_t * i = vam->input;
342 vl_api_acl_add_replace_t * mp;
344 u32 msg_size = sizeof (*mp); /* without the rules */
346 vl_api_acl_rule_t *rules = 0;
349 int n_rules_override = -1;
354 u32 tcpflags, tcpmask;
355 u32 src_prefix_length = 0, dst_prefix_length = 0;
356 ip4_address_t src_v4address, dst_v4address;
357 ip6_address_t src_v6address, dst_v6address;
361 if (!unformat (i, "%d", &acl_index)) {
365 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
367 if (unformat (i, "ipv6"))
369 vec_validate_acl_rules(rules, rule_idx);
370 rules[rule_idx].is_ipv6 = 1;
372 else if (unformat (i, "ipv4"))
374 vec_validate_acl_rules(rules, rule_idx);
375 rules[rule_idx].is_ipv6 = 0;
377 else if (unformat (i, "permit+reflect"))
379 vec_validate_acl_rules(rules, rule_idx);
380 rules[rule_idx].is_permit = 2;
382 else if (unformat (i, "permit"))
384 vec_validate_acl_rules(rules, rule_idx);
385 rules[rule_idx].is_permit = 1;
387 else if (unformat (i, "deny"))
389 vec_validate_acl_rules(rules, rule_idx);
390 rules[rule_idx].is_permit = 0;
392 else if (unformat (i, "count %d", &n_rules_override))
394 /* we will use this later */
396 else if (unformat (i, "action %d", &action))
398 vec_validate_acl_rules(rules, rule_idx);
399 rules[rule_idx].is_permit = action;
401 else if (unformat (i, "src %U/%d",
402 unformat_ip4_address, &src_v4address, &src_prefix_length))
404 vec_validate_acl_rules(rules, rule_idx);
405 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
406 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
407 rules[rule_idx].is_ipv6 = 0;
409 else if (unformat (i, "src %U/%d",
410 unformat_ip6_address, &src_v6address, &src_prefix_length))
412 vec_validate_acl_rules(rules, rule_idx);
413 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
414 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
415 rules[rule_idx].is_ipv6 = 1;
417 else if (unformat (i, "dst %U/%d",
418 unformat_ip4_address, &dst_v4address, &dst_prefix_length))
420 vec_validate_acl_rules(rules, rule_idx);
421 memcpy (rules[rule_idx].dst_ip_addr, &dst_v4address, 4);
422 rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
423 rules[rule_idx].is_ipv6 = 0;
425 else if (unformat (i, "dst %U/%d",
426 unformat_ip6_address, &dst_v6address, &dst_prefix_length))
428 vec_validate_acl_rules(rules, rule_idx);
429 memcpy (rules[rule_idx].dst_ip_addr, &dst_v6address, 16);
430 rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
431 rules[rule_idx].is_ipv6 = 1;
433 else if (unformat (i, "sport %d-%d", &port1, &port2))
435 vec_validate_acl_rules(rules, rule_idx);
436 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
437 rules[rule_idx].srcport_or_icmptype_last = htons(port2);
439 else if (unformat (i, "sport %d", &port1))
441 vec_validate_acl_rules(rules, rule_idx);
442 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
443 rules[rule_idx].srcport_or_icmptype_last = htons(port1);
445 else if (unformat (i, "dport %d-%d", &port1, &port2))
447 vec_validate_acl_rules(rules, rule_idx);
448 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
449 rules[rule_idx].dstport_or_icmpcode_last = htons(port2);
451 else if (unformat (i, "dport %d", &port1))
453 vec_validate_acl_rules(rules, rule_idx);
454 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
455 rules[rule_idx].dstport_or_icmpcode_last = htons(port1);
457 else if (unformat (i, "tcpflags %d %d", &tcpflags, &tcpmask))
459 vec_validate_acl_rules(rules, rule_idx);
460 rules[rule_idx].tcp_flags_value = tcpflags;
461 rules[rule_idx].tcp_flags_mask = tcpmask;
463 else if (unformat (i, "tcpflags %d mask %d", &tcpflags, &tcpmask))
465 vec_validate_acl_rules(rules, rule_idx);
466 rules[rule_idx].tcp_flags_value = tcpflags;
467 rules[rule_idx].tcp_flags_mask = tcpmask;
469 else if (unformat (i, "proto %d", &proto))
471 vec_validate_acl_rules(rules, rule_idx);
472 rules[rule_idx].proto = proto;
474 else if (unformat (i, "tag %s", &tag))
477 else if (unformat (i, ","))
480 vec_validate_acl_rules(rules, rule_idx);
486 /* Construct the API message */
487 vam->result_ready = 0;
490 n_rules = vec_len(rules);
494 if (n_rules_override >= 0)
495 n_rules = n_rules_override;
497 msg_size += n_rules*sizeof(rules[0]);
499 mp = vl_msg_api_alloc_as_if_client(msg_size);
500 memset (mp, 0, msg_size);
501 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
502 mp->client_index = vam->my_client_index;
503 if ((n_rules > 0) && rules)
504 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
507 if (vec_len(tag) >= sizeof(mp->tag))
509 tag[sizeof(mp->tag)-1] = 0;
510 _vec_len(tag) = sizeof(mp->tag);
512 clib_memcpy(mp->tag, tag, vec_len(tag));
515 mp->acl_index = ntohl(acl_index);
516 mp->count = htonl(n_rules);
521 /* Wait for a reply... */
526 static int api_acl_del (vat_main_t * vam)
528 unformat_input_t * i = vam->input;
529 vl_api_acl_del_t * mp;
533 if (!unformat (i, "%d", &acl_index)) {
534 errmsg ("missing acl index\n");
538 /* Construct the API message */
540 mp->acl_index = ntohl(acl_index);
545 /* Wait for a reply... */
550 static int api_macip_acl_del (vat_main_t * vam)
552 unformat_input_t * i = vam->input;
553 vl_api_acl_del_t * mp;
557 if (!unformat (i, "%d", &acl_index)) {
558 errmsg ("missing acl index\n");
562 /* Construct the API message */
563 M(MACIP_ACL_DEL, mp);
564 mp->acl_index = ntohl(acl_index);
569 /* Wait for a reply... */
574 static int api_acl_interface_add_del (vat_main_t * vam)
576 unformat_input_t * i = vam->input;
577 vl_api_acl_interface_add_del_t * mp;
578 u32 sw_if_index = ~0;
584 // acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del]
586 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
588 if (unformat (i, "%d", &acl_index))
595 /* Parse args required to build the message */
596 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
597 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
599 else if (unformat (i, "sw_if_index %d", &sw_if_index))
601 else if (unformat (i, "add"))
603 else if (unformat (i, "del"))
605 else if (unformat (i, "acl %d", &acl_index))
607 else if (unformat (i, "input"))
609 else if (unformat (i, "output"))
615 if (sw_if_index == ~0) {
616 errmsg ("missing interface name / explicit sw_if_index number \n");
620 if (acl_index == ~0) {
621 errmsg ("missing ACL index\n");
627 /* Construct the API message */
628 M(ACL_INTERFACE_ADD_DEL, mp);
629 mp->acl_index = ntohl(acl_index);
630 mp->sw_if_index = ntohl(sw_if_index);
632 mp->is_input = is_input;
637 /* Wait for a reply... */
642 static int api_macip_acl_interface_add_del (vat_main_t * vam)
644 unformat_input_t * i = vam->input;
645 vl_api_macip_acl_interface_add_del_t * mp;
646 u32 sw_if_index = ~0;
651 /* Parse args required to build the message */
652 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
653 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
655 else if (unformat (i, "sw_if_index %d", &sw_if_index))
657 else if (unformat (i, "add"))
659 else if (unformat (i, "del"))
661 else if (unformat (i, "acl %d", &acl_index))
667 if (sw_if_index == ~0) {
668 errmsg ("missing interface name / explicit sw_if_index number \n");
672 if (acl_index == ~0) {
673 errmsg ("missing ACL index\n");
679 /* Construct the API message */
680 M(MACIP_ACL_INTERFACE_ADD_DEL, mp);
681 mp->acl_index = ntohl(acl_index);
682 mp->sw_if_index = ntohl(sw_if_index);
688 /* Wait for a reply... */
693 static int api_acl_interface_set_acl_list (vat_main_t * vam)
695 unformat_input_t * i = vam->input;
696 vl_api_acl_interface_set_acl_list_t * mp;
697 u32 sw_if_index = ~0;
704 // acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]
706 /* Parse args required to build the message */
707 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
708 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
710 else if (unformat (i, "sw_if_index %d", &sw_if_index))
712 else if (unformat (i, "%d", &acl_index))
715 vec_add1(inacls, htonl(acl_index));
717 vec_add1(outacls, htonl(acl_index));
719 else if (unformat (i, "acl %d", &acl_index))
721 else if (unformat (i, "input"))
723 else if (unformat (i, "output"))
729 if (sw_if_index == ~0) {
730 errmsg ("missing interface name / explicit sw_if_index number \n");
734 /* Construct the API message */
735 M2(ACL_INTERFACE_SET_ACL_LIST, mp, sizeof(u32) * (vec_len(inacls) + vec_len(outacls)));
736 mp->sw_if_index = ntohl(sw_if_index);
737 mp->n_input = vec_len(inacls);
738 mp->count = vec_len(inacls) + vec_len(outacls);
739 vec_append(inacls, outacls);
740 if (vec_len(inacls) > 0)
741 clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32));
746 /* Wait for a reply... */
751 static int api_acl_interface_set_etype_whitelist (vat_main_t * vam)
753 unformat_input_t * i = vam->input;
754 vl_api_acl_interface_set_etype_whitelist_t * mp;
755 u32 sw_if_index = ~0;
762 // acl_interface_set_etype_whitelist <intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]
764 /* Parse args required to build the message */
765 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
766 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
768 else if (unformat (i, "sw_if_index %d", &sw_if_index))
770 else if (unformat (i, "%x", ðertype))
772 ethertype = ethertype & 0xffff;
774 vec_add1(etypes_in, htons(ethertype));
776 vec_add1(etypes_out, htons(ethertype));
778 else if (unformat (i, "input"))
780 else if (unformat (i, "output"))
786 if (sw_if_index == ~0) {
787 errmsg ("missing interface name / explicit sw_if_index number \n");
791 /* Construct the API message */
792 M2(ACL_INTERFACE_SET_ETYPE_WHITELIST, mp, sizeof(u32) * (vec_len(etypes_in) + vec_len(etypes_out)));
793 mp->sw_if_index = ntohl(sw_if_index);
794 mp->n_input = vec_len(etypes_in);
795 mp->count = vec_len(etypes_in) + vec_len(etypes_out);
796 vec_append(etypes_in, etypes_out);
797 if (vec_len(etypes_in) > 0)
798 clib_memcpy(mp->whitelist, etypes_in, vec_len(etypes_in)*sizeof(etypes_in[0]));
803 /* Wait for a reply... */
809 api_acl_send_control_ping(vat_main_t *vam)
811 vl_api_acl_plugin_control_ping_t *mp_ping;
813 M(ACL_PLUGIN_CONTROL_PING, mp_ping);
818 static int api_acl_interface_list_dump (vat_main_t * vam)
820 unformat_input_t * i = vam->input;
821 u32 sw_if_index = ~0;
822 vl_api_acl_interface_list_dump_t * mp;
825 /* Parse args required to build the message */
826 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
827 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
829 else if (unformat (i, "sw_if_index %d", &sw_if_index))
835 /* Construct the API message */
836 M(ACL_INTERFACE_LIST_DUMP, mp);
837 mp->sw_if_index = ntohl (sw_if_index);
842 /* Use control ping for synchronization */
843 api_acl_send_control_ping(vam);
845 /* Wait for a reply... */
850 static int api_acl_dump (vat_main_t * vam)
852 unformat_input_t * i = vam->input;
854 vl_api_acl_dump_t * mp;
857 /* Parse args required to build the message */
858 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
859 if (unformat (i, "%d", &acl_index))
865 /* Construct the API message */
867 mp->acl_index = ntohl (acl_index);
872 /* Use control ping for synchronization */
873 api_acl_send_control_ping(vam);
875 /* Wait for a reply... */
880 static int api_macip_acl_dump (vat_main_t * vam)
882 unformat_input_t * i = vam->input;
884 vl_api_acl_dump_t * mp;
887 /* Parse args required to build the message */
888 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
889 if (unformat (i, "%d", &acl_index))
895 /* Construct the API message */
896 M(MACIP_ACL_DUMP, mp);
897 mp->acl_index = ntohl (acl_index);
902 /* Use control ping for synchronization */
903 api_acl_send_control_ping(vam);
905 /* Wait for a reply... */
910 #define vec_validate_macip_acl_rules(v, idx) \
912 if (vec_len(v) < idx+1) { \
913 vec_validate(v, idx); \
914 v[idx].is_permit = 0x1; \
919 static int api_macip_acl_add (vat_main_t * vam)
921 acl_test_main_t * sm = &acl_test_main;
922 unformat_input_t * i = vam->input;
923 vl_api_macip_acl_add_t * mp;
924 u32 msg_size = sizeof (*mp); /* without the rules */
926 vl_api_macip_acl_rule_t *rules = 0;
929 int n_rules_override = -1;
930 u32 src_prefix_length = 0;
932 ip4_address_t src_v4address;
933 ip6_address_t src_v6address;
936 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
939 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
941 if (unformat (i, "ipv6"))
943 vec_validate_macip_acl_rules(rules, rule_idx);
944 rules[rule_idx].is_ipv6 = 1;
946 else if (unformat (i, "ipv4"))
948 vec_validate_macip_acl_rules(rules, rule_idx);
949 rules[rule_idx].is_ipv6 = 0;
951 else if (unformat (i, "permit"))
953 vec_validate_macip_acl_rules(rules, rule_idx);
954 rules[rule_idx].is_permit = 1;
956 else if (unformat (i, "deny"))
958 vec_validate_macip_acl_rules(rules, rule_idx);
959 rules[rule_idx].is_permit = 0;
961 else if (unformat (i, "count %d", &n_rules_override))
963 /* we will use this later */
965 else if (unformat (i, "action %d", &action))
967 vec_validate_macip_acl_rules(rules, rule_idx);
968 rules[rule_idx].is_permit = action;
970 else if (unformat (i, "ip %U/%d",
971 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
972 unformat (i, "ip %U",
973 unformat_ip4_address, &src_v4address))
975 if (src_prefix_length == 0)
976 src_prefix_length = 32;
977 vec_validate_macip_acl_rules(rules, rule_idx);
978 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
979 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
980 rules[rule_idx].is_ipv6 = 0;
982 else if (unformat (i, "src"))
984 /* Everything in MACIP is "source" but allow this verbosity */
986 else if (unformat (i, "ip %U/%d",
987 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
988 unformat (i, "ip %U",
989 unformat_ip6_address, &src_v6address))
991 if (src_prefix_length == 0)
992 src_prefix_length = 128;
993 vec_validate_macip_acl_rules(rules, rule_idx);
994 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
995 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
996 rules[rule_idx].is_ipv6 = 1;
998 else if (unformat (i, "mac %U",
999 my_unformat_mac_address, &src_mac))
1001 vec_validate_macip_acl_rules(rules, rule_idx);
1002 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1003 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1005 else if (unformat (i, "mask %U",
1006 my_unformat_mac_address, &src_mac))
1008 vec_validate_macip_acl_rules(rules, rule_idx);
1009 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1011 else if (unformat (i, "tag %s", &tag))
1014 else if (unformat (i, ","))
1017 vec_validate_macip_acl_rules(rules, rule_idx);
1023 /* Construct the API message */
1024 vam->result_ready = 0;
1027 n_rules = vec_len(rules);
1029 if (n_rules_override >= 0)
1030 n_rules = n_rules_override;
1032 msg_size += n_rules*sizeof(rules[0]);
1034 mp = vl_msg_api_alloc_as_if_client(msg_size);
1035 memset (mp, 0, msg_size);
1036 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD + sm->msg_id_base);
1037 mp->client_index = vam->my_client_index;
1038 if ((n_rules > 0) && rules)
1039 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1042 if (vec_len(tag) >= sizeof(mp->tag))
1044 tag[sizeof(mp->tag)-1] = 0;
1045 _vec_len(tag) = sizeof(mp->tag);
1047 clib_memcpy(mp->tag, tag, vec_len(tag));
1051 mp->count = htonl(n_rules);
1056 /* Wait for a reply... */
1061 static int api_macip_acl_add_replace (vat_main_t * vam)
1063 acl_test_main_t * sm = &acl_test_main;
1064 unformat_input_t * i = vam->input;
1065 vl_api_macip_acl_add_replace_t * mp;
1067 u32 msg_size = sizeof (*mp); /* without the rules */
1069 vl_api_macip_acl_rule_t *rules = 0;
1072 int n_rules_override = -1;
1073 u32 src_prefix_length = 0;
1075 ip4_address_t src_v4address;
1076 ip6_address_t src_v6address;
1079 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1082 if (!unformat (i, "%d", &acl_index)) {
1083 /* Just assume -1 */
1086 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1088 if (unformat (i, "ipv6"))
1090 vec_validate_macip_acl_rules(rules, rule_idx);
1091 rules[rule_idx].is_ipv6 = 1;
1093 else if (unformat (i, "ipv4"))
1095 vec_validate_macip_acl_rules(rules, rule_idx);
1096 rules[rule_idx].is_ipv6 = 0;
1098 else if (unformat (i, "permit"))
1100 vec_validate_macip_acl_rules(rules, rule_idx);
1101 rules[rule_idx].is_permit = 1;
1103 else if (unformat (i, "deny"))
1105 vec_validate_macip_acl_rules(rules, rule_idx);
1106 rules[rule_idx].is_permit = 0;
1108 else if (unformat (i, "count %d", &n_rules_override))
1110 /* we will use this later */
1112 else if (unformat (i, "action %d", &action))
1114 vec_validate_macip_acl_rules(rules, rule_idx);
1115 rules[rule_idx].is_permit = action;
1117 else if (unformat (i, "ip %U/%d",
1118 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1119 unformat (i, "ip %U",
1120 unformat_ip4_address, &src_v4address))
1122 if (src_prefix_length == 0)
1123 src_prefix_length = 32;
1124 vec_validate_macip_acl_rules(rules, rule_idx);
1125 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
1126 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1127 rules[rule_idx].is_ipv6 = 0;
1129 else if (unformat (i, "src"))
1131 /* Everything in MACIP is "source" but allow this verbosity */
1133 else if (unformat (i, "ip %U/%d",
1134 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1135 unformat (i, "ip %U",
1136 unformat_ip6_address, &src_v6address))
1138 if (src_prefix_length == 0)
1139 src_prefix_length = 128;
1140 vec_validate_macip_acl_rules(rules, rule_idx);
1141 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
1142 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1143 rules[rule_idx].is_ipv6 = 1;
1145 else if (unformat (i, "mac %U",
1146 my_unformat_mac_address, &src_mac))
1148 vec_validate_macip_acl_rules(rules, rule_idx);
1149 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1150 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1152 else if (unformat (i, "mask %U",
1153 my_unformat_mac_address, &src_mac))
1155 vec_validate_macip_acl_rules(rules, rule_idx);
1156 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1158 else if (unformat (i, "tag %s", &tag))
1161 else if (unformat (i, ","))
1164 vec_validate_macip_acl_rules(rules, rule_idx);
1172 errmsg ("rule/s required\n");
1175 /* Construct the API message */
1176 vam->result_ready = 0;
1179 n_rules = vec_len(rules);
1181 if (n_rules_override >= 0)
1182 n_rules = n_rules_override;
1184 msg_size += n_rules*sizeof(rules[0]);
1186 mp = vl_msg_api_alloc_as_if_client(msg_size);
1187 memset (mp, 0, msg_size);
1188 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
1189 mp->client_index = vam->my_client_index;
1190 if ((n_rules > 0) && rules)
1191 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1194 if (vec_len(tag) >= sizeof(mp->tag))
1196 tag[sizeof(mp->tag)-1] = 0;
1197 _vec_len(tag) = sizeof(mp->tag);
1199 clib_memcpy(mp->tag, tag, vec_len(tag));
1203 mp->acl_index = ntohl(acl_index);
1204 mp->count = htonl(n_rules);
1209 /* Wait for a reply... */
1215 * List of messages that the api test plugin sends,
1216 * and that the data plane plugin processes
1218 #define foreach_vpe_api_msg \
1219 _(acl_plugin_get_version, "") \
1220 _(acl_add_replace, "<acl-idx> [<ipv4|ipv6> <permit|permit+reflect|deny|action N> [src IP/plen] [dst IP/plen] [sport X-Y] [dport X-Y] [proto P] [tcpflags FL MASK], ... , ...") \
1221 _(acl_del, "<acl-idx>") \
1222 _(acl_dump, "[<acl-idx>]") \
1223 _(acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] [input|output] acl <acl-idx>") \
1224 _(acl_interface_set_acl_list, "<intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]") \
1225 _(acl_interface_set_etype_whitelist, "<intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]") \
1226 _(acl_interface_list_dump, "[<intfc> | sw_if_index <if-idx>]") \
1227 _(macip_acl_add, "...") \
1228 _(macip_acl_add_replace, "<acl-idx> [<ipv4|ipv6> <permit|deny|action N> [count <count>] [src] ip <ipaddress/[plen]> mac <mac> mask <mac_mask>, ... , ...") \
1229 _(macip_acl_del, "<acl-idx>")\
1230 _(macip_acl_dump, "[<acl-idx>]") \
1231 _(macip_acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] acl <acl-idx>") \
1232 _(macip_acl_interface_get, "")
1236 void acl_vat_api_hookup (vat_main_t *vam)
1238 acl_test_main_t * sm = &acl_test_main;
1239 /* Hook up handlers for replies from the data plane plug-in */
1241 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
1243 vl_api_##n##_t_handler, \
1245 vl_api_##n##_t_endian, \
1246 vl_api_##n##_t_print, \
1247 sizeof(vl_api_##n##_t), 1);
1248 foreach_vpe_api_reply_msg;
1251 /* API messages we can send */
1252 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
1253 foreach_vpe_api_msg;
1257 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
1258 foreach_vpe_api_msg;
1262 clib_error_t * vat_plugin_register (vat_main_t *vam)
1264 acl_test_main_t * sm = &acl_test_main;
1269 name = format (0, "acl_%08x%c", api_version, 0);
1270 sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
1272 if (sm->msg_id_base != (u16) ~0)
1273 acl_vat_api_hookup (vam);