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 #include <vnet/ip/ip_format_fns.h>
29 #include <vnet/ethernet/ethernet_format_fns.h>
31 #define __plugin_msg_base acl_test_main.msg_id_base
32 #include <vlibapi/vat_helper_macros.h>
34 uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
36 /* Declare message IDs */
37 #include <acl/acl.api_enum.h>
38 #include <acl/acl.api_types.h>
39 #define vl_print(handle, ...)
41 #define vl_endianfun /* define message structures */
42 #include <acl/acl.api.h>
46 /* API message ID base */
51 acl_test_main_t acl_test_main;
53 #define foreach_reply_retval_aclindex_handler \
54 _(acl_add_replace_reply) \
55 _(macip_acl_add_reply) \
56 _(macip_acl_add_replace_reply)
59 static void vl_api_##n##_t_handler \
60 (vl_api_##n##_t * mp) \
62 vat_main_t * vam = acl_test_main.vat_main; \
63 i32 retval = ntohl(mp->retval); \
64 if (vam->async_mode) { \
65 vam->async_errors += (retval < 0); \
67 clib_warning("ACL index: %d", ntohl(mp->acl_index)); \
68 vam->retval = retval; \
69 vam->result_ready = 1; \
72 foreach_reply_retval_aclindex_handler;
75 /* These two ought to be in a library somewhere but they aren't */
77 my_unformat_mac_address (unformat_input_t * input, va_list * args)
79 u8 *a = va_arg (*args, u8 *);
80 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
85 my_format_mac_address (u8 * s, va_list * args)
87 u8 *a = va_arg (*args, u8 *);
88 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
89 a[0], a[1], a[2], a[3], a[4], a[5]);
94 static void vl_api_acl_plugin_get_version_reply_t_handler
95 (vl_api_acl_plugin_get_version_reply_t * mp)
97 vat_main_t * vam = acl_test_main.vat_main;
98 clib_warning("ACL plugin version: %d.%d", ntohl(mp->major), ntohl(mp->minor));
99 vam->result_ready = 1;
102 static void vl_api_acl_interface_list_details_t_handler
103 (vl_api_acl_interface_list_details_t * mp)
106 vat_main_t * vam = acl_test_main.vat_main;
108 vl_api_acl_interface_list_details_t_endian(mp);
109 out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
110 out = format(out, " input ");
111 for(i=0; i<mp->count; i++) {
112 if (i == mp->n_input)
113 out = format(out, "\n output ");
114 out = format(out, "%d ", ntohl (mp->acls[i]));
116 out = format(out, "\n");
117 clib_warning("%s", out);
119 vam->result_ready = 1;
122 static void vl_api_macip_acl_interface_list_details_t_handler
123 (vl_api_macip_acl_interface_list_details_t * mp)
125 // NOT YET IMPLEMENTED
129 static void vl_api_acl_interface_etype_whitelist_details_t_handler
130 (vl_api_acl_interface_etype_whitelist_details_t * mp)
133 vat_main_t * vam = acl_test_main.vat_main;
135 vl_api_acl_interface_etype_whitelist_details_t_endian(mp);
136 out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
137 out = format(out, " input ");
138 for(i=0; i<mp->count; i++) {
139 if (i == mp->n_input)
140 out = format(out, "\n output ");
141 out = format(out, "%04x ", ntohs(mp->whitelist[i]));
143 out = format(out, "\n");
144 clib_warning("%s", out);
146 vam->result_ready = 1;
149 static void vl_api_acl_plugin_get_conn_table_max_entries_reply_t_handler
150 (vl_api_acl_plugin_get_conn_table_max_entries_reply_t * mp)
152 vat_main_t * vam = acl_test_main.vat_main;
153 clib_warning("\nConn table max entries: %d",
154 __bswap_64(mp->conn_table_max_entries) );
155 vam->result_ready = 1;
159 vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a)
161 int af = a->src_prefix.address.af ? AF_INET6 : AF_INET;
162 u8 src[INET6_ADDRSTRLEN];
163 u8 dst[INET6_ADDRSTRLEN];
164 inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
165 inet_ntop(af, &a->dst_prefix.address.un, (void *)dst, sizeof(dst));
167 out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d mask %d",
168 a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
169 src, a->src_prefix.len,
170 dst, a->dst_prefix.len,
172 a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
173 a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
174 a->tcp_flags_value, a->tcp_flags_mask);
180 static void vl_api_acl_details_t_handler
181 (vl_api_acl_details_t * mp)
184 vat_main_t * vam = acl_test_main.vat_main;
185 vl_api_acl_details_t_endian(mp);
187 out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
188 for(i=0; i<mp->count; i++) {
189 out = format(out, " ");
190 out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]);
191 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
193 clib_warning("%s", out);
195 vam->result_ready = 1;
199 vl_api_macip_acl_rule_t_pretty_format (u8 *out, vl_api_macip_acl_rule_t * a)
201 int af = a->src_prefix.address.af ? AF_INET6 : AF_INET;
202 u8 src[INET6_ADDRSTRLEN];
203 inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
205 out = format(out, "%s action %d ip %s/%d mac %U mask %U",
206 a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
207 src, a->src_prefix.len,
208 my_format_mac_address, a->src_mac,
209 my_format_mac_address, a->src_mac_mask);
214 static void vl_api_macip_acl_details_t_handler
215 (vl_api_macip_acl_details_t * mp)
218 vat_main_t * vam = acl_test_main.vat_main;
219 vl_api_macip_acl_details_t_endian(mp);
220 u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
221 for(i=0; i<mp->count; i++) {
222 out = format(out, " ");
223 out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]);
224 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
226 clib_warning("%s", out);
228 vam->result_ready = 1;
231 static void vl_api_macip_acl_interface_get_reply_t_handler
232 (vl_api_macip_acl_interface_get_reply_t * mp)
235 vat_main_t * vam = acl_test_main.vat_main;
236 u8 *out = format(0, "sw_if_index with MACIP ACL count: %d\n", ntohl(mp->count));
237 for(i=0; i<ntohl(mp->count); i++) {
238 out = format(out, " macip_acl_interface_add_del sw_if_index %d add acl %d\n", i, ntohl(mp->acls[i]));
240 out = format(out, "\n");
241 clib_warning("%s", out);
243 vam->result_ready = 1;
246 static void vl_api_acl_plugin_control_ping_reply_t_handler
247 (vl_api_acl_plugin_control_ping_reply_t * mp)
249 vat_main_t *vam = &vat_main;
250 i32 retval = ntohl (mp->retval);
253 vam->async_errors += (retval < 0);
257 vam->retval = retval;
258 vam->result_ready = 1;
262 static int api_acl_plugin_get_version (vat_main_t * vam)
264 acl_test_main_t * sm = &acl_test_main;
265 vl_api_acl_plugin_get_version_t * mp;
266 u32 msg_size = sizeof(*mp);
269 vam->result_ready = 0;
270 mp = vl_msg_api_alloc_as_if_client(msg_size);
271 clib_memset (mp, 0, msg_size);
272 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base);
273 mp->client_index = vam->my_client_index;
278 /* Wait for a reply... */
283 static int api_macip_acl_interface_get (vat_main_t * vam)
285 acl_test_main_t * sm = &acl_test_main;
286 vl_api_acl_plugin_get_version_t * mp;
287 u32 msg_size = sizeof(*mp);
290 vam->result_ready = 0;
291 mp = vl_msg_api_alloc_as_if_client(msg_size);
292 clib_memset (mp, 0, msg_size);
293 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_INTERFACE_GET + sm->msg_id_base);
294 mp->client_index = vam->my_client_index;
299 /* Wait for a reply... */
304 #define vec_validate_acl_rules(v, idx) \
306 if (vec_len(v) < idx+1) { \
307 vec_validate(v, idx); \
308 v[idx].is_permit = 0x1; \
309 v[idx].srcport_or_icmptype_last = 0xffff; \
310 v[idx].dstport_or_icmpcode_last = 0xffff; \
315 /* NOT YET IMPLEMENTED */
316 static int api_acl_plugin_control_ping (vat_main_t * vam)
320 static int api_macip_acl_interface_list_dump (vat_main_t * vam)
325 static int api_acl_add_replace (vat_main_t * vam)
327 acl_test_main_t * sm = &acl_test_main;
328 unformat_input_t * i = vam->input;
329 vl_api_acl_add_replace_t * mp;
331 u32 msg_size = sizeof (*mp); /* without the rules */
333 vl_api_acl_rule_t *rules = 0;
336 int n_rules_override = -1;
341 u32 tcpflags, tcpmask;
342 u32 src_prefix_length = 0, dst_prefix_length = 0;
343 ip4_address_t src_v4address, dst_v4address;
344 ip6_address_t src_v6address, dst_v6address;
348 if (!unformat (i, "%d", &acl_index)) {
352 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
354 if (unformat (i, "permit+reflect"))
356 vec_validate_acl_rules(rules, rule_idx);
357 rules[rule_idx].is_permit = 2;
359 else if (unformat (i, "permit"))
361 vec_validate_acl_rules(rules, rule_idx);
362 rules[rule_idx].is_permit = 1;
364 else if (unformat (i, "deny"))
366 vec_validate_acl_rules(rules, rule_idx);
367 rules[rule_idx].is_permit = 0;
369 else if (unformat (i, "count %d", &n_rules_override))
371 /* we will use this later */
373 else if (unformat (i, "action %d", &action))
375 vec_validate_acl_rules(rules, rule_idx);
376 rules[rule_idx].is_permit = action;
378 else if (unformat (i, "src %U/%d",
379 unformat_ip4_address, &src_v4address, &src_prefix_length))
381 vec_validate_acl_rules(rules, rule_idx);
382 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
383 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
384 rules[rule_idx].src_prefix.len = src_prefix_length;
386 else if (unformat (i, "src %U/%d",
387 unformat_ip6_address, &src_v6address, &src_prefix_length))
389 vec_validate_acl_rules(rules, rule_idx);
390 memcpy (rules[rule_idx].src_prefix.address.un.ip6, &src_v6address, 16);
391 rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
392 rules[rule_idx].src_prefix.len = src_prefix_length;
394 else if (unformat (i, "dst %U/%d",
395 unformat_ip4_address, &dst_v4address, &dst_prefix_length))
397 vec_validate_acl_rules(rules, rule_idx);
398 memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
399 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
400 rules[rule_idx].dst_prefix.len = dst_prefix_length;
402 else if (unformat (i, "dst %U/%d",
403 unformat_ip6_address, &dst_v6address, &dst_prefix_length))
405 vec_validate_acl_rules(rules, rule_idx);
406 memcpy (rules[rule_idx].dst_prefix.address.un.ip6, &dst_v6address, 16);
407 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP6;
408 rules[rule_idx].dst_prefix.len = dst_prefix_length;
410 else if (unformat (i, "sport %d-%d", &port1, &port2))
412 vec_validate_acl_rules(rules, rule_idx);
413 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
414 rules[rule_idx].srcport_or_icmptype_last = htons(port2);
416 else if (unformat (i, "sport %d", &port1))
418 vec_validate_acl_rules(rules, rule_idx);
419 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
420 rules[rule_idx].srcport_or_icmptype_last = htons(port1);
422 else if (unformat (i, "dport %d-%d", &port1, &port2))
424 vec_validate_acl_rules(rules, rule_idx);
425 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
426 rules[rule_idx].dstport_or_icmpcode_last = htons(port2);
428 else if (unformat (i, "dport %d", &port1))
430 vec_validate_acl_rules(rules, rule_idx);
431 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
432 rules[rule_idx].dstport_or_icmpcode_last = htons(port1);
434 else if (unformat (i, "tcpflags %d %d", &tcpflags, &tcpmask))
436 vec_validate_acl_rules(rules, rule_idx);
437 rules[rule_idx].tcp_flags_value = tcpflags;
438 rules[rule_idx].tcp_flags_mask = tcpmask;
440 else if (unformat (i, "tcpflags %d mask %d", &tcpflags, &tcpmask))
442 vec_validate_acl_rules(rules, rule_idx);
443 rules[rule_idx].tcp_flags_value = tcpflags;
444 rules[rule_idx].tcp_flags_mask = tcpmask;
446 else if (unformat (i, "proto %d", &proto))
448 vec_validate_acl_rules(rules, rule_idx);
449 rules[rule_idx].proto = proto;
451 else if (unformat (i, "tag %s", &tag))
454 else if (unformat (i, ","))
457 vec_validate_acl_rules(rules, rule_idx);
463 /* Construct the API message */
464 vam->result_ready = 0;
467 n_rules = vec_len(rules);
471 if (n_rules_override >= 0)
472 n_rules = n_rules_override;
474 msg_size += n_rules*sizeof(rules[0]);
476 mp = vl_msg_api_alloc_as_if_client(msg_size);
477 clib_memset (mp, 0, msg_size);
478 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
479 mp->client_index = vam->my_client_index;
480 if ((n_rules > 0) && rules)
481 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
484 if (vec_len(tag) >= sizeof(mp->tag))
486 tag[sizeof(mp->tag)-1] = 0;
487 _vec_len(tag) = sizeof(mp->tag);
489 clib_memcpy(mp->tag, tag, vec_len(tag));
492 mp->acl_index = ntohl(acl_index);
493 mp->count = htonl(n_rules);
498 /* Wait for a reply... */
503 static int api_acl_plugin_get_conn_table_max_entries (vat_main_t * vam)
505 acl_test_main_t * sm = &acl_test_main;
506 vl_api_acl_plugin_get_conn_table_max_entries_t * mp;
507 u32 msg_size = sizeof(*mp);
510 vam->result_ready = 0;
511 mp = vl_msg_api_alloc_as_if_client(msg_size);
512 memset (mp, 0, msg_size);
513 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_CONN_TABLE_MAX_ENTRIES + sm->msg_id_base);
514 mp->client_index = vam->my_client_index;
519 /* Wait for a reply... */
524 static int api_acl_stats_intf_counters_enable (vat_main_t * vam)
526 acl_test_main_t * sm = &acl_test_main;
527 unformat_input_t * i = vam->input;
528 vl_api_acl_stats_intf_counters_enable_t * mp;
529 u32 msg_size = sizeof(*mp);
532 vam->result_ready = 0;
533 mp = vl_msg_api_alloc_as_if_client(msg_size);
534 memset (mp, 0, msg_size);
535 mp->_vl_msg_id = ntohs (VL_API_ACL_STATS_INTF_COUNTERS_ENABLE + sm->msg_id_base);
536 mp->client_index = vam->my_client_index;
539 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
540 if (unformat (i, "disable"))
549 /* Wait for a reply... */
556 * Read the series of ACL entries from file in the following format:
559 @0.0.0.0/1 131.179.121.0/24 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
560 @128.0.0.0/1 85.54.226.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
561 @128.0.0.0/1 85.54.48.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
562 @128.0.0.0/1 31.237.44.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
563 @0.0.0.0/1 255.84.184.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
564 @132.92.0.0/16 0.0.0.0/0 0 : 65535 0 : 65535 0x01/0xFF 0x0000/0x0000
570 api_acl_add_replace_from_file (vat_main_t * vam)
573 unformat_input_t * input = vam->input;
574 acl_test_main_t * sm = &acl_test_main;
575 vl_api_acl_add_replace_t * mp;
577 u32 msg_size = sizeof (*mp); /* without the rules */
579 vl_api_acl_rule_t *rules = 0;
583 int append_default_permit = 0;
584 u32 tcpflags = 0, tcpmask = 0;
585 ip4_address_t src_v4address, dst_v4address;
588 char *file_name = NULL;
589 unformat_input_t file_input;
591 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
593 if (unformat (input, "filename %s", &file_name))
595 /* we will use this later */
597 else if (unformat (input, "acl-index %d", &acl_index))
599 /* we will try to replace an existing ACL */
601 else if (unformat (input, "permit+reflect"))
605 else if (unformat (input, "permit"))
609 else if (unformat (input, "append-default-permit"))
611 append_default_permit = 1;
617 if (file_name == NULL)
620 fd = open(file_name, O_RDONLY);
623 clib_warning("Could not open file '%s'", file_name);
627 /* input from file */
629 unformat_init_clib_file(input, fd);
631 unsigned sport_low, sport_high, dport_low, dport_high;
632 unsigned proto, protomask;
633 u32 src_prefix_length, dst_prefix_length;
634 u32 unused1, unused2;
636 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
638 if (!unformat(input, "@%U/%d\t%U/%d\t%d : %d\t%d : %d\t0x%x/0x%x\t0x%x/0x%x",
639 unformat_ip4_address, &src_v4address, &src_prefix_length,
640 unformat_ip4_address, &dst_v4address, &dst_prefix_length,
641 &sport_low, &sport_high, &dport_low, &dport_high, &proto, &protomask, &unused1, &unused2)) {
642 clib_warning("Error parsing");
647 vec_validate_acl_rules(rules, rule_idx);
649 rules[rule_idx].is_permit = is_permit;
650 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
651 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
652 rules[rule_idx].src_prefix.len = src_prefix_length;
653 memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
654 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
655 rules[rule_idx].dst_prefix.len = dst_prefix_length;
656 rules[rule_idx].srcport_or_icmptype_first = htons(sport_low);
657 rules[rule_idx].srcport_or_icmptype_last = htons(sport_high);
658 rules[rule_idx].dstport_or_icmpcode_first = htons(dport_low);
659 rules[rule_idx].dstport_or_icmpcode_last = htons(dport_high);
660 rules[rule_idx].tcp_flags_value = tcpflags;
661 rules[rule_idx].tcp_flags_mask = tcpmask;
662 rules[rule_idx].proto = proto;
666 if (append_default_permit) {
668 vec_validate_acl_rules(rules, rule_idx);
670 rules[rule_idx].is_permit = is_permit == 2 ? 2 : 1;
672 src_v4address.data[0]=0;
673 src_v4address.data[1]=0;
674 src_v4address.data[2]=0;
675 src_v4address.data[3]=0;
676 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
677 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
678 rules[rule_idx].src_prefix.len = 0;
680 dst_v4address.data[0]=0;
681 dst_v4address.data[1]=0;
682 dst_v4address.data[2]=0;
683 dst_v4address.data[3]=0;
684 memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
685 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
686 rules[rule_idx].dst_prefix.len = 0;
688 rules[rule_idx].srcport_or_icmptype_first = htons(0);
689 rules[rule_idx].srcport_or_icmptype_last = htons(65535);
690 rules[rule_idx].dstport_or_icmpcode_first = htons(0);
691 rules[rule_idx].dstport_or_icmpcode_last = htons(65535);
692 rules[rule_idx].tcp_flags_value = 0;
693 rules[rule_idx].tcp_flags_mask = 0;
694 rules[rule_idx].proto = 0;
697 /* Construct the API message */
699 vam->result_ready = 0;
701 n_rules = vec_len(rules);
703 msg_size += n_rules*sizeof(rules[0]);
705 mp = vl_msg_api_alloc_as_if_client(msg_size);
706 clib_memset (mp, 0, msg_size);
707 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
708 mp->client_index = vam->my_client_index;
710 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
711 mp->acl_index = ntohl(acl_index);
712 mp->count = htonl(n_rules);
717 /* Wait for a reply... */
728 static int api_acl_del (vat_main_t * vam)
730 unformat_input_t * i = vam->input;
731 vl_api_acl_del_t * mp;
735 if (!unformat (i, "%d", &acl_index)) {
736 errmsg ("missing acl index\n");
740 /* Construct the API message */
742 mp->acl_index = ntohl(acl_index);
747 /* Wait for a reply... */
752 static int api_macip_acl_del (vat_main_t * vam)
754 unformat_input_t * i = vam->input;
755 vl_api_acl_del_t * mp;
759 if (!unformat (i, "%d", &acl_index)) {
760 errmsg ("missing acl index\n");
764 /* Construct the API message */
765 M(MACIP_ACL_DEL, mp);
766 mp->acl_index = ntohl(acl_index);
771 /* Wait for a reply... */
776 static int api_acl_interface_add_del (vat_main_t * vam)
778 unformat_input_t * i = vam->input;
779 vl_api_acl_interface_add_del_t * mp;
780 u32 sw_if_index = ~0;
786 // acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del]
788 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
790 if (unformat (i, "%d", &acl_index))
797 /* Parse args required to build the message */
798 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
799 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
801 else if (unformat (i, "sw_if_index %d", &sw_if_index))
803 else if (unformat (i, "add"))
805 else if (unformat (i, "del"))
807 else if (unformat (i, "acl %d", &acl_index))
809 else if (unformat (i, "input"))
811 else if (unformat (i, "output"))
817 if (sw_if_index == ~0) {
818 errmsg ("missing interface name / explicit sw_if_index number \n");
822 if (acl_index == ~0) {
823 errmsg ("missing ACL index\n");
829 /* Construct the API message */
830 M(ACL_INTERFACE_ADD_DEL, mp);
831 mp->acl_index = ntohl(acl_index);
832 mp->sw_if_index = ntohl(sw_if_index);
834 mp->is_input = is_input;
839 /* Wait for a reply... */
844 static int api_macip_acl_interface_add_del (vat_main_t * vam)
846 unformat_input_t * i = vam->input;
847 vl_api_macip_acl_interface_add_del_t * mp;
848 u32 sw_if_index = ~0;
853 /* Parse args required to build the message */
854 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
855 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
857 else if (unformat (i, "sw_if_index %d", &sw_if_index))
859 else if (unformat (i, "add"))
861 else if (unformat (i, "del"))
863 else if (unformat (i, "acl %d", &acl_index))
869 if (sw_if_index == ~0) {
870 errmsg ("missing interface name / explicit sw_if_index number \n");
874 if (acl_index == ~0) {
875 errmsg ("missing ACL index\n");
881 /* Construct the API message */
882 M(MACIP_ACL_INTERFACE_ADD_DEL, mp);
883 mp->acl_index = ntohl(acl_index);
884 mp->sw_if_index = ntohl(sw_if_index);
890 /* Wait for a reply... */
895 static int api_acl_interface_set_acl_list (vat_main_t * vam)
897 unformat_input_t * i = vam->input;
898 vl_api_acl_interface_set_acl_list_t * mp;
899 u32 sw_if_index = ~0;
906 // acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]
908 /* Parse args required to build the message */
909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
910 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
912 else if (unformat (i, "sw_if_index %d", &sw_if_index))
914 else if (unformat (i, "%d", &acl_index))
917 vec_add1(inacls, htonl(acl_index));
919 vec_add1(outacls, htonl(acl_index));
921 else if (unformat (i, "acl %d", &acl_index))
923 else if (unformat (i, "input"))
925 else if (unformat (i, "output"))
931 if (sw_if_index == ~0) {
932 errmsg ("missing interface name / explicit sw_if_index number \n");
936 /* Construct the API message */
937 M2(ACL_INTERFACE_SET_ACL_LIST, mp, sizeof(u32) * (vec_len(inacls) + vec_len(outacls)));
938 mp->sw_if_index = ntohl(sw_if_index);
939 mp->n_input = vec_len(inacls);
940 mp->count = vec_len(inacls) + vec_len(outacls);
941 vec_append(inacls, outacls);
942 if (vec_len(inacls) > 0)
943 clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32));
948 /* Wait for a reply... */
953 static int api_acl_interface_set_etype_whitelist (vat_main_t * vam)
955 unformat_input_t * i = vam->input;
956 vl_api_acl_interface_set_etype_whitelist_t * mp;
957 u32 sw_if_index = ~0;
964 // acl_interface_set_etype_whitelist <intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]
966 /* Parse args required to build the message */
967 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
968 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
970 else if (unformat (i, "sw_if_index %d", &sw_if_index))
972 else if (unformat (i, "%x", ðertype))
974 ethertype = ethertype & 0xffff;
976 vec_add1(etypes_in, htons(ethertype));
978 vec_add1(etypes_out, htons(ethertype));
980 else if (unformat (i, "input"))
982 else if (unformat (i, "output"))
988 if (sw_if_index == ~0) {
989 errmsg ("missing interface name / explicit sw_if_index number \n");
993 /* Construct the API message */
994 M2(ACL_INTERFACE_SET_ETYPE_WHITELIST, mp, sizeof(u32) * (vec_len(etypes_in) + vec_len(etypes_out)));
995 mp->sw_if_index = ntohl(sw_if_index);
996 mp->n_input = vec_len(etypes_in);
997 mp->count = vec_len(etypes_in) + vec_len(etypes_out);
998 vec_append(etypes_in, etypes_out);
999 if (vec_len(etypes_in) > 0)
1000 clib_memcpy(mp->whitelist, etypes_in, vec_len(etypes_in)*sizeof(etypes_in[0]));
1005 /* Wait for a reply... */
1011 api_acl_send_control_ping(vat_main_t *vam)
1013 vl_api_acl_plugin_control_ping_t *mp_ping;
1015 M(ACL_PLUGIN_CONTROL_PING, mp_ping);
1020 static int api_acl_interface_list_dump (vat_main_t * vam)
1022 unformat_input_t * i = vam->input;
1023 u32 sw_if_index = ~0;
1024 vl_api_acl_interface_list_dump_t * mp;
1027 /* Parse args required to build the message */
1028 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1029 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1031 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1037 /* Construct the API message */
1038 M(ACL_INTERFACE_LIST_DUMP, mp);
1039 mp->sw_if_index = ntohl (sw_if_index);
1044 /* Use control ping for synchronization */
1045 api_acl_send_control_ping(vam);
1047 /* Wait for a reply... */
1052 static int api_acl_dump (vat_main_t * vam)
1054 unformat_input_t * i = vam->input;
1056 vl_api_acl_dump_t * mp;
1059 /* Parse args required to build the message */
1060 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1061 if (unformat (i, "%d", &acl_index))
1067 /* Construct the API message */
1069 mp->acl_index = ntohl (acl_index);
1074 /* Use control ping for synchronization */
1075 api_acl_send_control_ping(vam);
1077 /* Wait for a reply... */
1082 static int api_macip_acl_dump (vat_main_t * vam)
1084 unformat_input_t * i = vam->input;
1086 vl_api_acl_dump_t * mp;
1089 /* Parse args required to build the message */
1090 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1091 if (unformat (i, "%d", &acl_index))
1097 /* Construct the API message */
1098 M(MACIP_ACL_DUMP, mp);
1099 mp->acl_index = ntohl (acl_index);
1104 /* Use control ping for synchronization */
1105 api_acl_send_control_ping(vam);
1107 /* Wait for a reply... */
1112 static int api_acl_interface_etype_whitelist_dump (vat_main_t * vam)
1114 unformat_input_t * i = vam->input;
1115 u32 sw_if_index = ~0;
1116 vl_api_acl_interface_etype_whitelist_dump_t * mp;
1119 /* Parse args required to build the message */
1120 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1121 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1123 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1129 /* Construct the API message */
1130 M(ACL_INTERFACE_ETYPE_WHITELIST_DUMP, mp);
1131 mp->sw_if_index = ntohl (sw_if_index);
1136 /* Use control ping for synchronization */
1137 api_acl_send_control_ping(vam);
1139 /* Wait for a reply... */
1145 #define vec_validate_macip_acl_rules(v, idx) \
1147 if (vec_len(v) < idx+1) { \
1148 vec_validate(v, idx); \
1149 v[idx].is_permit = 0x1; \
1154 static int api_macip_acl_add (vat_main_t * vam)
1156 acl_test_main_t * sm = &acl_test_main;
1157 unformat_input_t * i = vam->input;
1158 vl_api_macip_acl_add_t * mp;
1159 u32 msg_size = sizeof (*mp); /* without the rules */
1161 vl_api_macip_acl_rule_t *rules = 0;
1164 int n_rules_override = -1;
1165 u32 src_prefix_length = 0;
1167 ip4_address_t src_v4address;
1168 ip6_address_t src_v6address;
1171 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1176 if (unformat (i, "permit"))
1178 vec_validate_macip_acl_rules(rules, rule_idx);
1179 rules[rule_idx].is_permit = 1;
1181 else if (unformat (i, "deny"))
1183 vec_validate_macip_acl_rules(rules, rule_idx);
1184 rules[rule_idx].is_permit = 0;
1186 else if (unformat (i, "count %d", &n_rules_override))
1188 /* we will use this later */
1190 else if (unformat (i, "action %d", &action))
1192 vec_validate_macip_acl_rules(rules, rule_idx);
1193 rules[rule_idx].is_permit = action;
1195 else if (unformat (i, "ip %U/%d",
1196 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1197 unformat (i, "ip %U",
1198 unformat_ip4_address, &src_v4address))
1200 if (src_prefix_length == 0)
1201 src_prefix_length = 32;
1202 vec_validate_macip_acl_rules(rules, rule_idx);
1203 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
1204 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
1205 rules[rule_idx].src_prefix.len = src_prefix_length;
1207 else if (unformat (i, "src"))
1209 /* Everything in MACIP is "source" but allow this verbosity */
1211 else if (unformat (i, "ip %U/%d",
1212 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1213 unformat (i, "ip %U",
1214 unformat_ip6_address, &src_v6address))
1216 if (src_prefix_length == 0)
1217 src_prefix_length = 128;
1218 vec_validate_macip_acl_rules(rules, rule_idx);
1219 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v6address, 4);
1220 rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
1221 rules[rule_idx].src_prefix.len = src_prefix_length;
1223 else if (unformat (i, "mac %U",
1224 my_unformat_mac_address, &src_mac))
1226 vec_validate_macip_acl_rules(rules, rule_idx);
1227 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1228 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1230 else if (unformat (i, "mask %U",
1231 my_unformat_mac_address, &src_mac))
1233 vec_validate_macip_acl_rules(rules, rule_idx);
1234 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1236 else if (unformat (i, "tag %s", &tag))
1239 else if (unformat (i, ","))
1242 vec_validate_macip_acl_rules(rules, rule_idx);
1248 /* Construct the API message */
1249 vam->result_ready = 0;
1252 n_rules = vec_len(rules);
1254 if (n_rules_override >= 0)
1255 n_rules = n_rules_override;
1257 msg_size += n_rules*sizeof(rules[0]);
1259 mp = vl_msg_api_alloc_as_if_client(msg_size);
1260 clib_memset (mp, 0, msg_size);
1261 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD + sm->msg_id_base);
1262 mp->client_index = vam->my_client_index;
1263 if ((n_rules > 0) && rules)
1264 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1267 if (vec_len(tag) >= sizeof(mp->tag))
1269 tag[sizeof(mp->tag)-1] = 0;
1270 _vec_len(tag) = sizeof(mp->tag);
1272 clib_memcpy(mp->tag, tag, vec_len(tag));
1276 mp->count = htonl(n_rules);
1281 /* Wait for a reply... */
1286 static int api_macip_acl_add_replace (vat_main_t * vam)
1288 acl_test_main_t * sm = &acl_test_main;
1289 unformat_input_t * i = vam->input;
1290 vl_api_macip_acl_add_replace_t * mp;
1292 u32 msg_size = sizeof (*mp); /* without the rules */
1294 vl_api_macip_acl_rule_t *rules = 0;
1297 int n_rules_override = -1;
1298 u32 src_prefix_length = 0;
1300 ip4_address_t src_v4address;
1301 ip6_address_t src_v6address;
1304 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1307 if (!unformat (i, "%d", &acl_index)) {
1308 /* Just assume -1 */
1311 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1313 if (unformat (i, "permit"))
1315 vec_validate_macip_acl_rules(rules, rule_idx);
1316 rules[rule_idx].is_permit = 1;
1318 else if (unformat (i, "deny"))
1320 vec_validate_macip_acl_rules(rules, rule_idx);
1321 rules[rule_idx].is_permit = 0;
1323 else if (unformat (i, "count %d", &n_rules_override))
1325 /* we will use this later */
1327 else if (unformat (i, "action %d", &action))
1329 vec_validate_macip_acl_rules(rules, rule_idx);
1330 rules[rule_idx].is_permit = action;
1332 else if (unformat (i, "ip %U/%d",
1333 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1334 unformat (i, "ip %U",
1335 unformat_ip4_address, &src_v4address))
1337 if (src_prefix_length == 0)
1338 src_prefix_length = 32;
1339 vec_validate_macip_acl_rules(rules, rule_idx);
1340 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
1341 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
1342 rules[rule_idx].src_prefix.len = src_prefix_length;
1344 else if (unformat (i, "src"))
1346 /* Everything in MACIP is "source" but allow this verbosity */
1348 else if (unformat (i, "ip %U/%d",
1349 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1350 unformat (i, "ip %U",
1351 unformat_ip6_address, &src_v6address))
1353 if (src_prefix_length == 0)
1354 src_prefix_length = 128;
1355 vec_validate_macip_acl_rules(rules, rule_idx);
1356 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v6address, 4);
1357 rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
1358 rules[rule_idx].src_prefix.len = src_prefix_length;
1360 else if (unformat (i, "mac %U",
1361 my_unformat_mac_address, &src_mac))
1363 vec_validate_macip_acl_rules(rules, rule_idx);
1364 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1365 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1367 else if (unformat (i, "mask %U",
1368 my_unformat_mac_address, &src_mac))
1370 vec_validate_macip_acl_rules(rules, rule_idx);
1371 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1373 else if (unformat (i, "tag %s", &tag))
1376 else if (unformat (i, ","))
1379 vec_validate_macip_acl_rules(rules, rule_idx);
1387 errmsg ("rule/s required\n");
1390 /* Construct the API message */
1391 vam->result_ready = 0;
1394 n_rules = vec_len(rules);
1396 if (n_rules_override >= 0)
1397 n_rules = n_rules_override;
1399 msg_size += n_rules*sizeof(rules[0]);
1401 mp = vl_msg_api_alloc_as_if_client(msg_size);
1402 clib_memset (mp, 0, msg_size);
1403 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
1404 mp->client_index = vam->my_client_index;
1405 if ((n_rules > 0) && rules)
1406 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1409 if (vec_len(tag) >= sizeof(mp->tag))
1411 tag[sizeof(mp->tag)-1] = 0;
1412 _vec_len(tag) = sizeof(mp->tag);
1414 clib_memcpy(mp->tag, tag, vec_len(tag));
1418 mp->acl_index = ntohl(acl_index);
1419 mp->count = htonl(n_rules);
1424 /* Wait for a reply... */
1429 #define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE local_setup_message_id_table
1430 static void local_setup_message_id_table (vat_main_t * vam)
1432 hash_set_mem (vam->function_by_name, "acl_add_replace_from_file", api_acl_add_replace_from_file);
1433 hash_set_mem (vam->help_by_name, "acl_add_replace_from_file",
1434 "filename <file> [permit] [append-default-permit]");
1437 #include <acl/acl.api_test.c>