Line data Source code
1 : /*
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:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
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.
14 : */
15 : /*
16 : *------------------------------------------------------------------
17 : * acl_test.c - test harness plugin
18 : *------------------------------------------------------------------
19 : */
20 :
21 : #include <vat/vat.h>
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>
27 :
28 : #include <vnet/ip/ip_format_fns.h>
29 : #include <vnet/ethernet/ethernet_format_fns.h>
30 :
31 : #define __plugin_msg_base acl_test_main.msg_id_base
32 : #include <vlibapi/vat_helper_macros.h>
33 :
34 : uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
35 :
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>
41 : #undef vl_endianfun
42 :
43 : typedef struct {
44 : /* API message ID base */
45 : u16 msg_id_base;
46 : vat_main_t *vat_main;
47 : } acl_test_main_t;
48 :
49 : acl_test_main_t acl_test_main;
50 :
51 : #define foreach_reply_retval_aclindex_handler \
52 : _(acl_add_replace_reply) \
53 : _(macip_acl_add_reply) \
54 : _(macip_acl_add_replace_reply)
55 :
56 : #define _(n) \
57 : static void vl_api_##n##_t_handler \
58 : (vl_api_##n##_t * mp) \
59 : { \
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); \
64 : } else { \
65 : clib_warning("ACL index: %d", ntohl(mp->acl_index)); \
66 : vam->retval = retval; \
67 : vam->result_ready = 1; \
68 : } \
69 : }
70 0 : foreach_reply_retval_aclindex_handler;
71 : #undef _
72 :
73 : /* These two ought to be in a library somewhere but they aren't */
74 : static uword
75 0 : my_unformat_mac_address (unformat_input_t * input, va_list * args)
76 : {
77 0 : u8 *a = va_arg (*args, u8 *);
78 0 : return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
79 : &a[4], &a[5]);
80 : }
81 :
82 : static u8 *
83 0 : my_format_mac_address (u8 * s, va_list * args)
84 : {
85 0 : u8 *a = va_arg (*args, u8 *);
86 0 : return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
87 0 : a[0], a[1], a[2], a[3], a[4], a[5]);
88 : }
89 :
90 :
91 :
92 0 : static void vl_api_acl_plugin_get_version_reply_t_handler
93 : (vl_api_acl_plugin_get_version_reply_t * mp)
94 : {
95 0 : vat_main_t * vam = acl_test_main.vat_main;
96 0 : clib_warning("ACL plugin version: %d.%d", ntohl(mp->major), ntohl(mp->minor));
97 0 : vam->result_ready = 1;
98 0 : }
99 :
100 : static void
101 0 : vl_api_acl_plugin_use_hash_lookup_get_reply_t_handler (
102 : vl_api_acl_plugin_use_hash_lookup_get_reply_t *mp)
103 : {
104 0 : vat_main_t *vam = acl_test_main.vat_main;
105 0 : clib_warning ("ACL hash lookups enabled: %d", mp->enable);
106 0 : vam->result_ready = 1;
107 0 : }
108 :
109 0 : static void vl_api_acl_interface_list_details_t_handler
110 : (vl_api_acl_interface_list_details_t * mp)
111 : {
112 : int i;
113 0 : vat_main_t * vam = acl_test_main.vat_main;
114 0 : u8 *out = 0;
115 0 : vl_api_acl_interface_list_details_t_endian(mp);
116 0 : out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
117 0 : out = format(out, " input ");
118 0 : for(i=0; i<mp->count; i++) {
119 0 : if (i == mp->n_input)
120 0 : out = format(out, "\n output ");
121 0 : out = format(out, "%d ", ntohl (mp->acls[i]));
122 : }
123 0 : out = format(out, "\n");
124 0 : clib_warning("%s", out);
125 0 : vec_free(out);
126 0 : vam->result_ready = 1;
127 0 : }
128 :
129 0 : static void vl_api_macip_acl_interface_list_details_t_handler
130 : (vl_api_macip_acl_interface_list_details_t * mp)
131 : {
132 : // NOT YET IMPLEMENTED
133 0 : }
134 :
135 :
136 0 : static void vl_api_acl_interface_etype_whitelist_details_t_handler
137 : (vl_api_acl_interface_etype_whitelist_details_t * mp)
138 : {
139 : int i;
140 0 : vat_main_t * vam = acl_test_main.vat_main;
141 0 : u8 *out = 0;
142 0 : vl_api_acl_interface_etype_whitelist_details_t_endian(mp);
143 0 : out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
144 0 : out = format(out, " input ");
145 0 : for(i=0; i<mp->count; i++) {
146 0 : if (i == mp->n_input)
147 0 : out = format(out, "\n output ");
148 0 : out = format(out, "%04x ", ntohs(mp->whitelist[i]));
149 : }
150 0 : out = format(out, "\n");
151 0 : clib_warning("%s", out);
152 0 : vec_free(out);
153 0 : vam->result_ready = 1;
154 0 : }
155 :
156 0 : 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)
158 : {
159 0 : vat_main_t * vam = acl_test_main.vat_main;
160 0 : clib_warning("\nConn table max entries: %d",
161 : __bswap_64(mp->conn_table_max_entries) );
162 0 : vam->result_ready = 1;
163 0 : }
164 :
165 : static inline u8 *
166 0 : vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a)
167 : {
168 0 : int af = a->src_prefix.address.af ? AF_INET6 : AF_INET;
169 : u8 src[INET6_ADDRSTRLEN];
170 : u8 dst[INET6_ADDRSTRLEN];
171 0 : inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
172 0 : inet_ntop(af, &a->dst_prefix.address.un, (void *)dst, sizeof(dst));
173 :
174 0 : 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 0 : a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
176 0 : src, a->src_prefix.len,
177 0 : dst, a->dst_prefix.len,
178 0 : a->proto,
179 0 : a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
180 0 : a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
181 0 : a->tcp_flags_value, a->tcp_flags_mask);
182 0 : return(out);
183 : }
184 :
185 :
186 :
187 0 : static void vl_api_acl_details_t_handler
188 : (vl_api_acl_details_t * mp)
189 : {
190 : int i;
191 0 : vat_main_t * vam = acl_test_main.vat_main;
192 0 : vl_api_acl_details_t_endian(mp);
193 0 : u8 *out = 0;
194 0 : out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
195 0 : for(i=0; i<mp->count; i++) {
196 0 : out = format(out, " ");
197 0 : out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]);
198 0 : out = format(out, "%s\n", i<mp->count-1 ? "," : "");
199 : }
200 0 : clib_warning("%s", out);
201 0 : vec_free(out);
202 0 : vam->result_ready = 1;
203 0 : }
204 :
205 : static inline u8 *
206 0 : vl_api_macip_acl_rule_t_pretty_format (u8 *out, vl_api_macip_acl_rule_t * a)
207 : {
208 0 : int af = a->src_prefix.address.af ? AF_INET6 : AF_INET;
209 : u8 src[INET6_ADDRSTRLEN];
210 0 : inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
211 :
212 0 : out = format(out, "%s action %d ip %s/%d mac %U mask %U",
213 0 : a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
214 0 : src, a->src_prefix.len,
215 0 : my_format_mac_address, a->src_mac,
216 0 : my_format_mac_address, a->src_mac_mask);
217 0 : return(out);
218 : }
219 :
220 :
221 0 : static void vl_api_macip_acl_details_t_handler
222 : (vl_api_macip_acl_details_t * mp)
223 : {
224 : int i;
225 0 : vat_main_t * vam = acl_test_main.vat_main;
226 0 : vl_api_macip_acl_details_t_endian(mp);
227 0 : u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag);
228 0 : for(i=0; i<mp->count; i++) {
229 0 : out = format(out, " ");
230 0 : out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]);
231 0 : out = format(out, "%s\n", i<mp->count-1 ? "," : "");
232 : }
233 0 : clib_warning("%s", out);
234 0 : vec_free(out);
235 0 : vam->result_ready = 1;
236 0 : }
237 :
238 0 : static void vl_api_macip_acl_interface_get_reply_t_handler
239 : (vl_api_macip_acl_interface_get_reply_t * mp)
240 : {
241 : int i;
242 0 : vat_main_t * vam = acl_test_main.vat_main;
243 0 : u8 *out = format(0, "sw_if_index with MACIP ACL count: %d\n", ntohl(mp->count));
244 0 : for(i=0; i<ntohl(mp->count); i++) {
245 0 : out = format(out, " macip_acl_interface_add_del sw_if_index %d add acl %d\n", i, ntohl(mp->acls[i]));
246 : }
247 0 : out = format(out, "\n");
248 0 : clib_warning("%s", out);
249 0 : vec_free(out);
250 0 : vam->result_ready = 1;
251 0 : }
252 :
253 0 : static void vl_api_acl_plugin_control_ping_reply_t_handler
254 : (vl_api_acl_plugin_control_ping_reply_t * mp)
255 : {
256 0 : vat_main_t *vam = &vat_main;
257 0 : i32 retval = ntohl (mp->retval);
258 0 : if (vam->async_mode)
259 : {
260 0 : vam->async_errors += (retval < 0);
261 : }
262 : else
263 : {
264 0 : vam->retval = retval;
265 0 : vam->result_ready = 1;
266 : }
267 0 : }
268 :
269 0 : static int api_acl_plugin_get_version (vat_main_t * vam)
270 : {
271 0 : acl_test_main_t * sm = &acl_test_main;
272 : vl_api_acl_plugin_get_version_t * mp;
273 0 : u32 msg_size = sizeof(*mp);
274 : int ret;
275 :
276 0 : vam->result_ready = 0;
277 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
278 0 : clib_memset (mp, 0, msg_size);
279 0 : mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base);
280 0 : mp->client_index = vam->my_client_index;
281 :
282 : /* send it... */
283 0 : S(mp);
284 :
285 : /* Wait for a reply... */
286 0 : W (ret);
287 0 : return ret;
288 : }
289 :
290 0 : static int api_macip_acl_interface_get (vat_main_t * vam)
291 : {
292 0 : acl_test_main_t * sm = &acl_test_main;
293 : vl_api_acl_plugin_get_version_t * mp;
294 0 : u32 msg_size = sizeof(*mp);
295 : int ret;
296 :
297 0 : vam->result_ready = 0;
298 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
299 0 : clib_memset (mp, 0, msg_size);
300 0 : mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_INTERFACE_GET + sm->msg_id_base);
301 0 : mp->client_index = vam->my_client_index;
302 :
303 : /* send it... */
304 0 : S(mp);
305 :
306 : /* Wait for a reply... */
307 0 : W (ret);
308 0 : return ret;
309 : }
310 :
311 : #define vec_validate_acl_rules(v, idx) \
312 : do { \
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; \
318 : } \
319 : } while (0)
320 :
321 :
322 : /* NOT YET IMPLEMENTED */
323 0 : static int api_acl_plugin_control_ping (vat_main_t * vam)
324 : {
325 0 : return 0;
326 : }
327 0 : static int api_macip_acl_interface_list_dump (vat_main_t * vam)
328 : {
329 0 : return 0;
330 : }
331 :
332 0 : static int api_acl_add_replace (vat_main_t * vam)
333 : {
334 0 : acl_test_main_t * sm = &acl_test_main;
335 0 : unformat_input_t * i = vam->input;
336 : vl_api_acl_add_replace_t * mp;
337 0 : u32 acl_index = ~0;
338 0 : u32 msg_size = sizeof (*mp); /* without the rules */
339 :
340 0 : vl_api_acl_rule_t *rules = 0;
341 0 : int rule_idx = 0;
342 0 : int n_rules = 0;
343 0 : int n_rules_override = -1;
344 0 : u32 proto = 0;
345 0 : u32 port1 = 0;
346 0 : u32 port2 = 0;
347 0 : u32 action = 0;
348 : u32 tcpflags, tcpmask;
349 0 : 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;
352 0 : u8 *tag = 0;
353 : int ret;
354 :
355 0 : if (!unformat (i, "%d", &acl_index)) {
356 : /* Just assume -1 */
357 : }
358 :
359 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
360 : {
361 0 : if (unformat (i, "permit+reflect"))
362 : {
363 0 : vec_validate_acl_rules(rules, rule_idx);
364 0 : rules[rule_idx].is_permit = 2;
365 : }
366 0 : else if (unformat (i, "permit"))
367 : {
368 0 : vec_validate_acl_rules(rules, rule_idx);
369 0 : rules[rule_idx].is_permit = 1;
370 : }
371 0 : else if (unformat (i, "deny"))
372 : {
373 0 : vec_validate_acl_rules(rules, rule_idx);
374 0 : rules[rule_idx].is_permit = 0;
375 : }
376 0 : else if (unformat (i, "count %d", &n_rules_override))
377 : {
378 : /* we will use this later */
379 : }
380 0 : else if (unformat (i, "action %d", &action))
381 : {
382 0 : vec_validate_acl_rules(rules, rule_idx);
383 0 : rules[rule_idx].is_permit = action;
384 : }
385 0 : else if (unformat (i, "src %U/%d",
386 : unformat_ip4_address, &src_v4address, &src_prefix_length))
387 : {
388 0 : vec_validate_acl_rules(rules, rule_idx);
389 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
390 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
391 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
392 : }
393 0 : else if (unformat (i, "src %U/%d",
394 : unformat_ip6_address, &src_v6address, &src_prefix_length))
395 : {
396 0 : vec_validate_acl_rules(rules, rule_idx);
397 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip6, &src_v6address, 16);
398 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
399 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
400 : }
401 0 : else if (unformat (i, "dst %U/%d",
402 : unformat_ip4_address, &dst_v4address, &dst_prefix_length))
403 : {
404 0 : vec_validate_acl_rules(rules, rule_idx);
405 0 : memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
406 0 : rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
407 0 : rules[rule_idx].dst_prefix.len = dst_prefix_length;
408 : }
409 0 : else if (unformat (i, "dst %U/%d",
410 : unformat_ip6_address, &dst_v6address, &dst_prefix_length))
411 : {
412 0 : vec_validate_acl_rules(rules, rule_idx);
413 0 : memcpy (rules[rule_idx].dst_prefix.address.un.ip6, &dst_v6address, 16);
414 0 : rules[rule_idx].dst_prefix.address.af = ADDRESS_IP6;
415 0 : rules[rule_idx].dst_prefix.len = dst_prefix_length;
416 : }
417 0 : else if (unformat (i, "sport %d-%d", &port1, &port2))
418 : {
419 0 : vec_validate_acl_rules(rules, rule_idx);
420 0 : rules[rule_idx].srcport_or_icmptype_first = htons(port1);
421 0 : rules[rule_idx].srcport_or_icmptype_last = htons(port2);
422 : }
423 0 : else if (unformat (i, "sport %d", &port1))
424 : {
425 0 : vec_validate_acl_rules(rules, rule_idx);
426 0 : rules[rule_idx].srcport_or_icmptype_first = htons(port1);
427 0 : rules[rule_idx].srcport_or_icmptype_last = htons(port1);
428 : }
429 0 : else if (unformat (i, "dport %d-%d", &port1, &port2))
430 : {
431 0 : vec_validate_acl_rules(rules, rule_idx);
432 0 : rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
433 0 : rules[rule_idx].dstport_or_icmpcode_last = htons(port2);
434 : }
435 0 : else if (unformat (i, "dport %d", &port1))
436 : {
437 0 : vec_validate_acl_rules(rules, rule_idx);
438 0 : rules[rule_idx].dstport_or_icmpcode_first = htons(port1);
439 0 : rules[rule_idx].dstport_or_icmpcode_last = htons(port1);
440 : }
441 0 : else if (unformat (i, "tcpflags %d %d", &tcpflags, &tcpmask))
442 : {
443 0 : vec_validate_acl_rules(rules, rule_idx);
444 0 : rules[rule_idx].tcp_flags_value = tcpflags;
445 0 : rules[rule_idx].tcp_flags_mask = tcpmask;
446 : }
447 0 : else if (unformat (i, "tcpflags %d mask %d", &tcpflags, &tcpmask))
448 : {
449 0 : vec_validate_acl_rules(rules, rule_idx);
450 0 : rules[rule_idx].tcp_flags_value = tcpflags;
451 0 : rules[rule_idx].tcp_flags_mask = tcpmask;
452 : }
453 0 : else if (unformat (i, "proto %d", &proto))
454 : {
455 0 : vec_validate_acl_rules(rules, rule_idx);
456 0 : rules[rule_idx].proto = proto;
457 : }
458 0 : else if (unformat (i, "tag %s", &tag))
459 : {
460 : }
461 0 : else if (unformat (i, ","))
462 : {
463 0 : rule_idx++;
464 0 : vec_validate_acl_rules(rules, rule_idx);
465 : }
466 : else
467 0 : break;
468 : }
469 :
470 : /* Construct the API message */
471 0 : vam->result_ready = 0;
472 :
473 0 : if(rules)
474 0 : n_rules = vec_len(rules);
475 : else
476 0 : n_rules = 0;
477 :
478 0 : if (n_rules_override >= 0)
479 0 : n_rules = n_rules_override;
480 :
481 0 : msg_size += n_rules*sizeof(rules[0]);
482 :
483 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
484 0 : clib_memset (mp, 0, msg_size);
485 0 : mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
486 0 : mp->client_index = vam->my_client_index;
487 0 : if ((n_rules > 0) && rules)
488 0 : clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
489 0 : if (tag)
490 : {
491 0 : if (vec_len(tag) >= sizeof(mp->tag))
492 : {
493 0 : tag[sizeof(mp->tag)-1] = 0;
494 0 : vec_set_len (tag, sizeof (mp->tag));
495 : }
496 0 : clib_memcpy (mp->tag, tag, vec_len (tag));
497 0 : vec_free (tag);
498 : }
499 0 : mp->acl_index = ntohl(acl_index);
500 0 : mp->count = htonl(n_rules);
501 :
502 : /* send it... */
503 0 : S(mp);
504 :
505 : /* Wait for a reply... */
506 0 : W (ret);
507 0 : return ret;
508 : }
509 :
510 0 : static int api_acl_plugin_get_conn_table_max_entries (vat_main_t * vam)
511 : {
512 0 : acl_test_main_t * sm = &acl_test_main;
513 : vl_api_acl_plugin_get_conn_table_max_entries_t * mp;
514 0 : u32 msg_size = sizeof(*mp);
515 : int ret;
516 :
517 0 : vam->result_ready = 0;
518 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
519 0 : memset (mp, 0, msg_size);
520 0 : mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_CONN_TABLE_MAX_ENTRIES + sm->msg_id_base);
521 0 : mp->client_index = vam->my_client_index;
522 :
523 : /* send it... */
524 0 : S(mp);
525 :
526 : /* Wait for a reply... */
527 0 : W (ret);
528 0 : return ret;
529 : }
530 :
531 0 : static int api_acl_stats_intf_counters_enable (vat_main_t * vam)
532 : {
533 0 : acl_test_main_t * sm = &acl_test_main;
534 0 : unformat_input_t * i = vam->input;
535 : vl_api_acl_stats_intf_counters_enable_t * mp;
536 0 : u32 msg_size = sizeof(*mp);
537 : int ret;
538 :
539 0 : vam->result_ready = 0;
540 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
541 0 : memset (mp, 0, msg_size);
542 0 : mp->_vl_msg_id = ntohs (VL_API_ACL_STATS_INTF_COUNTERS_ENABLE + sm->msg_id_base);
543 0 : mp->client_index = vam->my_client_index;
544 0 : mp->enable = 1;
545 :
546 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
547 0 : if (unformat (i, "disable"))
548 0 : mp->enable = 0;
549 : else
550 0 : break;
551 : }
552 :
553 : /* send it... */
554 0 : S(mp);
555 :
556 : /* Wait for a reply... */
557 0 : W (ret);
558 0 : return ret;
559 : }
560 :
561 : static int
562 0 : api_acl_plugin_use_hash_lookup_set (vat_main_t *vam)
563 : {
564 0 : acl_test_main_t *sm = &acl_test_main;
565 0 : unformat_input_t *i = vam->input;
566 : vl_api_acl_plugin_use_hash_lookup_set_t *mp;
567 0 : u32 msg_size = sizeof (*mp);
568 : int ret;
569 :
570 0 : vam->result_ready = 0;
571 0 : mp = vl_msg_api_alloc_as_if_client (msg_size);
572 0 : memset (mp, 0, msg_size);
573 0 : mp->_vl_msg_id =
574 0 : ntohs (VL_API_ACL_PLUGIN_USE_HASH_LOOKUP_SET + sm->msg_id_base);
575 0 : mp->client_index = vam->my_client_index;
576 0 : mp->enable = 1;
577 :
578 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
579 : {
580 0 : if (unformat (i, "disable"))
581 0 : mp->enable = 0;
582 0 : else if (unformat (i, "enable"))
583 0 : mp->enable = 1;
584 : else
585 0 : break;
586 : }
587 :
588 : /* send it... */
589 0 : S (mp);
590 :
591 : /* Wait for a reply... */
592 0 : W (ret);
593 0 : return ret;
594 : }
595 :
596 : static int
597 0 : api_acl_plugin_use_hash_lookup_get (vat_main_t *vam)
598 : {
599 0 : acl_test_main_t *sm = &acl_test_main;
600 : vl_api_acl_plugin_use_hash_lookup_set_t *mp;
601 0 : u32 msg_size = sizeof (*mp);
602 : int ret;
603 :
604 0 : vam->result_ready = 0;
605 0 : mp = vl_msg_api_alloc_as_if_client (msg_size);
606 0 : memset (mp, 0, msg_size);
607 0 : mp->_vl_msg_id =
608 0 : ntohs (VL_API_ACL_PLUGIN_USE_HASH_LOOKUP_GET + sm->msg_id_base);
609 0 : mp->client_index = vam->my_client_index;
610 :
611 : /* send it... */
612 0 : S (mp);
613 :
614 : /* Wait for a reply... */
615 0 : W (ret);
616 0 : return ret;
617 : }
618 :
619 : /*
620 : * Read the series of ACL entries from file in the following format:
621 : *
622 :
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
629 :
630 : *
631 : */
632 :
633 : static int
634 0 : api_acl_add_replace_from_file (vat_main_t * vam)
635 : {
636 0 : int ret = -1;
637 0 : unformat_input_t * input = vam->input;
638 0 : acl_test_main_t * sm = &acl_test_main;
639 : vl_api_acl_add_replace_t * mp;
640 0 : u32 acl_index = ~0;
641 0 : u32 msg_size = sizeof (*mp); /* without the rules */
642 :
643 0 : vl_api_acl_rule_t *rules = 0;
644 0 : int rule_idx = -1;
645 0 : int n_rules = 0;
646 0 : int is_permit = 0;
647 0 : int append_default_permit = 0;
648 0 : u32 tcpflags = 0, tcpmask = 0;
649 : ip4_address_t src_v4address, dst_v4address;
650 0 : int fd = -1;
651 :
652 0 : char *file_name = NULL;
653 : unformat_input_t file_input;
654 :
655 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
656 : {
657 0 : if (unformat (input, "filename %s", &file_name))
658 : {
659 : /* we will use this later */
660 : }
661 0 : else if (unformat (input, "acl-index %d", &acl_index))
662 : {
663 : /* we will try to replace an existing ACL */
664 : }
665 0 : else if (unformat (input, "permit+reflect"))
666 : {
667 0 : is_permit = 2;
668 : }
669 0 : else if (unformat (input, "permit"))
670 : {
671 0 : is_permit = 1;
672 : }
673 0 : else if (unformat (input, "append-default-permit"))
674 : {
675 0 : append_default_permit = 1;
676 : }
677 : else
678 0 : break;
679 : }
680 :
681 0 : if (file_name == NULL)
682 0 : goto done;
683 :
684 0 : fd = open(file_name, O_RDONLY);
685 0 : if (fd < 0)
686 : {
687 0 : clib_warning("Could not open file '%s'", file_name);
688 0 : goto done;
689 : }
690 :
691 : /* input from file */
692 0 : input = &file_input;
693 0 : unformat_init_clib_file(input, fd);
694 :
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;
699 :
700 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
701 : {
702 0 : 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 0 : clib_warning("Error parsing");
707 0 : break;
708 : }
709 :
710 0 : rule_idx++;
711 0 : vec_validate_acl_rules(rules, rule_idx);
712 :
713 0 : rules[rule_idx].is_permit = is_permit;
714 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
715 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
716 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
717 0 : memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
718 0 : rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
719 0 : rules[rule_idx].dst_prefix.len = dst_prefix_length;
720 0 : rules[rule_idx].srcport_or_icmptype_first = htons(sport_low);
721 0 : rules[rule_idx].srcport_or_icmptype_last = htons(sport_high);
722 0 : rules[rule_idx].dstport_or_icmpcode_first = htons(dport_low);
723 0 : rules[rule_idx].dstport_or_icmpcode_last = htons(dport_high);
724 0 : rules[rule_idx].tcp_flags_value = tcpflags;
725 0 : rules[rule_idx].tcp_flags_mask = tcpmask;
726 0 : rules[rule_idx].proto = proto;
727 :
728 : }
729 :
730 0 : if (append_default_permit) {
731 0 : rule_idx++;
732 0 : vec_validate_acl_rules(rules, rule_idx);
733 :
734 0 : rules[rule_idx].is_permit = is_permit == 2 ? 2 : 1;
735 :
736 0 : src_v4address.data[0]=0;
737 0 : src_v4address.data[1]=0;
738 0 : src_v4address.data[2]=0;
739 0 : src_v4address.data[3]=0;
740 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
741 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
742 0 : rules[rule_idx].src_prefix.len = 0;
743 :
744 0 : dst_v4address.data[0]=0;
745 0 : dst_v4address.data[1]=0;
746 0 : dst_v4address.data[2]=0;
747 0 : dst_v4address.data[3]=0;
748 0 : memcpy (rules[rule_idx].dst_prefix.address.un.ip4, &dst_v4address, 4);
749 0 : rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4;
750 0 : rules[rule_idx].dst_prefix.len = 0;
751 :
752 0 : rules[rule_idx].srcport_or_icmptype_first = htons(0);
753 0 : rules[rule_idx].srcport_or_icmptype_last = htons(65535);
754 0 : rules[rule_idx].dstport_or_icmpcode_first = htons(0);
755 0 : rules[rule_idx].dstport_or_icmpcode_last = htons(65535);
756 0 : rules[rule_idx].tcp_flags_value = 0;
757 0 : rules[rule_idx].tcp_flags_mask = 0;
758 0 : rules[rule_idx].proto = 0;
759 : }
760 :
761 : /* Construct the API message */
762 :
763 0 : vam->result_ready = 0;
764 :
765 0 : n_rules = vec_len(rules);
766 :
767 0 : msg_size += n_rules*sizeof(rules[0]);
768 :
769 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
770 0 : clib_memset (mp, 0, msg_size);
771 0 : mp->_vl_msg_id = ntohs (VL_API_ACL_ADD_REPLACE + sm->msg_id_base);
772 0 : mp->client_index = vam->my_client_index;
773 0 : if (n_rules > 0)
774 0 : clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t));
775 0 : mp->acl_index = ntohl(acl_index);
776 0 : mp->count = htonl(n_rules);
777 :
778 : /* send it... */
779 0 : S(mp);
780 :
781 : /* Wait for a reply... */
782 0 : W (ret);
783 0 : done:
784 0 : if (fd > 0)
785 0 : close (fd);
786 0 : vec_free(file_name);
787 :
788 0 : return ret;
789 : }
790 :
791 :
792 0 : static int api_acl_del (vat_main_t * vam)
793 : {
794 0 : unformat_input_t * i = vam->input;
795 : vl_api_acl_del_t * mp;
796 0 : u32 acl_index = ~0;
797 : int ret;
798 :
799 0 : if (!unformat (i, "%d", &acl_index)) {
800 0 : errmsg ("missing acl index\n");
801 0 : return -99;
802 : }
803 :
804 : /* Construct the API message */
805 0 : M(ACL_DEL, mp);
806 0 : mp->acl_index = ntohl(acl_index);
807 :
808 : /* send it... */
809 0 : S(mp);
810 :
811 : /* Wait for a reply... */
812 0 : W (ret);
813 0 : return ret;
814 : }
815 :
816 0 : static int api_macip_acl_del (vat_main_t * vam)
817 : {
818 0 : unformat_input_t * i = vam->input;
819 : vl_api_acl_del_t * mp;
820 0 : u32 acl_index = ~0;
821 : int ret;
822 :
823 0 : if (!unformat (i, "%d", &acl_index)) {
824 0 : errmsg ("missing acl index\n");
825 0 : return -99;
826 : }
827 :
828 : /* Construct the API message */
829 0 : M(MACIP_ACL_DEL, mp);
830 0 : mp->acl_index = ntohl(acl_index);
831 :
832 : /* send it... */
833 0 : S(mp);
834 :
835 : /* Wait for a reply... */
836 0 : W (ret);
837 0 : return ret;
838 : }
839 :
840 0 : static int api_acl_interface_add_del (vat_main_t * vam)
841 : {
842 0 : unformat_input_t * i = vam->input;
843 : vl_api_acl_interface_add_del_t * mp;
844 0 : u32 sw_if_index = ~0;
845 0 : u32 acl_index = ~0;
846 0 : u8 is_input = 0;
847 0 : u8 is_add = 0;
848 : int ret;
849 :
850 : // acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del]
851 :
852 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
853 : {
854 0 : if (unformat (i, "%d", &acl_index))
855 : ;
856 : else
857 0 : break;
858 : }
859 :
860 :
861 : /* Parse args required to build the message */
862 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
863 0 : if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
864 : ;
865 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
866 : ;
867 0 : else if (unformat (i, "add"))
868 0 : is_add = 1;
869 0 : else if (unformat (i, "del"))
870 0 : is_add = 0;
871 0 : else if (unformat (i, "acl %d", &acl_index))
872 : ;
873 0 : else if (unformat (i, "input"))
874 0 : is_input = 1;
875 0 : else if (unformat (i, "output"))
876 0 : is_input = 0;
877 : else
878 0 : break;
879 : }
880 :
881 0 : if (sw_if_index == ~0) {
882 0 : errmsg ("missing interface name / explicit sw_if_index number \n");
883 0 : return -99;
884 : }
885 :
886 0 : if (acl_index == ~0) {
887 0 : errmsg ("missing ACL index\n");
888 0 : return -99;
889 : }
890 :
891 :
892 :
893 : /* Construct the API message */
894 0 : M(ACL_INTERFACE_ADD_DEL, mp);
895 0 : mp->acl_index = ntohl(acl_index);
896 0 : mp->sw_if_index = ntohl(sw_if_index);
897 0 : mp->is_add = is_add;
898 0 : mp->is_input = is_input;
899 :
900 : /* send it... */
901 0 : S(mp);
902 :
903 : /* Wait for a reply... */
904 0 : W (ret);
905 0 : return ret;
906 : }
907 :
908 0 : static int api_macip_acl_interface_add_del (vat_main_t * vam)
909 : {
910 0 : unformat_input_t * i = vam->input;
911 : vl_api_macip_acl_interface_add_del_t * mp;
912 0 : u32 sw_if_index = ~0;
913 0 : u32 acl_index = ~0;
914 0 : u8 is_add = 0;
915 : int ret;
916 :
917 : /* Parse args required to build the message */
918 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
919 0 : if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
920 : ;
921 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
922 : ;
923 0 : else if (unformat (i, "add"))
924 0 : is_add = 1;
925 0 : else if (unformat (i, "del"))
926 0 : is_add = 0;
927 0 : else if (unformat (i, "acl %d", &acl_index))
928 : ;
929 : else
930 0 : break;
931 : }
932 :
933 0 : if (sw_if_index == ~0) {
934 0 : errmsg ("missing interface name / explicit sw_if_index number \n");
935 0 : return -99;
936 : }
937 :
938 0 : if (acl_index == ~0) {
939 0 : errmsg ("missing ACL index\n");
940 0 : return -99;
941 : }
942 :
943 :
944 :
945 : /* Construct the API message */
946 0 : M(MACIP_ACL_INTERFACE_ADD_DEL, mp);
947 0 : mp->acl_index = ntohl(acl_index);
948 0 : mp->sw_if_index = ntohl(sw_if_index);
949 0 : mp->is_add = is_add;
950 :
951 : /* send it... */
952 0 : S(mp);
953 :
954 : /* Wait for a reply... */
955 0 : W (ret);
956 0 : return ret;
957 : }
958 :
959 0 : static int api_acl_interface_set_acl_list (vat_main_t * vam)
960 : {
961 0 : unformat_input_t * i = vam->input;
962 : vl_api_acl_interface_set_acl_list_t * mp;
963 0 : u32 sw_if_index = ~0;
964 0 : u32 acl_index = ~0;
965 0 : u32 *inacls = 0;
966 0 : u32 *outacls = 0;
967 0 : u8 is_input = 0;
968 : int ret;
969 :
970 : // acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]
971 :
972 : /* Parse args required to build the message */
973 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
974 0 : if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
975 : ;
976 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
977 : ;
978 0 : else if (unformat (i, "%d", &acl_index))
979 : {
980 0 : if(is_input)
981 0 : vec_add1(inacls, htonl(acl_index));
982 : else
983 0 : vec_add1(outacls, htonl(acl_index));
984 : }
985 0 : else if (unformat (i, "acl %d", &acl_index))
986 : ;
987 0 : else if (unformat (i, "input"))
988 0 : is_input = 1;
989 0 : else if (unformat (i, "output"))
990 0 : is_input = 0;
991 : else
992 0 : break;
993 : }
994 :
995 0 : if (sw_if_index == ~0) {
996 0 : errmsg ("missing interface name / explicit sw_if_index number \n");
997 0 : return -99;
998 : }
999 :
1000 : /* Construct the API message */
1001 0 : M2(ACL_INTERFACE_SET_ACL_LIST, mp, sizeof(u32) * (vec_len(inacls) + vec_len(outacls)));
1002 0 : mp->sw_if_index = ntohl(sw_if_index);
1003 0 : mp->n_input = vec_len(inacls);
1004 0 : mp->count = vec_len(inacls) + vec_len(outacls);
1005 0 : vec_append(inacls, outacls);
1006 0 : if (vec_len(inacls) > 0)
1007 0 : clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32));
1008 :
1009 : /* send it... */
1010 0 : S(mp);
1011 :
1012 : /* Wait for a reply... */
1013 0 : W (ret);
1014 0 : return ret;
1015 : }
1016 :
1017 0 : static int api_acl_interface_set_etype_whitelist (vat_main_t * vam)
1018 : {
1019 0 : unformat_input_t * i = vam->input;
1020 : vl_api_acl_interface_set_etype_whitelist_t * mp;
1021 0 : u32 sw_if_index = ~0;
1022 0 : u32 ethertype = ~0;
1023 0 : u16 *etypes_in = 0;
1024 0 : u16 *etypes_out = 0;
1025 0 : u8 is_input = 1;
1026 : int ret;
1027 :
1028 : // acl_interface_set_etype_whitelist <intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list]
1029 :
1030 : /* Parse args required to build the message */
1031 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1032 0 : if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1033 : ;
1034 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
1035 : ;
1036 0 : else if (unformat (i, "%x", ðertype))
1037 : {
1038 0 : ethertype = ethertype & 0xffff;
1039 0 : if(is_input)
1040 0 : vec_add1(etypes_in, htons(ethertype));
1041 : else
1042 0 : vec_add1(etypes_out, htons(ethertype));
1043 : }
1044 0 : else if (unformat (i, "input"))
1045 0 : is_input = 1;
1046 0 : else if (unformat (i, "output"))
1047 0 : is_input = 0;
1048 : else
1049 0 : break;
1050 : }
1051 :
1052 0 : if (sw_if_index == ~0) {
1053 0 : errmsg ("missing interface name / explicit sw_if_index number \n");
1054 0 : return -99;
1055 : }
1056 :
1057 : /* Construct the API message */
1058 0 : M2(ACL_INTERFACE_SET_ETYPE_WHITELIST, mp, sizeof(u32) * (vec_len(etypes_in) + vec_len(etypes_out)));
1059 0 : mp->sw_if_index = ntohl(sw_if_index);
1060 0 : mp->n_input = vec_len(etypes_in);
1061 0 : mp->count = vec_len(etypes_in) + vec_len(etypes_out);
1062 0 : vec_append(etypes_in, etypes_out);
1063 0 : if (vec_len(etypes_in) > 0)
1064 0 : clib_memcpy(mp->whitelist, etypes_in, vec_len(etypes_in)*sizeof(etypes_in[0]));
1065 :
1066 : /* send it... */
1067 0 : S(mp);
1068 :
1069 : /* Wait for a reply... */
1070 0 : W (ret);
1071 0 : return ret;
1072 : }
1073 :
1074 : static void
1075 0 : api_acl_send_control_ping(vat_main_t *vam)
1076 : {
1077 : vl_api_acl_plugin_control_ping_t *mp_ping;
1078 :
1079 0 : M(ACL_PLUGIN_CONTROL_PING, mp_ping);
1080 0 : S(mp_ping);
1081 0 : }
1082 :
1083 :
1084 0 : static int api_acl_interface_list_dump (vat_main_t * vam)
1085 : {
1086 0 : unformat_input_t * i = vam->input;
1087 0 : u32 sw_if_index = ~0;
1088 : vl_api_acl_interface_list_dump_t * mp;
1089 : int ret;
1090 :
1091 : /* Parse args required to build the message */
1092 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1093 0 : if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1094 : ;
1095 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
1096 : ;
1097 : else
1098 0 : break;
1099 : }
1100 :
1101 : /* Construct the API message */
1102 0 : M(ACL_INTERFACE_LIST_DUMP, mp);
1103 0 : mp->sw_if_index = ntohl (sw_if_index);
1104 :
1105 : /* send it... */
1106 0 : S(mp);
1107 :
1108 : /* Use control ping for synchronization */
1109 0 : api_acl_send_control_ping(vam);
1110 :
1111 : /* Wait for a reply... */
1112 0 : W (ret);
1113 0 : return ret;
1114 : }
1115 :
1116 0 : static int api_acl_dump (vat_main_t * vam)
1117 : {
1118 0 : unformat_input_t * i = vam->input;
1119 0 : u32 acl_index = ~0;
1120 : vl_api_acl_dump_t * mp;
1121 : int ret;
1122 :
1123 : /* Parse args required to build the message */
1124 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1125 0 : if (unformat (i, "%d", &acl_index))
1126 : ;
1127 : else
1128 0 : break;
1129 : }
1130 :
1131 : /* Construct the API message */
1132 0 : M(ACL_DUMP, mp);
1133 0 : mp->acl_index = ntohl (acl_index);
1134 :
1135 : /* send it... */
1136 0 : S(mp);
1137 :
1138 : /* Use control ping for synchronization */
1139 0 : api_acl_send_control_ping(vam);
1140 :
1141 : /* Wait for a reply... */
1142 0 : W (ret);
1143 0 : return ret;
1144 : }
1145 :
1146 0 : static int api_macip_acl_dump (vat_main_t * vam)
1147 : {
1148 0 : unformat_input_t * i = vam->input;
1149 0 : u32 acl_index = ~0;
1150 : vl_api_acl_dump_t * mp;
1151 : int ret;
1152 :
1153 : /* Parse args required to build the message */
1154 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1155 0 : if (unformat (i, "%d", &acl_index))
1156 : ;
1157 : else
1158 0 : break;
1159 : }
1160 :
1161 : /* Construct the API message */
1162 0 : M(MACIP_ACL_DUMP, mp);
1163 0 : mp->acl_index = ntohl (acl_index);
1164 :
1165 : /* send it... */
1166 0 : S(mp);
1167 :
1168 : /* Use control ping for synchronization */
1169 0 : api_acl_send_control_ping(vam);
1170 :
1171 : /* Wait for a reply... */
1172 0 : W (ret);
1173 0 : return ret;
1174 : }
1175 :
1176 0 : static int api_acl_interface_etype_whitelist_dump (vat_main_t * vam)
1177 : {
1178 0 : unformat_input_t * i = vam->input;
1179 0 : u32 sw_if_index = ~0;
1180 : vl_api_acl_interface_etype_whitelist_dump_t * mp;
1181 : int ret;
1182 :
1183 : /* Parse args required to build the message */
1184 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
1185 0 : if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
1186 : ;
1187 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
1188 : ;
1189 : else
1190 0 : break;
1191 : }
1192 :
1193 : /* Construct the API message */
1194 0 : M(ACL_INTERFACE_ETYPE_WHITELIST_DUMP, mp);
1195 0 : mp->sw_if_index = ntohl (sw_if_index);
1196 :
1197 : /* send it... */
1198 0 : S(mp);
1199 :
1200 : /* Use control ping for synchronization */
1201 0 : api_acl_send_control_ping(vam);
1202 :
1203 : /* Wait for a reply... */
1204 0 : W (ret);
1205 0 : return ret;
1206 : }
1207 :
1208 :
1209 : #define vec_validate_macip_acl_rules(v, idx) \
1210 : do { \
1211 : if (vec_len(v) < idx+1) { \
1212 : vec_validate(v, idx); \
1213 : v[idx].is_permit = 0x1; \
1214 : } \
1215 : } while (0)
1216 :
1217 :
1218 0 : static int api_macip_acl_add (vat_main_t * vam)
1219 : {
1220 0 : acl_test_main_t * sm = &acl_test_main;
1221 0 : unformat_input_t * i = vam->input;
1222 : vl_api_macip_acl_add_t * mp;
1223 0 : u32 msg_size = sizeof (*mp); /* without the rules */
1224 :
1225 0 : vl_api_macip_acl_rule_t *rules = 0;
1226 0 : int rule_idx = 0;
1227 0 : int n_rules = 0;
1228 0 : int n_rules_override = -1;
1229 0 : u32 src_prefix_length = 0;
1230 0 : u32 action = 0;
1231 : ip4_address_t src_v4address;
1232 : ip6_address_t src_v6address;
1233 : u8 src_mac[6];
1234 0 : u8 *tag = 0;
1235 0 : u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1236 : int ret;
1237 :
1238 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1239 : {
1240 0 : if (unformat (i, "permit"))
1241 : {
1242 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1243 0 : rules[rule_idx].is_permit = 1;
1244 : }
1245 0 : else if (unformat (i, "deny"))
1246 : {
1247 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1248 0 : rules[rule_idx].is_permit = 0;
1249 : }
1250 0 : else if (unformat (i, "count %d", &n_rules_override))
1251 : {
1252 : /* we will use this later */
1253 : }
1254 0 : else if (unformat (i, "action %d", &action))
1255 : {
1256 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1257 0 : rules[rule_idx].is_permit = action;
1258 : }
1259 0 : else if (unformat (i, "ip %U/%d",
1260 0 : unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1261 0 : unformat (i, "ip %U",
1262 : unformat_ip4_address, &src_v4address))
1263 : {
1264 0 : if (src_prefix_length == 0)
1265 0 : src_prefix_length = 32;
1266 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1267 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
1268 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
1269 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
1270 : }
1271 0 : else if (unformat (i, "src"))
1272 : {
1273 : /* Everything in MACIP is "source" but allow this verbosity */
1274 : }
1275 0 : else if (unformat (i, "ip %U/%d",
1276 0 : unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1277 0 : unformat (i, "ip %U",
1278 : unformat_ip6_address, &src_v6address))
1279 : {
1280 0 : if (src_prefix_length == 0)
1281 0 : src_prefix_length = 128;
1282 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1283 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v6address, 4);
1284 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
1285 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
1286 : }
1287 0 : else if (unformat (i, "mac %U",
1288 : my_unformat_mac_address, &src_mac))
1289 : {
1290 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1291 0 : memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1292 0 : memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1293 : }
1294 0 : else if (unformat (i, "mask %U",
1295 : my_unformat_mac_address, &src_mac))
1296 : {
1297 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1298 0 : memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1299 : }
1300 0 : else if (unformat (i, "tag %s", &tag))
1301 : {
1302 : }
1303 0 : else if (unformat (i, ","))
1304 : {
1305 0 : rule_idx++;
1306 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1307 : }
1308 : else
1309 0 : break;
1310 : }
1311 :
1312 : /* Construct the API message */
1313 0 : vam->result_ready = 0;
1314 :
1315 0 : if(rules)
1316 0 : n_rules = vec_len(rules);
1317 :
1318 0 : if (n_rules_override >= 0)
1319 0 : n_rules = n_rules_override;
1320 :
1321 0 : msg_size += n_rules*sizeof(rules[0]);
1322 :
1323 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
1324 0 : clib_memset (mp, 0, msg_size);
1325 0 : mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD + sm->msg_id_base);
1326 0 : mp->client_index = vam->my_client_index;
1327 0 : if ((n_rules > 0) && rules)
1328 0 : clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1329 0 : if (tag)
1330 : {
1331 0 : if (vec_len(tag) >= sizeof(mp->tag))
1332 : {
1333 0 : tag[sizeof(mp->tag)-1] = 0;
1334 0 : vec_set_len (tag, sizeof (mp->tag));
1335 : }
1336 0 : clib_memcpy (mp->tag, tag, vec_len (tag));
1337 0 : vec_free (tag);
1338 : }
1339 :
1340 0 : mp->count = htonl(n_rules);
1341 :
1342 : /* send it... */
1343 0 : S(mp);
1344 :
1345 : /* Wait for a reply... */
1346 0 : W (ret);
1347 0 : return ret;
1348 : }
1349 :
1350 0 : static int api_macip_acl_add_replace (vat_main_t * vam)
1351 : {
1352 0 : acl_test_main_t * sm = &acl_test_main;
1353 0 : unformat_input_t * i = vam->input;
1354 : vl_api_macip_acl_add_replace_t * mp;
1355 0 : u32 acl_index = ~0;
1356 0 : u32 msg_size = sizeof (*mp); /* without the rules */
1357 :
1358 0 : vl_api_macip_acl_rule_t *rules = 0;
1359 0 : int rule_idx = 0;
1360 0 : int n_rules = 0;
1361 0 : int n_rules_override = -1;
1362 0 : u32 src_prefix_length = 0;
1363 0 : u32 action = 0;
1364 : ip4_address_t src_v4address;
1365 : ip6_address_t src_v6address;
1366 : u8 src_mac[6];
1367 0 : u8 *tag = 0;
1368 0 : u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1369 : int ret;
1370 :
1371 0 : if (!unformat (i, "%d", &acl_index)) {
1372 : /* Just assume -1 */
1373 : }
1374 :
1375 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1376 : {
1377 0 : if (unformat (i, "permit"))
1378 : {
1379 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1380 0 : rules[rule_idx].is_permit = 1;
1381 : }
1382 0 : else if (unformat (i, "deny"))
1383 : {
1384 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1385 0 : rules[rule_idx].is_permit = 0;
1386 : }
1387 0 : else if (unformat (i, "count %d", &n_rules_override))
1388 : {
1389 : /* we will use this later */
1390 : }
1391 0 : else if (unformat (i, "action %d", &action))
1392 : {
1393 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1394 0 : rules[rule_idx].is_permit = action;
1395 : }
1396 0 : else if (unformat (i, "ip %U/%d",
1397 0 : unformat_ip4_address, &src_v4address, &src_prefix_length) ||
1398 0 : unformat (i, "ip %U",
1399 : unformat_ip4_address, &src_v4address))
1400 : {
1401 0 : if (src_prefix_length == 0)
1402 0 : src_prefix_length = 32;
1403 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1404 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v4address, 4);
1405 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP4;
1406 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
1407 : }
1408 0 : else if (unformat (i, "src"))
1409 : {
1410 : /* Everything in MACIP is "source" but allow this verbosity */
1411 : }
1412 0 : else if (unformat (i, "ip %U/%d",
1413 0 : unformat_ip6_address, &src_v6address, &src_prefix_length) ||
1414 0 : unformat (i, "ip %U",
1415 : unformat_ip6_address, &src_v6address))
1416 : {
1417 0 : if (src_prefix_length == 0)
1418 0 : src_prefix_length = 128;
1419 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1420 0 : memcpy (rules[rule_idx].src_prefix.address.un.ip4, &src_v6address, 4);
1421 0 : rules[rule_idx].src_prefix.address.af = ADDRESS_IP6;
1422 0 : rules[rule_idx].src_prefix.len = src_prefix_length;
1423 : }
1424 0 : else if (unformat (i, "mac %U",
1425 : my_unformat_mac_address, &src_mac))
1426 : {
1427 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1428 0 : memcpy (rules[rule_idx].src_mac, &src_mac, 6);
1429 0 : memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
1430 : }
1431 0 : else if (unformat (i, "mask %U",
1432 : my_unformat_mac_address, &src_mac))
1433 : {
1434 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1435 0 : memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
1436 : }
1437 0 : else if (unformat (i, "tag %s", &tag))
1438 : {
1439 : }
1440 0 : else if (unformat (i, ","))
1441 : {
1442 0 : rule_idx++;
1443 0 : vec_validate_macip_acl_rules(rules, rule_idx);
1444 : }
1445 : else
1446 0 : break;
1447 : }
1448 :
1449 0 : if (!rules)
1450 : {
1451 0 : errmsg ("rule/s required\n");
1452 0 : return -99;
1453 : }
1454 : /* Construct the API message */
1455 0 : vam->result_ready = 0;
1456 :
1457 0 : if(rules)
1458 0 : n_rules = vec_len(rules);
1459 :
1460 0 : if (n_rules_override >= 0)
1461 0 : n_rules = n_rules_override;
1462 :
1463 0 : msg_size += n_rules*sizeof(rules[0]);
1464 :
1465 0 : mp = vl_msg_api_alloc_as_if_client(msg_size);
1466 0 : clib_memset (mp, 0, msg_size);
1467 0 : mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
1468 0 : mp->client_index = vam->my_client_index;
1469 0 : if ((n_rules > 0) && rules)
1470 0 : clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
1471 0 : if (tag)
1472 : {
1473 0 : if (vec_len(tag) >= sizeof(mp->tag))
1474 : {
1475 0 : tag[sizeof(mp->tag)-1] = 0;
1476 0 : vec_set_len (tag, sizeof (mp->tag));
1477 : }
1478 0 : clib_memcpy (mp->tag, tag, vec_len (tag));
1479 0 : vec_free (tag);
1480 : }
1481 :
1482 0 : mp->acl_index = ntohl(acl_index);
1483 0 : mp->count = htonl(n_rules);
1484 :
1485 : /* send it... */
1486 0 : S(mp);
1487 :
1488 : /* Wait for a reply... */
1489 0 : W (ret);
1490 0 : return ret;
1491 : }
1492 :
1493 : #define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE local_setup_message_id_table
1494 559 : static void local_setup_message_id_table (vat_main_t * vam)
1495 : {
1496 1118 : hash_set_mem (vam->function_by_name, "acl_add_replace_from_file", api_acl_add_replace_from_file);
1497 1118 : hash_set_mem (vam->help_by_name, "acl_add_replace_from_file",
1498 : "filename <file> [permit] [append-default-permit]");
1499 559 : }
1500 :
1501 : #include <acl/acl.api_test.c>
|