diff options
author | Andrew Yourtchenko <ayourtch@gmail.com> | 2018-02-06 17:42:32 +0100 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2018-02-08 15:51:46 +0000 |
commit | c43b3f986476ffb4506b7115898e809a6e34f601 (patch) | |
tree | 63576d278689bfc0ebd6b15eb9178006151c33aa /src/plugins/acl/acl_test.c | |
parent | be2251b0c5b10a3a556e75c9bfbea96df4799297 (diff) |
acl-plugin: add whitelisted ethertype mode (VPP-1163)
Currently, ACL plugin largely does not care about the
ethertypes other than 0x0800 (IPv4) and 0x86dd (IPv6),
the only exception being 0x0806 (ARP), which is
dealt with by the MACIP ACLs.
The other ethertypes in L2 mode are just let through.
This adds a new API message acl_interface_set_etype_whitelist,
which allows to flip the mode of a given interface
into "ethertype whitelist mode": the caller of this message
must supply the two lists (inbound and outbound) of the ethertypes
that are to be permitted, the rest of the ethertypes are
dropped.
The whitelisting for a given interface and direction takes
effect only when a policy ACL is also applied.
This operates on the same classifier node as the one used for
dispatching the policy ACL, thus, if one wishes for most of the
reasonable IPv4 deployments to continue to operate within
the whitelist mode, they must permit ARP ethertype (0x0806)
The empty list for a given direction resets the processing
to allow the unknown ethertypes. So, if one wants to just
permit the IPv4 and IPv6 and nothing else, one can add
their ethertypes to the whitelist.
Add the "show acl-plugin interface" corresponding outputs
about the whitelists, vat command, and unittests.
Change-Id: I4659978c801f36d554b6615e56e424b77876662c
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Diffstat (limited to 'src/plugins/acl/acl_test.c')
-rw-r--r-- | src/plugins/acl/acl_test.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/plugins/acl/acl_test.c b/src/plugins/acl/acl_test.c index 90fd49980de..c264034c939 100644 --- a/src/plugins/acl/acl_test.c +++ b/src/plugins/acl/acl_test.c @@ -67,6 +67,7 @@ _(acl_del_reply) \ _(acl_interface_add_del_reply) \ _(macip_acl_interface_add_del_reply) \ _(acl_interface_set_acl_list_reply) \ +_(acl_interface_set_etype_whitelist_reply) \ _(macip_acl_del_reply) #define foreach_reply_retval_aclindex_handler \ @@ -269,6 +270,7 @@ _(ACL_ADD_REPLACE_REPLY, acl_add_replace_reply) \ _(ACL_DEL_REPLY, acl_del_reply) \ _(ACL_INTERFACE_ADD_DEL_REPLY, acl_interface_add_del_reply) \ _(ACL_INTERFACE_SET_ACL_LIST_REPLY, acl_interface_set_acl_list_reply) \ +_(ACL_INTERFACE_SET_ETYPE_WHITELIST_REPLY, acl_interface_set_etype_whitelist_reply) \ _(ACL_INTERFACE_LIST_DETAILS, acl_interface_list_details) \ _(ACL_DETAILS, acl_details) \ _(MACIP_ACL_ADD_REPLY, macip_acl_add_reply) \ @@ -746,6 +748,63 @@ static int api_acl_interface_set_acl_list (vat_main_t * vam) return ret; } +static int api_acl_interface_set_etype_whitelist (vat_main_t * vam) +{ + unformat_input_t * i = vam->input; + vl_api_acl_interface_set_etype_whitelist_t * mp; + u32 sw_if_index = ~0; + u32 ethertype = ~0; + u16 *etypes_in = 0; + u16 *etypes_out = 0; + u8 is_input = 1; + int ret; + +// acl_interface_set_etype_whitelist <intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype list] + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { + if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index)) + ; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + ; + else if (unformat (i, "%x", ðertype)) + { + ethertype = ethertype & 0xffff; + if(is_input) + vec_add1(etypes_in, htons(ethertype)); + else + vec_add1(etypes_out, htons(ethertype)); + } + else if (unformat (i, "input")) + is_input = 1; + else if (unformat (i, "output")) + is_input = 0; + else + break; + } + + if (sw_if_index == ~0) { + errmsg ("missing interface name / explicit sw_if_index number \n"); + return -99; + } + + /* Construct the API message */ + M2(ACL_INTERFACE_SET_ETYPE_WHITELIST, mp, sizeof(u32) * (vec_len(etypes_in) + vec_len(etypes_out))); + mp->sw_if_index = ntohl(sw_if_index); + mp->n_input = vec_len(etypes_in); + mp->count = vec_len(etypes_in) + vec_len(etypes_out); + vec_append(etypes_in, etypes_out); + if (vec_len(etypes_in) > 0) + clib_memcpy(mp->whitelist, etypes_in, vec_len(etypes_in)*sizeof(etypes_in[0])); + + /* send it... */ + S(mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + static void api_acl_send_control_ping(vat_main_t *vam) { @@ -1163,6 +1222,7 @@ _(acl_del, "<acl-idx>") \ _(acl_dump, "[<acl-idx>]") \ _(acl_interface_add_del, "<intfc> | sw_if_index <if-idx> [add|del] [input|output] acl <acl-idx>") \ _(acl_interface_set_acl_list, "<intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx list]") \ +_(acl_interface_set_etype_whitelist, "<intfc> | sw_if_index <if-idx> input [ethertype list] output [ethertype 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>, ... , ...") \ |