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;
158 static void vl_api_acl_interface_etype_whitelist_details_t_handler
159 (vl_api_acl_interface_etype_whitelist_details_t * mp)
162 vat_main_t * vam = acl_test_main.vat_main;
164 vl_api_acl_interface_etype_whitelist_details_t_endian(mp);
165 out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
166 out = format(out, " input ");
167 for(i=0; i<mp->count; i++) {
168 if (i == mp->n_input)
169 out = format(out, "\n output ");
170 out = format(out, "%04x ", ntohs(mp->whitelist[i]));
172 out = format(out, "\n");
173 clib_warning("%s", out);
175 vam->result_ready = 1;
181 vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a)
183 int af = a->is_ipv6 ? AF_INET6 : AF_INET;
184 u8 src[INET6_ADDRSTRLEN];
185 u8 dst[INET6_ADDRSTRLEN];
186 inet_ntop(af, a->src_ip_addr, (void *)src, sizeof(src));
187 inet_ntop(af, a->dst_ip_addr, (void *)dst, sizeof(dst));
189 out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d mask %d",
190 a->is_ipv6 ? "ipv6" : "ipv4", a->is_permit,
191 src, a->src_ip_prefix_len,
192 dst, a->dst_ip_prefix_len,
194 a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
195 a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
196 a->tcp_flags_value, a->tcp_flags_mask);
202 static void vl_api_acl_details_t_handler
203 (vl_api_acl_details_t * mp)
206 vat_main_t * vam = acl_test_main.vat_main;
207 vl_api_acl_details_t_endian(mp);
209 out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
210 for(i=0; i<mp->count; i++) {
211 out = format(out, " ");
212 out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]);
213 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
215 clib_warning("%s", out);
217 vam->result_ready = 1;
221 vl_api_macip_acl_rule_t_pretty_format (u8 *out, vl_api_macip_acl_rule_t * a)
223 int af = a->is_ipv6 ? AF_INET6 : AF_INET;
224 u8 src[INET6_ADDRSTRLEN];
225 inet_ntop(af, a->src_ip_addr, (void *)src, sizeof(src));
227 out = format(out, "%s action %d ip %s/%d mac %U mask %U",
228 a->is_ipv6 ? "ipv6" : "ipv4", a->is_permit,
229 src, a->src_ip_prefix_len,
230 my_format_mac_address, a->src_mac,
231 my_format_mac_address, a->src_mac_mask);
236 static void vl_api_macip_acl_details_t_handler
237 (vl_api_macip_acl_details_t * mp)
240 vat_main_t * vam = acl_test_main.vat_main;
241 vl_api_macip_acl_details_t_endian(mp);
242 u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
243 for(i=0; i<mp->count; i++) {
244 out = format(out, " ");
245 out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]);
246 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
248 clib_warning("%s", out);
250 vam->result_ready = 1;
253 static void vl_api_macip_acl_interface_get_reply_t_handler
254 (vl_api_macip_acl_interface_get_reply_t * mp)
257 vat_main_t * vam = acl_test_main.vat_main;
258 u8 *out = format(0, "sw_if_index with MACIP ACL count: %d\n", ntohl(mp->count));
259 for(i=0; i<ntohl(mp->count); i++) {
260 out = format(out, " macip_acl_interface_add_del sw_if_index %d add acl %d\n", i, ntohl(mp->acls[i]));
262 out = format(out, "\n");
263 clib_warning("%s", out);
265 vam->result_ready = 1;
268 static void vl_api_acl_plugin_control_ping_reply_t_handler
269 (vl_api_acl_plugin_control_ping_reply_t * mp)
271 vat_main_t *vam = &vat_main;
272 i32 retval = ntohl (mp->retval);
275 vam->async_errors += (retval < 0);
279 vam->retval = retval;
280 vam->result_ready = 1;
286 * Table of message reply handlers, must include boilerplate handlers
289 #define foreach_vpe_api_reply_msg \
290 _(ACL_ADD_REPLACE_REPLY, acl_add_replace_reply) \
291 _(ACL_DEL_REPLY, acl_del_reply) \
292 _(ACL_INTERFACE_ADD_DEL_REPLY, acl_interface_add_del_reply) \
293 _(ACL_INTERFACE_SET_ACL_LIST_REPLY, acl_interface_set_acl_list_reply) \
294 _(ACL_INTERFACE_SET_ETYPE_WHITELIST_REPLY, acl_interface_set_etype_whitelist_reply) \
295 _(ACL_INTERFACE_ETYPE_WHITELIST_DETAILS, acl_interface_etype_whitelist_details) \
296 _(ACL_INTERFACE_LIST_DETAILS, acl_interface_list_details) \
297 _(ACL_DETAILS, acl_details) \
298 _(MACIP_ACL_ADD_REPLY, macip_acl_add_reply) \
299 _(MACIP_ACL_ADD_REPLACE_REPLY, macip_acl_add_replace_reply) \
300 _(MACIP_ACL_DEL_REPLY, macip_acl_del_reply) \
301 _(MACIP_ACL_DETAILS, macip_acl_details) \
302 _(MACIP_ACL_INTERFACE_ADD_DEL_REPLY, macip_acl_interface_add_del_reply) \
303 _(MACIP_ACL_INTERFACE_GET_REPLY, macip_acl_interface_get_reply) \
304 _(ACL_PLUGIN_CONTROL_PING_REPLY, acl_plugin_control_ping_reply) \
305 _(ACL_PLUGIN_GET_VERSION_REPLY, acl_plugin_get_version_reply)
307 static int api_acl_plugin_get_version (vat_main_t * vam)
309 acl_test_main_t * sm = &acl_test_main;
310 vl_api_acl_plugin_get_version_t * mp;
311 u32 msg_size = sizeof(*mp);
314 vam->result_ready = 0;
315 mp = vl_msg_api_alloc_as_if_client(msg_size);
316 memset (mp, 0, msg_size);
317 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base);
318 mp->client_index = vam->my_client_index;
323 /* Wait for a reply... */
328 static int api_macip_acl_interface_get (vat_main_t * vam)
330 acl_test_main_t * sm = &acl_test_main;
331 vl_api_acl_plugin_get_version_t * mp;
332 u32 msg_size = sizeof(*mp);
335 vam->result_ready = 0;
336 mp = vl_msg_api_alloc_as_if_client(msg_size);
337 memset (mp, 0, msg_size);
338 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_INTERFACE_GET + sm->msg_id_base);
339 mp->client_index = vam->my_client_index;
344 /* Wait for a reply... */
349 #define vec_validate_acl_rules(v, idx) \
351 if (vec_len(v) < idx+1) { \
352 vec_validate(v, idx); \
353 v[idx].is_permit = 0x1; \
354 v[idx].srcport_or_icmptype_last = 0xffff; \
355 v[idx].dstport_or_icmpcode_last = 0xffff; \
360 static int api_acl_add_replace (vat_main_t * vam)
362 acl_test_main_t * sm = &acl_test_main;
363 unformat_input_t * i = vam->input;
364 vl_api_acl_add_replace_t * mp;
366 u32 msg_size = sizeof (*mp); /* without the rules */
368 vl_api_acl_rule_t *rules = 0;
371 int n_rules_override = -1;
376 u32 tcpflags, tcpmask;
377 u32 src_prefix_length = 0, dst_prefix_length = 0;
378 ip4_address_t src_v4address, dst_v4address;
379 ip6_address_t src_v6address, dst_v6address;
383 if (!unformat (i, "%d", &acl_index)) {
387 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
389 if (unformat (i, "ipv6"))
391 vec_validate_acl_rules(rules, rule_idx);
392 rules[rule_idx].is_ipv6 = 1;
394 else if (unformat (i, "ipv4"))
396 vec_validate_acl_rules(rules, rule_idx);
397 rules[rule_idx].is_ipv6 = 0;
399 else if (unformat (i, "permit+reflect"))
401 vec_validate_acl_rules(rules, rule_idx);
402 rules[rule_idx].is_permit = 2;
404 else if (unformat (i, "permit"))
406 vec_validate_acl_rules(rules, rule_idx);
407 rules[rule_idx].is_permit = 1;
409 else if (unformat (i, "deny"))
411 vec_validate_acl_rules(rules, rule_idx);
412 rules[rule_idx].is_permit = 0;
414 else if (unformat (i, "count %d", &n_rules_override))
416 /* we will use this later */
418 else if (unformat (i, "action %d", &action))
420 vec_validate_acl_rules(rules, rule_idx);
421 rules[rule_idx].is_permit = action;
423 else if (unformat (i, "src %U/%d",
424 unformat_ip4_address, &src_v4address, &src_prefix_length))
426 vec_validate_acl_rules(rules, rule_idx);
427 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
428 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
429 rules[rule_idx].is_ipv6 = 0;
431 else if (unformat (i, "src %U/%d",
432 unformat_ip6_address, &src_v6address, &src_prefix_length))
434 vec_validate_acl_rules(rules, rule_idx);
435 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
436 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
437 rules[rule_idx].is_ipv6 = 1;
439 else if (unformat (i, "dst %U/%d",
440 unformat_ip4_address, &dst_v4address, &dst_prefix_length))
442 vec_validate_acl_rules(rules, rule_idx);
443 memcpy (rules[rule_idx].dst_ip_addr, &dst_v4address, 4);
444 rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
445 rules[rule_idx].is_ipv6 = 0;
447 else if (unformat (i, "dst %U/%d",
448 unformat_ip6_address, &dst_v6address, &dst_prefix_length))
450 vec_validate_acl_rules(rules, rule_idx);
451 memcpy (rules[rule_idx].dst_ip_addr, &dst_v6address, 16);
452 rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
453 rules[rule_idx].is_ipv6 = 1;
455 else if (unformat (i, "sport %d-%d", &port1, &port2))
457 vec_validate_acl_rules(rules, rule_idx);
458 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
459 rules[rule_idx].srcport_or_icmptype_last = htons(port2);
461 else if (unformat (i, "sport %d", &port1))
463 vec_validate_acl_rules(rules, rule_idx);
464 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
465 rules[rule_idx].srcport_or_icmptype_last = htons(port1);
467 else if (unformat (i, "dport %d-%d", &port1, &port2))
469 vec_validate_acl_rules(rules, rule_idx);
470 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
471 rules[rule_idx].dstport_or_icmpcode_last = htons(port2);
473 else if (unformat (i, "dport %d", &port1))
475 vec_validate_acl_rules(rules, rule_idx);
476 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
477 rules[rule_idx].dstport_or_icmpcode_last = htons(port1);
479 else if (unformat (i, "tcpflags %d %d", &tcpflags, &tcpmask))
481 vec_validate_acl_rules(rules, rule_idx);
482 rules[rule_idx].tcp_flags_value = tcpflags;
483 rules[rule_idx].tcp_flags_mask = tcpmask;
485 else if (unformat (i, "tcpflags %d mask %d", &tcpflags, &tcpmask))
487 vec_validate_acl_rules(rules, rule_idx);
488 rules[rule_idx].tcp_flags_value = tcpflags;
489 rules[rule_idx].tcp_flags_mask = tcpmask;
491 else if (unformat (i, "proto %d", &proto))
493 vec_validate_acl_rules(rules, rule_idx);
494 rules[rule_idx].proto = proto;
496 else if (unformat (i, "tag %s", &tag))
499 else if (unformat (i, ","))
502 vec_validate_acl_rules(rules, rule_idx);
508 /* Construct the API message */
509 vam->result_ready = 0;
512 n_rules = vec_len(rules);
516 if (n_rules_override >= 0)
517 n_rules = n_rules_override;
519 msg_size += n_rules*sizeof(rules[0]);
521 mp = vl_msg_api_alloc_as_if_client(msg_size);
522 memset (mp, 0, msg_size);
523 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
524 mp->client_index = vam->my_client_index;
525 if ((n_rules > 0) && rules)
526 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
529 if (vec_len(tag) >= sizeof(mp->tag))
531 tag[sizeof(mp->tag)-1] = 0;
532 _vec_len(tag) = sizeof(mp->tag);
534 clib_memcpy(mp->tag, tag, vec_len(tag));
537 mp->acl_index = ntohl(acl_index);
538 mp->count = htonl(n_rules);
543 /* Wait for a reply... */
548 static int api_acl_del (vat_main_t * vam)
550 unformat_input_t * i = vam->input;
551 vl_api_acl_del_t * mp;
555 if (!unformat (i, "%d", &acl_index)) {
556 errmsg ("missing acl index\n");
560 /* Construct the API message */
562 mp->acl_index = ntohl(acl_index);
567 /* Wait for a reply... */
572 static int api_macip_acl_del (vat_main_t * vam)
574 unformat_input_t * i = vam->input;
575 vl_api_acl_del_t * mp;
579 if (!unformat (i, "%d", &acl_index)) {
580 errmsg ("missing acl index\n");
584 /* Construct the API message */
585 M(MACIP_ACL_DEL, mp);
586 mp->acl_index = ntohl(acl_index);
591 /* Wait for a reply... */
596 static int api_acl_interface_add_del (vat_main_t * vam)
598 unformat_input_t * i = vam->input;
599 vl_api_acl_interface_add_del_t * mp;
600 u32 sw_if_index = ~0;
606 // acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del]
608 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
610 if (unformat (i, "%d", &acl_index))
617 /* Parse args required to build the message */
618 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
619 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
621 else if (unformat (i, "sw_if_index %d", &sw_if_index))
623 else if (unformat (i, "add"))
625 else if (unformat (i, "del"))
627 else if (unformat (i, "acl %d", &acl_index))
629 else if (unformat (i, "input"))
631 else if (unformat (i, "output"))
637 if (sw_if_index == ~0) {
638 errmsg ("missing interface name / explicit sw_if_index number \n");
642 if (acl_index == ~0) {
643 errmsg ("missing ACL index\n");
649 /* Construct the API message */
650 M(ACL_INTERFACE_ADD_DEL, mp);
651 mp->acl_index = ntohl(acl_index);
652 mp->sw_if_index = ntohl(sw_if_index);
654 mp->is_input = is_input;
659 /* Wait for a reply... */
664 static int api_macip_acl_interface_add_del (vat_main_t * vam)
666 unformat_input_t * i = vam->input;
667 vl_api_macip_acl_interface_add_del_t * mp;
668 u32 sw_if_index = ~0;
673 /* Parse args required to build the message */
674 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
675 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
677 else if (unformat (i, "sw_if_index %d", &sw_if_index))
679 else if (unformat (i, "add"))
681 else if (unformat (i, "del"))
683 else if (unformat (i, "acl %d", &acl_index))
689 if (sw_if_index == ~0) {
690 errmsg ("missing interface name / explicit sw_if_index number \n");
694 if (acl_index == ~0) {
695 errmsg ("missing ACL index\n");
701 /* Construct the API message */
702 M(MACIP_ACL_INTERFACE_ADD_DEL, mp);
703 mp->acl_index = ntohl(acl_index);
704 mp->sw_if_index = ntohl(sw_if_index);
710 /* Wait for a reply... */
715 static int api_acl_interface_set_acl_list (vat_main_t * vam)
717 unformat_input_t * i = vam->input;
718 vl_api_acl_interface_set_acl_list_t * mp;
719 u32 sw_if_index = ~0;
726 // acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]
728 /* Parse args required to build the message */
729 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
730 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
732 else if (unformat (i, "sw_if_index %d", &sw_if_index))
734 else if (unformat (i, "%d", &acl_index))
737 vec_add1(inacls, htonl(acl_index));
739 vec_add1(outacls, htonl(acl_index));
741 else if (unformat (i, "acl %d", &acl_index))
743 else if (unformat (i, "input"))
745 else if (unformat (i, "output"))
751 if (sw_if_index == ~0) {
752 errmsg ("missing interface name / explicit sw_if_index number \n");
756 /* Construct the API message */
757 M2(ACL_INTERFACE_SET_ACL_LIST, mp, sizeof(u32) * (vec_len(inacls) + vec_len(outacls)));
758 mp->sw_if_index = ntohl(sw_if_index);
759 mp->n_input = vec_len(inacls);
760 mp->count = vec_len(inacls) + vec_len(outacls);
761 vec_append(inacls, outacls);
762 if (vec_len(inacls) > 0)
763 clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32));
768 /* Wait for a reply... */
773 static int api_acl_interface_set_etype_whitelist (vat_main_t * vam)
775 unformat_input_t * i = vam->input;
776 vl_api_acl_interface_set_etype_whitelist_t * mp;
777 u32 sw_if_index = ~0;
784 // acl_interface_set_etype_whitelist <intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]
786 /* Parse args required to build the message */
787 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
788 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
790 else if (unformat (i, "sw_if_index %d", &sw_if_index))
792 else if (unformat (i, "%x", ðertype))
794 ethertype = ethertype & 0xffff;
796 vec_add1(etypes_in, htons(ethertype));
798 vec_add1(etypes_out, htons(ethertype));
800 else if (unformat (i, "input"))
802 else if (unformat (i, "output"))
808 if (sw_if_index == ~0) {
809 errmsg ("missing interface name / explicit sw_if_index number \n");
813 /* Construct the API message */
814 M2(ACL_INTERFACE_SET_ETYPE_WHITELIST, mp, sizeof(u32) * (vec_len(etypes_in) + vec_len(etypes_out)));
815 mp->sw_if_index = ntohl(sw_if_index);
816 mp->n_input = vec_len(etypes_in);
817 mp->count = vec_len(etypes_in) + vec_len(etypes_out);
818 vec_append(etypes_in, etypes_out);
819 if (vec_len(etypes_in) > 0)
820 clib_memcpy(mp->whitelist, etypes_in, vec_len(etypes_in)*sizeof(etypes_in[0]));
825 /* Wait for a reply... */
831 api_acl_send_control_ping(vat_main_t *vam)
833 vl_api_acl_plugin_control_ping_t *mp_ping;
835 M(ACL_PLUGIN_CONTROL_PING, mp_ping);
840 static int api_acl_interface_list_dump (vat_main_t * vam)
842 unformat_input_t * i = vam->input;
843 u32 sw_if_index = ~0;
844 vl_api_acl_interface_list_dump_t * mp;
847 /* Parse args required to build the message */
848 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
849 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
851 else if (unformat (i, "sw_if_index %d", &sw_if_index))
857 /* Construct the API message */
858 M(ACL_INTERFACE_LIST_DUMP, mp);
859 mp->sw_if_index = ntohl (sw_if_index);
864 /* Use control ping for synchronization */
865 api_acl_send_control_ping(vam);
867 /* Wait for a reply... */
872 static int api_acl_dump (vat_main_t * vam)
874 unformat_input_t * i = vam->input;
876 vl_api_acl_dump_t * mp;
879 /* Parse args required to build the message */
880 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
881 if (unformat (i, "%d", &acl_index))
887 /* Construct the API message */
889 mp->acl_index = ntohl (acl_index);
894 /* Use control ping for synchronization */
895 api_acl_send_control_ping(vam);
897 /* Wait for a reply... */
902 static int api_macip_acl_dump (vat_main_t * vam)
904 unformat_input_t * i = vam->input;
906 vl_api_acl_dump_t * mp;
909 /* Parse args required to build the message */
910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
911 if (unformat (i, "%d", &acl_index))
917 /* Construct the API message */
918 M(MACIP_ACL_DUMP, mp);
919 mp->acl_index = ntohl (acl_index);
924 /* Use control ping for synchronization */
925 api_acl_send_control_ping(vam);
927 /* Wait for a reply... */
932 static int api_acl_interface_etype_whitelist_dump (vat_main_t * vam)
934 unformat_input_t * i = vam->input;
935 u32 sw_if_index = ~0;
936 vl_api_acl_interface_etype_whitelist_dump_t * mp;
939 /* Parse args required to build the message */
940 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
941 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
943 else if (unformat (i, "sw_if_index %d", &sw_if_index))
949 /* Construct the API message */
950 M(ACL_INTERFACE_ETYPE_WHITELIST_DUMP, mp);
951 mp->sw_if_index = ntohl (sw_if_index);
956 /* Use control ping for synchronization */
957 api_acl_send_control_ping(vam);
959 /* Wait for a reply... */
965 #define vec_validate_macip_acl_rules(v, idx) \
967 if (vec_len(v) < idx+1) { \
968 vec_validate(v, idx); \
969 v[idx].is_permit = 0x1; \
974 static int api_macip_acl_add (vat_main_t * vam)
976 acl_test_main_t * sm = &acl_test_main;
977 unformat_input_t * i = vam->input;
978 vl_api_macip_acl_add_t * mp;
979 u32 msg_size = sizeof (*mp); /* without the rules */
981 vl_api_macip_acl_rule_t *rules = 0;
984 int n_rules_override = -1;
985 u32 src_prefix_length = 0;
987 ip4_address_t src_v4address;
988 ip6_address_t src_v6address;
991 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
994 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
996 if (unformat (i, "ipv6"))
998 vec_validate_macip_acl_rules(rules, rule_idx);
999 rules[rule_idx].is_ipv6 = 1;
1001 else if (unformat (i, "ipv4"))
1003 vec_validate_macip_acl_rules(rules, rule_idx);
1004 rules[rule_idx].is_ipv6 = 0;
1006 else if (unformat (i, "permit"))
1008 vec_validate_macip_acl_rules(rules, rule_idx);
1009 rules[rule_idx].is_permit = 1;
1011 else if (unformat (i, "deny"))
1013 vec_validate_macip_acl_rules(rules, rule_idx);
1014 rules[rule_idx].is_permit = 0;
1016 else if (unformat (i, "count %d", &n_rules_override))
1018 /* we will use this later */
1020 else if (unformat (i, "action %d", &action))
1022 vec_validate_macip_acl_rules(rules, rule_idx);
1023 rules[rule_idx].is_permit = action;
1025 else if (unformat (i, "ip %U/%d",
1026 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1027 unformat (i, "ip %U",
1028 unformat_ip4_address, &src_v4address))
1030 if (src_prefix_length == 0)
1031 src_prefix_length = 32;
1032 vec_validate_macip_acl_rules(rules, rule_idx);
1033 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
1034 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1035 rules[rule_idx].is_ipv6 = 0;
1037 else if (unformat (i, "src"))
1039 /* Everything in MACIP is "source" but allow this verbosity */
1041 else if (unformat (i, "ip %U/%d",
1042 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1043 unformat (i, "ip %U",
1044 unformat_ip6_address, &src_v6address))
1046 if (src_prefix_length == 0)
1047 src_prefix_length = 128;
1048 vec_validate_macip_acl_rules(rules, rule_idx);
1049 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
1050 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1051 rules[rule_idx].is_ipv6 = 1;
1053 else if (unformat (i, "mac %U",
1054 my_unformat_mac_address, &src_mac))
1056 vec_validate_macip_acl_rules(rules, rule_idx);
1057 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1058 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1060 else if (unformat (i, "mask %U",
1061 my_unformat_mac_address, &src_mac))
1063 vec_validate_macip_acl_rules(rules, rule_idx);
1064 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1066 else if (unformat (i, "tag %s", &tag))
1069 else if (unformat (i, ","))
1072 vec_validate_macip_acl_rules(rules, rule_idx);
1078 /* Construct the API message */
1079 vam->result_ready = 0;
1082 n_rules = vec_len(rules);
1084 if (n_rules_override >= 0)
1085 n_rules = n_rules_override;
1087 msg_size += n_rules*sizeof(rules[0]);
1089 mp = vl_msg_api_alloc_as_if_client(msg_size);
1090 memset (mp, 0, msg_size);
1091 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD + sm->msg_id_base);
1092 mp->client_index = vam->my_client_index;
1093 if ((n_rules > 0) && rules)
1094 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1097 if (vec_len(tag) >= sizeof(mp->tag))
1099 tag[sizeof(mp->tag)-1] = 0;
1100 _vec_len(tag) = sizeof(mp->tag);
1102 clib_memcpy(mp->tag, tag, vec_len(tag));
1106 mp->count = htonl(n_rules);
1111 /* Wait for a reply... */
1116 static int api_macip_acl_add_replace (vat_main_t * vam)
1118 acl_test_main_t * sm = &acl_test_main;
1119 unformat_input_t * i = vam->input;
1120 vl_api_macip_acl_add_replace_t * mp;
1122 u32 msg_size = sizeof (*mp); /* without the rules */
1124 vl_api_macip_acl_rule_t *rules = 0;
1127 int n_rules_override = -1;
1128 u32 src_prefix_length = 0;
1130 ip4_address_t src_v4address;
1131 ip6_address_t src_v6address;
1134 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1137 if (!unformat (i, "%d", &acl_index)) {
1138 /* Just assume -1 */
1141 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1143 if (unformat (i, "ipv6"))
1145 vec_validate_macip_acl_rules(rules, rule_idx);
1146 rules[rule_idx].is_ipv6 = 1;
1148 else if (unformat (i, "ipv4"))
1150 vec_validate_macip_acl_rules(rules, rule_idx);
1151 rules[rule_idx].is_ipv6 = 0;
1153 else if (unformat (i, "permit"))
1155 vec_validate_macip_acl_rules(rules, rule_idx);
1156 rules[rule_idx].is_permit = 1;
1158 else if (unformat (i, "deny"))
1160 vec_validate_macip_acl_rules(rules, rule_idx);
1161 rules[rule_idx].is_permit = 0;
1163 else if (unformat (i, "count %d", &n_rules_override))
1165 /* we will use this later */
1167 else if (unformat (i, "action %d", &action))
1169 vec_validate_macip_acl_rules(rules, rule_idx);
1170 rules[rule_idx].is_permit = action;
1172 else if (unformat (i, "ip %U/%d",
1173 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1174 unformat (i, "ip %U",
1175 unformat_ip4_address, &src_v4address))
1177 if (src_prefix_length == 0)
1178 src_prefix_length = 32;
1179 vec_validate_macip_acl_rules(rules, rule_idx);
1180 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
1181 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1182 rules[rule_idx].is_ipv6 = 0;
1184 else if (unformat (i, "src"))
1186 /* Everything in MACIP is "source" but allow this verbosity */
1188 else if (unformat (i, "ip %U/%d",
1189 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1190 unformat (i, "ip %U",
1191 unformat_ip6_address, &src_v6address))
1193 if (src_prefix_length == 0)
1194 src_prefix_length = 128;
1195 vec_validate_macip_acl_rules(rules, rule_idx);
1196 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
1197 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1198 rules[rule_idx].is_ipv6 = 1;
1200 else if (unformat (i, "mac %U",
1201 my_unformat_mac_address, &src_mac))
1203 vec_validate_macip_acl_rules(rules, rule_idx);
1204 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1205 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1207 else if (unformat (i, "mask %U",
1208 my_unformat_mac_address, &src_mac))
1210 vec_validate_macip_acl_rules(rules, rule_idx);
1211 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1213 else if (unformat (i, "tag %s", &tag))
1216 else if (unformat (i, ","))
1219 vec_validate_macip_acl_rules(rules, rule_idx);
1227 errmsg ("rule/s required\n");
1230 /* Construct the API message */
1231 vam->result_ready = 0;
1234 n_rules = vec_len(rules);
1236 if (n_rules_override >= 0)
1237 n_rules = n_rules_override;
1239 msg_size += n_rules*sizeof(rules[0]);
1241 mp = vl_msg_api_alloc_as_if_client(msg_size);
1242 memset (mp, 0, msg_size);
1243 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
1244 mp->client_index = vam->my_client_index;
1245 if ((n_rules > 0) && rules)
1246 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1249 if (vec_len(tag) >= sizeof(mp->tag))
1251 tag[sizeof(mp->tag)-1] = 0;
1252 _vec_len(tag) = sizeof(mp->tag);
1254 clib_memcpy(mp->tag, tag, vec_len(tag));
1258 mp->acl_index = ntohl(acl_index);
1259 mp->count = htonl(n_rules);
1264 /* Wait for a reply... */
1270 * List of messages that the api test plugin sends,
1271 * and that the data plane plugin processes
1273 #define foreach_vpe_api_msg \
1274 _(acl_plugin_get_version, "") \
1275 _(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], ... , ...") \
1276 _(acl_del, "<acl-idx>") \
1277 _(acl_dump, "[<acl-idx>]") \
1278 _(acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] [input|output] acl <acl-idx>") \
1279 _(acl_interface_set_acl_list, "<intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]") \
1280 _(acl_interface_set_etype_whitelist, "<intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]") \
1281 _(acl_interface_etype_whitelist_dump, "[<intfc> | sw_if_index <if-idx>]") \
1282 _(acl_interface_list_dump, "[<intfc> | sw_if_index <if-idx>]") \
1283 _(macip_acl_add, "...") \
1284 _(macip_acl_add_replace, "<acl-idx> [<ipv4|ipv6> <permit|deny|action N> [count <count>] [src] ip <ipaddress/[plen]> mac <mac> mask <mac_mask>, ... , ...") \
1285 _(macip_acl_del, "<acl-idx>")\
1286 _(macip_acl_dump, "[<acl-idx>]") \
1287 _(macip_acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] acl <acl-idx>") \
1288 _(macip_acl_interface_get, "")
1292 void acl_vat_api_hookup (vat_main_t *vam)
1294 acl_test_main_t * sm = &acl_test_main;
1295 /* Hook up handlers for replies from the data plane plug-in */
1297 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
1299 vl_api_##n##_t_handler, \
1301 vl_api_##n##_t_endian, \
1302 vl_api_##n##_t_print, \
1303 sizeof(vl_api_##n##_t), 1);
1304 foreach_vpe_api_reply_msg;
1307 /* API messages we can send */
1308 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
1309 foreach_vpe_api_msg;
1313 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
1314 foreach_vpe_api_msg;
1318 clib_error_t * vat_plugin_register (vat_main_t *vam)
1320 acl_test_main_t * sm = &acl_test_main;
1325 name = format (0, "acl_%08x%c", api_version, 0);
1326 sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
1328 if (sm->msg_id_base != (u16) ~0)
1329 acl_vat_api_hookup (vam);