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_endianfun /* define message structures */
40 #include <acl/acl.api.h>
44 /* API message ID base */
49 acl_test_main_t acl_test_main;
51 #define foreach_reply_retval_aclindex_handler \
52 _(acl_add_replace_reply) \
53 _(macip_acl_add_reply) \
54 _(macip_acl_add_replace_reply)
57 static void vl_api_##n##_t_handler \
58 (vl_api_##n##_t * mp) \
60 vat_main_t * vam = acl_test_main.vat_main; \
61 i32 retval = ntohl(mp->retval); \
62 if (vam->async_mode) { \
63 vam->async_errors += (retval < 0); \
65 clib_warning("ACL index: %d", ntohl(mp->acl_index)); \
66 vam->retval = retval; \
67 vam->result_ready = 1; \
70 foreach_reply_retval_aclindex_handler;
73 /* These two ought to be in a library somewhere but they aren't */
75 my_unformat_mac_address (unformat_input_t * input, va_list * args)
77 u8 *a = va_arg (*args, u8 *);
78 return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
83 my_format_mac_address (u8 * s, va_list * args)
85 u8 *a = va_arg (*args, u8 *);
86 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
87 a[0], a[1], a[2], a[3], a[4], a[5]);
92 static void vl_api_acl_plugin_get_version_reply_t_handler
93 (vl_api_acl_plugin_get_version_reply_t * mp)
95 vat_main_t * vam = acl_test_main.vat_main;
96 clib_warning("ACL plugin version: %d.%d", ntohl(mp->major), ntohl(mp->minor));
97 vam->result_ready = 1;
101 vl_api_acl_plugin_use_hash_lookup_get_reply_t_handler (
102 vl_api_acl_plugin_use_hash_lookup_get_reply_t *mp)
104 vat_main_t *vam = acl_test_main.vat_main;
105 clib_warning ("ACL hash lookups enabled: %d", mp->enable);
106 vam->result_ready = 1;
109 static void vl_api_acl_interface_list_details_t_handler
110 (vl_api_acl_interface_list_details_t * mp)
113 vat_main_t * vam = acl_test_main.vat_main;
115 vl_api_acl_interface_list_details_t_endian(mp);
116 out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
117 out = format(out, " input ");
118 for(i=0; i<mp->count; i++) {
119 if (i == mp->n_input)
120 out = format(out, "\n output ");
121 out = format(out, "%d ", ntohl (mp->acls[i]));
123 out = format(out, "\n");
124 clib_warning("%s", out);
126 vam->result_ready = 1;
129 static void vl_api_macip_acl_interface_list_details_t_handler
130 (vl_api_macip_acl_interface_list_details_t * mp)
132 // NOT YET IMPLEMENTED
136 static void vl_api_acl_interface_etype_whitelist_details_t_handler
137 (vl_api_acl_interface_etype_whitelist_details_t * mp)
140 vat_main_t * vam = acl_test_main.vat_main;
142 vl_api_acl_interface_etype_whitelist_details_t_endian(mp);
143 out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
144 out = format(out, " input ");
145 for(i=0; i<mp->count; i++) {
146 if (i == mp->n_input)
147 out = format(out, "\n output ");
148 out = format(out, "%04x ", ntohs(mp->whitelist[i]));
150 out = format(out, "\n");
151 clib_warning("%s", out);
153 vam->result_ready = 1;
156 static void vl_api_acl_plugin_get_conn_table_max_entries_reply_t_handler
157 (vl_api_acl_plugin_get_conn_table_max_entries_reply_t * mp)
159 vat_main_t * vam = acl_test_main.vat_main;
160 clib_warning("\nConn table max entries: %d",
161 __bswap_64(mp->conn_table_max_entries) );
162 vam->result_ready = 1;
166 vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a)
168 int af = a->src_prefix.address.af ? AF_INET6 : AF_INET;
169 u8 src[INET6_ADDRSTRLEN];
170 u8 dst[INET6_ADDRSTRLEN];
171 inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
172 inet_ntop(af, &a->dst_prefix.address.un, (void *)dst, sizeof(dst));
174 out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d mask %d",
175 a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
176 src, a->src_prefix.len,
177 dst, a->dst_prefix.len,
179 a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
180 a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
181 a->tcp_flags_value, a->tcp_flags_mask);
187 static void vl_api_acl_details_t_handler
188 (vl_api_acl_details_t * mp)
191 vat_main_t * vam = acl_test_main.vat_main;
192 vl_api_acl_details_t_endian(mp);
194 out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
195 for(i=0; i<mp->count; i++) {
196 out = format(out, " ");
197 out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]);
198 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
200 clib_warning("%s", out);
202 vam->result_ready = 1;
206 vl_api_macip_acl_rule_t_pretty_format (u8 *out, vl_api_macip_acl_rule_t * a)
208 int af = a->src_prefix.address.af ? AF_INET6 : AF_INET;
209 u8 src[INET6_ADDRSTRLEN];
210 inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
212 out = format(out, "%s action %d ip %s/%d mac %U mask %U",
213 a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
214 src, a->src_prefix.len,
215 my_format_mac_address, a->src_mac,
216 my_format_mac_address, a->src_mac_mask);
221 static void vl_api_macip_acl_details_t_handler
222 (vl_api_macip_acl_details_t * mp)
225 vat_main_t * vam = acl_test_main.vat_main;
226 vl_api_macip_acl_details_t_endian(mp);
227 u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
228 for(i=0; i<mp->count; i++) {
229 out = format(out, " ");
230 out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]);
231 out = format(out, "%s\n", i<mp->count-1 ? "," : "");
233 clib_warning("%s", out);
235 vam->result_ready = 1;
238 static void vl_api_macip_acl_interface_get_reply_t_handler
239 (vl_api_macip_acl_interface_get_reply_t * mp)
242 vat_main_t * vam = acl_test_main.vat_main;
243 u8 *out = format(0, "sw_if_index with MACIP ACL count: %d\n", ntohl(mp->count));
244 for(i=0; i<ntohl(mp->count); i++) {
245 out = format(out, " macip_acl_interface_add_del sw_if_index %d add acl %d\n", i, ntohl(mp->acls[i]));
247 out = format(out, "\n");
248 clib_warning("%s", out);
250 vam->result_ready = 1;
253 static void vl_api_acl_plugin_control_ping_reply_t_handler
254 (vl_api_acl_plugin_control_ping_reply_t * mp)
256 vat_main_t *vam = &vat_main;
257 i32 retval = ntohl (mp->retval);
260 vam->async_errors += (retval < 0);
264 vam->retval = retval;
265 vam->result_ready = 1;
269 static int api_acl_plugin_get_version (vat_main_t * vam)
271 acl_test_main_t * sm = &acl_test_main;
272 vl_api_acl_plugin_get_version_t * mp;
273 u32 msg_size = sizeof(*mp);
276 vam->result_ready = 0;
277 mp = vl_msg_api_alloc_as_if_client(msg_size);
278 clib_memset (mp, 0, msg_size);
279 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base);
280 mp->client_index = vam->my_client_index;
285 /* Wait for a reply... */
290 static int api_macip_acl_interface_get (vat_main_t * vam)
292 acl_test_main_t * sm = &acl_test_main;
293 vl_api_acl_plugin_get_version_t * mp;
294 u32 msg_size = sizeof(*mp);
297 vam->result_ready = 0;
298 mp = vl_msg_api_alloc_as_if_client(msg_size);
299 clib_memset (mp, 0, msg_size);
300 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_INTERFACE_GET + sm->msg_id_base);
301 mp->client_index = vam->my_client_index;
306 /* Wait for a reply... */
311 #define vec_validate_acl_rules(v, idx) \
313 if (vec_len(v) < idx+1) { \
314 vec_validate(v, idx); \
315 v[idx].is_permit = 0x1; \
316 v[idx].srcport_or_icmptype_last = 0xffff; \
317 v[idx].dstport_or_icmpcode_last = 0xffff; \
322 /* NOT YET IMPLEMENTED */
323 static int api_acl_plugin_control_ping (vat_main_t * vam)
327 static int api_macip_acl_interface_list_dump (vat_main_t * vam)
332 static int api_acl_add_replace (vat_main_t * vam)
334 acl_test_main_t * sm = &acl_test_main;
335 unformat_input_t * i = vam->input;
336 vl_api_acl_add_replace_t * mp;
338 u32 msg_size = sizeof (*mp); /* without the rules */
340 vl_api_acl_rule_t *rules = 0;
343 int n_rules_override = -1;
348 u32 tcpflags, tcpmask;
349 u32 src_prefix_length = 0, dst_prefix_length = 0;
350 ip4_address_t src_v4address, dst_v4address;
351 ip6_address_t src_v6address, dst_v6address;
355 if (!unformat (i, "%d", &acl_index)) {
359 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
361 if (unformat (i, "permit+reflect"))
363 vec_validate_acl_rules(rules, rule_idx);
364 rules[rule_idx].is_permit = 2;
366 else if (unformat (i, "permit"))
368 vec_validate_acl_rules(rules, rule_idx);
369 rules[rule_idx].is_permit = 1;
371 else if (unformat (i, "deny"))
373 vec_validate_acl_rules(rules, rule_idx);
374 rules[rule_idx].is_permit = 0;
376 else if (unformat (i, "count %d", &n_rules_override))
378 /* we will use this later */
380 else if (unformat (i, "action %d", &action))
382 vec_validate_acl_rules(rules, rule_idx);
383 rules[rule_idx].is_permit = action;
385 else if (unformat (i, "src %U/%d",
386 unformat_ip4_address, &src_v4address, &src_prefix_length))
388 vec_validate_acl_rules(rules, rule_idx);
389 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
390 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
391 rules[rule_idx].src_prefix.len = src_prefix_length;
393 else if (unformat (i, "src %U/%d",
394 unformat_ip6_address, &src_v6address, &src_prefix_length))
396 vec_validate_acl_rules(rules, rule_idx);
397 memcpy (rules[rule_idx].src_prefix.address.un.ip6, &src_v6address, 16);
398 rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
399 rules[rule_idx].src_prefix.len = src_prefix_length;
401 else if (unformat (i, "dst %U/%d",
402 unformat_ip4_address, &dst_v4address, &dst_prefix_length))
404 vec_validate_acl_rules(rules, rule_idx);
405 memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
406 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
407 rules[rule_idx].dst_prefix.len = dst_prefix_length;
409 else if (unformat (i, "dst %U/%d",
410 unformat_ip6_address, &dst_v6address, &dst_prefix_length))
412 vec_validate_acl_rules(rules, rule_idx);
413 memcpy (rules[rule_idx].dst_prefix.address.un.ip6, &dst_v6address, 16);
414 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP6;
415 rules[rule_idx].dst_prefix.len = dst_prefix_length;
417 else if (unformat (i, "sport %d-%d", &port1, &port2))
419 vec_validate_acl_rules(rules, rule_idx);
420 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
421 rules[rule_idx].srcport_or_icmptype_last = htons(port2);
423 else if (unformat (i, "sport %d", &port1))
425 vec_validate_acl_rules(rules, rule_idx);
426 rules[rule_idx].srcport_or_icmptype_first = htons(port1);
427 rules[rule_idx].srcport_or_icmptype_last = htons(port1);
429 else if (unformat (i, "dport %d-%d", &port1, &port2))
431 vec_validate_acl_rules(rules, rule_idx);
432 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
433 rules[rule_idx].dstport_or_icmpcode_last = htons(port2);
435 else if (unformat (i, "dport %d", &port1))
437 vec_validate_acl_rules(rules, rule_idx);
438 rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
439 rules[rule_idx].dstport_or_icmpcode_last = htons(port1);
441 else if (unformat (i, "tcpflags %d %d", &tcpflags, &tcpmask))
443 vec_validate_acl_rules(rules, rule_idx);
444 rules[rule_idx].tcp_flags_value = tcpflags;
445 rules[rule_idx].tcp_flags_mask = tcpmask;
447 else if (unformat (i, "tcpflags %d mask %d", &tcpflags, &tcpmask))
449 vec_validate_acl_rules(rules, rule_idx);
450 rules[rule_idx].tcp_flags_value = tcpflags;
451 rules[rule_idx].tcp_flags_mask = tcpmask;
453 else if (unformat (i, "proto %d", &proto))
455 vec_validate_acl_rules(rules, rule_idx);
456 rules[rule_idx].proto = proto;
458 else if (unformat (i, "tag %s", &tag))
461 else if (unformat (i, ","))
464 vec_validate_acl_rules(rules, rule_idx);
470 /* Construct the API message */
471 vam->result_ready = 0;
474 n_rules = vec_len(rules);
478 if (n_rules_override >= 0)
479 n_rules = n_rules_override;
481 msg_size += n_rules*sizeof(rules[0]);
483 mp = vl_msg_api_alloc_as_if_client(msg_size);
484 clib_memset (mp, 0, msg_size);
485 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
486 mp->client_index = vam->my_client_index;
487 if ((n_rules > 0) && rules)
488 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
491 if (vec_len(tag) >= sizeof(mp->tag))
493 tag[sizeof(mp->tag)-1] = 0;
494 vec_set_len (tag, sizeof (mp->tag));
496 clib_memcpy (mp->tag, tag, vec_len (tag));
499 mp->acl_index = ntohl(acl_index);
500 mp->count = htonl(n_rules);
505 /* Wait for a reply... */
510 static int api_acl_plugin_get_conn_table_max_entries (vat_main_t * vam)
512 acl_test_main_t * sm = &acl_test_main;
513 vl_api_acl_plugin_get_conn_table_max_entries_t * mp;
514 u32 msg_size = sizeof(*mp);
517 vam->result_ready = 0;
518 mp = vl_msg_api_alloc_as_if_client(msg_size);
519 memset (mp, 0, msg_size);
520 mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_CONN_TABLE_MAX_ENTRIES + sm->msg_id_base);
521 mp->client_index = vam->my_client_index;
526 /* Wait for a reply... */
531 static int api_acl_stats_intf_counters_enable (vat_main_t * vam)
533 acl_test_main_t * sm = &acl_test_main;
534 unformat_input_t * i = vam->input;
535 vl_api_acl_stats_intf_counters_enable_t * mp;
536 u32 msg_size = sizeof(*mp);
539 vam->result_ready = 0;
540 mp = vl_msg_api_alloc_as_if_client(msg_size);
541 memset (mp, 0, msg_size);
542 mp->_vl_msg_id = ntohs (VL_API_ACL_STATS_INTF_COUNTERS_ENABLE + sm->msg_id_base);
543 mp->client_index = vam->my_client_index;
546 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
547 if (unformat (i, "disable"))
556 /* Wait for a reply... */
562 api_acl_plugin_use_hash_lookup_set (vat_main_t *vam)
564 acl_test_main_t *sm = &acl_test_main;
565 unformat_input_t *i = vam->input;
566 vl_api_acl_plugin_use_hash_lookup_set_t *mp;
567 u32 msg_size = sizeof (*mp);
570 vam->result_ready = 0;
571 mp = vl_msg_api_alloc_as_if_client (msg_size);
572 memset (mp, 0, msg_size);
574 ntohs (VL_API_ACL_PLUGIN_USE_HASH_LOOKUP_SET + sm->msg_id_base);
575 mp->client_index = vam->my_client_index;
578 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
580 if (unformat (i, "disable"))
582 else if (unformat (i, "enable"))
591 /* Wait for a reply... */
597 api_acl_plugin_use_hash_lookup_get (vat_main_t *vam)
599 acl_test_main_t *sm = &acl_test_main;
600 vl_api_acl_plugin_use_hash_lookup_set_t *mp;
601 u32 msg_size = sizeof (*mp);
604 vam->result_ready = 0;
605 mp = vl_msg_api_alloc_as_if_client (msg_size);
606 memset (mp, 0, msg_size);
608 ntohs (VL_API_ACL_PLUGIN_USE_HASH_LOOKUP_GET + sm->msg_id_base);
609 mp->client_index = vam->my_client_index;
614 /* Wait for a reply... */
620 * Read the series of ACL entries from file in the following format:
623 @0.0.0.0/1 131.179.121.0/24 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
624 @128.0.0.0/1 85.54.226.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
625 @128.0.0.0/1 85.54.48.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
626 @128.0.0.0/1 31.237.44.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
627 @0.0.0.0/1 255.84.184.0/23 0 : 65535 0 : 65535 0x00/0x00 0x0000/0x0000
628 @132.92.0.0/16 0.0.0.0/0 0 : 65535 0 : 65535 0x01/0xFF 0x0000/0x0000
634 api_acl_add_replace_from_file (vat_main_t * vam)
637 unformat_input_t * input = vam->input;
638 acl_test_main_t * sm = &acl_test_main;
639 vl_api_acl_add_replace_t * mp;
641 u32 msg_size = sizeof (*mp); /* without the rules */
643 vl_api_acl_rule_t *rules = 0;
647 int append_default_permit = 0;
648 u32 tcpflags = 0, tcpmask = 0;
649 ip4_address_t src_v4address, dst_v4address;
652 char *file_name = NULL;
653 unformat_input_t file_input;
655 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
657 if (unformat (input, "filename %s", &file_name))
659 /* we will use this later */
661 else if (unformat (input, "acl-index %d", &acl_index))
663 /* we will try to replace an existing ACL */
665 else if (unformat (input, "permit+reflect"))
669 else if (unformat (input, "permit"))
673 else if (unformat (input, "append-default-permit"))
675 append_default_permit = 1;
681 if (file_name == NULL)
684 fd = open(file_name, O_RDONLY);
687 clib_warning("Could not open file '%s'", file_name);
691 /* input from file */
693 unformat_init_clib_file(input, fd);
695 unsigned sport_low, sport_high, dport_low, dport_high;
696 unsigned proto, protomask;
697 u32 src_prefix_length, dst_prefix_length;
698 u32 unused1, unused2;
700 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
702 if (!unformat(input, "@%U/%d\t%U/%d\t%d : %d\t%d : %d\t0x%x/0x%x\t0x%x/0x%x",
703 unformat_ip4_address, &src_v4address, &src_prefix_length,
704 unformat_ip4_address, &dst_v4address, &dst_prefix_length,
705 &sport_low, &sport_high, &dport_low, &dport_high, &proto, &protomask, &unused1, &unused2)) {
706 clib_warning("Error parsing");
711 vec_validate_acl_rules(rules, rule_idx);
713 rules[rule_idx].is_permit = is_permit;
714 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
715 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
716 rules[rule_idx].src_prefix.len = src_prefix_length;
717 memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
718 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
719 rules[rule_idx].dst_prefix.len = dst_prefix_length;
720 rules[rule_idx].srcport_or_icmptype_first = htons(sport_low);
721 rules[rule_idx].srcport_or_icmptype_last = htons(sport_high);
722 rules[rule_idx].dstport_or_icmpcode_first = htons(dport_low);
723 rules[rule_idx].dstport_or_icmpcode_last = htons(dport_high);
724 rules[rule_idx].tcp_flags_value = tcpflags;
725 rules[rule_idx].tcp_flags_mask = tcpmask;
726 rules[rule_idx].proto = proto;
730 if (append_default_permit) {
732 vec_validate_acl_rules(rules, rule_idx);
734 rules[rule_idx].is_permit = is_permit == 2 ? 2 : 1;
736 src_v4address.data[0]=0;
737 src_v4address.data[1]=0;
738 src_v4address.data[2]=0;
739 src_v4address.data[3]=0;
740 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
741 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
742 rules[rule_idx].src_prefix.len = 0;
744 dst_v4address.data[0]=0;
745 dst_v4address.data[1]=0;
746 dst_v4address.data[2]=0;
747 dst_v4address.data[3]=0;
748 memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
749 rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
750 rules[rule_idx].dst_prefix.len = 0;
752 rules[rule_idx].srcport_or_icmptype_first = htons(0);
753 rules[rule_idx].srcport_or_icmptype_last = htons(65535);
754 rules[rule_idx].dstport_or_icmpcode_first = htons(0);
755 rules[rule_idx].dstport_or_icmpcode_last = htons(65535);
756 rules[rule_idx].tcp_flags_value = 0;
757 rules[rule_idx].tcp_flags_mask = 0;
758 rules[rule_idx].proto = 0;
761 /* Construct the API message */
763 vam->result_ready = 0;
765 n_rules = vec_len(rules);
767 msg_size += n_rules*sizeof(rules[0]);
769 mp = vl_msg_api_alloc_as_if_client(msg_size);
770 clib_memset (mp, 0, msg_size);
771 mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
772 mp->client_index = vam->my_client_index;
774 clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
775 mp->acl_index = ntohl(acl_index);
776 mp->count = htonl(n_rules);
781 /* Wait for a reply... */
792 static int api_acl_del (vat_main_t * vam)
794 unformat_input_t * i = vam->input;
795 vl_api_acl_del_t * mp;
799 if (!unformat (i, "%d", &acl_index)) {
800 errmsg ("missing acl index\n");
804 /* Construct the API message */
806 mp->acl_index = ntohl(acl_index);
811 /* Wait for a reply... */
816 static int api_macip_acl_del (vat_main_t * vam)
818 unformat_input_t * i = vam->input;
819 vl_api_acl_del_t * mp;
823 if (!unformat (i, "%d", &acl_index)) {
824 errmsg ("missing acl index\n");
828 /* Construct the API message */
829 M(MACIP_ACL_DEL, mp);
830 mp->acl_index = ntohl(acl_index);
835 /* Wait for a reply... */
840 static int api_acl_interface_add_del (vat_main_t * vam)
842 unformat_input_t * i = vam->input;
843 vl_api_acl_interface_add_del_t * mp;
844 u32 sw_if_index = ~0;
850 // acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del]
852 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
854 if (unformat (i, "%d", &acl_index))
861 /* Parse args required to build the message */
862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
863 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
865 else if (unformat (i, "sw_if_index %d", &sw_if_index))
867 else if (unformat (i, "add"))
869 else if (unformat (i, "del"))
871 else if (unformat (i, "acl %d", &acl_index))
873 else if (unformat (i, "input"))
875 else if (unformat (i, "output"))
881 if (sw_if_index == ~0) {
882 errmsg ("missing interface name / explicit sw_if_index number \n");
886 if (acl_index == ~0) {
887 errmsg ("missing ACL index\n");
893 /* Construct the API message */
894 M(ACL_INTERFACE_ADD_DEL, mp);
895 mp->acl_index = ntohl(acl_index);
896 mp->sw_if_index = ntohl(sw_if_index);
898 mp->is_input = is_input;
903 /* Wait for a reply... */
908 static int api_macip_acl_interface_add_del (vat_main_t * vam)
910 unformat_input_t * i = vam->input;
911 vl_api_macip_acl_interface_add_del_t * mp;
912 u32 sw_if_index = ~0;
917 /* Parse args required to build the message */
918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
919 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
921 else if (unformat (i, "sw_if_index %d", &sw_if_index))
923 else if (unformat (i, "add"))
925 else if (unformat (i, "del"))
927 else if (unformat (i, "acl %d", &acl_index))
933 if (sw_if_index == ~0) {
934 errmsg ("missing interface name / explicit sw_if_index number \n");
938 if (acl_index == ~0) {
939 errmsg ("missing ACL index\n");
945 /* Construct the API message */
946 M(MACIP_ACL_INTERFACE_ADD_DEL, mp);
947 mp->acl_index = ntohl(acl_index);
948 mp->sw_if_index = ntohl(sw_if_index);
954 /* Wait for a reply... */
959 static int api_acl_interface_set_acl_list (vat_main_t * vam)
961 unformat_input_t * i = vam->input;
962 vl_api_acl_interface_set_acl_list_t * mp;
963 u32 sw_if_index = ~0;
970 // acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]
972 /* Parse args required to build the message */
973 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
974 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
976 else if (unformat (i, "sw_if_index %d", &sw_if_index))
978 else if (unformat (i, "%d", &acl_index))
981 vec_add1(inacls, htonl(acl_index));
983 vec_add1(outacls, htonl(acl_index));
985 else if (unformat (i, "acl %d", &acl_index))
987 else if (unformat (i, "input"))
989 else if (unformat (i, "output"))
995 if (sw_if_index == ~0) {
996 errmsg ("missing interface name / explicit sw_if_index number \n");
1000 /* Construct the API message */
1001 M2(ACL_INTERFACE_SET_ACL_LIST, mp, sizeof(u32) * (vec_len(inacls) + vec_len(outacls)));
1002 mp->sw_if_index = ntohl(sw_if_index);
1003 mp->n_input = vec_len(inacls);
1004 mp->count = vec_len(inacls) + vec_len(outacls);
1005 vec_append(inacls, outacls);
1006 if (vec_len(inacls) > 0)
1007 clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32));
1012 /* Wait for a reply... */
1017 static int api_acl_interface_set_etype_whitelist (vat_main_t * vam)
1019 unformat_input_t * i = vam->input;
1020 vl_api_acl_interface_set_etype_whitelist_t * mp;
1021 u32 sw_if_index = ~0;
1024 u16 *etypes_out = 0;
1028 // acl_interface_set_etype_whitelist <intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]
1030 /* Parse args required to build the message */
1031 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1032 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1034 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1036 else if (unformat (i, "%x", ðertype))
1038 ethertype = ethertype & 0xffff;
1040 vec_add1(etypes_in, htons(ethertype));
1042 vec_add1(etypes_out, htons(ethertype));
1044 else if (unformat (i, "input"))
1046 else if (unformat (i, "output"))
1052 if (sw_if_index == ~0) {
1053 errmsg ("missing interface name / explicit sw_if_index number \n");
1057 /* Construct the API message */
1058 M2(ACL_INTERFACE_SET_ETYPE_WHITELIST, mp, sizeof(u32) * (vec_len(etypes_in) + vec_len(etypes_out)));
1059 mp->sw_if_index = ntohl(sw_if_index);
1060 mp->n_input = vec_len(etypes_in);
1061 mp->count = vec_len(etypes_in) + vec_len(etypes_out);
1062 vec_append(etypes_in, etypes_out);
1063 if (vec_len(etypes_in) > 0)
1064 clib_memcpy(mp->whitelist, etypes_in, vec_len(etypes_in)*sizeof(etypes_in[0]));
1069 /* Wait for a reply... */
1075 api_acl_send_control_ping(vat_main_t *vam)
1077 vl_api_acl_plugin_control_ping_t *mp_ping;
1079 M(ACL_PLUGIN_CONTROL_PING, mp_ping);
1084 static int api_acl_interface_list_dump (vat_main_t * vam)
1086 unformat_input_t * i = vam->input;
1087 u32 sw_if_index = ~0;
1088 vl_api_acl_interface_list_dump_t * mp;
1091 /* Parse args required to build the message */
1092 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1093 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1095 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1101 /* Construct the API message */
1102 M(ACL_INTERFACE_LIST_DUMP, mp);
1103 mp->sw_if_index = ntohl (sw_if_index);
1108 /* Use control ping for synchronization */
1109 api_acl_send_control_ping(vam);
1111 /* Wait for a reply... */
1116 static int api_acl_dump (vat_main_t * vam)
1118 unformat_input_t * i = vam->input;
1120 vl_api_acl_dump_t * mp;
1123 /* Parse args required to build the message */
1124 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1125 if (unformat (i, "%d", &acl_index))
1131 /* Construct the API message */
1133 mp->acl_index = ntohl (acl_index);
1138 /* Use control ping for synchronization */
1139 api_acl_send_control_ping(vam);
1141 /* Wait for a reply... */
1146 static int api_macip_acl_dump (vat_main_t * vam)
1148 unformat_input_t * i = vam->input;
1150 vl_api_acl_dump_t * mp;
1153 /* Parse args required to build the message */
1154 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1155 if (unformat (i, "%d", &acl_index))
1161 /* Construct the API message */
1162 M(MACIP_ACL_DUMP, mp);
1163 mp->acl_index = ntohl (acl_index);
1168 /* Use control ping for synchronization */
1169 api_acl_send_control_ping(vam);
1171 /* Wait for a reply... */
1176 static int api_acl_interface_etype_whitelist_dump (vat_main_t * vam)
1178 unformat_input_t * i = vam->input;
1179 u32 sw_if_index = ~0;
1180 vl_api_acl_interface_etype_whitelist_dump_t * mp;
1183 /* Parse args required to build the message */
1184 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1185 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1187 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1193 /* Construct the API message */
1194 M(ACL_INTERFACE_ETYPE_WHITELIST_DUMP, mp);
1195 mp->sw_if_index = ntohl (sw_if_index);
1200 /* Use control ping for synchronization */
1201 api_acl_send_control_ping(vam);
1203 /* Wait for a reply... */
1209 #define vec_validate_macip_acl_rules(v, idx) \
1211 if (vec_len(v) < idx+1) { \
1212 vec_validate(v, idx); \
1213 v[idx].is_permit = 0x1; \
1218 static int api_macip_acl_add (vat_main_t * vam)
1220 acl_test_main_t * sm = &acl_test_main;
1221 unformat_input_t * i = vam->input;
1222 vl_api_macip_acl_add_t * mp;
1223 u32 msg_size = sizeof (*mp); /* without the rules */
1225 vl_api_macip_acl_rule_t *rules = 0;
1228 int n_rules_override = -1;
1229 u32 src_prefix_length = 0;
1231 ip4_address_t src_v4address;
1232 ip6_address_t src_v6address;
1235 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1238 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1240 if (unformat (i, "permit"))
1242 vec_validate_macip_acl_rules(rules, rule_idx);
1243 rules[rule_idx].is_permit = 1;
1245 else if (unformat (i, "deny"))
1247 vec_validate_macip_acl_rules(rules, rule_idx);
1248 rules[rule_idx].is_permit = 0;
1250 else if (unformat (i, "count %d", &n_rules_override))
1252 /* we will use this later */
1254 else if (unformat (i, "action %d", &action))
1256 vec_validate_macip_acl_rules(rules, rule_idx);
1257 rules[rule_idx].is_permit = action;
1259 else if (unformat (i, "ip %U/%d",
1260 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1261 unformat (i, "ip %U",
1262 unformat_ip4_address, &src_v4address))
1264 if (src_prefix_length == 0)
1265 src_prefix_length = 32;
1266 vec_validate_macip_acl_rules(rules, rule_idx);
1267 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
1268 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
1269 rules[rule_idx].src_prefix.len = src_prefix_length;
1271 else if (unformat (i, "src"))
1273 /* Everything in MACIP is "source" but allow this verbosity */
1275 else if (unformat (i, "ip %U/%d",
1276 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1277 unformat (i, "ip %U",
1278 unformat_ip6_address, &src_v6address))
1280 if (src_prefix_length == 0)
1281 src_prefix_length = 128;
1282 vec_validate_macip_acl_rules(rules, rule_idx);
1283 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v6address, 4);
1284 rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
1285 rules[rule_idx].src_prefix.len = src_prefix_length;
1287 else if (unformat (i, "mac %U",
1288 my_unformat_mac_address, &src_mac))
1290 vec_validate_macip_acl_rules(rules, rule_idx);
1291 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1292 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1294 else if (unformat (i, "mask %U",
1295 my_unformat_mac_address, &src_mac))
1297 vec_validate_macip_acl_rules(rules, rule_idx);
1298 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1300 else if (unformat (i, "tag %s", &tag))
1303 else if (unformat (i, ","))
1306 vec_validate_macip_acl_rules(rules, rule_idx);
1312 /* Construct the API message */
1313 vam->result_ready = 0;
1316 n_rules = vec_len(rules);
1318 if (n_rules_override >= 0)
1319 n_rules = n_rules_override;
1321 msg_size += n_rules*sizeof(rules[0]);
1323 mp = vl_msg_api_alloc_as_if_client(msg_size);
1324 clib_memset (mp, 0, msg_size);
1325 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD + sm->msg_id_base);
1326 mp->client_index = vam->my_client_index;
1327 if ((n_rules > 0) && rules)
1328 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1331 if (vec_len(tag) >= sizeof(mp->tag))
1333 tag[sizeof(mp->tag)-1] = 0;
1334 vec_set_len (tag, sizeof (mp->tag));
1336 clib_memcpy (mp->tag, tag, vec_len (tag));
1340 mp->count = htonl(n_rules);
1345 /* Wait for a reply... */
1350 static int api_macip_acl_add_replace (vat_main_t * vam)
1352 acl_test_main_t * sm = &acl_test_main;
1353 unformat_input_t * i = vam->input;
1354 vl_api_macip_acl_add_replace_t * mp;
1356 u32 msg_size = sizeof (*mp); /* without the rules */
1358 vl_api_macip_acl_rule_t *rules = 0;
1361 int n_rules_override = -1;
1362 u32 src_prefix_length = 0;
1364 ip4_address_t src_v4address;
1365 ip6_address_t src_v6address;
1368 u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1371 if (!unformat (i, "%d", &acl_index)) {
1372 /* Just assume -1 */
1375 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1377 if (unformat (i, "permit"))
1379 vec_validate_macip_acl_rules(rules, rule_idx);
1380 rules[rule_idx].is_permit = 1;
1382 else if (unformat (i, "deny"))
1384 vec_validate_macip_acl_rules(rules, rule_idx);
1385 rules[rule_idx].is_permit = 0;
1387 else if (unformat (i, "count %d", &n_rules_override))
1389 /* we will use this later */
1391 else if (unformat (i, "action %d", &action))
1393 vec_validate_macip_acl_rules(rules, rule_idx);
1394 rules[rule_idx].is_permit = action;
1396 else if (unformat (i, "ip %U/%d",
1397 unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1398 unformat (i, "ip %U",
1399 unformat_ip4_address, &src_v4address))
1401 if (src_prefix_length == 0)
1402 src_prefix_length = 32;
1403 vec_validate_macip_acl_rules(rules, rule_idx);
1404 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
1405 rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
1406 rules[rule_idx].src_prefix.len = src_prefix_length;
1408 else if (unformat (i, "src"))
1410 /* Everything in MACIP is "source" but allow this verbosity */
1412 else if (unformat (i, "ip %U/%d",
1413 unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1414 unformat (i, "ip %U",
1415 unformat_ip6_address, &src_v6address))
1417 if (src_prefix_length == 0)
1418 src_prefix_length = 128;
1419 vec_validate_macip_acl_rules(rules, rule_idx);
1420 memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v6address, 4);
1421 rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
1422 rules[rule_idx].src_prefix.len = src_prefix_length;
1424 else if (unformat (i, "mac %U",
1425 my_unformat_mac_address, &src_mac))
1427 vec_validate_macip_acl_rules(rules, rule_idx);
1428 memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1429 memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1431 else if (unformat (i, "mask %U",
1432 my_unformat_mac_address, &src_mac))
1434 vec_validate_macip_acl_rules(rules, rule_idx);
1435 memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1437 else if (unformat (i, "tag %s", &tag))
1440 else if (unformat (i, ","))
1443 vec_validate_macip_acl_rules(rules, rule_idx);
1451 errmsg ("rule/s required\n");
1454 /* Construct the API message */
1455 vam->result_ready = 0;
1458 n_rules = vec_len(rules);
1460 if (n_rules_override >= 0)
1461 n_rules = n_rules_override;
1463 msg_size += n_rules*sizeof(rules[0]);
1465 mp = vl_msg_api_alloc_as_if_client(msg_size);
1466 clib_memset (mp, 0, msg_size);
1467 mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
1468 mp->client_index = vam->my_client_index;
1469 if ((n_rules > 0) && rules)
1470 clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1473 if (vec_len(tag) >= sizeof(mp->tag))
1475 tag[sizeof(mp->tag)-1] = 0;
1476 vec_set_len (tag, sizeof (mp->tag));
1478 clib_memcpy (mp->tag, tag, vec_len (tag));
1482 mp->acl_index = ntohl(acl_index);
1483 mp->count = htonl(n_rules);
1488 /* Wait for a reply... */
1493 #define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE local_setup_message_id_table
1494 static void local_setup_message_id_table (vat_main_t * vam)
1496 hash_set_mem (vam->function_by_name, "acl_add_replace_from_file", api_acl_add_replace_from_file);
1497 hash_set_mem (vam->help_by_name, "acl_add_replace_from_file",
1498 "filename <file> [permit] [append-default-permit]");
1501 #include <acl/acl.api_test.c>