aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/acl
diff options
context:
space:
mode:
authorPavel Kotucek <pkotucek@cisco.com>2017-09-07 08:17:31 +0200
committerOle Trøan <otroan@employees.org>2017-09-12 08:38:25 +0000
commitc29940c58de3e44c0c1dd5c4eda5e0268d963b14 (patch)
tree4d4f84747757439422aa61ab7c2edaf00246ba54 /src/plugins/acl
parent6b3a8eff76f27f2b919887582006b2290d12ecfa (diff)
ACL-plugin add "replace" semantics for adding a new MacIP acl
Change-Id: Ia5c869b2d8b8ad012b9e89fb6720c9c32d9ee065 Signed-off-by: Pavel Kotucek <pkotucek@cisco.com>
Diffstat (limited to 'src/plugins/acl')
-rw-r--r--src/plugins/acl/acl.api52
-rw-r--r--src/plugins/acl/acl.c59
-rw-r--r--src/plugins/acl/acl_test.c160
-rw-r--r--src/plugins/acl/manual_fns.h42
4 files changed, 295 insertions, 18 deletions
diff --git a/src/plugins/acl/acl.api b/src/plugins/acl/acl.api
index 48d6aece3a9..a0de24a2340 100644
--- a/src/plugins/acl/acl.api
+++ b/src/plugins/acl/acl.api
@@ -305,7 +305,7 @@ define acl_interface_list_details
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param tag - descriptive value for this MACIP ACL
- @param count - number of rules in this ACL
+ @param count - number of rules in this MACIP ACL
@param r - vector of MACIP ACL rules
*/
@@ -320,7 +320,7 @@ manual_endian manual_print define macip_acl_add
/** \brief Reply to add MACIP ACL
@param context - returned sender context, to match reply w/ request
- @param acl_index - index of the newly created ACL
+ @param acl_index - index of the newly created MACIP ACL
@param retval 0 - no error
*/
@@ -331,6 +331,38 @@ define macip_acl_add_reply
i32 retval;
};
+/** \brief Add/Replace a MACIP ACL
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param acl_index - an existing MACIP ACL entry (0..0xfffffffe) to replace, or 0xffffffff to make new MACIP ACL
+ @param tag - descriptive value for this MACIP ACL
+ @param count - number of rules in this MACIP ACL
+ @param r - vector of MACIP ACL rules
+*/
+
+manual_endian manual_print define macip_acl_add_replace
+{
+ u32 client_index;
+ u32 context;
+ u32 acl_index; /* ~0 to add, existing MACIP ACL# to replace */
+ u8 tag[64];
+ u32 count;
+ vl_api_macip_acl_rule_t r[count];
+};
+
+/** \brief Reply to add/replace MACIP ACL
+ @param context - returned sender context, to match reply w/ request
+ @param acl_index - index of the newly created MACIP ACL
+ @param retval 0 - no error
+*/
+
+define macip_acl_add_replace_reply
+{
+ u32 context;
+ u32 acl_index;
+ i32 retval;
+};
+
/** \brief Delete a MACIP ACL
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@@ -347,7 +379,7 @@ autoreply manual_print define macip_acl_del
/** \brief Add or delete a MACIP ACL to/from interface
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
- @param is_add - add (1) or delete (0) ACL from being used on an interface
+ @param is_add - add (1) or delete (0) MACIP ACL from being used on an interface
@param sw_if_index - interface to apply the action to
@param acl_index - MACIP ACL index
*/
@@ -357,7 +389,7 @@ autoreply manual_print define macip_acl_interface_add_del
u32 client_index;
u32 context;
u8 is_add;
- /* macip ACLs are always input */
+ /* MACIP ACLs are always input */
u32 sw_if_index;
u32 acl_index;
};
@@ -365,7 +397,7 @@ autoreply manual_print define macip_acl_interface_add_del
/** \brief Dump one or all defined MACIP ACLs
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
- @param acl_index - MACIP ACL index or ~0 to dump all ACLs
+ @param acl_index - MACIP ACL index or ~0 to dump all MACIP ACLs
*/
define macip_acl_dump
@@ -380,7 +412,7 @@ define macip_acl_dump
@param acl_index - index of this MACIP ACL
@param tag - descriptive tag which was supplied during the creation
@param count - length of the vector of MACIP ACL rules
- @param r - rules comprising this ACL
+ @param r - rules comprising this MACIP ACL
*/
manual_endian manual_print define macip_acl_details
@@ -406,7 +438,7 @@ define macip_acl_interface_get
/** \brief Reply with the vector of MACIP ACLs by sw_if_index
@param context - returned sender context, to match reply w/ request
@param count - total number of elements in the vector
- @param acls - the vector of active MACACL indices per sw_if_index
+ @param acls - the vector of active MACIP ACL indices per sw_if_index
*/
define macip_acl_interface_get_reply
@@ -419,7 +451,7 @@ define macip_acl_interface_get_reply
/** \brief Dump the list(s) of MACIP ACLs applied to specific or all interfaces
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
- @param sw_if_index - interface to dump the ACL list for
+ @param sw_if_index - interface to dump the MACIP ACL list for
*/
define macip_acl_interface_list_dump
@@ -431,9 +463,9 @@ define macip_acl_interface_list_dump
/** \brief Details about a single MACIP ACL contents
@param context - returned sender context, to match reply w/ request
- @param sw_if_index - interface for which the list of ACLs is applied
+ @param sw_if_index - interface for which the list of MACIP ACLs is applied
@param count - total length of acl indices vector
- @param acls - the vector of ACL indices
+ @param acls - the vector of MACIP ACL indices
*/
define macip_acl_interface_list_details
diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c
index bf484f6cc41..611efbb7be6 100644
--- a/src/plugins/acl/acl.c
+++ b/src/plugins/acl/acl.c
@@ -71,6 +71,7 @@ _(ACL_INTERFACE_SET_ACL_LIST, acl_interface_set_acl_list) \
_(ACL_DUMP, acl_dump) \
_(ACL_INTERFACE_LIST_DUMP, acl_interface_list_dump) \
_(MACIP_ACL_ADD, macip_acl_add) \
+_(MACIP_ACL_ADD_REPLACE, macip_acl_add_replace) \
_(MACIP_ACL_DEL, macip_acl_del) \
_(MACIP_ACL_INTERFACE_ADD_DEL, macip_acl_interface_add_del) \
_(MACIP_ACL_DUMP, macip_acl_dump) \
@@ -1158,6 +1159,18 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
macip_acl_rule_t *r;
macip_acl_rule_t *acl_new_rules = 0;
int i;
+
+ if (*acl_list_index != ~0)
+ {
+ /* They supplied some number, let's see if this MACIP ACL exists */
+ if (pool_is_free_index (am->macip_acls, *acl_list_index))
+ {
+ /* tried to replace a non-existent ACL, no point doing anything */
+ clib_warning("acl-plugin-error: Trying to replace nonexistent MACIP ACL %d (tag %s)", *acl_list_index, tag);
+ return -1;
+ }
+ }
+
if (0 == count) {
clib_warning("acl-plugin-warning: Trying to create empty MACIP ACL (tag %s)", tag);
}
@@ -1180,11 +1193,23 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
r->src_prefixlen = rules[i].src_ip_prefix_len;
}
- /* Get ACL index */
- pool_get_aligned (am->macip_acls, a, CLIB_CACHE_LINE_BYTES);
- memset (a, 0, sizeof (*a));
- /* Will return the newly allocated ACL index */
- *acl_list_index = a - am->macip_acls;
+ if (~0 == *acl_list_index)
+ {
+ /* Get ACL index */
+ pool_get_aligned (am->macip_acls, a, CLIB_CACHE_LINE_BYTES);
+ memset (a, 0, sizeof (*a));
+ /* Will return the newly allocated ACL index */
+ *acl_list_index = a - am->macip_acls;
+ }
+ else
+ {
+ a = &am->macip_acls[*acl_list_index];
+ if (a->rules)
+ {
+ vec_free (a->rules);
+ }
+ macip_destroy_classify_tables (am, *acl_list_index);
+ }
a->rules = acl_new_rules;
a->count = count;
@@ -1634,6 +1659,30 @@ vl_api_macip_acl_add_t_handler (vl_api_macip_acl_add_t * mp)
}
static void
+vl_api_macip_acl_add_replace_t_handler (vl_api_macip_acl_add_replace_t * mp)
+{
+ vl_api_macip_acl_add_replace_reply_t *rmp;
+ acl_main_t *am = &acl_main;
+ int rv;
+ u32 acl_list_index = ntohl (mp->acl_index);
+ u32 acl_count = ntohl (mp->count);
+ u32 expected_len = sizeof(*mp) + acl_count*sizeof(mp->r[0]);
+
+ if (verify_message_len(mp, expected_len, "macip_acl_add_replace")) {
+ rv = macip_acl_add_list (acl_count, mp->r, &acl_list_index, mp->tag);
+ } else {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ }
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2(VL_API_MACIP_ACL_ADD_REPLACE_REPLY,
+ ({
+ rmp->acl_index = htonl(acl_list_index);
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
vl_api_macip_acl_del_t_handler (vl_api_macip_acl_del_t * mp)
{
acl_main_t *am = &acl_main;
diff --git a/src/plugins/acl/acl_test.c b/src/plugins/acl/acl_test.c
index 2b5175852e4..abb9643ef1c 100644
--- a/src/plugins/acl/acl_test.c
+++ b/src/plugins/acl/acl_test.c
@@ -72,7 +72,8 @@ _(macip_acl_del_reply)
#define foreach_reply_retval_aclindex_handler \
_(acl_add_replace_reply) \
-_(macip_acl_add_reply)
+_(macip_acl_add_reply) \
+_(macip_acl_add_replace_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -272,6 +273,7 @@ _(ACL_INTERFACE_SET_ACL_LIST_REPLY, acl_interface_set_acl_list_reply) \
_(ACL_INTERFACE_LIST_DETAILS, acl_interface_list_details) \
_(ACL_DETAILS, acl_details) \
_(MACIP_ACL_ADD_REPLY, macip_acl_add_reply) \
+_(MACIP_ACL_ADD_REPLACE_REPLY, macip_acl_add_replace_reply) \
_(MACIP_ACL_DEL_REPLY, macip_acl_del_reply) \
_(MACIP_ACL_DETAILS, macip_acl_details) \
_(MACIP_ACL_INTERFACE_ADD_DEL_REPLY, macip_acl_interface_add_del_reply) \
@@ -965,8 +967,6 @@ static int api_macip_acl_add (vat_main_t * vam)
if(rules)
n_rules = vec_len(rules);
- else
- n_rules = 0;
if (n_rules_override >= 0)
n_rules = n_rules_override;
@@ -1000,6 +1000,159 @@ static int api_macip_acl_add (vat_main_t * vam)
return ret;
}
+static int api_macip_acl_add_replace (vat_main_t * vam)
+{
+ acl_test_main_t * sm = &acl_test_main;
+ unformat_input_t * i = vam->input;
+ vl_api_macip_acl_add_replace_t * mp;
+ u32 acl_index = ~0;
+ u32 msg_size = sizeof (*mp); /* without the rules */
+
+ vl_api_macip_acl_rule_t *rules = 0;
+ int rule_idx = 0;
+ int n_rules = 0;
+ int n_rules_override = -1;
+ u32 src_prefix_length = 0;
+ u32 action = 0;
+ ip4_address_t src_v4address;
+ ip6_address_t src_v6address;
+ u8 src_mac[6];
+ u8 *tag = 0;
+ u8 mac_mask_all_1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ int ret;
+
+ if (!unformat (i, "%d", &acl_index)) {
+ /* Just assume -1 */
+ }
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "ipv6"))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ rules[rule_idx].is_ipv6 = 1;
+ }
+ else if (unformat (i, "ipv4"))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ rules[rule_idx].is_ipv6 = 0;
+ }
+ else if (unformat (i, "permit"))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ rules[rule_idx].is_permit = 1;
+ }
+ else if (unformat (i, "deny"))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ rules[rule_idx].is_permit = 0;
+ }
+ else if (unformat (i, "count %d", &n_rules_override))
+ {
+ /* we will use this later */
+ }
+ else if (unformat (i, "action %d", &action))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ rules[rule_idx].is_permit = action;
+ }
+ else if (unformat (i, "ip %U/%d",
+ unformat_ip4_address, &src_v4address, &src_prefix_length) ||
+ unformat (i, "ip %U",
+ unformat_ip4_address, &src_v4address))
+ {
+ if (src_prefix_length == 0)
+ src_prefix_length = 32;
+ vec_validate_macip_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 (i, "src"))
+ {
+ /* Everything in MACIP is "source" but allow this verbosity */
+ }
+ else if (unformat (i, "ip %U/%d",
+ unformat_ip6_address, &src_v6address, &src_prefix_length) ||
+ unformat (i, "ip %U",
+ unformat_ip6_address, &src_v6address))
+ {
+ if (src_prefix_length == 0)
+ src_prefix_length = 128;
+ vec_validate_macip_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 (i, "mac %U",
+ my_unformat_mac_address, &src_mac))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ memcpy (rules[rule_idx].src_mac, &src_mac, 6);
+ memcpy (rules[rule_idx].src_mac_mask, &mac_mask_all_1, 6);
+ }
+ else if (unformat (i, "mask %U",
+ my_unformat_mac_address, &src_mac))
+ {
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ memcpy (rules[rule_idx].src_mac_mask, &src_mac, 6);
+ }
+ else if (unformat (i, "tag %s", &tag))
+ {
+ }
+ else if (unformat (i, ","))
+ {
+ rule_idx++;
+ vec_validate_macip_acl_rules(rules, rule_idx);
+ }
+ else
+ break;
+ }
+
+ if (!rules)
+ {
+ errmsg ("rule/s required\n");
+ return -99;
+ }
+ /* Construct the API message */
+ vam->result_ready = 0;
+
+ if(rules)
+ n_rules = vec_len(rules);
+
+ if (n_rules_override >= 0)
+ n_rules = n_rules_override;
+
+ msg_size += n_rules*sizeof(rules[0]);
+
+ mp = vl_msg_api_alloc_as_if_client(msg_size);
+ memset (mp, 0, msg_size);
+ mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_ADD_REPLACE + sm->msg_id_base);
+ mp->client_index = vam->my_client_index;
+ if ((n_rules > 0) && rules)
+ clib_memcpy(mp->r, rules, n_rules*sizeof (mp->r[0]));
+ if (tag)
+ {
+ if (vec_len(tag) >= sizeof(mp->tag))
+ {
+ tag[sizeof(mp->tag)-1] = 0;
+ _vec_len(tag) = sizeof(mp->tag);
+ }
+ clib_memcpy(mp->tag, tag, vec_len(tag));
+ vec_free(tag);
+ }
+
+ mp->acl_index = ntohl(acl_index);
+ mp->count = htonl(n_rules);
+
+ /* send it... */
+ S(mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
/*
* List of messages that the api test plugin sends,
* and that the data plane plugin processes
@@ -1013,6 +1166,7 @@ _(acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] [input|output
_(acl_interface_set_acl_list, "<intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]") \
_(acl_interface_list_dump, "[<intfc> | sw_if_index <if-idx>]") \
_(macip_acl_add, "...") \
+_(macip_acl_add_replace, "<acl-idx> [<ipv4|ipv6> <permit|deny|action N> [count <count>] [src] ip <ipaddress/[plen]> mac <mac> mask <mac_mask>, ... , ...") \
_(macip_acl_del, "<acl-idx>")\
_(macip_acl_dump, "[<acl-idx>]") \
_(macip_acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] acl <acl-idx>") \
diff --git a/src/plugins/acl/manual_fns.h b/src/plugins/acl/manual_fns.h
index c37d14b63a9..e00f1abcc61 100644
--- a/src/plugins/acl/manual_fns.h
+++ b/src/plugins/acl/manual_fns.h
@@ -89,6 +89,18 @@ vl_api_macip_acl_add_t_endian (vl_api_macip_acl_add_t * a)
vl_api_macip_acl_rule_t_array_endian (a->r, a->count);
}
+static inline void
+vl_api_macip_acl_add_replace_t_endian (vl_api_macip_acl_add_replace_t * a)
+{
+ a->_vl_msg_id = clib_net_to_host_u16 (a->_vl_msg_id);
+ a->client_index = clib_net_to_host_u32 (a->client_index);
+ a->context = clib_net_to_host_u32 (a->context);
+ a->acl_index = clib_net_to_host_u32 (a->acl_index);
+ /* a->tag[0..63] = a->tag[0..63] (no-op) */
+ a->count = clib_net_to_host_u32 (a->count);
+ vl_api_macip_acl_rule_t_array_endian (a->r, a->count);
+}
+
static inline u8 *
format_acl_action(u8 *s, u8 action)
{
@@ -292,6 +304,36 @@ vl_api_macip_acl_add_t_print (vl_api_macip_acl_add_t * a, void *handle)
return handle;
}
+static inline void *
+vl_api_macip_acl_add_replace_t_print (vl_api_macip_acl_add_replace_t * a, void *handle)
+{
+ u8 *s = 0;
+ int i;
+ u32 acl_index = clib_net_to_host_u32 (a->acl_index);
+ u32 count = clib_net_to_host_u32 (a->count);
+ if (count > 0x100000)
+ {
+ s = format (s, "WARN: macip_acl_add_replace count endianness wrong? Fixup to avoid long loop.\n");
+ count = a->count;
+ }
+
+ s = format (s, "SCRIPT: macip_acl_add_replace %d count %d ",
+ acl_index, count);
+ if (a->tag[0])
+ s = format (s, "tag %s ", a->tag);
+
+ s = format (s, "count %d \\\n", count);
+
+ PRINT_S;
+
+ for (i = 0; i < count; i++)
+ vl_api_macip_acl_rule_t_print (&a->r[i], handle);
+
+ s = format (0, "\n");
+ PRINT_S;
+
+ return handle;
+}
static inline void *
vl_api_acl_interface_set_acl_list_t_print (vl_api_acl_interface_set_acl_list_t