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 <vlibsocket/api.h>
25 #include <vppinfra/error.h>
26 #include <vnet/ip/ip.h>
27 #include <arpa/inet.h>
29 #define __plugin_msg_base acl_test_main.msg_id_base
30 #include <vlibapi/vat_helper_macros.h>
32 uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
34 /* Declare message IDs */
35 #include <acl/acl_msg_enum.h>
37 /* define message structures */
39 #include <acl/acl_all_api_h.h>
42 /* define message structures */
44 #include <acl/acl_all_api_h.h>
47 /* instantiate all the print functions we know about */
48 #define vl_print(handle, ...)
50 #include <acl/acl_all_api_h.h>
53 /* Get the API version number. */
54 #define vl_api_version(n,v) static u32 api_version=(v);
55 #include <acl/acl_all_api_h.h>
59 /* API message ID base */
64 acl_test_main_t acl_test_main;
66 #define foreach_standard_reply_retval_handler \
68 _(acl_interface_add_del_reply) \
69 _(macip_acl_interface_add_del_reply) \
70 _(acl_interface_set_acl_list_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_LIST_DETAILS, acl_interface_list_details) \
274 _(ACL_DETAILS, acl_details) \
275 _(MACIP_ACL_ADD_REPLY, macip_acl_add_reply) \
276 _(MACIP_ACL_ADD_REPLACE_REPLY, macip_acl_add_replace_reply) \
277 _(MACIP_ACL_DEL_REPLY, macip_acl_del_reply) \
278 _(MACIP_ACL_DETAILS, macip_acl_details) \
279 _(MACIP_ACL_INTERFACE_ADD_DEL_REPLY, macip_acl_interface_add_del_reply) \
280 _(MACIP_ACL_INTERFACE_GET_REPLY, macip_acl_interface_get_reply) \
281 _(ACL_PLUGIN_CONTROL_PING_REPLY, acl_plugin_control_ping_reply) \
282 _(ACL_PLUGIN_GET_VERSION_REPLY, acl_plugin_get_version_reply)
284 static int api_acl_plugin_get_version (vat_main_t * vam)
286 acl_test_main_t * sm = &acl_test_main;
287 vl_api_acl_plugin_get_version_t * mp;
288 u32 msg_size = sizeof(*mp);
291 vam->result_ready = 0;
292 mp = vl_msg_api_alloc_as_if_client(msg_size);
293 memset (mp, 0, msg_size);
294 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base);
295 mp->client_index = vam->my_client_index;
300 /* Wait for a reply... */
305 static int api_macip_acl_interface_get (vat_main_t * vam)
307 acl_test_main_t * sm = &acl_test_main;
308 vl_api_acl_plugin_get_version_t * mp;
309 u32 msg_size = sizeof(*mp);
312 vam->result_ready = 0;
313 mp = vl_msg_api_alloc_as_if_client(msg_size);
314 memset (mp, 0, msg_size);
315 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_INTERFACE_GET + sm->msg_id_base);
316 mp->client_index = vam->my_client_index;
321 /* Wait for a reply... */
326 #define vec_validate_acl_rules(v, idx) \
328 if (vec_len(v) < idx+1) { \
329 vec_validate(v, idx); \
330 v[idx].is_permit = 0x1; \
331 v[idx].srcport_or_icmptype_last = 0xffff; \
332 v[idx].dstport_or_icmpcode_last = 0xffff; \
337 static int api_acl_add_replace (vat_main_t * vam)
339 acl_test_main_t * sm = &acl_test_main;
340 unformat_input_t * i = vam->input;
341 vl_api_acl_add_replace_t * mp;
343 u32 msg_size = sizeof (*mp); /* without the rules */
345 vl_api_acl_rule_t *rules = 0;
348 int n_rules_override = -1;
353 u32 tcpflags, tcpmask;
354 u32 src_prefix_length = 0, dst_prefix_length = 0;
355 ip4_address_t src_v4address, dst_v4address;
356 ip6_address_t src_v6address, dst_v6address;
360 if (!unformat (i, "%d", &acl_index)) {
364 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
366 if (unformat (i, "ipv6"))
368 vec_validate_acl_rules(rules, rule_idx);
369 rules[rule_idx].is_ipv6 = 1;
371 else if (unformat (i, "ipv4"))
373 vec_validate_acl_rules(rules, rule_idx);
374 rules[rule_idx].is_ipv6 = 0;
376 else if (unformat (i, "permit+reflect"))
378 vec_validate_acl_rules(rules, rule_idx);
379 rules[rule_idx].is_permit = 2;
381 else if (unformat (i, "permit"))
383 vec_validate_acl_rules(rules, rule_idx);
384 rules[rule_idx].is_permit = 1;
386 else if (unformat (i, "deny"))
388 vec_validate_acl_rules(rules, rule_idx);
389 rules[rule_idx].is_permit = 0;
391 else if (unformat (i, "count %d", &n_rules_override))
393 /* we will use this later */
395 else if (unformat (i, "action %d", &action))
397 vec_validate_acl_rules(rules, rule_idx);
398 rules[rule_idx].is_permit = action;
400 else if (unformat (i, "src %U/%d",
401 unformat_ip4_address, &src_v4address, &src_prefix_length))
403 vec_validate_acl_rules(rules, rule_idx);
404 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
405 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
406 rules[rule_idx].is_ipv6 = 0;
408 else if (unformat (i, "src %U/%d",
409 unformat_ip6_address, &src_v6address, &src_prefix_length))
411 vec_validate_acl_rules(rules, rule_idx);
412 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
413 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
414 rules[rule_idx].is_ipv6 = 1;
416 else if (unformat (i, "dst %U/%d",
417 unformat_ip4_address, &dst_v4address, &dst_prefix_length))
419 vec_validate_acl_rules(rules, rule_idx);
420 memcpy (rules[rule_idx].dst_ip_addr, &dst_v4address, 4);
421 rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
422 rules[rule_idx].is_ipv6 = 0;
424 else if (unformat (i, "dst %U/%d",
425 unformat_ip6_address, &dst_v6address, &dst_prefix_length))
427 vec_validate_acl_rules(rules, rule_idx);
428 memcpy (rules[rule_idx].dst_ip_addr, &dst_v6address, 16);
429 rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
430 rules[rule_idx].is_ipv6 = 1;
432 else if (unformat (i, "sport %d-%d", &port1, &port2))
434 vec_validate_acl_rules(rules, rule_idx);
435 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
436 rules[rule_idx].srcport_or_icmptype_last = htons(port2);
438 else if (unformat (i, "sport %d", &port1))
440 vec_validate_acl_rules(rules, rule_idx);
441 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
442 rules[rule_idx].srcport_or_icmptype_last = htons(port1);
444 else if (unformat (i, "dport %d-%d", &port1, &port2))
446 vec_validate_acl_rules(rules, rule_idx);
447 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
448 rules[rule_idx].dstport_or_icmpcode_last = htons(port2);
450 else if (unformat (i, "dport %d", &port1))
452 vec_validate_acl_rules(rules, rule_idx);
453 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
454 rules[rule_idx].dstport_or_icmpcode_last = htons(port1);
456 else if (unformat (i, "tcpflags %d %d", &tcpflags, &tcpmask))
458 vec_validate_acl_rules(rules, rule_idx);
459 rules[rule_idx].tcp_flags_value = tcpflags;
460 rules[rule_idx].tcp_flags_mask = tcpmask;
462 else if (unformat (i, "tcpflags %d mask %d", &tcpflags, &tcpmask))
464 vec_validate_acl_rules(rules, rule_idx);
465 rules[rule_idx].tcp_flags_value = tcpflags;
466 rules[rule_idx].tcp_flags_mask = tcpmask;
468 else if (unformat (i, "proto %d", &proto))
470 vec_validate_acl_rules(rules, rule_idx);
471 rules[rule_idx].proto = proto;
473 else if (unformat (i, "tag %s", &tag))
476 else if (unformat (i, ","))
479 vec_validate_acl_rules(rules, rule_idx);
485 /* Construct the API message */
486 vam->result_ready = 0;
489 n_rules = vec_len(rules);
493 if (n_rules_override >= 0)
494 n_rules = n_rules_override;
496 msg_size += n_rules*sizeof(rules[0]);
498 mp = vl_msg_api_alloc_as_if_client(msg_size);
499 memset (mp, 0, msg_size);
500 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
501 mp->client_index = vam->my_client_index;
502 if ((n_rules > 0) && rules)
503 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
506 if (vec_len(tag) >= sizeof(mp->tag))
508 tag[sizeof(mp->tag)-1] = 0;
509 _vec_len(tag) = sizeof(mp->tag);
511 clib_memcpy(mp->tag, tag, vec_len(tag));
514 mp->acl_index = ntohl(acl_index);
515 mp->count = htonl(n_rules);
520 /* Wait for a reply... */
525 static int api_acl_del (vat_main_t * vam)
527 unformat_input_t * i = vam->input;
528 vl_api_acl_del_t * mp;
532 if (!unformat (i, "%d", &acl_index)) {
533 errmsg ("missing acl index\n");
537 /* Construct the API message */
539 mp->acl_index = ntohl(acl_index);
544 /* Wait for a reply... */
549 static int api_macip_acl_del (vat_main_t * vam)
551 unformat_input_t * i = vam->input;
552 vl_api_acl_del_t * mp;
556 if (!unformat (i, "%d", &acl_index)) {
557 errmsg ("missing acl index\n");
561 /* Construct the API message */
562 M(MACIP_ACL_DEL, mp);
563 mp->acl_index = ntohl(acl_index);
568 /* Wait for a reply... */
573 static int api_acl_interface_add_del (vat_main_t * vam)
575 unformat_input_t * i = vam->input;
576 vl_api_acl_interface_add_del_t * mp;
577 u32 sw_if_index = ~0;
583 // acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del]
585 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
587 if (unformat (i, "%d", &acl_index))
594 /* Parse args required to build the message */
595 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
596 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
598 else if (unformat (i, "sw_if_index %d", &sw_if_index))
600 else if (unformat (i, "add"))
602 else if (unformat (i, "del"))
604 else if (unformat (i, "acl %d", &acl_index))
606 else if (unformat (i, "input"))
608 else if (unformat (i, "output"))
614 if (sw_if_index == ~0) {
615 errmsg ("missing interface name / explicit sw_if_index number \n");
619 if (acl_index == ~0) {
620 errmsg ("missing ACL index\n");
626 /* Construct the API message */
627 M(ACL_INTERFACE_ADD_DEL, mp);
628 mp->acl_index = ntohl(acl_index);
629 mp->sw_if_index = ntohl(sw_if_index);
631 mp->is_input = is_input;
636 /* Wait for a reply... */
641 static int api_macip_acl_interface_add_del (vat_main_t * vam)
643 unformat_input_t * i = vam->input;
644 vl_api_macip_acl_interface_add_del_t * mp;
645 u32 sw_if_index = ~0;
650 /* Parse args required to build the message */
651 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
652 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
654 else if (unformat (i, "sw_if_index %d", &sw_if_index))
656 else if (unformat (i, "add"))
658 else if (unformat (i, "del"))
660 else if (unformat (i, "acl %d", &acl_index))
666 if (sw_if_index == ~0) {
667 errmsg ("missing interface name / explicit sw_if_index number \n");
671 if (acl_index == ~0) {
672 errmsg ("missing ACL index\n");
678 /* Construct the API message */
679 M(MACIP_ACL_INTERFACE_ADD_DEL, mp);
680 mp->acl_index = ntohl(acl_index);
681 mp->sw_if_index = ntohl(sw_if_index);
687 /* Wait for a reply... */
692 static int api_acl_interface_set_acl_list (vat_main_t * vam)
694 unformat_input_t * i = vam->input;
695 vl_api_acl_interface_set_acl_list_t * mp;
696 u32 sw_if_index = ~0;
703 // acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]
705 /* Parse args required to build the message */
706 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
707 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
709 else if (unformat (i, "sw_if_index %d", &sw_if_index))
711 else if (unformat (i, "%d", &acl_index))
714 vec_add1(inacls, htonl(acl_index));
716 vec_add1(outacls, htonl(acl_index));
718 else if (unformat (i, "acl %d", &acl_index))
720 else if (unformat (i, "input"))
722 else if (unformat (i, "output"))
728 if (sw_if_index == ~0) {
729 errmsg ("missing interface name / explicit sw_if_index number \n");
733 /* Construct the API message */
734 M2(ACL_INTERFACE_SET_ACL_LIST, mp, sizeof(u32) * (vec_len(inacls) + vec_len(outacls)));
735 mp->sw_if_index = ntohl(sw_if_index);
736 mp->n_input = vec_len(inacls);
737 mp->count = vec_len(inacls) + vec_len(outacls);
738 vec_append(inacls, outacls);
739 if (vec_len(inacls) > 0)
740 clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32));
745 /* Wait for a reply... */
751 api_acl_send_control_ping(vat_main_t *vam)
753 vl_api_acl_plugin_control_ping_t *mp_ping;
755 M(ACL_PLUGIN_CONTROL_PING, mp_ping);
760 static int api_acl_interface_list_dump (vat_main_t * vam)
762 unformat_input_t * i = vam->input;
763 u32 sw_if_index = ~0;
764 vl_api_acl_interface_list_dump_t * mp;
767 /* Parse args required to build the message */
768 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
769 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
771 else if (unformat (i, "sw_if_index %d", &sw_if_index))
777 /* Construct the API message */
778 M(ACL_INTERFACE_LIST_DUMP, mp);
779 mp->sw_if_index = ntohl (sw_if_index);
784 /* Use control ping for synchronization */
785 api_acl_send_control_ping(vam);
787 /* Wait for a reply... */
792 static int api_acl_dump (vat_main_t * vam)
794 unformat_input_t * i = vam->input;
796 vl_api_acl_dump_t * mp;
799 /* Parse args required to build the message */
800 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
801 if (unformat (i, "%d", &acl_index))
807 /* Construct the API message */
809 mp->acl_index = ntohl (acl_index);
814 /* Use control ping for synchronization */
815 api_acl_send_control_ping(vam);
817 /* Wait for a reply... */
822 static int api_macip_acl_dump (vat_main_t * vam)
824 unformat_input_t * i = vam->input;
826 vl_api_acl_dump_t * mp;
829 /* Parse args required to build the message */
830 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
831 if (unformat (i, "%d", &acl_index))
837 /* Construct the API message */
838 M(MACIP_ACL_DUMP, mp);
839 mp->acl_index = ntohl (acl_index);
844 /* Use control ping for synchronization */
845 api_acl_send_control_ping(vam);
847 /* Wait for a reply... */
852 #define vec_validate_macip_acl_rules(v, idx) \
854 if (vec_len(v) < idx+1) { \
855 vec_validate(v, idx); \
856 v[idx].is_permit = 0x1; \
861 static int api_macip_acl_add (vat_main_t * vam)
863 acl_test_main_t * sm = &acl_test_main;
864 unformat_input_t * i = vam->input;
865 vl_api_macip_acl_add_t * mp;
866 u32 msg_size = sizeof (*mp); /* without the rules */
868 vl_api_macip_acl_rule_t *rules = 0;
871 int n_rules_override = -1;
872 u32 src_prefix_length = 0;
874 ip4_address_t src_v4address;
875 ip6_address_t src_v6address;
878 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
881 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
883 if (unformat (i, "ipv6"))
885 vec_validate_macip_acl_rules(rules, rule_idx);
886 rules[rule_idx].is_ipv6 = 1;
888 else if (unformat (i, "ipv4"))
890 vec_validate_macip_acl_rules(rules, rule_idx);
891 rules[rule_idx].is_ipv6 = 0;
893 else if (unformat (i, "permit"))
895 vec_validate_macip_acl_rules(rules, rule_idx);
896 rules[rule_idx].is_permit = 1;
898 else if (unformat (i, "deny"))
900 vec_validate_macip_acl_rules(rules, rule_idx);
901 rules[rule_idx].is_permit = 0;
903 else if (unformat (i, "count %d", &n_rules_override))
905 /* we will use this later */
907 else if (unformat (i, "action %d", &action))
909 vec_validate_macip_acl_rules(rules, rule_idx);
910 rules[rule_idx].is_permit = action;
912 else if (unformat (i, "ip %U/%d",
913 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
914 unformat (i, "ip %U",
915 unformat_ip4_address, &src_v4address))
917 if (src_prefix_length == 0)
918 src_prefix_length = 32;
919 vec_validate_macip_acl_rules(rules, rule_idx);
920 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
921 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
922 rules[rule_idx].is_ipv6 = 0;
924 else if (unformat (i, "src"))
926 /* Everything in MACIP is "source" but allow this verbosity */
928 else if (unformat (i, "ip %U/%d",
929 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
930 unformat (i, "ip %U",
931 unformat_ip6_address, &src_v6address))
933 if (src_prefix_length == 0)
934 src_prefix_length = 128;
935 vec_validate_macip_acl_rules(rules, rule_idx);
936 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
937 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
938 rules[rule_idx].is_ipv6 = 1;
940 else if (unformat (i, "mac %U",
941 my_unformat_mac_address, &src_mac))
943 vec_validate_macip_acl_rules(rules, rule_idx);
944 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
945 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
947 else if (unformat (i, "mask %U",
948 my_unformat_mac_address, &src_mac))
950 vec_validate_macip_acl_rules(rules, rule_idx);
951 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
953 else if (unformat (i, "tag %s", &tag))
956 else if (unformat (i, ","))
959 vec_validate_macip_acl_rules(rules, rule_idx);
965 /* Construct the API message */
966 vam->result_ready = 0;
969 n_rules = vec_len(rules);
971 if (n_rules_override >= 0)
972 n_rules = n_rules_override;
974 msg_size += n_rules*sizeof(rules[0]);
976 mp = vl_msg_api_alloc_as_if_client(msg_size);
977 memset (mp, 0, msg_size);
978 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD + sm->msg_id_base);
979 mp->client_index = vam->my_client_index;
980 if ((n_rules > 0) && rules)
981 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
984 if (vec_len(tag) >= sizeof(mp->tag))
986 tag[sizeof(mp->tag)-1] = 0;
987 _vec_len(tag) = sizeof(mp->tag);
989 clib_memcpy(mp->tag, tag, vec_len(tag));
993 mp->count = htonl(n_rules);
998 /* Wait for a reply... */
1003 static int api_macip_acl_add_replace (vat_main_t * vam)
1005 acl_test_main_t * sm = &acl_test_main;
1006 unformat_input_t * i = vam->input;
1007 vl_api_macip_acl_add_replace_t * mp;
1009 u32 msg_size = sizeof (*mp); /* without the rules */
1011 vl_api_macip_acl_rule_t *rules = 0;
1014 int n_rules_override = -1;
1015 u32 src_prefix_length = 0;
1017 ip4_address_t src_v4address;
1018 ip6_address_t src_v6address;
1021 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1024 if (!unformat (i, "%d", &acl_index)) {
1025 /* Just assume -1 */
1028 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1030 if (unformat (i, "ipv6"))
1032 vec_validate_macip_acl_rules(rules, rule_idx);
1033 rules[rule_idx].is_ipv6 = 1;
1035 else if (unformat (i, "ipv4"))
1037 vec_validate_macip_acl_rules(rules, rule_idx);
1038 rules[rule_idx].is_ipv6 = 0;
1040 else if (unformat (i, "permit"))
1042 vec_validate_macip_acl_rules(rules, rule_idx);
1043 rules[rule_idx].is_permit = 1;
1045 else if (unformat (i, "deny"))
1047 vec_validate_macip_acl_rules(rules, rule_idx);
1048 rules[rule_idx].is_permit = 0;
1050 else if (unformat (i, "count %d", &n_rules_override))
1052 /* we will use this later */
1054 else if (unformat (i, "action %d", &action))
1056 vec_validate_macip_acl_rules(rules, rule_idx);
1057 rules[rule_idx].is_permit = action;
1059 else if (unformat (i, "ip %U/%d",
1060 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1061 unformat (i, "ip %U",
1062 unformat_ip4_address, &src_v4address))
1064 if (src_prefix_length == 0)
1065 src_prefix_length = 32;
1066 vec_validate_macip_acl_rules(rules, rule_idx);
1067 memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
1068 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1069 rules[rule_idx].is_ipv6 = 0;
1071 else if (unformat (i, "src"))
1073 /* Everything in MACIP is "source" but allow this verbosity */
1075 else if (unformat (i, "ip %U/%d",
1076 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1077 unformat (i, "ip %U",
1078 unformat_ip6_address, &src_v6address))
1080 if (src_prefix_length == 0)
1081 src_prefix_length = 128;
1082 vec_validate_macip_acl_rules(rules, rule_idx);
1083 memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
1084 rules[rule_idx].src_ip_prefix_len = src_prefix_length;
1085 rules[rule_idx].is_ipv6 = 1;
1087 else if (unformat (i, "mac %U",
1088 my_unformat_mac_address, &src_mac))
1090 vec_validate_macip_acl_rules(rules, rule_idx);
1091 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1092 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1094 else if (unformat (i, "mask %U",
1095 my_unformat_mac_address, &src_mac))
1097 vec_validate_macip_acl_rules(rules, rule_idx);
1098 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1100 else if (unformat (i, "tag %s", &tag))
1103 else if (unformat (i, ","))
1106 vec_validate_macip_acl_rules(rules, rule_idx);
1114 errmsg ("rule/s required\n");
1117 /* Construct the API message */
1118 vam->result_ready = 0;
1121 n_rules = vec_len(rules);
1123 if (n_rules_override >= 0)
1124 n_rules = n_rules_override;
1126 msg_size += n_rules*sizeof(rules[0]);
1128 mp = vl_msg_api_alloc_as_if_client(msg_size);
1129 memset (mp, 0, msg_size);
1130 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
1131 mp->client_index = vam->my_client_index;
1132 if ((n_rules > 0) && rules)
1133 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1136 if (vec_len(tag) >= sizeof(mp->tag))
1138 tag[sizeof(mp->tag)-1] = 0;
1139 _vec_len(tag) = sizeof(mp->tag);
1141 clib_memcpy(mp->tag, tag, vec_len(tag));
1145 mp->acl_index = ntohl(acl_index);
1146 mp->count = htonl(n_rules);
1151 /* Wait for a reply... */
1157 * List of messages that the api test plugin sends,
1158 * and that the data plane plugin processes
1160 #define foreach_vpe_api_msg \
1161 _(acl_plugin_get_version, "") \
1162 _(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], ... , ...") \
1163 _(acl_del, "<acl-idx>") \
1164 _(acl_dump, "[<acl-idx>]") \
1165 _(acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] [input|output] acl <acl-idx>") \
1166 _(acl_interface_set_acl_list, "<intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]") \
1167 _(acl_interface_list_dump, "[<intfc> | sw_if_index <if-idx>]") \
1168 _(macip_acl_add, "...") \
1169 _(macip_acl_add_replace, "<acl-idx> [<ipv4|ipv6> <permit|deny|action N> [count <count>] [src] ip <ipaddress/[plen]> mac <mac> mask <mac_mask>, ... , ...") \
1170 _(macip_acl_del, "<acl-idx>")\
1171 _(macip_acl_dump, "[<acl-idx>]") \
1172 _(macip_acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] acl <acl-idx>") \
1173 _(macip_acl_interface_get, "")
1177 void acl_vat_api_hookup (vat_main_t *vam)
1179 acl_test_main_t * sm = &acl_test_main;
1180 /* Hook up handlers for replies from the data plane plug-in */
1182 vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
1184 vl_api_##n##_t_handler, \
1186 vl_api_##n##_t_endian, \
1187 vl_api_##n##_t_print, \
1188 sizeof(vl_api_##n##_t), 1);
1189 foreach_vpe_api_reply_msg;
1192 /* API messages we can send */
1193 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
1194 foreach_vpe_api_msg;
1198 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
1199 foreach_vpe_api_msg;
1203 clib_error_t * vat_plugin_register (vat_main_t *vam)
1205 acl_test_main_t * sm = &acl_test_main;
1210 name = format (0, "acl_%08x%c", api_version, 0);
1211 sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
1213 if (sm->msg_id_base != (u16) ~0)
1214 acl_vat_api_hookup (vam);