aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/acl/acl.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2020-03-24 15:09:41 +0000
committerDave Barach <openvpp@barachs.net>2020-03-25 11:54:09 +0000
commit40490db79b755c5ca7113e2b772fe6052925f044 (patch)
tree5102fbb9c951f2547a58abd3fff17b766999614d /src/plugins/acl/acl.c
parente7f7190381c66cca6c1c3c77b3d43148818a5a4e (diff)
acl: Add CLI additions
Type: improvement Signed-off-by: Neale Ranns <nranns@cisco.com> Change-Id: I172d3d907f324d8cb21e73aa08ef66da029ed365
Diffstat (limited to 'src/plugins/acl/acl.c')
-rw-r--r--src/plugins/acl/acl.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c
index 6a62f7b3db7..48678f5e48f 100644
--- a/src/plugins/acl/acl.c
+++ b/src/plugins/acl/acl.c
@@ -2925,6 +2925,223 @@ macip_acl_print (acl_main_t * am, u32 macip_acl_index)
}
static clib_error_t *
+acl_set_aclplugin_interface_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u32 sw_if_index, is_add, is_input, acl_index;
+
+ is_add = is_input = 1;
+ acl_index = sw_if_index = ~0;
+
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U",
+ unformat_vnet_sw_interface, vnet_get_main (),
+ &sw_if_index))
+ ;
+ else if (unformat (line_input, "add"))
+ is_add = 1;
+ else if (unformat (line_input, "del"))
+ is_add = 0;
+ else if (unformat (line_input, "acl %d", &acl_index))
+ ;
+ else if (unformat (line_input, "input"))
+ is_input = 1;
+ else if (unformat (line_input, "output"))
+ is_input = 0;
+ else
+ break;
+ }
+
+ if (~0 == sw_if_index)
+ return (clib_error_return (0, "invalid interface"));
+ if (~0 == acl_index)
+ return (clib_error_return (0, "invalid acl"));
+
+ acl_interface_add_del_inout_acl (sw_if_index, is_add, is_input, acl_index);
+
+ unformat_free (line_input);
+ return (NULL);
+}
+
+#define vec_validate_acl_rules(v, idx) \
+ do { \
+ if (vec_len(v) < idx+1) { \
+ vec_validate(v, idx); \
+ v[idx].is_permit = 0x1; \
+ v[idx].srcport_or_icmptype_last = 0xffff; \
+ v[idx].dstport_or_icmpcode_last = 0xffff; \
+ } \
+ } while (0)
+
+static clib_error_t *
+acl_set_aclplugin_acl_fn (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ vl_api_acl_rule_t *rules = 0;
+ int rv;
+ int rule_idx = 0;
+ int n_rules_override = -1;
+ u32 proto = 0;
+ u32 port1 = 0;
+ u32 port2 = 0;
+ u32 action = 0;
+ u32 tcpflags, tcpmask;
+ u32 src_prefix_length = 0, dst_prefix_length = 0;
+ ip4_address_t src_v4address, dst_v4address;
+ ip6_address_t src_v6address, dst_v6address;
+ u8 *tag = (u8 *) "cli";
+
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "ipv6"))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].is_ipv6 = 1;
+ }
+ else if (unformat (line_input, "ipv4"))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].is_ipv6 = 0;
+ }
+ else if (unformat (line_input, "permit+reflect"))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].is_permit = 2;
+ }
+ else if (unformat (line_input, "permit"))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].is_permit = 1;
+ }
+ else if (unformat (line_input, "deny"))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].is_permit = 0;
+ }
+ else if (unformat (line_input, "count %d", &n_rules_override))
+ {
+ /* we will use this later */
+ }
+ else if (unformat (line_input, "action %d", &action))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].is_permit = action;
+ }
+ else if (unformat (line_input, "src %U/%d",
+ unformat_ip4_address, &src_v4address,
+ &src_prefix_length))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ memcpy (rules[rule_idx].src_ip_addr, &src_v4address, 4);
+ rules[rule_idx].src_ip_prefix_len = src_prefix_length;
+ rules[rule_idx].is_ipv6 = 0;
+ }
+ else if (unformat (line_input, "src %U/%d",
+ unformat_ip6_address, &src_v6address,
+ &src_prefix_length))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ memcpy (rules[rule_idx].src_ip_addr, &src_v6address, 16);
+ rules[rule_idx].src_ip_prefix_len = src_prefix_length;
+ rules[rule_idx].is_ipv6 = 1;
+ }
+ else if (unformat (line_input, "dst %U/%d",
+ unformat_ip4_address, &dst_v4address,
+ &dst_prefix_length))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ memcpy (rules[rule_idx].dst_ip_addr, &dst_v4address, 4);
+ rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
+ rules[rule_idx].is_ipv6 = 0;
+ }
+ else if (unformat (line_input, "dst %U/%d",
+ unformat_ip6_address, &dst_v6address,
+ &dst_prefix_length))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ memcpy (rules[rule_idx].dst_ip_addr, &dst_v6address, 16);
+ rules[rule_idx].dst_ip_prefix_len = dst_prefix_length;
+ rules[rule_idx].is_ipv6 = 1;
+ }
+ else if (unformat (line_input, "sport %d-%d", &port1, &port2))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].srcport_or_icmptype_first = htons (port1);
+ rules[rule_idx].srcport_or_icmptype_last = htons (port2);
+ }
+ else if (unformat (line_input, "sport %d", &port1))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].srcport_or_icmptype_first = htons (port1);
+ rules[rule_idx].srcport_or_icmptype_last = htons (port1);
+ }
+ else if (unformat (line_input, "dport %d-%d", &port1, &port2))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].dstport_or_icmpcode_first = htons (port1);
+ rules[rule_idx].dstport_or_icmpcode_last = htons (port2);
+ }
+ else if (unformat (line_input, "dport %d", &port1))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].dstport_or_icmpcode_first = htons (port1);
+ rules[rule_idx].dstport_or_icmpcode_last = htons (port1);
+ }
+ else if (unformat (line_input, "tcpflags %d %d", &tcpflags, &tcpmask))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].tcp_flags_value = tcpflags;
+ rules[rule_idx].tcp_flags_mask = tcpmask;
+ }
+ else
+ if (unformat (line_input, "tcpflags %d mask %d", &tcpflags, &tcpmask))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].tcp_flags_value = tcpflags;
+ rules[rule_idx].tcp_flags_mask = tcpmask;
+ }
+ else if (unformat (line_input, "proto %d", &proto))
+ {
+ vec_validate_acl_rules (rules, rule_idx);
+ rules[rule_idx].proto = proto;
+ }
+ else if (unformat (line_input, "tag %s", &tag))
+ {
+ }
+ else if (unformat (line_input, ","))
+ {
+ rule_idx++;
+ vec_validate_acl_rules (rules, rule_idx);
+ }
+ else
+ break;
+ }
+
+ u32 acl_index = ~0;
+
+ rv = acl_add_list (vec_len (rules), rules, &acl_index, tag);
+
+ vec_free (rules);
+
+ if (rv)
+ return (clib_error_return (0, "failed"));
+
+ vlib_cli_output (vm, "ACL index:%d", acl_index);
+
+ return (NULL);
+}
+
+static clib_error_t *
acl_show_aclplugin_macip_acl_fn (vlib_main_t * vm,
unformat_input_t *
input, vlib_cli_command_t * cmd)
@@ -3520,6 +3737,43 @@ VLIB_CLI_COMMAND (aclplugin_clear_command, static) = {
.short_help = "clear acl-plugin sessions",
.function = acl_clear_aclplugin_fn,
};
+
+/*?
+ * [un]Apply an ACL to an interface.
+ * The ACL is applied in a given direction, either input or output.
+ * The ACL being applied must already exist.
+ *
+ * @cliexpar
+ * <b><em> set acl-plugin interface <input|output> acl <index> [del] </b></em>
+ * @cliexend
+ ?*/
+VLIB_CLI_COMMAND (aclplugin_set_interface_command, static) = {
+ .path = "set acl-plugin interface",
+ .short_help = "set acl-plugin interface <interface> <input|output> <acl INDEX> [del] ",
+ .function = acl_set_aclplugin_interface_fn,
+};
+
+/*?
+ * Create an Access Control List (ACL)
+ * an ACL is composed of more than one Access control element (ACE). Multiple
+ * ACEs can be specified with this command using a comma separated list.
+ *
+ * Each ACE describes a tuple of src+dst IP prefix, ip protocol, src+dst port ranges.
+ * (the ACL plugin also support ICMP types/codes instead of UDP/TCP ports, but
+ * this CLI does not).
+ *
+ * An ACL can optionally be assigned a 'tag' - which is an identifier understood
+ * by the client. VPP does not examine it in any way.
+ *
+ * @cliexpar
+ * <b><em> set acl-plugin acl <permit|deny> src <PREFIX> dst <PREFIX> proto <TCP|UDP> sport <X-Y> dport <X-Y> [tag FOO] </b></em>
+ * @cliexend
+ ?*/
+VLIB_CLI_COMMAND (aclplugin_set_acl_command, static) = {
+ .path = "set acl-plugin acl",
+ .short_help = "set acl-plugin acl <permit|deny> src <PREFIX> dst <PREFIX> proto X sport X-Y dport X-Y [tag FOO] {use comma separated list for multiple rules}",
+ .function = acl_set_aclplugin_acl_fn,
+};
/* *INDENT-ON* */
static clib_error_t *