diff options
Diffstat (limited to 'plugins/acl-plugin/acl')
20 files changed, 0 insertions, 6057 deletions
diff --git a/plugins/acl-plugin/acl/acl.api b/plugins/acl-plugin/acl/acl.api deleted file mode 100644 index 58a5a17180e..00000000000 --- a/plugins/acl-plugin/acl/acl.api +++ /dev/null @@ -1,444 +0,0 @@ -/* Hey Emacs use -*- mode: C -*- */ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - This file defines the vpp control-plane API messages - used to control the ACL plugin -*/ - - -/** \brief Get the plugin version - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ - -define acl_plugin_get_version -{ - u32 client_index; - u32 context; -}; - -/** \brief Reply to get the plugin version - @param context - returned sender context, to match reply w/ request - @param major - Incremented every time a known breaking behavior change is introduced - @param minor - Incremented with small changes, may be used to avoid buggy versions -*/ - -define acl_plugin_get_version_reply -{ - u32 context; - u32 major; - u32 minor; -}; - -/** \brief Access List Rule entry - @param is_permit - deny (0), permit (1), or permit+reflect(2) action on this rule. - @param is_ipv6 - IP addresses in this rule are IPv6 (1) or IPv4 (0) - @param src_ip_addr - Source prefix value - @param src_ip_prefix_len - Source prefix length - @param dst_ip_addr - Destination prefix value - @param dst_ip_prefix_len - Destination prefix length - @param proto - L4 protocol (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml) - @param srcport_or_icmptype_first - beginning of source port or ICMP4/6 type range - @param srcport_or_icmptype_last - end of source port or ICMP4/6 type range - @param dstport_or_icmpcode_first - beginning of destination port or ICMP4/6 code range - @param dstport_or_icmpcode_last - end of destination port or ICMP4/6 code range - @param tcp_flags_mask - if proto==6, match masked TCP flags with this value - @param tcp_flags_value - if proto==6, mask to AND the TCP flags in the packet with -*/ - -typeonly manual_print manual_endian define acl_rule -{ - u8 is_permit; - u8 is_ipv6; - u8 src_ip_addr[16]; - u8 src_ip_prefix_len; - u8 dst_ip_addr[16]; - u8 dst_ip_prefix_len; -/* - * L4 protocol. IANA number. 1 = ICMP, 58 = ICMPv6, 6 = TCP, 17 = UDP. - * 0 => ignore L4 and ignore the ports/tcpflags when matching. - */ - u8 proto; -/* - * If the L4 protocol is TCP or UDP, the below - * hold ranges of ports, else if the L4 is ICMP/ICMPv6 - * they hold ranges of ICMP(v6) types/codes. - * - * Ranges are inclusive, i.e. to match "any" TCP/UDP port, - * use first=0,last=65535. For ICMP(v6), - * use first=0,last=255. - */ - u16 srcport_or_icmptype_first; - u16 srcport_or_icmptype_last; - u16 dstport_or_icmpcode_first; - u16 dstport_or_icmpcode_last; -/* - * for proto = 6, this matches if the - * TCP flags in the packet, ANDed with tcp_flags_mask, - * is equal to tcp_flags_value. - */ - u8 tcp_flags_mask; - u8 tcp_flags_value; -}; - -/** \brief MACIP Access List Rule entry - @param is_permit - deny (0), permit (1) action on this rule. - @param is_ipv6 - IP addresses in this rule are IPv6 (1) or IPv4 (0) - @param src_mac - match masked source MAC address against this value - @param src_mac_mask - AND source MAC address with this value before matching - @param src_ip_addr - Source prefix value - @param src_ip_prefix_len - Source prefix length -*/ - -typeonly manual_print manual_endian define macip_acl_rule -{ - u8 is_permit; - u8 is_ipv6; -/* - * The source mac of the packet ANDed with src_mac_mask. - * The source ip[46] address in the packet is matched - * against src_ip_addr, with src_ip_prefix_len set to 0. - * - * For better performance, minimize the number of - * (src_mac_mask, src_ip_prefix_len) combinations - * in a MACIP ACL. - */ - u8 src_mac[6]; - u8 src_mac_mask[6]; - u8 src_ip_addr[16]; - u8 src_ip_prefix_len; -}; - -/** \brief Replace an existing ACL in-place or create a new ACL - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param acl_index - an existing ACL entry (0..0xfffffffe) to replace, or 0xffffffff to make new ACL - @param tag - a string value stored along with the ACL, for descriptive purposes - @param count - number of ACL rules - @r - Rules for this access-list -*/ - -manual_print manual_endian define acl_add_replace -{ - u32 client_index; - u32 context; - u32 acl_index; /* ~0 to add, existing ACL# to replace */ - u8 tag[64]; /* What gets in here gets out in the corresponding tag field when dumping the ACLs. */ - u32 count; - vl_api_acl_rule_t r[count]; -}; - -/** \brief Reply to add/replace ACL - @param context - returned sender context, to match reply w/ request - @param acl_index - index of the updated or newly created ACL - @param retval 0 - no error -*/ - -define acl_add_replace_reply -{ - u32 context; - u32 acl_index; - i32 retval; -}; - -/** \brief Delete an ACL - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param acl_index - ACL index to delete -*/ - -define acl_del -{ - u32 client_index; - u32 context; - u32 acl_index; -}; - -/** \brief Reply to delete the ACL - @param context - returned sender context, to match reply w/ request - @param retval 0 - no error -*/ - -define acl_del_reply -{ - u32 context; - i32 retval; -}; - -/* acl_interface_add_del(_reply) to be deprecated in lieu of acl_interface_set_acl_list */ -/** \brief Use acl_interface_set_acl_list instead - Append/remove an ACL index to/from the list of ACLs checked for an interface - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add or delete the ACL index from the list - @param is_input - check the ACL on input (1) or output (0) - @param sw_if_index - the interface to alter the list of ACLs on - @param acl_index - index of ACL for the operation -*/ - -define acl_interface_add_del -{ - u32 client_index; - u32 context; - u8 is_add; -/* - * is_input = 0 => ACL applied on interface egress - * is_input = 1 => ACL applied on interface ingress - */ - u8 is_input; - u32 sw_if_index; - u32 acl_index; -}; - -/** \brief Reply to alter the ACL list - @param context - returned sender context, to match reply w/ request - @param retval 0 - no error -*/ - -define acl_interface_add_del_reply -{ - u32 context; - i32 retval; -}; - -/** \brief Set the vector of input/output ACLs checked for an interface - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - the interface to alter the list of ACLs on - @param count - total number of ACL indices in the vector - @param n_input - this many first elements correspond to input ACLs, the rest - output - @param acls - vector of ACL indices -*/ - -manual_endian define acl_interface_set_acl_list -{ - u32 client_index; - u32 context; - u32 sw_if_index; - u8 count; - u8 n_input; /* First n_input ACLs are set as a list of input ACLs, the rest are applied as output */ - u32 acls[count]; -}; - -/** \brief Reply to set the ACL list on an interface - @param context - returned sender context, to match reply w/ request - @param retval 0 - no error -*/ - -define acl_interface_set_acl_list_reply -{ - u32 context; - i32 retval; -}; - -/** \brief Dump the specific ACL contents or all of the ACLs' contents - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param acl_index - ACL index to dump, ~0 to dump all ACLs -*/ - -define acl_dump -{ - u32 client_index; - u32 context; - u32 acl_index; /* ~0 for all ACLs */ -}; - -/** \brief Details about a single ACL contents - @param context - returned sender context, to match reply w/ request - @param acl_index - ACL index whose contents are being sent in this message - @param tag - Descriptive tag value which was supplied at ACL creation - @param count - Number of rules in this ACL - @param r - Array of rules within this ACL -*/ - -manual_print manual_endian define acl_details -{ - u32 context; - u32 acl_index; - u8 tag[64]; /* Same blob that was supplied to us when creating the ACL, one hopes. */ - u32 count; - vl_api_acl_rule_t r[count]; -}; - -/** \brief Dump the list(s) of ACL 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 -*/ - -define acl_interface_list_dump -{ - u32 client_index; - u32 context; - u32 sw_if_index; /* ~0 for all interfaces */ -}; - -/** \brief Details about a single 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 count - total length of acl indices vector - @param n_input - this many of indices in the beginning are input ACLs, the rest - output - @param acls - the vector of ACL indices -*/ - -manual_endian define acl_interface_list_details -{ - u32 context; - u32 sw_if_index; - u8 count; - u8 n_input; - u32 acls[count]; -}; - -/** \brief Add a MACIP ACL - @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 r - vector of MACIP ACL rules -*/ - -manual_print manual_endian define macip_acl_add -{ - u32 client_index; - u32 context; - u8 tag[64]; - u32 count; - vl_api_macip_acl_rule_t r[count]; -}; - -/** \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 retval 0 - no error -*/ - -define macip_acl_add_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 - @param acl_index - MACIP ACL index to delete -*/ - -define macip_acl_del -{ - u32 client_index; - u32 context; - u32 acl_index; -}; - -/** \brief Reply to delete the MACIP ACL - @param context - returned sender context, to match reply w/ request - @param retval 0 - no error -*/ - -define macip_acl_del_reply -{ - u32 context; - i32 retval; -}; - -/** \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 sw_if_index - interface to apply the action to - @param acl_index - MACIP ACL index -*/ - -define macip_acl_interface_add_del -{ - u32 client_index; - u32 context; - u8 is_add; - /* macip ACLs are always input */ - u32 sw_if_index; - u32 acl_index; -}; - -/** \brief Reply to apply/unapply the MACIP ACL - @param context - returned sender context, to match reply w/ request - @param retval 0 - no error -*/ - -define macip_acl_interface_add_del_reply -{ - u32 context; - i32 retval; -}; - -/** \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 -*/ - -define macip_acl_dump -{ - u32 client_index; - u32 context; - u32 acl_index; /* ~0 for all ACLs */ -}; - -/** \brief Details about one MACIP ACL - @param context - returned sender context, to match reply w/ request - @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 -*/ - -manual_print manual_endian define macip_acl_details -{ - u32 context; - u32 acl_index; - u8 tag[64]; - u32 count; - vl_api_macip_acl_rule_t r[count]; -}; - -/** \brief Get the vector of MACIP ACL IDs applied to the interfaces - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ - -define macip_acl_interface_get -{ - u32 client_index; - u32 context; -}; - -/** \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 -*/ - -define macip_acl_interface_get_reply -{ - u32 context; - u32 count; - u32 acls[count]; -}; - diff --git a/plugins/acl-plugin/acl/acl.c b/plugins/acl-plugin/acl/acl.c deleted file mode 100644 index 8ff5a6b721c..00000000000 --- a/plugins/acl-plugin/acl/acl.c +++ /dev/null @@ -1,1901 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stddef.h> - -#include <vnet/vnet.h> -#include <vnet/plugin/plugin.h> -#include <acl/acl.h> -#include <acl/l2sess.h> - -#include <vnet/l2/l2_classify.h> -#include <vnet/classify/input_acl.h> - -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vlibsocket/api.h> - -/* define message IDs */ -#include <acl/acl_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <acl/acl_all_api_h.h> -#undef vl_typedefs - -/* define generated endian-swappers */ -#define vl_endianfun -#include <acl/acl_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) -#define vl_printfun -#include <acl/acl_all_api_h.h> -#undef vl_printfun - -/* Get the API version number */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <acl/acl_all_api_h.h> -#undef vl_api_version - -#include "node_in.h" -#include "node_out.h" - -acl_main_t acl_main; - -/* - * A handy macro to set up a message reply. - * Assumes that the following variables are available: - * mp - pointer to request message - * rmp - pointer to reply message type - * rv - return value - */ - -#define REPLY_MACRO(t) \ -do { \ - unix_shared_memory_queue_t * q = \ - vl_api_client_index_to_input_queue (mp->client_index); \ - if (!q) \ - return; \ - \ - rmp = vl_msg_api_alloc (sizeof (*rmp)); \ - rmp->_vl_msg_id = ntohs((t)+sm->msg_id_base); \ - rmp->context = mp->context; \ - rmp->retval = ntohl(rv); \ - \ - vl_msg_api_send_shmem (q, (u8 *)&rmp); \ -} while(0); - -#define REPLY_MACRO2(t, body) \ -do { \ - unix_shared_memory_queue_t * q; \ - rv = vl_msg_api_pd_handler (mp, rv); \ - q = vl_api_client_index_to_input_queue (mp->client_index); \ - if (!q) \ - return; \ - \ - rmp = vl_msg_api_alloc (sizeof (*rmp)); \ - rmp->_vl_msg_id = ntohs((t)+am->msg_id_base); \ - rmp->context = mp->context; \ - rmp->retval = ntohl(rv); \ - do {body;} while (0); \ - vl_msg_api_send_shmem (q, (u8 *)&rmp); \ -} while(0); - -#define REPLY_MACRO3(t, n, body) \ -do { \ - unix_shared_memory_queue_t * q; \ - rv = vl_msg_api_pd_handler (mp, rv); \ - q = vl_api_client_index_to_input_queue (mp->client_index); \ - if (!q) \ - return; \ - \ - rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \ - rmp->_vl_msg_id = ntohs((t)+am->msg_id_base); \ - rmp->context = mp->context; \ - rmp->retval = ntohl(rv); \ - do {body;} while (0); \ - vl_msg_api_send_shmem (q, (u8 *)&rmp); \ -} while(0); - - -/* List of message types that this plugin understands */ - -#define foreach_acl_plugin_api_msg \ -_(ACL_PLUGIN_GET_VERSION, acl_plugin_get_version) \ -_(ACL_ADD_REPLACE, acl_add_replace) \ -_(ACL_DEL, acl_del) \ -_(ACL_INTERFACE_ADD_DEL, acl_interface_add_del) \ -_(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_DEL, macip_acl_del) \ -_(MACIP_ACL_INTERFACE_ADD_DEL, macip_acl_interface_add_del) \ -_(MACIP_ACL_DUMP, macip_acl_dump) \ -_(MACIP_ACL_INTERFACE_GET, macip_acl_interface_get) - -/* - * This routine exists to convince the vlib plugin framework that - * we haven't accidentally copied a random .dll into the plugin directory. - * - * Also collects global variable pointers passed from the vpp engine - */ - -clib_error_t * -vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h, - int from_early_init) -{ - acl_main_t *am = &acl_main; - clib_error_t *error = 0; - - am->vlib_main = vm; - am->vnet_main = h->vnet_main; - am->ethernet_main = h->ethernet_main; - - l2sess_vlib_plugin_register(vm, h, from_early_init); - - return error; -} - - -static void -vl_api_acl_plugin_get_version_t_handler (vl_api_acl_plugin_get_version_t * mp) -{ - acl_main_t *am = &acl_main; - vl_api_acl_plugin_get_version_reply_t *rmp; - int msg_size = sizeof (*rmp); - unix_shared_memory_queue_t *q; - - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - { - return; - } - - rmp = vl_msg_api_alloc (msg_size); - memset (rmp, 0, msg_size); - rmp->_vl_msg_id = - ntohs (VL_API_ACL_PLUGIN_GET_VERSION_REPLY + am->msg_id_base); - rmp->context = mp->context; - rmp->major = htonl (ACL_PLUGIN_VERSION_MAJOR); - rmp->minor = htonl (ACL_PLUGIN_VERSION_MINOR); - - vl_msg_api_send_shmem (q, (u8 *) & rmp); -} - - -static int -acl_add_list (u32 count, vl_api_acl_rule_t rules[], - u32 * acl_list_index, u8 * tag) -{ - acl_main_t *am = &acl_main; - acl_list_t *a; - acl_rule_t *r; - acl_rule_t *acl_new_rules; - int i; - - if (*acl_list_index != ~0) - { - /* They supplied some number, let's see if this ACL exists */ - if (pool_is_free_index (am->acls, *acl_list_index)) - { - /* tried to replace a non-existent ACL, no point doing anything */ - return -1; - } - } - - /* Create and populate the rules */ - acl_new_rules = clib_mem_alloc_aligned (sizeof (acl_rule_t) * count, - CLIB_CACHE_LINE_BYTES); - if (!acl_new_rules) - { - /* Could not allocate rules. New or existing ACL - bail out regardless */ - return -1; - } - - for (i = 0; i < count; i++) - { - r = &acl_new_rules[i]; - r->is_permit = rules[i].is_permit; - r->is_ipv6 = rules[i].is_ipv6; - if (r->is_ipv6) - { - memcpy (&r->src, rules[i].src_ip_addr, sizeof (r->src)); - memcpy (&r->dst, rules[i].dst_ip_addr, sizeof (r->dst)); - } - else - { - memcpy (&r->src.ip4, rules[i].src_ip_addr, sizeof (r->src.ip4)); - memcpy (&r->dst.ip4, rules[i].dst_ip_addr, sizeof (r->dst.ip4)); - } - r->src_prefixlen = rules[i].src_ip_prefix_len; - r->dst_prefixlen = rules[i].dst_ip_prefix_len; - r->proto = rules[i].proto; - r->src_port_or_type_first = rules[i].srcport_or_icmptype_first; - r->src_port_or_type_last = rules[i].srcport_or_icmptype_last; - r->dst_port_or_code_first = rules[i].dstport_or_icmpcode_first; - r->dst_port_or_code_last = rules[i].dstport_or_icmpcode_last; - r->tcp_flags_value = rules[i].tcp_flags_value; - r->tcp_flags_mask = rules[i].tcp_flags_mask; - } - - if (~0 == *acl_list_index) - { - /* Get ACL index */ - pool_get_aligned (am->acls, a, CLIB_CACHE_LINE_BYTES); - memset (a, 0, sizeof (*a)); - /* Will return the newly allocated ACL index */ - *acl_list_index = a - am->acls; - } - else - { - a = am->acls + *acl_list_index; - /* Get rid of the old rules */ - clib_mem_free (a->rules); - } - a->rules = acl_new_rules; - a->count = count; - memcpy (a->tag, tag, sizeof (a->tag)); - - return 0; -} - -static int -acl_del_list (u32 acl_list_index) -{ - acl_main_t *am = &acl_main; - acl_list_t *a; - int i, ii; - if (pool_is_free_index (am->acls, acl_list_index)) - { - return -1; - } - - /* delete any references to the ACL */ - for (i = 0; i < vec_len (am->output_acl_vec_by_sw_if_index); i++) - { - for (ii = 0; ii < vec_len (am->output_acl_vec_by_sw_if_index[i]); - /* see body */ ) - { - if (acl_list_index == am->output_acl_vec_by_sw_if_index[i][ii]) - { - vec_del1 (am->output_acl_vec_by_sw_if_index[i], ii); - } - else - { - ii++; - } - } - } - for (i = 0; i < vec_len (am->input_acl_vec_by_sw_if_index); i++) - { - for (ii = 0; ii < vec_len (am->input_acl_vec_by_sw_if_index[i]); - /* see body */ ) - { - if (acl_list_index == am->input_acl_vec_by_sw_if_index[i][ii]) - { - vec_del1 (am->input_acl_vec_by_sw_if_index[i], ii); - } - else - { - ii++; - } - } - } - - /* now we can delete the ACL itself */ - a = &am->acls[acl_list_index]; - if (a->rules) - { - clib_mem_free (a->rules); - } - pool_put (am->acls, a); - return 0; -} - -/* Some aids in ASCII graphing the content */ -#define XX "\377" -#define __ "\000" -#define _(x) -#define v - -u8 ip4_5tuple_mask[] = -_(" dmac smac etype ") -_(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v - _(" v ihl totlen ") - _(0x0000) - __ __ __ __ - _(" ident fl+fo ") - _(0x0004) - __ __ __ __ - _(" ttl pr checksum ") - _(0x0008) - __ XX __ __ - _(" src address ") - _(0x000C) - XX XX XX XX - _(" dst address ") - _(0x0010) - XX XX XX XX - _("L4 T/U sport dport ") - _(tcpudp) - XX XX XX XX - _(padpad) - __ __ __ __ - _(padpad) - __ __ __ __ - _(padeth) - __ __; - - u8 ip6_5tuple_mask[] = - _(" dmac smac etype ") - _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v - _(" v tc + flow ") - _(0x0000) __ __ __ __ - _(" plen nh hl ") - _(0x0004) __ __ XX __ - _(" src address ") - _(0x0008) XX XX XX XX - _(0x000C) XX XX XX XX - _(0x0010) XX XX XX XX - _(0x0014) XX XX XX XX - _(" dst address ") - _(0x0018) XX XX XX XX - _(0x001C) XX XX XX XX - _(0x0020) XX XX XX XX - _(0x0024) XX XX XX XX - _("L4T/U sport dport ") - _(tcpudp) XX XX XX XX _(padpad) __ __ __ __ _(padeth) __ __; - -#undef XX -#undef __ -#undef _ -#undef v - - static int count_skip (u8 * p, u32 size) -{ - u64 *p64 = (u64 *) p; - /* Be tolerant to null pointer */ - if (0 == p) - return 0; - - while ((0ULL == *p64) && ((u8 *) p64 - p) < size) - { - p64++; - } - return (p64 - (u64 *) p) / 2; -} - -static int -acl_classify_add_del_table_big (vnet_classify_main_t * cm, u8 * mask, - u32 mask_len, u32 next_table_index, - u32 miss_next_index, u32 * table_index, - int is_add) -{ - u32 nbuckets = 65536; - u32 memory_size = 2 << 30; - u32 skip = count_skip (mask, mask_len); - u32 match = (mask_len / 16) - skip; - u8 *skip_mask_ptr = mask + 16 * skip; - u32 current_data_flag = 0; - int current_data_offset = 0; - - if (0 == match) - match = 1; - - return vnet_classify_add_del_table (cm, skip_mask_ptr, nbuckets, - memory_size, skip, match, - next_table_index, miss_next_index, - table_index, current_data_flag, - current_data_offset, is_add, - 1 /* delete_chain */); -} - -static int -acl_classify_add_del_table_small (vnet_classify_main_t * cm, u8 * mask, - u32 mask_len, u32 next_table_index, - u32 miss_next_index, u32 * table_index, - int is_add) -{ - u32 nbuckets = 32; - u32 memory_size = 2 << 20; - u32 skip = count_skip (mask, mask_len); - u32 match = (mask_len / 16) - skip; - u8 *skip_mask_ptr = mask + 16 * skip; - u32 current_data_flag = 0; - int current_data_offset = 0; - - if (0 == match) - match = 1; - - return vnet_classify_add_del_table (cm, skip_mask_ptr, nbuckets, - memory_size, skip, match, - next_table_index, miss_next_index, - table_index, current_data_flag, - current_data_offset, is_add, - 1 /* delete_chain */); -} - - -static int -acl_unhook_l2_input_classify (acl_main_t * am, u32 sw_if_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - u32 ip4_table_index = ~0; - u32 ip6_table_index = ~0; - - vec_validate_init_empty (am->acl_ip4_input_classify_table_by_sw_if_index, - sw_if_index, ~0); - vec_validate_init_empty (am->acl_ip6_input_classify_table_by_sw_if_index, - sw_if_index, ~0); - - vnet_l2_input_classify_enable_disable (sw_if_index, 0); - - if (am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index] != ~0) - { - ip4_table_index = - am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index]; - am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index] = ~0; - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip4_table_index, 0); - } - if (am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index] != ~0) - { - ip6_table_index = - am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index]; - am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index] = ~0; - acl_classify_add_del_table_big (cm, ip6_5tuple_mask, - sizeof (ip6_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip6_table_index, 0); - } - - return 0; -} - -static int -acl_unhook_l2_output_classify (acl_main_t * am, u32 sw_if_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - u32 ip4_table_index = ~0; - u32 ip6_table_index = ~0; - - vec_validate_init_empty (am->acl_ip4_output_classify_table_by_sw_if_index, - sw_if_index, ~0); - vec_validate_init_empty (am->acl_ip6_output_classify_table_by_sw_if_index, - sw_if_index, ~0); - - vnet_l2_output_classify_enable_disable (sw_if_index, 0); - - if (am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index] != ~0) - { - ip4_table_index = - am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index]; - am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index] = ~0; - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip4_table_index, 0); - } - if (am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index] != ~0) - { - ip6_table_index = - am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index]; - am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index] = ~0; - acl_classify_add_del_table_big (cm, ip6_5tuple_mask, - sizeof (ip6_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip6_table_index, 0); - } - - return 0; -} - -static int -acl_hook_l2_input_classify (acl_main_t * am, u32 sw_if_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - u32 ip4_table_index = ~0; - u32 ip6_table_index = ~0; - int rv; - - /* in case there were previous tables attached */ - acl_unhook_l2_input_classify (am, sw_if_index); - rv = - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip4_table_index, 1); - if (rv) - return rv; - rv = - acl_classify_add_del_table_big (cm, ip6_5tuple_mask, - sizeof (ip6_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip6_table_index, 1); - if (rv) - { - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip4_table_index, 0); - return rv; - } - rv = - vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index, - ip6_table_index, ~0); - clib_warning - ("ACL enabling on interface sw_if_index %d, setting tables to the following: ip4: %d ip6: %d\n", - sw_if_index, ip4_table_index, ip6_table_index); - if (rv) - { - acl_classify_add_del_table_big (cm, ip6_5tuple_mask, - sizeof (ip6_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip6_table_index, 0); - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_input_classify_next_acl, - &ip4_table_index, 0); - return rv; - } - - am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index] = - ip4_table_index; - am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index] = - ip6_table_index; - - vnet_l2_input_classify_enable_disable (sw_if_index, 1); - return rv; -} - -static int -acl_hook_l2_output_classify (acl_main_t * am, u32 sw_if_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - u32 ip4_table_index = ~0; - u32 ip6_table_index = ~0; - int rv; - - /* in case there were previous tables attached */ - acl_unhook_l2_output_classify (am, sw_if_index); - rv = - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip4_table_index, 1); - if (rv) - return rv; - rv = - acl_classify_add_del_table_big (cm, ip6_5tuple_mask, - sizeof (ip6_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip6_table_index, 1); - if (rv) - { - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip4_table_index, 0); - return rv; - } - rv = - vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index, - ip6_table_index, ~0); - clib_warning - ("ACL enabling on interface sw_if_index %d, setting tables to the following: ip4: %d ip6: %d\n", - sw_if_index, ip4_table_index, ip6_table_index); - if (rv) - { - acl_classify_add_del_table_big (cm, ip6_5tuple_mask, - sizeof (ip6_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip6_table_index, 0); - acl_classify_add_del_table_big (cm, ip4_5tuple_mask, - sizeof (ip4_5tuple_mask) - 1, ~0, - am->l2_output_classify_next_acl, - &ip4_table_index, 0); - return rv; - } - - am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index] = - ip4_table_index; - am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index] = - ip6_table_index; - - vnet_l2_output_classify_enable_disable (sw_if_index, 1); - return rv; -} - - -int -acl_interface_in_enable_disable (acl_main_t * am, u32 sw_if_index, - int enable_disable) -{ - int rv; - - /* Utterly wrong? */ - if (pool_is_free_index (am->vnet_main->interface_main.sw_interfaces, - sw_if_index)) - return VNET_API_ERROR_INVALID_SW_IF_INDEX; - - if (enable_disable) - { - rv = acl_hook_l2_input_classify (am, sw_if_index); - } - else - { - rv = acl_unhook_l2_input_classify (am, sw_if_index); - } - - return rv; -} - -int -acl_interface_out_enable_disable (acl_main_t * am, u32 sw_if_index, - int enable_disable) -{ - int rv; - - /* Utterly wrong? */ - if (pool_is_free_index (am->vnet_main->interface_main.sw_interfaces, - sw_if_index)) - return VNET_API_ERROR_INVALID_SW_IF_INDEX; - - if (enable_disable) - { - rv = acl_hook_l2_output_classify (am, sw_if_index); - } - else - { - rv = acl_unhook_l2_output_classify (am, sw_if_index); - } - - return rv; -} - - -static int -acl_interface_add_inout_acl (u32 sw_if_index, u8 is_input, u32 acl_list_index) -{ - acl_main_t *am = &acl_main; - if (is_input) - { - vec_validate (am->input_acl_vec_by_sw_if_index, sw_if_index); - vec_add (am->input_acl_vec_by_sw_if_index[sw_if_index], &acl_list_index, - 1); - acl_interface_in_enable_disable (am, sw_if_index, 1); - } - else - { - vec_validate (am->output_acl_vec_by_sw_if_index, sw_if_index); - vec_add (am->output_acl_vec_by_sw_if_index[sw_if_index], - &acl_list_index, 1); - acl_interface_out_enable_disable (am, sw_if_index, 1); - } - return 0; -} - -static int -acl_interface_del_inout_acl (u32 sw_if_index, u8 is_input, u32 acl_list_index) -{ - acl_main_t *am = &acl_main; - int i; - int rv = -1; - if (is_input) - { - vec_validate (am->input_acl_vec_by_sw_if_index, sw_if_index); - for (i = 0; i < vec_len (am->input_acl_vec_by_sw_if_index[sw_if_index]); - i++) - { - if (acl_list_index == - am->input_acl_vec_by_sw_if_index[sw_if_index][i]) - { - vec_del1 (am->input_acl_vec_by_sw_if_index[sw_if_index], i); - rv = 0; - break; - } - } - if (0 == vec_len (am->input_acl_vec_by_sw_if_index[sw_if_index])) - { - acl_interface_in_enable_disable (am, sw_if_index, 0); - } - } - else - { - vec_validate (am->output_acl_vec_by_sw_if_index, sw_if_index); - for (i = 0; - i < vec_len (am->output_acl_vec_by_sw_if_index[sw_if_index]); i++) - { - if (acl_list_index == - am->output_acl_vec_by_sw_if_index[sw_if_index][i]) - { - vec_del1 (am->output_acl_vec_by_sw_if_index[sw_if_index], i); - rv = 0; - break; - } - } - if (0 == vec_len (am->output_acl_vec_by_sw_if_index[sw_if_index])) - { - acl_interface_out_enable_disable (am, sw_if_index, 0); - } - } - return rv; -} - -static void -acl_interface_reset_inout_acls (u32 sw_if_index, u8 is_input) -{ - acl_main_t *am = &acl_main; - if (is_input) - { - acl_interface_in_enable_disable (am, sw_if_index, 0); - vec_validate (am->input_acl_vec_by_sw_if_index, sw_if_index); - vec_reset_length (am->input_acl_vec_by_sw_if_index[sw_if_index]); - } - else - { - acl_interface_out_enable_disable (am, sw_if_index, 0); - vec_validate (am->output_acl_vec_by_sw_if_index, sw_if_index); - vec_reset_length (am->output_acl_vec_by_sw_if_index[sw_if_index]); - } -} - -static int -acl_interface_add_del_inout_acl (u32 sw_if_index, u8 is_add, u8 is_input, - u32 acl_list_index) -{ - int rv = -1; - if (is_add) - { - rv = - acl_interface_add_inout_acl (sw_if_index, is_input, acl_list_index); - } - else - { - rv = - acl_interface_del_inout_acl (sw_if_index, is_input, acl_list_index); - } - return rv; -} - - -static void * -get_ptr_to_offset (vlib_buffer_t * b0, int offset) -{ - u8 *p = vlib_buffer_get_current (b0) + offset; - return p; -} - -static u8 -acl_get_l4_proto (vlib_buffer_t * b0, int node_is_ip6) -{ - u8 proto; - int proto_offset; - if (node_is_ip6) - { - proto_offset = 20; - } - else - { - proto_offset = 23; - } - proto = *((u8 *) vlib_buffer_get_current (b0) + proto_offset); - return proto; -} - -static int -acl_match_addr (ip46_address_t * addr1, ip46_address_t * addr2, int prefixlen, - int is_ip6) -{ - if (prefixlen == 0) - { - /* match any always succeeds */ - return 1; - } - if (is_ip6) - { - if (memcmp (addr1, addr2, prefixlen / 8)) - { - /* If the starting full bytes do not match, no point in bittwidling the thumbs further */ - return 0; - } - if (prefixlen % 8) - { - u8 b1 = *((u8 *) addr1 + 1 + prefixlen / 8); - u8 b2 = *((u8 *) addr2 + 1 + prefixlen / 8); - u8 mask0 = (0xff - ((1 << (8 - (prefixlen % 8))) - 1)); - return (b1 & mask0) == b2; - } - else - { - /* The prefix fits into integer number of bytes, so nothing left to do */ - return 1; - } - } - else - { - uint32_t a1 = ntohl (addr1->ip4.as_u32); - uint32_t a2 = ntohl (addr2->ip4.as_u32); - uint32_t mask0 = 0xffffffff - ((1 << (32 - prefixlen)) - 1); - return (a1 & mask0) == a2; - } -} - -static int -acl_match_port (u16 port, u16 port_first, u16 port_last, int is_ip6) -{ - return ((port >= port_first) && (port <= port_last)); -} - -static int -acl_packet_match (acl_main_t * am, u32 acl_index, vlib_buffer_t * b0, - u8 * r_action, int *r_is_ip6, u32 * r_acl_match_p, - u32 * r_rule_match_p, u32 * trace_bitmap) -{ - ethernet_header_t *h0; - u16 type0; - - ip46_address_t src, dst; - int is_ip6; - int is_ip4; - u8 proto; - u16 src_port; - u16 dst_port; - u8 tcp_flags = 0; - int i; - acl_list_t *a; - acl_rule_t *r; - - h0 = vlib_buffer_get_current (b0); - type0 = clib_net_to_host_u16 (h0->type); - is_ip4 = (type0 == ETHERNET_TYPE_IP4); - is_ip6 = (type0 == ETHERNET_TYPE_IP6); - - if (!(is_ip4 || is_ip6)) - { - return 0; - } - /* The bunch of hardcoded offsets here is intentional to get rid of them - ASAP, when getting to a faster matching code */ - if (is_ip4) - { - clib_memcpy (&src.ip4, get_ptr_to_offset (b0, 26), 4); - clib_memcpy (&dst.ip4, get_ptr_to_offset (b0, 30), 4); - proto = acl_get_l4_proto (b0, 0); - if (1 == proto) - { - *trace_bitmap |= 0x00000001; - /* type */ - src_port = *(u8 *) get_ptr_to_offset (b0, 34); - /* code */ - dst_port = *(u8 *) get_ptr_to_offset (b0, 35); - } - else - { - /* assume TCP/UDP */ - src_port = (*(u16 *) get_ptr_to_offset (b0, 34)); - dst_port = (*(u16 *) get_ptr_to_offset (b0, 36)); - /* UDP gets ability to check on an oddball data byte as a bonus */ - tcp_flags = *(u8 *) get_ptr_to_offset (b0, 14 + 20 + 13); - } - } - else /* is_ipv6 implicitly */ - { - clib_memcpy (&src, get_ptr_to_offset (b0, 22), 16); - clib_memcpy (&dst, get_ptr_to_offset (b0, 38), 16); - proto = acl_get_l4_proto (b0, 1); - if (58 == proto) - { - *trace_bitmap |= 0x00000002; - /* type */ - src_port = *(u8 *) get_ptr_to_offset (b0, 54); - /* code */ - dst_port = *(u8 *) get_ptr_to_offset (b0, 55); - } - else - { - /* assume TCP/UDP */ - src_port = (*(u16 *) get_ptr_to_offset (b0, 54)); - dst_port = (*(u16 *) get_ptr_to_offset (b0, 56)); - tcp_flags = *(u8 *) get_ptr_to_offset (b0, 14 + 40 + 13); - } - } - if (pool_is_free_index (am->acls, acl_index)) - { - if (r_acl_match_p) - *r_acl_match_p = acl_index; - if (r_rule_match_p) - *r_rule_match_p = -1; - /* the ACL does not exist but is used for policy. Block traffic. */ - return 0; - } - a = am->acls + acl_index; - for (i = 0; i < a->count; i++) - { - r = a->rules + i; - if (is_ip6 != r->is_ipv6) - { - continue; - } - if (!acl_match_addr (&dst, &r->dst, r->dst_prefixlen, is_ip6)) - continue; - if (!acl_match_addr (&src, &r->src, r->src_prefixlen, is_ip6)) - continue; - if (r->proto) - { - if (proto != r->proto) - continue; - if (!acl_match_port - (src_port, r->src_port_or_type_first, r->src_port_or_type_last, - is_ip6)) - continue; - if (!acl_match_port - (dst_port, r->dst_port_or_code_first, r->dst_port_or_code_last, - is_ip6)) - continue; - /* No need for check of proto == TCP, since in other rules both fields should be zero, so this match will succeed */ - if ((tcp_flags & r->tcp_flags_mask) != r->tcp_flags_value) - continue; - } - /* everything matches! */ - *r_action = r->is_permit; - *r_is_ip6 = is_ip6; - if (r_acl_match_p) - *r_acl_match_p = acl_index; - if (r_rule_match_p) - *r_rule_match_p = i; - return 1; - } - return 0; -} - -void -input_acl_packet_match (u32 sw_if_index, vlib_buffer_t * b0, u32 * nextp, - u32 * acl_match_p, u32 * rule_match_p, - u32 * trace_bitmap) -{ - acl_main_t *am = &acl_main; - uint8_t action = 0; - int is_ip6 = 0; - int i; - vec_validate (am->input_acl_vec_by_sw_if_index, sw_if_index); - for (i = 0; i < vec_len (am->input_acl_vec_by_sw_if_index[sw_if_index]); - i++) - { - if (acl_packet_match - (am, am->input_acl_vec_by_sw_if_index[sw_if_index][i], b0, &action, - &is_ip6, acl_match_p, rule_match_p, trace_bitmap)) - { - if (is_ip6) - { - *nextp = am->acl_in_ip6_match_next[action]; - } - else - { - *nextp = am->acl_in_ip4_match_next[action]; - } - return; - } - } - if (vec_len (am->input_acl_vec_by_sw_if_index[sw_if_index]) > 0) - { - /* If there are ACLs and none matched, deny by default */ - *nextp = 0; - } - -} - -void -output_acl_packet_match (u32 sw_if_index, vlib_buffer_t * b0, u32 * nextp, - u32 * acl_match_p, u32 * rule_match_p, - u32 * trace_bitmap) -{ - acl_main_t *am = &acl_main; - uint8_t action = 0; - int is_ip6 = 0; - int i; - vec_validate (am->output_acl_vec_by_sw_if_index, sw_if_index); - for (i = 0; i < vec_len (am->output_acl_vec_by_sw_if_index[sw_if_index]); - i++) - { - if (acl_packet_match - (am, am->output_acl_vec_by_sw_if_index[sw_if_index][i], b0, &action, - &is_ip6, acl_match_p, rule_match_p, trace_bitmap)) - { - if (is_ip6) - { - *nextp = am->acl_out_ip6_match_next[action]; - } - else - { - *nextp = am->acl_out_ip4_match_next[action]; - } - return; - } - } - if (vec_len (am->output_acl_vec_by_sw_if_index[sw_if_index]) > 0) - { - /* If there are ACLs and none matched, deny by default */ - *nextp = 0; - } -} - -typedef struct -{ - u8 is_ipv6; - u8 mac_mask[6]; - u8 prefix_len; - u32 count; - u32 table_index; -} macip_match_type_t; - -static u32 -macip_find_match_type (macip_match_type_t * mv, u8 * mac_mask, u8 prefix_len, - u8 is_ipv6) -{ - u32 i; - if (mv) - { - for (i = 0; i < vec_len (mv); i++) - { - if ((mv[i].prefix_len == prefix_len) && (mv[i].is_ipv6 == is_ipv6) - && (0 == memcmp (mv[i].mac_mask, mac_mask, 6))) - { - return i; - } - } - } - return ~0; -} - - -/* Get metric used to sort match types. - The more specific and the more often seen - the bigger the metric */ -static int -match_type_metric (macip_match_type_t * m) -{ - /* FIXME: count the ones in the MAC mask as well, check how well this heuristic works in real life */ - return m->prefix_len + m->is_ipv6 + 10 * m->count; -} - -static int -match_type_compare (macip_match_type_t * m1, macip_match_type_t * m2) -{ - /* Ascending sort based on the metric values */ - return match_type_metric (m1) - match_type_metric (m2); -} - -/* Get the offset of L3 source within ethernet packet */ -static int -get_l3_src_offset(int is6) -{ - if(is6) - return (sizeof(ethernet_header_t) + offsetof(ip6_header_t, src_address)); - else - return (sizeof(ethernet_header_t) + offsetof(ip4_header_t, src_address)); -} - -static int -macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index) -{ - macip_match_type_t *mvec = NULL; - macip_match_type_t *mt; - macip_acl_list_t *a = &am->macip_acls[macip_acl_index]; - int i; - u32 match_type_index; - u32 last_table; - u8 mask[5 * 16]; - vnet_classify_main_t *cm = &vnet_classify_main; - - /* Count the number of different types of rules */ - for (i = 0; i < a->count; i++) - { - if (~0 == - (match_type_index = - macip_find_match_type (mvec, a->rules[i].src_mac_mask, - a->rules[i].src_prefixlen, - a->rules[i].is_ipv6))) - { - match_type_index = vec_len (mvec); - vec_validate (mvec, match_type_index); - memcpy (mvec[match_type_index].mac_mask, - a->rules[match_type_index].src_mac_mask, 6); - mvec[match_type_index].prefix_len = a->rules[i].src_prefixlen; - mvec[match_type_index].is_ipv6 = a->rules[i].is_ipv6; - mvec[match_type_index].table_index = ~0; - } - mvec[match_type_index].count++; - } - /* Put the most frequently used tables last in the list so we can create classifier tables in reverse order */ - vec_sort_with_function (mvec, match_type_compare); - /* Create the classifier tables */ - last_table = ~0; - vec_foreach (mt, mvec) - { - int mask_len; - int is6 = mt->is_ipv6; - int l3_src_offs = get_l3_src_offset(is6); - memset (mask, 0, sizeof (mask)); - memcpy (&mask[6], mt->mac_mask, 6); - for (i = 0; i < (mt->prefix_len / 8); i++) - { - mask[l3_src_offs + i] = 0xff; - } - if (mt->prefix_len % 8) - { - mask[l3_src_offs + (mt->prefix_len / 8)] = - 0xff - ((1 << (8 - mt->prefix_len % 8)) - 1); - } - /* - * Round-up the number of bytes needed to store the prefix, - * and round up the number of vectors too - */ - mask_len = ((l3_src_offs + ((mt->prefix_len+7) / 8) + - (sizeof (u32x4)-1))/sizeof(u32x4)) * sizeof (u32x4); - acl_classify_add_del_table_small (cm, mask, mask_len, last_table, - (~0 == last_table) ? 0 : ~0, &mt->table_index, - 1); - last_table = mt->table_index; - } - a->ip4_table_index = ~0; - a->ip6_table_index = ~0; - a->l2_table_index = last_table; - - /* Populate the classifier tables with rules from the MACIP ACL */ - for (i = 0; i < a->count; i++) - { - u32 action = 0; - u32 metadata = 0; - int is6 = a->rules[i].is_ipv6; - int l3_src_offs = get_l3_src_offset(is6); - memset (mask, 0, sizeof (mask)); - memcpy (&mask[6], a->rules[i].src_mac, 6); - if (is6) - { - memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip6, 16); - } - else - { - memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip4, 4); - } - match_type_index = - macip_find_match_type (mvec, a->rules[i].src_mac_mask, - a->rules[i].src_prefixlen, - a->rules[i].is_ipv6); - /* add session to table mvec[match_type_index].table_index; */ - vnet_classify_add_del_session (cm, mvec[match_type_index].table_index, - mask, a->rules[i].is_permit ? ~0 : 0, i, - 0, action, metadata, 1); - } - return 0; -} - -static void -macip_destroy_classify_tables (acl_main_t * am, u32 macip_acl_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - macip_acl_list_t *a = &am->macip_acls[macip_acl_index]; - - if (a->ip4_table_index != ~0) - { - acl_classify_add_del_table_small (cm, 0, ~0, ~0, ~0, &a->ip4_table_index, 0); - a->ip4_table_index = ~0; - } - if (a->ip6_table_index != ~0) - { - acl_classify_add_del_table_small (cm, 0, ~0, ~0, ~0, &a->ip6_table_index, 0); - a->ip6_table_index = ~0; - } - if (a->l2_table_index != ~0) - { - acl_classify_add_del_table_small (cm, 0, ~0, ~0, ~0, &a->l2_table_index, 0); - a->l2_table_index = ~0; - } -} - -static int -macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[], - u32 * acl_list_index, u8 * tag) -{ - acl_main_t *am = &acl_main; - macip_acl_list_t *a; - macip_acl_rule_t *r; - macip_acl_rule_t *acl_new_rules; - int i; - - /* Create and populate the rules */ - acl_new_rules = clib_mem_alloc_aligned (sizeof (macip_acl_rule_t) * count, - CLIB_CACHE_LINE_BYTES); - if (!acl_new_rules) - { - /* Could not allocate rules. New or existing ACL - bail out regardless */ - return -1; - } - - for (i = 0; i < count; i++) - { - r = &acl_new_rules[i]; - r->is_permit = rules[i].is_permit; - r->is_ipv6 = rules[i].is_ipv6; - memcpy (&r->src_mac, rules[i].src_mac, 6); - memcpy (&r->src_mac_mask, rules[i].src_mac_mask, 6); - if(rules[i].is_ipv6) - memcpy (&r->src_ip_addr.ip6, rules[i].src_ip_addr, 16); - else - memcpy (&r->src_ip_addr.ip4, rules[i].src_ip_addr, 4); - 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; - - a->rules = acl_new_rules; - a->count = count; - memcpy (a->tag, tag, sizeof (a->tag)); - - /* Create and populate the classifer tables */ - macip_create_classify_tables (am, *acl_list_index); - - return 0; -} - - -/* No check for validity of sw_if_index - the callers were supposed to validate */ - -static int -macip_acl_interface_del_acl (acl_main_t * am, u32 sw_if_index) -{ - int rv; - u32 macip_acl_index; - macip_acl_list_t *a; - vec_validate_init_empty (am->macip_acl_by_sw_if_index, sw_if_index, ~0); - macip_acl_index = am->macip_acl_by_sw_if_index[sw_if_index]; - /* No point in deleting MACIP ACL which is not applied */ - if (~0 == macip_acl_index) - return -1; - a = &am->macip_acls[macip_acl_index]; - /* remove the classifier tables off the interface L2 ACL */ - rv = - vnet_set_input_acl_intfc (am->vlib_main, sw_if_index, a->ip4_table_index, - a->ip6_table_index, a->l2_table_index, 0); - /* Unset the MACIP ACL index */ - am->macip_acl_by_sw_if_index[sw_if_index] = ~0; - return rv; -} - -/* No check for validity of sw_if_index - the callers were supposed to validate */ - -static int -macip_acl_interface_add_acl (acl_main_t * am, u32 sw_if_index, - u32 macip_acl_index) -{ - macip_acl_list_t *a; - int rv; - if (pool_is_free_index (am->macip_acls, macip_acl_index)) - { - return -1; - } - a = &am->macip_acls[macip_acl_index]; - vec_validate_init_empty (am->macip_acl_by_sw_if_index, sw_if_index, ~0); - /* If there already a MACIP ACL applied, unapply it */ - if (~0 != am->macip_acl_by_sw_if_index[sw_if_index]) - macip_acl_interface_del_acl(am, sw_if_index); - am->macip_acl_by_sw_if_index[sw_if_index] = macip_acl_index; - /* Apply the classifier tables for L2 ACLs */ - rv = - vnet_set_input_acl_intfc (am->vlib_main, sw_if_index, a->ip4_table_index, - a->ip6_table_index, a->l2_table_index, 1); - return rv; -} - -static int -macip_acl_del_list (u32 acl_list_index) -{ - acl_main_t *am = &acl_main; - macip_acl_list_t *a; - int i; - if (pool_is_free_index (am->macip_acls, acl_list_index)) - { - return -1; - } - - /* delete any references to the ACL */ - for (i = 0; i < vec_len (am->macip_acl_by_sw_if_index); i++) - { - if (am->macip_acl_by_sw_if_index[i] == acl_list_index) - { - macip_acl_interface_del_acl (am, i); - } - } - - /* Now that classifier tables are detached, clean them up */ - macip_destroy_classify_tables (am, acl_list_index); - - /* now we can delete the ACL itself */ - a = &am->macip_acls[acl_list_index]; - if (a->rules) - { - clib_mem_free (a->rules); - } - pool_put (am->macip_acls, a); - return 0; -} - - -static int -macip_acl_interface_add_del_acl (u32 sw_if_index, u8 is_add, - u32 acl_list_index) -{ - acl_main_t *am = &acl_main; - int rv = -1; - if (is_add) - { - rv = macip_acl_interface_add_acl (am, sw_if_index, acl_list_index); - } - else - { - rv = macip_acl_interface_del_acl (am, sw_if_index); - } - return rv; -} - -/* API message handler */ -static void -vl_api_acl_add_replace_t_handler (vl_api_acl_add_replace_t * mp) -{ - vl_api_acl_add_replace_reply_t *rmp; - acl_main_t *am = &acl_main; - int rv; - u32 acl_list_index = ntohl (mp->acl_index); - - rv = acl_add_list (ntohl (mp->count), mp->r, &acl_list_index, mp->tag); - - /* *INDENT-OFF* */ - REPLY_MACRO2(VL_API_ACL_ADD_REPLACE_REPLY, - ({ - rmp->acl_index = htonl(acl_list_index); - })); - /* *INDENT-ON* */ -} - -static void -vl_api_acl_del_t_handler (vl_api_acl_del_t * mp) -{ - acl_main_t *sm = &acl_main; - vl_api_acl_del_reply_t *rmp; - int rv; - - rv = acl_del_list (ntohl (mp->acl_index)); - - REPLY_MACRO (VL_API_ACL_DEL_REPLY); -} - -static void -vl_api_acl_interface_add_del_t_handler (vl_api_acl_interface_add_del_t * mp) -{ - acl_main_t *sm = &acl_main; - vnet_interface_main_t *im = &sm->vnet_main->interface_main; - u32 sw_if_index = ntohl (mp->sw_if_index); - vl_api_acl_interface_add_del_reply_t *rmp; - int rv = -1; - - if (pool_is_free_index(im->sw_interfaces, sw_if_index)) - rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; - else - rv = - acl_interface_add_del_inout_acl (sw_if_index, mp->is_add, - mp->is_input, ntohl (mp->acl_index)); - - REPLY_MACRO (VL_API_ACL_INTERFACE_ADD_DEL_REPLY); -} - -static void -vl_api_acl_interface_set_acl_list_t_handler - (vl_api_acl_interface_set_acl_list_t * mp) -{ - acl_main_t *sm = &acl_main; - vl_api_acl_interface_set_acl_list_reply_t *rmp; - int rv = 0; - int i; - vnet_interface_main_t *im = &sm->vnet_main->interface_main; - u32 sw_if_index = ntohl (mp->sw_if_index); - - if (pool_is_free_index(im->sw_interfaces, sw_if_index)) - rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; - else - { - acl_interface_reset_inout_acls (sw_if_index, 0); - acl_interface_reset_inout_acls (sw_if_index, 1); - - for (i = 0; i < mp->count; i++) - { - acl_interface_add_del_inout_acl (sw_if_index, 1, (i < mp->n_input), - ntohl (mp->acls[i])); - } - } - - REPLY_MACRO (VL_API_ACL_INTERFACE_SET_ACL_LIST_REPLY); -} - -static void -copy_acl_rule_to_api_rule (vl_api_acl_rule_t * api_rule, acl_rule_t * r) -{ - api_rule->is_permit = r->is_permit; - api_rule->is_ipv6 = r->is_ipv6; - if(r->is_ipv6) - { - memcpy (api_rule->src_ip_addr, &r->src, sizeof (r->src)); - memcpy (api_rule->dst_ip_addr, &r->dst, sizeof (r->dst)); - } - else - { - memcpy (api_rule->src_ip_addr, &r->src.ip4, sizeof (r->src.ip4)); - memcpy (api_rule->dst_ip_addr, &r->dst.ip4, sizeof (r->dst.ip4)); - } - api_rule->src_ip_prefix_len = r->src_prefixlen; - api_rule->dst_ip_prefix_len = r->dst_prefixlen; - api_rule->proto = r->proto; - api_rule->srcport_or_icmptype_first = r->src_port_or_type_first; - api_rule->srcport_or_icmptype_last = r->src_port_or_type_last; - api_rule->dstport_or_icmpcode_first = r->dst_port_or_code_first; - api_rule->dstport_or_icmpcode_last = r->dst_port_or_code_last; - api_rule->tcp_flags_mask = r->tcp_flags_mask; - api_rule->tcp_flags_value = r->tcp_flags_value; -} - -static void -send_acl_details (acl_main_t * am, unix_shared_memory_queue_t * q, - acl_list_t * acl, u32 context) -{ - vl_api_acl_details_t *mp; - vl_api_acl_rule_t *rules; - int i; - int msg_size = sizeof (*mp) + sizeof (mp->r[0]) * acl->count; - - mp = vl_msg_api_alloc (msg_size); - memset (mp, 0, msg_size); - mp->_vl_msg_id = ntohs (VL_API_ACL_DETAILS + am->msg_id_base); - - /* fill in the message */ - mp->context = context; - mp->count = htonl (acl->count); - mp->acl_index = htonl (acl - am->acls); - memcpy (mp->tag, acl->tag, sizeof (mp->tag)); - // clib_memcpy (mp->r, acl->rules, acl->count * sizeof(acl->rules[0])); - rules = mp->r; - for (i = 0; i < acl->count; i++) - { - copy_acl_rule_to_api_rule (&rules[i], &acl->rules[i]); - } - - clib_warning("Sending acl details for ACL index %d", ntohl(mp->acl_index)); - vl_msg_api_send_shmem (q, (u8 *) & mp); -} - - -static void -vl_api_acl_dump_t_handler (vl_api_acl_dump_t * mp) -{ - acl_main_t *am = &acl_main; - u32 acl_index; - acl_list_t *acl; - - int rv = -1; - unix_shared_memory_queue_t *q; - - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - { - return; - } - - if (mp->acl_index == ~0) - { - /* *INDENT-OFF* */ - /* Just dump all ACLs */ - pool_foreach (acl, am->acls, - ({ - send_acl_details(am, q, acl, mp->context); - })); - /* *INDENT-ON* */ - } - else - { - acl_index = ntohl (mp->acl_index); - if (!pool_is_free_index (am->acls, acl_index)) - { - acl = &am->acls[acl_index]; - send_acl_details (am, q, acl, mp->context); - } - } - - if (rv == -1) - { - /* FIXME API: should we signal an error here at all ? */ - return; - } -} - -static void -send_acl_interface_list_details (acl_main_t * am, - unix_shared_memory_queue_t * q, - u32 sw_if_index, u32 context) -{ - vl_api_acl_interface_list_details_t *mp; - int msg_size; - int n_input; - int n_output; - int count; - int i = 0; - - vec_validate (am->input_acl_vec_by_sw_if_index, sw_if_index); - vec_validate (am->output_acl_vec_by_sw_if_index, sw_if_index); - - n_input = vec_len (am->input_acl_vec_by_sw_if_index[sw_if_index]); - n_output = vec_len (am->output_acl_vec_by_sw_if_index[sw_if_index]); - count = n_input + n_output; - - msg_size = sizeof (*mp); - msg_size += sizeof (mp->acls[0]) * count; - - mp = vl_msg_api_alloc (msg_size); - memset (mp, 0, msg_size); - mp->_vl_msg_id = - ntohs (VL_API_ACL_INTERFACE_LIST_DETAILS + am->msg_id_base); - - /* fill in the message */ - mp->context = context; - mp->sw_if_index = htonl (sw_if_index); - mp->count = count; - mp->n_input = n_input; - for (i = 0; i < n_input; i++) - { - mp->acls[i] = htonl (am->input_acl_vec_by_sw_if_index[sw_if_index][i]); - } - for (i = 0; i < n_output; i++) - { - mp->acls[n_input + i] = - htonl (am->output_acl_vec_by_sw_if_index[sw_if_index][i]); - } - - vl_msg_api_send_shmem (q, (u8 *) & mp); -} - -static void -vl_api_acl_interface_list_dump_t_handler (vl_api_acl_interface_list_dump_t * - mp) -{ - acl_main_t *am = &acl_main; - vnet_sw_interface_t *swif; - vnet_interface_main_t *im = &am->vnet_main->interface_main; - - u32 sw_if_index; - unix_shared_memory_queue_t *q; - - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - { - return; - } - - if (mp->sw_if_index == ~0) - { - /* *INDENT-OFF* */ - pool_foreach (swif, im->sw_interfaces, - ({ - send_acl_interface_list_details(am, q, swif->sw_if_index, mp->context); - })); - /* *INDENT-ON* */ - } - else - { - sw_if_index = ntohl (mp->sw_if_index); - if (!pool_is_free_index(im->sw_interfaces, sw_if_index)) - send_acl_interface_list_details (am, q, sw_if_index, mp->context); - } -} - -/* MACIP ACL API handlers */ - -static void -vl_api_macip_acl_add_t_handler (vl_api_macip_acl_add_t * mp) -{ - vl_api_macip_acl_add_reply_t *rmp; - acl_main_t *am = &acl_main; - int rv; - u32 acl_list_index = ~0; - - rv = - macip_acl_add_list (ntohl (mp->count), mp->r, &acl_list_index, mp->tag); - - /* *INDENT-OFF* */ - REPLY_MACRO2(VL_API_MACIP_ACL_ADD_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 *sm = &acl_main; - vl_api_macip_acl_del_reply_t *rmp; - int rv; - - rv = macip_acl_del_list (ntohl (mp->acl_index)); - - REPLY_MACRO (VL_API_MACIP_ACL_DEL_REPLY); -} - -static void -vl_api_macip_acl_interface_add_del_t_handler - (vl_api_macip_acl_interface_add_del_t * mp) -{ - acl_main_t *sm = &acl_main; - vl_api_macip_acl_interface_add_del_reply_t *rmp; - int rv = -1; - vnet_interface_main_t *im = &sm->vnet_main->interface_main; - u32 sw_if_index = ntohl (mp->sw_if_index); - - if (pool_is_free_index(im->sw_interfaces, sw_if_index)) - rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; - else - rv = - macip_acl_interface_add_del_acl (ntohl (mp->sw_if_index), mp->is_add, - ntohl (mp->acl_index)); - - REPLY_MACRO (VL_API_MACIP_ACL_INTERFACE_ADD_DEL_REPLY); -} - -static void -send_macip_acl_details (acl_main_t * am, unix_shared_memory_queue_t * q, - macip_acl_list_t * acl, u32 context) -{ - vl_api_macip_acl_details_t *mp; - vl_api_macip_acl_rule_t *rules; - macip_acl_rule_t *r; - int i; - int msg_size = sizeof (*mp) + (acl ? sizeof (mp->r[0]) * acl->count : 0); - - mp = vl_msg_api_alloc (msg_size); - memset (mp, 0, msg_size); - mp->_vl_msg_id = ntohs (VL_API_MACIP_ACL_DETAILS + am->msg_id_base); - - /* fill in the message */ - mp->context = context; - if (acl) - { - memcpy (mp->tag, acl->tag, sizeof (mp->tag)); - mp->count = htonl (acl->count); - mp->acl_index = htonl (acl - am->macip_acls); - rules = mp->r; - for (i = 0; i < acl->count; i++) - { - r = &acl->rules[i]; - rules[i].is_permit = r->is_permit; - rules[i].is_ipv6 = r->is_ipv6; - memcpy (rules[i].src_mac, &r->src_mac, sizeof (r->src_mac)); - memcpy (rules[i].src_mac_mask, &r->src_mac_mask, - sizeof (r->src_mac_mask)); - if (r->is_ipv6) - memcpy (rules[i].src_ip_addr, &r->src_ip_addr.ip6, - sizeof (r->src_ip_addr.ip6)); - else - memcpy (rules[i].src_ip_addr, &r->src_ip_addr.ip4, - sizeof (r->src_ip_addr.ip4)); - rules[i].src_ip_prefix_len = r->src_prefixlen; - } - } - else - { - /* No martini, no party - no ACL applied to this interface. */ - mp->acl_index = ~0; - mp->count = 0; - } - - vl_msg_api_send_shmem (q, (u8 *) & mp); -} - - -static void -vl_api_macip_acl_dump_t_handler (vl_api_macip_acl_dump_t * mp) -{ - acl_main_t *am = &acl_main; - macip_acl_list_t *acl; - - unix_shared_memory_queue_t *q; - - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - { - return; - } - - if (mp->acl_index == ~0) - { - /* Just dump all ACLs for now, with sw_if_index = ~0 */ - pool_foreach (acl, am->macip_acls, ( - { - send_macip_acl_details (am, q, acl, - mp-> - context);} - )); - /* *INDENT-ON* */ - } - else - { - u32 acl_index = ntohl (mp->acl_index); - if (!pool_is_free_index (am->macip_acls, acl_index)) - { - acl = &am->macip_acls[acl_index]; - send_macip_acl_details (am, q, acl, mp->context); - } - } -} - -static void -vl_api_macip_acl_interface_get_t_handler (vl_api_macip_acl_interface_get_t * - mp) -{ - acl_main_t *am = &acl_main; - vl_api_macip_acl_interface_get_reply_t *rmp; - u32 count = vec_len (am->macip_acl_by_sw_if_index); - int msg_size = sizeof (*rmp) + sizeof (rmp->acls[0]) * count; - unix_shared_memory_queue_t *q; - int i; - - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - { - return; - } - - rmp = vl_msg_api_alloc (msg_size); - memset (rmp, 0, msg_size); - rmp->_vl_msg_id = - ntohs (VL_API_MACIP_ACL_INTERFACE_GET_REPLY + am->msg_id_base); - rmp->context = mp->context; - rmp->count = htonl (count); - for (i = 0; i < count; i++) - { - rmp->acls[i] = htonl (am->macip_acl_by_sw_if_index[i]); - } - - vl_msg_api_send_shmem (q, (u8 *) & rmp); -} - - - -/* Set up the API message handling tables */ -static clib_error_t * -acl_plugin_api_hookup (vlib_main_t * vm) -{ - acl_main_t *sm = &acl_main; -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \ - #n, \ - vl_api_##n##_t_handler, \ - vl_noop_handler, \ - vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 1); - foreach_acl_plugin_api_msg; -#undef _ - - return 0; -} - -#define vl_msg_name_crc_list -#include <acl/acl_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (acl_main_t * sm, api_main_t * am) -{ -#define _(id,n,crc) \ - vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base); - foreach_vl_msg_name_crc_acl; -#undef _ -} - -u32 -register_match_action_nexts (u32 next_in_ip4, u32 next_in_ip6, - u32 next_out_ip4, u32 next_out_ip6) -{ - acl_main_t *am = &acl_main; - u32 act = am->n_match_actions; - if (am->n_match_actions == 255) - { - return ~0; - } - am->n_match_actions++; - am->acl_in_ip4_match_next[act] = next_in_ip4; - am->acl_in_ip6_match_next[act] = next_in_ip6; - am->acl_out_ip4_match_next[act] = next_out_ip4; - am->acl_out_ip6_match_next[act] = next_out_ip6; - return act; -} - -void -acl_setup_nodes (void) -{ - vlib_main_t *vm = vlib_get_main (); - acl_main_t *am = &acl_main; - vlib_node_t *n; - - n = vlib_get_node_by_name (vm, (u8 *) "l2-input-classify"); - am->l2_input_classify_next_acl = - vlib_node_add_next_with_slot (vm, n->index, acl_in_node.index, ~0); - n = vlib_get_node_by_name (vm, (u8 *) "l2-output-classify"); - am->l2_output_classify_next_acl = - vlib_node_add_next_with_slot (vm, n->index, acl_out_node.index, ~0); - - feat_bitmap_init_next_nodes (vm, acl_in_node.index, L2INPUT_N_FEAT, - l2input_get_feat_names (), - am->acl_in_node_input_next_node_index); - - memset (&am->acl_in_ip4_match_next[0], 0, - sizeof (am->acl_in_ip4_match_next)); - memset (&am->acl_in_ip6_match_next[0], 0, - sizeof (am->acl_in_ip6_match_next)); - memset (&am->acl_out_ip4_match_next[0], 0, - sizeof (am->acl_out_ip4_match_next)); - memset (&am->acl_out_ip6_match_next[0], 0, - sizeof (am->acl_out_ip6_match_next)); - am->n_match_actions = 0; - - register_match_action_nexts (0, 0, 0, 0); /* drop */ - register_match_action_nexts (~0, ~0, ~0, ~0); /* permit */ - register_match_action_nexts (ACL_IN_L2S_INPUT_IP4_ADD, ACL_IN_L2S_INPUT_IP6_ADD, ACL_OUT_L2S_OUTPUT_IP4_ADD, ACL_OUT_L2S_OUTPUT_IP6_ADD); /* permit + create session */ -} - - - -static clib_error_t * -acl_init (vlib_main_t * vm) -{ - acl_main_t *am = &acl_main; - clib_error_t *error = 0; - memset (am, 0, sizeof (*am)); - am->vlib_main = vm; - am->vnet_main = vnet_get_main (); - - u8 *name = format (0, "acl_%08x%c", api_version, 0); - - /* Ask for a correctly-sized block of API message decode slots */ - am->msg_id_base = vl_msg_api_get_msg_ids ((char *) name, - VL_MSG_FIRST_AVAILABLE); - - error = acl_plugin_api_hookup (vm); - acl_setup_nodes (); - - /* Add our API messages to the global name_crc hash table */ - setup_message_id_table (am, &api_main); - - vec_free (name); - - return error; -} - -VLIB_INIT_FUNCTION (acl_init); diff --git a/plugins/acl-plugin/acl/acl.h b/plugins/acl-plugin/acl/acl.h deleted file mode 100644 index afc9b289cee..00000000000 --- a/plugins/acl-plugin/acl/acl.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef included_acl_h -#define included_acl_h - -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/ethernet/ethernet.h> -#include <vnet/l2/l2_output.h> - - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vppinfra/elog.h> - -#define ACL_PLUGIN_VERSION_MAJOR 1 -#define ACL_PLUGIN_VERSION_MINOR 1 - -extern vlib_node_registration_t acl_in_node; -extern vlib_node_registration_t acl_out_node; - -void input_acl_packet_match(u32 sw_if_index, vlib_buffer_t * b0, u32 *nextp, u32 *acl_match_p, u32 *rule_match_p, u32 *trace_bitmap); -void output_acl_packet_match(u32 sw_if_index, vlib_buffer_t * b0, u32 *nextp, u32 *acl_match_p, u32 *rule_match_p, u32 *trace_bitmap); - -enum address_e { IP4, IP6 }; -typedef struct -{ - enum address_e type; - union { - ip6_address_t ip6; - ip4_address_t ip4; - } addr; -} address_t; - -/* - * ACL rules - */ -typedef struct -{ - u8 is_permit; - u8 is_ipv6; - ip46_address_t src; - u8 src_prefixlen; - ip46_address_t dst; - u8 dst_prefixlen; - u8 proto; - u16 src_port_or_type_first; - u16 src_port_or_type_last; - u16 dst_port_or_code_first; - u16 dst_port_or_code_last; - u8 tcp_flags_value; - u8 tcp_flags_mask; -} acl_rule_t; - -typedef struct -{ - u8 is_permit; - u8 is_ipv6; - u8 src_mac[6]; - u8 src_mac_mask[6]; - ip46_address_t src_ip_addr; - u8 src_prefixlen; -} macip_acl_rule_t; - -/* - * ACL - */ -typedef struct -{ - u8 tag[64]; - u32 count; - acl_rule_t *rules; -} acl_list_t; - -typedef struct -{ - u8 tag[64]; - u32 count; - macip_acl_rule_t *rules; - /* References to the classifier tables that will enforce the rules */ - u32 ip4_table_index; - u32 ip6_table_index; - u32 l2_table_index; -} macip_acl_list_t; - -typedef struct { - /* API message ID base */ - u16 msg_id_base; - - acl_list_t *acls; /* Pool of ACLs */ - macip_acl_list_t *macip_acls; /* Pool of MAC-IP ACLs */ - - /* ACLs associated with interfaces */ - u32 **input_acl_vec_by_sw_if_index; - u32 **output_acl_vec_by_sw_if_index; - - /* - * Classify tables used to grab the packets for the ACL check, - * and serving as the 5-tuple session tables at the same time - */ - u32 *acl_ip4_input_classify_table_by_sw_if_index; - u32 *acl_ip6_input_classify_table_by_sw_if_index; - u32 *acl_ip4_output_classify_table_by_sw_if_index; - u32 *acl_ip6_output_classify_table_by_sw_if_index; - - /* MACIP (input) ACLs associated with the interfaces */ - u32 *macip_acl_by_sw_if_index; - - /* next indices for our nodes in the l2-classify tables */ - u32 l2_input_classify_next_acl; - u32 l2_output_classify_next_acl; - - /* next node indices for feature bitmap */ - u32 acl_in_node_input_next_node_index[32]; - /* the respective thing for the output feature */ - l2_output_next_nodes_st acl_out_output_next_nodes; - - /* ACL match actions (must be coherent across in/out ACLs to next indices (can differ) */ - - u32 acl_in_ip4_match_next[256]; - u32 acl_in_ip6_match_next[256]; - u32 acl_out_ip4_match_next[256]; - u32 acl_out_ip6_match_next[256]; - u32 n_match_actions; - - - /* convenience */ - vlib_main_t * vlib_main; - vnet_main_t * vnet_main; - ethernet_main_t * ethernet_main; -} acl_main_t; - -extern acl_main_t acl_main; - - -#endif diff --git a/plugins/acl-plugin/acl/acl_all_api_h.h b/plugins/acl-plugin/acl/acl_all_api_h.h deleted file mode 100644 index 96eca56d31c..00000000000 --- a/plugins/acl-plugin/acl/acl_all_api_h.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* Include the generated file, see BUILT_SOURCES in Makefile.am */ -#include <acl/acl.api.h> - -#ifdef vl_printfun - -#ifdef LP64 -#define _uword_fmt "%lld" -#define _uword_cast (long long) -#else -#define _uword_fmt "%ld" -#define _uword_cast long -#endif - -static inline void * -vl_api_acl_rule_t_print (vl_api_acl_rule_t * a, void *handle) -{ - vl_print (handle, "vl_api_acl_rule_t:\n"); - vl_print (handle, "is_permit: %u\n", (unsigned) a->is_permit); - vl_print (handle, "is_ipv6: %u\n", (unsigned) a->is_ipv6); - { - int _i; - for (_i = 0; _i < 16; _i++) - { - vl_print (handle, "src_ip_addr[%d]: %u\n", _i, a->src_ip_addr[_i]); - } - } - vl_print (handle, "src_ip_prefix_len: %u\n", - (unsigned) a->src_ip_prefix_len); - { - int _i; - for (_i = 0; _i < 16; _i++) - { - vl_print (handle, "dst_ip_addr[%d]: %u\n", _i, a->dst_ip_addr[_i]); - } - } - vl_print (handle, "dst_ip_prefix_len: %u\n", - (unsigned) a->dst_ip_prefix_len); - vl_print (handle, "proto: %u\n", (unsigned) a->proto); - vl_print (handle, "srcport_or_icmptype_first: %u\n", - (unsigned) a->srcport_or_icmptype_first); - vl_print (handle, "srcport_or_icmptype_last: %u\n", - (unsigned) a->srcport_or_icmptype_last); - vl_print (handle, "dstport_or_icmpcode_first: %u\n", - (unsigned) a->dstport_or_icmpcode_first); - vl_print (handle, "dstport_or_icmpcode_last: %u\n", - (unsigned) a->dstport_or_icmpcode_last); - vl_print (handle, "tcp_flags_mask: %u\n", (unsigned) a->tcp_flags_mask); - vl_print (handle, "tcp_flags_value: %u\n", (unsigned) a->tcp_flags_value); - return handle; -} - -static inline void * -vl_api_acl_add_replace_t_print (vl_api_acl_add_replace_t * a, void *handle) -{ - int i; - vl_print (handle, "vl_api_acl_add_replace_t:\n"); - vl_print (handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id); - vl_print (handle, "client_index: %u\n", (unsigned) a->client_index); - vl_print (handle, "context: %u\n", (unsigned) a->context); - vl_print (handle, "acl_index: %u\n", (unsigned) a->acl_index); - vl_print (handle, "count: %u\n", (unsigned) a->count); - vl_print (handle, "r ----- \n"); - for (i = 0; i < a->count; i++) - { - vl_print (handle, " r[%d]:\n", i); - vl_api_acl_rule_t_print (&a->r[i], handle); - } - vl_print (handle, "r ----- END \n"); - return handle; -} - - -static inline void *vl_api_acl_details_t_print (vl_api_acl_details_t *a,void *handle) -{ - vl_print(handle, "vl_api_acl_details_t:\n"); - vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id); - vl_print(handle, "context: %u\n", (unsigned) a->context); - vl_print(handle, "acl_index: %u\n", (unsigned) a->acl_index); - { - int _i; - for (_i = 0; _i < 64; _i++) { - vl_print(handle, "tag[%d]: %u\n", _i, a->tag[_i]); - } - } - vl_print(handle, "count: %u\n", (unsigned) a->count); - vl_print(handle, "r ----- \n"); - // FIXME vl_api_acl_rule_t_print(&a->r, handle); - vl_print(handle, "r ----- END \n"); - return handle; -} - -static inline void * -vl_api_macip_acl_rule_t_print (vl_api_macip_acl_rule_t * a, void *handle) -{ - vl_print (handle, "vl_api_macip_acl_rule_t:\n"); - vl_print (handle, "is_permit: %u\n", (unsigned) a->is_permit); - vl_print (handle, "is_ipv6: %u\n", (unsigned) a->is_ipv6); - { - int _i; - for (_i = 0; _i < 6; _i++) - { - vl_print (handle, "src_mac[%d]: %u\n", _i, a->src_mac[_i]); - } - } - { - int _i; - for (_i = 0; _i < 6; _i++) - { - vl_print (handle, "src_mac_mask[%d]: %u\n", _i, a->src_mac_mask[_i]); - } - } - { - int _i; - for (_i = 0; _i < 16; _i++) - { - vl_print (handle, "src_ip_addr[%d]: %u\n", _i, a->src_ip_addr[_i]); - } - } - vl_print (handle, "src_ip_prefix_len: %u\n", - (unsigned) a->src_ip_prefix_len); - return handle; -} - -static inline void * -vl_api_macip_acl_add_t_print (vl_api_macip_acl_add_t * a, void *handle) -{ - int i; - vl_print (handle, "vl_api_macip_acl_add_t:\n"); - vl_print (handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id); - vl_print (handle, "client_index: %u\n", (unsigned) a->client_index); - vl_print (handle, "context: %u\n", (unsigned) a->context); - vl_print (handle, "count: %u\n", (unsigned) a->count); - vl_print (handle, "r ----- \n"); - for (i = 0; i < a->count; i++) - { - vl_print (handle, " r[%d]:\n", i); - vl_api_macip_acl_rule_t_print (&a->r[i], handle); - } - vl_print (handle, "r ----- END \n"); - return handle; -} - -static inline void *vl_api_macip_acl_details_t_print (vl_api_macip_acl_details_t *a,void *handle) -{ - int i; - vl_print(handle, "vl_api_macip_acl_details_t:\n"); - vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id); - vl_print(handle, "context: %u\n", (unsigned) a->context); - vl_print(handle, "acl_index: %u\n", (unsigned) a->acl_index); - { - int _i; - for (_i = 0; _i < 64; _i++) { - vl_print(handle, "tag[%d]: %u\n", _i, a->tag[_i]); - } - } - vl_print(handle, "count: %u\n", (unsigned) a->count); - vl_print(handle, "r ----- \n"); - for (i = 0; i < a->count; i++) - { - vl_print (handle, " r[%d]:\n", i); - vl_api_macip_acl_rule_t_print (&a->r[i], handle); - } - vl_print(handle, "r ----- END \n"); - return handle; -} - -#endif /* vl_printfun */ - - -#ifdef vl_endianfun - -#undef clib_net_to_host_uword -#ifdef LP64 -#define clib_net_to_host_uword clib_net_to_host_u64 -#else -#define clib_net_to_host_uword clib_net_to_host_u32 -#endif - -/* - * Manual endian/print functions created by copypasting the automatically - * generated ones with small required adjustments. Appears the codegen - * can't make code to print the contents of custom-type array. - */ - -static inline void -vl_api_acl_rule_t_endian (vl_api_acl_rule_t * a) -{ - /* a->is_permit = a->is_permit (no-op) */ - /* a->is_ipv6 = a->is_ipv6 (no-op) */ - /* a->src_ip_addr[0..15] = a->src_ip_addr[0..15] (no-op) */ - /* a->src_ip_prefix_len = a->src_ip_prefix_len (no-op) */ - /* a->dst_ip_addr[0..15] = a->dst_ip_addr[0..15] (no-op) */ - /* a->dst_ip_prefix_len = a->dst_ip_prefix_len (no-op) */ - /* a->proto = a->proto (no-op) */ - a->srcport_or_icmptype_first = - clib_net_to_host_u16 (a->srcport_or_icmptype_first); - a->srcport_or_icmptype_last = - clib_net_to_host_u16 (a->srcport_or_icmptype_last); - a->dstport_or_icmpcode_first = - clib_net_to_host_u16 (a->dstport_or_icmpcode_first); - a->dstport_or_icmpcode_last = - clib_net_to_host_u16 (a->dstport_or_icmpcode_last); - /* a->tcp_flags_mask = a->tcp_flags_mask (no-op) */ - /* a->tcp_flags_value = a->tcp_flags_value (no-op) */ -} - -static inline void -vl_api_acl_add_replace_t_endian (vl_api_acl_add_replace_t * a) -{ - int i; - 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->count = clib_net_to_host_u32 (a->count); - for (i = 0; i < a->count; i++) - { - vl_api_acl_rule_t_endian (&a->r[i]); - } -} - -static inline void vl_api_acl_details_t_endian (vl_api_acl_details_t *a) -{ - int i; - a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id); - 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); - for (i = 0; i < a->count; i++) - { - vl_api_acl_rule_t_endian (&a->r[i]); - } -} - -static inline void vl_api_acl_interface_list_details_t_endian (vl_api_acl_interface_list_details_t *a) -{ - int i; - a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id); - a->context = clib_net_to_host_u32(a->context); - a->sw_if_index = clib_net_to_host_u32(a->sw_if_index); - /* a->count = a->count (no-op) */ - /* a->n_input = a->n_input (no-op) */ - for(i=0; i<a->count; i++) { - a->acls[i] = clib_net_to_host_u32(a->acls[i]); - } -} - -static inline void vl_api_acl_interface_set_acl_list_t_endian (vl_api_acl_interface_set_acl_list_t *a) -{ - int i; - 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->sw_if_index = clib_net_to_host_u32(a->sw_if_index); - /* a->count = a->count (no-op) */ - /* a->n_input = a->n_input (no-op) */ - for(i=0; i<a->count; i++) { - a->acls[i] = clib_net_to_host_u32(a->acls[i]); - } -} - -static inline void -vl_api_macip_acl_rule_t_endian (vl_api_macip_acl_rule_t * a) -{ - /* a->is_permit = a->is_permit (no-op) */ - /* a->is_ipv6 = a->is_ipv6 (no-op) */ - /* a->src_mac[0..5] = a->src_mac[0..5] (no-op) */ - /* a->src_mac_mask[0..5] = a->src_mac_mask[0..5] (no-op) */ - /* a->src_ip_addr[0..15] = a->src_ip_addr[0..15] (no-op) */ - /* a->src_ip_prefix_len = a->src_ip_prefix_len (no-op) */ -} - -static inline void -vl_api_macip_acl_add_t_endian (vl_api_macip_acl_add_t * a) -{ - int i; - 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->count = clib_net_to_host_u32 (a->count); - for (i = 0; i < a->count; i++) - { - vl_api_macip_acl_rule_t_endian (&a->r[i]); - } -} - -static inline void vl_api_macip_acl_details_t_endian (vl_api_macip_acl_details_t *a) -{ - int i; - a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id); - 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); - for (i = 0; i < a->count; i++) - { - vl_api_macip_acl_rule_t_endian (&a->r[i]); - } -} - - - - -#endif /* vl_printfun */ - - diff --git a/plugins/acl-plugin/acl/acl_msg_enum.h b/plugins/acl-plugin/acl/acl_msg_enum.h deleted file mode 100644 index 14d8b48c207..00000000000 --- a/plugins/acl-plugin/acl/acl_msg_enum.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef included_acl_msg_enum_h -#define included_acl_msg_enum_h - -#include <vppinfra/byte_order.h> - -#define vl_msg_id(n,h) n, -typedef enum { -#include <acl/acl_all_api_h.h> - /* We'll want to know how many messages IDs we need... */ - VL_MSG_FIRST_AVAILABLE, -} vl_msg_id_t; -#undef vl_msg_id - -#endif diff --git a/plugins/acl-plugin/acl/acl_test.c b/plugins/acl-plugin/acl/acl_test.c deleted file mode 100644 index a0e413e16da..00000000000 --- a/plugins/acl-plugin/acl/acl_test.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - *------------------------------------------------------------------ - * acl_test.c - test harness plugin - *------------------------------------------------------------------ - */ - -#include <vat/vat.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vlibsocket/api.h> -#include <vppinfra/error.h> -#include <vnet/ip/ip.h> -#include <arpa/inet.h> - -uword unformat_sw_if_index (unformat_input_t * input, va_list * args); - -/* Declare message IDs */ -#include <acl/acl_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <acl/acl_all_api_h.h> -#undef vl_typedefs - -/* define message structures */ -#define vl_endianfun -#include <acl/acl_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) -#define vl_printfun -#include <acl/acl_all_api_h.h> -#undef vl_printfun - -/* Get the API version number. */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <acl/acl_all_api_h.h> -#undef vl_api_version - -typedef struct { - /* API message ID base */ - u16 msg_id_base; - vat_main_t *vat_main; -} acl_test_main_t; - -acl_test_main_t acl_test_main; - -#define foreach_standard_reply_retval_handler \ -_(acl_del_reply) \ -_(acl_interface_add_del_reply) \ -_(macip_acl_interface_add_del_reply) \ -_(acl_interface_set_acl_list_reply) \ -_(macip_acl_del_reply) - -#define foreach_reply_retval_aclindex_handler \ -_(acl_add_replace_reply) \ -_(macip_acl_add_reply) - -#define _(n) \ - static void vl_api_##n##_t_handler \ - (vl_api_##n##_t * mp) \ - { \ - vat_main_t * vam = acl_test_main.vat_main; \ - i32 retval = ntohl(mp->retval); \ - if (vam->async_mode) { \ - vam->async_errors += (retval < 0); \ - } else { \ - vam->retval = retval; \ - vam->result_ready = 1; \ - } \ - } -foreach_standard_reply_retval_handler; -#undef _ - -#define _(n) \ - static void vl_api_##n##_t_handler \ - (vl_api_##n##_t * mp) \ - { \ - vat_main_t * vam = acl_test_main.vat_main; \ - i32 retval = ntohl(mp->retval); \ - if (vam->async_mode) { \ - vam->async_errors += (retval < 0); \ - } else { \ - clib_warning("ACL index: %d", ntohl(mp->acl_index)); \ - vam->retval = retval; \ - vam->result_ready = 1; \ - } \ - } -foreach_reply_retval_aclindex_handler; -#undef _ - -/* These two ought to be in a library somewhere but they aren't */ -static uword -my_unformat_mac_address (unformat_input_t * input, va_list * args) -{ - u8 *a = va_arg (*args, u8 *); - return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5]); -} - -static u8 * -my_format_mac_address (u8 * s, va_list * args) -{ - u8 *a = va_arg (*args, u8 *); - return format (s, "%02x:%02x:%02x:%02x:%02x:%02x", - a[0], a[1], a[2], a[3], a[4], a[5]); -} - - - -static void vl_api_acl_plugin_get_version_reply_t_handler - (vl_api_acl_plugin_get_version_reply_t * mp) - { - vat_main_t * vam = acl_test_main.vat_main; - clib_warning("ACL plugin version: %d.%d", ntohl(mp->major), ntohl(mp->minor)); - vam->result_ready = 1; - } - -static void vl_api_acl_interface_list_details_t_handler - (vl_api_acl_interface_list_details_t * mp) - { - int i; - vat_main_t * vam = acl_test_main.vat_main; - u8 *out = 0; - vl_api_acl_interface_list_details_t_endian(mp); - out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input); - out = format(out, " input "); - for(i=0; i<mp->count; i++) { - out = format(out, "%d ", mp->acls[i]); - if (i == mp->n_input-1) - out = format(out, "\n output "); - } - out = format(out, "\n"); - clib_warning("%s", out); - vec_free(out); - vam->result_ready = 1; - } - - -static inline u8 * -vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a) -{ - int af = a->is_ipv6 ? AF_INET6 : AF_INET; - u8 src[INET6_ADDRSTRLEN]; - u8 dst[INET6_ADDRSTRLEN]; - inet_ntop(af, a->src_ip_addr, (void *)src, sizeof(src)); - inet_ntop(af, a->dst_ip_addr, (void *)dst, sizeof(dst)); - - out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d %d", - a->is_ipv6 ? "ipv6" : "ipv4", a->is_permit, - src, a->src_ip_prefix_len, - dst, a->dst_ip_prefix_len, - a->proto, - a->srcport_or_icmptype_first, a->srcport_or_icmptype_last, - a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last, - a->tcp_flags_mask, a->tcp_flags_value); - return(out); -} - - - -static void vl_api_acl_details_t_handler - (vl_api_acl_details_t * mp) - { - int i; - vat_main_t * vam = acl_test_main.vat_main; - vl_api_acl_details_t_endian(mp); - u8 *out = 0; - out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag); - for(i=0; i<mp->count; i++) { - out = format(out, " "); - out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]); - out = format(out, "%s\n", i<mp->count-1 ? "," : ""); - } - clib_warning("%s", out); - vec_free(out); - vam->result_ready = 1; - } - -static inline u8 * -vl_api_macip_acl_rule_t_pretty_format (u8 *out, vl_api_macip_acl_rule_t * a) -{ - int af = a->is_ipv6 ? AF_INET6 : AF_INET; - u8 src[INET6_ADDRSTRLEN]; - inet_ntop(af, a->src_ip_addr, (void *)src, sizeof(src)); - - out = format(out, "%s action %d ip %s/%d mac %U mask %U", - a->is_ipv6 ? "ipv6" : "ipv4", a->is_permit, - src, a->src_ip_prefix_len, - my_format_mac_address, a->src_mac, - my_format_mac_address, a->src_mac_mask); - return(out); -} - - -static void vl_api_macip_acl_details_t_handler - (vl_api_macip_acl_details_t * mp) - { - int i; - vat_main_t * vam = acl_test_main.vat_main; - vl_api_macip_acl_details_t_endian(mp); - u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag); - for(i=0; i<mp->count; i++) { - out = format(out, " "); - out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]); - out = format(out, "%s\n", i<mp->count-1 ? "," : ""); - } - clib_warning("%s", out); - vec_free(out); - vam->result_ready = 1; - } - -static void vl_api_macip_acl_interface_get_reply_t_handler - (vl_api_macip_acl_interface_get_reply_t * mp) - { - int i; - vat_main_t * vam = acl_test_main.vat_main; - u8 *out = format(0, "sw_if_index with MACIP ACL count: %d\n", ntohl(mp->count)); - for(i=0; i<ntohl(mp->count); i++) { - out = format(out, " macip_acl_interface_add_del sw_if_index %d add acl %d\n", i, ntohl(mp->acls[i])); - } - out = format(out, "\n"); - clib_warning("%s", out); - vec_free(out); - vam->result_ready = 1; - } - - -/* - * Table of message reply handlers, must include boilerplate handlers - * we just generated - */ -#define foreach_vpe_api_reply_msg \ -_(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_LIST_DETAILS, acl_interface_list_details) \ -_(ACL_DETAILS, acl_details) \ -_(MACIP_ACL_ADD_REPLY, macip_acl_add_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) \ -_(MACIP_ACL_INTERFACE_GET_REPLY, macip_acl_interface_get_reply) \ -_(ACL_PLUGIN_GET_VERSION_REPLY, acl_plugin_get_version_reply) - -/* M: construct, but don't yet send a message */ - -#define M(T,t) \ -do { \ - vam->result_ready = 0; \ - mp = vl_msg_api_alloc(sizeof(*mp)); \ - memset (mp, 0, sizeof (*mp)); \ - mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base); \ - mp->client_index = vam->my_client_index; \ -} while(0); - -#define M2(T,t,n) \ -do { \ - vam->result_ready = 0; \ - mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \ - memset (mp, 0, sizeof (*mp)); \ - mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base); \ - mp->client_index = vam->my_client_index; \ -} while(0); - -/* S: send a message */ -#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp)) - -/* W: wait for results, with timeout */ -#define W \ -do { \ - timeout = vat_time_now (vam) + 1.0; \ - \ - while (vat_time_now (vam) < timeout) { \ - if (vam->result_ready == 1) { \ - return (vam->retval); \ - } \ - } \ - return -99; \ -} while(0); - -static int api_acl_plugin_get_version (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - vl_api_acl_plugin_get_version_t * mp; - u32 msg_size = sizeof(*mp); - f64 timeout; - - vam->result_ready = 0; - mp = vl_msg_api_alloc_as_if_client(msg_size); - memset (mp, 0, msg_size); - mp->_vl_msg_id = ntohs (VL_API_ACL_PLUGIN_GET_VERSION + sm->msg_id_base); - mp->client_index = vam->my_client_index; - - /* send it... */ - S; - - /* Wait for a reply... */ - W; - - return 0; -} - -static int api_macip_acl_interface_get (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - vl_api_acl_plugin_get_version_t * mp; - u32 msg_size = sizeof(*mp); - f64 timeout; - - vam->result_ready = 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_INTERFACE_GET + sm->msg_id_base); - mp->client_index = vam->my_client_index; - - /* send it... */ - S; - - /* Wait for a reply... */ - W; - - return 0; -} - -#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 int api_acl_add_replace (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_acl_add_replace_t * mp; - u32 acl_index = ~0; - u32 msg_size = sizeof (*mp); /* without the rules */ - - vl_api_acl_rule_t *rules = 0; - int rule_idx = 0; - int n_rules = 0; - 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 = 0; - - if (!unformat (i, "%d", &acl_index)) { - /* Just assume -1 */ - } - - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) - { - if (unformat (i, "ipv6")) - { - vec_validate_acl_rules(rules, rule_idx); - rules[rule_idx].is_ipv6 = 1; - } - else if (unformat (i, "ipv4")) - { - vec_validate_acl_rules(rules, rule_idx); - rules[rule_idx].is_ipv6 = 0; - } - else if (unformat (i, "permit+reflect")) - { - vec_validate_acl_rules(rules, rule_idx); - rules[rule_idx].is_permit = 2; - } - else if (unformat (i, "permit")) - { - vec_validate_acl_rules(rules, rule_idx); - rules[rule_idx].is_permit = 1; - } - else if (unformat (i, "action %d", &action)) - { - vec_validate_acl_rules(rules, rule_idx); - rules[rule_idx].is_permit = action; - } - else if (unformat (i, "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 (i, "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 (i, "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 (i, "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 (i, "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 (i, "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 (i, "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 (i, "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 (i, "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 (i, "proto %d", &proto)) - { - vec_validate_acl_rules(rules, rule_idx); - rules[rule_idx].proto = proto; - } - else if (unformat (i, "tag %s", &tag)) - { - } - else if (unformat (i, ",")) - { - rule_idx++; - vec_validate_acl_rules(rules, rule_idx); - } - else - break; - } - - /* Construct the API message */ - vam->result_ready = 0; - - if(rules) - n_rules = vec_len(rules); - else - n_rules = 0; - - 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_ACL_ADD_REPLACE + sm->msg_id_base); - mp->client_index = vam->my_client_index; - if (n_rules > 0) - clib_memcpy(mp->r, rules, n_rules*sizeof (vl_api_acl_rule_t)); - 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; - - /* Wait for a reply... */ - W; -} - -static int api_acl_del (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_acl_del_t * mp; - u32 acl_index = ~0; - - if (!unformat (i, "%d", &acl_index)) { - errmsg ("missing acl index\n"); - return -99; - } - - /* Construct the API message */ - M(ACL_DEL, acl_del); - mp->acl_index = ntohl(acl_index); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -static int api_macip_acl_del (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_acl_del_t * mp; - u32 acl_index = ~0; - - if (!unformat (i, "%d", &acl_index)) { - errmsg ("missing acl index\n"); - return -99; - } - - /* Construct the API message */ - M(MACIP_ACL_DEL, acl_del); - mp->acl_index = ntohl(acl_index); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -static int api_acl_interface_add_del (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_acl_interface_add_del_t * mp; - u32 sw_if_index = ~0; - u32 acl_index = ~0; - u8 is_input = 0; - u8 is_add = 0; - -// acl_interface_add_del <intfc> | sw_if_index <if-idx> acl_index <acl-idx> [out] [del] - - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) - { - if (unformat (i, "%d", &acl_index)) - ; - else - break; - } - - - /* 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, "add")) - is_add = 1; - else if (unformat (i, "del")) - is_add = 0; - else if (unformat (i, "acl %d", &acl_index)) - ; - 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; - } - - if (acl_index == ~0) { - errmsg ("missing ACL index\n"); - return -99; - } - - - - /* Construct the API message */ - M(ACL_INTERFACE_ADD_DEL, acl_interface_add_del); - mp->acl_index = ntohl(acl_index); - mp->sw_if_index = ntohl(sw_if_index); - mp->is_add = is_add; - mp->is_input = is_input; - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -static int api_macip_acl_interface_add_del (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_macip_acl_interface_add_del_t * mp; - u32 sw_if_index = ~0; - u32 acl_index = ~0; - u8 is_add = 0; - - /* 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, "add")) - is_add = 1; - else if (unformat (i, "del")) - is_add = 0; - else if (unformat (i, "acl %d", &acl_index)) - ; - else - break; - } - - if (sw_if_index == ~0) { - errmsg ("missing interface name / explicit sw_if_index number \n"); - return -99; - } - - if (acl_index == ~0) { - errmsg ("missing ACL index\n"); - return -99; - } - - - - /* Construct the API message */ - M(MACIP_ACL_INTERFACE_ADD_DEL, macip_acl_interface_add_del); - mp->acl_index = ntohl(acl_index); - mp->sw_if_index = ntohl(sw_if_index); - mp->is_add = is_add; - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -static int api_acl_interface_set_acl_list (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_acl_interface_set_acl_list_t * mp; - u32 sw_if_index = ~0; - u32 acl_index = ~0; - u32 *inacls = 0; - u32 *outacls = 0; - u8 is_input = 0; - -// acl_interface_set_acl_list <intfc> | sw_if_index <if-idx> input [acl-idx list] output [acl-idx 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, "%d", &acl_index)) - { - if(is_input) - vec_add1(inacls, htonl(acl_index)); - else - vec_add1(outacls, htonl(acl_index)); - } - else if (unformat (i, "acl %d", &acl_index)) - ; - 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_ACL_LIST, acl_interface_set_acl_list, sizeof(u32) * (vec_len(inacls) + vec_len(outacls))); - mp->sw_if_index = ntohl(sw_if_index); - mp->n_input = vec_len(inacls); - mp->count = vec_len(inacls) + vec_len(outacls); - vec_append(inacls, outacls); - if (vec_len(inacls) > 0) - clib_memcpy(mp->acls, inacls, vec_len(inacls)*sizeof(u32)); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - - -static int api_acl_interface_list_dump (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - u32 sw_if_index = ~0; - vl_api_acl_interface_list_dump_t * mp; - - /* 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 - break; - } - - /* Construct the API message */ - M(ACL_INTERFACE_LIST_DUMP, acl_interface_list_dump); - mp->sw_if_index = ntohl (sw_if_index); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -static int api_acl_dump (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - u32 acl_index = ~0; - vl_api_acl_dump_t * mp; - - /* Parse args required to build the message */ - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { - if (unformat (i, "%d", &acl_index)) - ; - else - break; - } - - /* Construct the API message */ - M(ACL_DUMP, acl_dump); - mp->acl_index = ntohl (acl_index); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -static int api_macip_acl_dump (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - u32 acl_index = ~0; - vl_api_acl_dump_t * mp; - - /* Parse args required to build the message */ - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { - if (unformat (i, "%d", &acl_index)) - ; - else - break; - } - - /* Construct the API message */ - M(MACIP_ACL_DUMP, macip_acl_dump); - mp->acl_index = ntohl (acl_index); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -#define vec_validate_macip_acl_rules(v, idx) \ - do { \ - if (vec_len(v) < idx+1) { \ - vec_validate(v, idx); \ - v[idx].is_permit = 0x1; \ - } \ - } while (0) - - -static int api_macip_acl_add (vat_main_t * vam) -{ - acl_test_main_t * sm = &acl_test_main; - unformat_input_t * i = vam->input; - f64 timeout; - vl_api_macip_acl_add_t * mp; - u32 msg_size = sizeof (*mp); /* without the rules */ - - vl_api_macip_acl_rule_t *rules = 0; - int rule_idx = 0; - int n_rules = 0; - 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 }; - - 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 = 1; - } - 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, "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)) - { - 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, "ip %U/%d", - unformat_ip6_address, &src_v6address, &src_prefix_length)) - { - 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; - } - - /* Construct the API message */ - vam->result_ready = 0; - - if(rules) - n_rules = vec_len(rules); - else - n_rules = 0; - - 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 + sm->msg_id_base); - mp->client_index = vam->my_client_index; - if (n_rules > 0) - 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->count = htonl(n_rules); - - /* send it... */ - S; - - /* Wait for a reply... */ - W; -} - -/* - * List of messages that the api test plugin sends, - * and that the data plane plugin processes - */ -#define foreach_vpe_api_msg \ -_(acl_plugin_get_version, "") \ -_(acl_add_replace, "<acl-idx> [<ipv4|ipv6> <permit|permit+reflect|deny|action N> [src IP/plen] [dst IP/plen] [sport X-Y] [dport X-Y] [proto P] [tcpflags FL MASK], ... , ...") \ -_(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_list_dump, "[<intfc> | sw_if_index <if-idx>]") \ -_(macip_acl_add, "...") \ -_(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>") \ -_(macip_acl_interface_get, "") - - - -void vat_api_hookup (vat_main_t *vam) -{ - acl_test_main_t * sm = &acl_test_main; - /* Hook up handlers for replies from the data plane plug-in */ -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \ - #n, \ - vl_api_##n##_t_handler, \ - vl_noop_handler, \ - vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 1); - foreach_vpe_api_reply_msg; -#undef _ - - /* API messages we can send */ -#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n); - foreach_vpe_api_msg; -#undef _ - - /* Help strings */ -#define _(n,h) hash_set_mem (vam->help_by_name, #n, h); - foreach_vpe_api_msg; -#undef _ -} - -clib_error_t * vat_plugin_register (vat_main_t *vam) -{ - acl_test_main_t * sm = &acl_test_main; - u8 * name; - - sm->vat_main = vam; - - name = format (0, "acl_%08x%c", api_version, 0); - sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name); - - if (sm->msg_id_base != (u16) ~0) - vat_api_hookup (vam); - - vec_free(name); - - return 0; -} diff --git a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclExpectedDumpData.java b/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclExpectedDumpData.java deleted file mode 100644 index 979edbc4c6c..00000000000 --- a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclExpectedDumpData.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.vpp.jvpp.acl.test; - - -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_ADDRESS_2_AS_ARRAY; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_ADDRESS_AS_ARRAY; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_DST_ICMP_TYPE_END; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_DST_ICMP_TYPE_START; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_MAC; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_MAC_MASK; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_PREFIX; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_PREFIX_2; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_SRC_ICMP_TYPE_END; -import static io.fd.vpp.jvpp.acl.test.AclTestData.FIRST_RULE_SRC_ICMP_TYPE_START; -import static io.fd.vpp.jvpp.acl.test.AclTestData.ICMP_PROTOCOL; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_ADDRESS_2_AS_ARRAY; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_ADDRESS_AS_ARRAY; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_DST_PORT_RANGE_END; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_DST_PORT_RANGE_START; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_MAC; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_MAC_MASK; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_PREFIX; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_PREFIX_2; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_SRC_PORT_RANGE_END; -import static io.fd.vpp.jvpp.acl.test.AclTestData.SECOND_RULE_SRC_PORT_RANGE_START; -import static io.fd.vpp.jvpp.acl.test.AclTestData.UDP_PROTOCOL; - -import io.fd.vpp.jvpp.acl.dto.AclDetails; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails; -import io.fd.vpp.jvpp.acl.dto.MacipAclDetails; -import io.fd.vpp.jvpp.acl.types.AclRule; -import io.fd.vpp.jvpp.acl.types.MacipAclRule; -import java.util.Arrays; - -class AclExpectedDumpData { - - static void verifyMacIpDump(final MacipAclDetails macipAclDetails) { - // asserting data create by previous call - assertEquals(0, macipAclDetails.aclIndex); - assertEquals(2, macipAclDetails.count); - - final MacipAclRule currentIpv4Rule = macipAclDetails.r[0]; - final MacipAclRule currentIpv6Rule = macipAclDetails.r[1]; - - // Comparing one property at the time to better pointer if something is wrong - //Ipv4 rule - assertEquals(0, currentIpv4Rule.isIpv6); - assertEquals(1, currentIpv4Rule.isPermit); - - // cutting expected ipv4 to 4 bytes,vpp sends it as 16 always - assertArrays(FIRST_RULE_ADDRESS_AS_ARRAY, Arrays.copyOfRange(currentIpv4Rule.srcIpAddr, 0, 4)); - assertEquals(FIRST_RULE_PREFIX, currentIpv4Rule.srcIpPrefixLen); - assertArrays(FIRST_RULE_MAC, currentIpv4Rule.srcMac); - assertArrays(FIRST_RULE_MAC_MASK, currentIpv4Rule.srcMacMask); - - //Ipv6 rule - assertEquals(1, currentIpv6Rule.isIpv6); - assertEquals(0, currentIpv6Rule.isPermit); - assertArrays(SECOND_RULE_ADDRESS_AS_ARRAY, currentIpv6Rule.srcIpAddr); - assertEquals(SECOND_RULE_PREFIX, currentIpv6Rule.srcIpPrefixLen); - assertArrays(SECOND_RULE_MAC, currentIpv6Rule.srcMac); - assertArrays(SECOND_RULE_MAC_MASK, currentIpv6Rule.srcMacMask); - } - - static void verifyAclDump(final AclDetails aclDetails) { - assertEquals(0, aclDetails.aclIndex); - assertEquals(2, aclDetails.count); - - final AclRule currentIpv4Rule = aclDetails.r[0]; - final AclRule currentIpv6Rule = aclDetails.r[1]; - - // Comparing one property at the time to better pointer if something is wrong - //Ipv4 rule - assertEquals(0, currentIpv4Rule.isIpv6); - assertEquals(1, currentIpv4Rule.isPermit); - - // cutting expected ipv4 to 4 bytes,vpp sends it as 16 always - assertArrays(FIRST_RULE_ADDRESS_AS_ARRAY, Arrays.copyOfRange(currentIpv4Rule.srcIpAddr, 0, 4)); - assertEquals(FIRST_RULE_PREFIX, currentIpv4Rule.srcIpPrefixLen); - assertArrays(FIRST_RULE_ADDRESS_2_AS_ARRAY, Arrays.copyOfRange(currentIpv4Rule.dstIpAddr, 0, 4)); - assertEquals(FIRST_RULE_PREFIX_2, currentIpv4Rule.dstIpPrefixLen); - - assertEquals(ICMP_PROTOCOL, currentIpv4Rule.proto); - assertEquals(FIRST_RULE_SRC_ICMP_TYPE_START, currentIpv4Rule.srcportOrIcmptypeFirst); - assertEquals(FIRST_RULE_SRC_ICMP_TYPE_END, currentIpv4Rule.srcportOrIcmptypeLast); - assertEquals(FIRST_RULE_DST_ICMP_TYPE_START, currentIpv4Rule.dstportOrIcmpcodeFirst); - assertEquals(FIRST_RULE_DST_ICMP_TYPE_END, currentIpv4Rule.dstportOrIcmpcodeLast); - - assertArrays(SECOND_RULE_ADDRESS_AS_ARRAY, currentIpv6Rule.srcIpAddr); - assertEquals(SECOND_RULE_PREFIX, currentIpv6Rule.srcIpPrefixLen); - assertArrays(SECOND_RULE_ADDRESS_2_AS_ARRAY, currentIpv6Rule.dstIpAddr); - assertEquals(SECOND_RULE_PREFIX_2, currentIpv6Rule.dstIpPrefixLen); - - assertEquals(UDP_PROTOCOL, currentIpv6Rule.proto); - assertEquals(SECOND_RULE_SRC_PORT_RANGE_START, currentIpv6Rule.srcportOrIcmptypeFirst); - assertEquals(SECOND_RULE_SRC_PORT_RANGE_END, currentIpv6Rule.srcportOrIcmptypeLast); - assertEquals(SECOND_RULE_DST_PORT_RANGE_START, currentIpv6Rule.dstportOrIcmpcodeFirst); - assertEquals(SECOND_RULE_DST_PORT_RANGE_END, currentIpv6Rule.dstportOrIcmpcodeLast); - } - - static void verifyAclInterfaceList(final AclInterfaceListDetails aclInterfaceListDetails) { - assertEquals(1, aclInterfaceListDetails.count); - assertEquals(1, aclInterfaceListDetails.acls[0]); - assertEquals(0, aclInterfaceListDetails.nInput); - assertEquals(0, aclInterfaceListDetails.swIfIndex); - } - - private static void assertArrays(final byte[] expected, final byte[] actual) { - if (!Arrays.equals(expected, actual)) { - throw new IllegalArgumentException( - String.format("Expected[%s]/Actual[%s]", Arrays.toString(expected), Arrays.toString(actual))); - } - } - - private static void assertEquals(final int expected, final int actual) { - if (expected != actual) { - throw new IllegalArgumentException(String.format("Expected[%s]/Actual[%s]", expected, actual)); - } - } -} diff --git a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclTestData.java b/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclTestData.java deleted file mode 100644 index 5d228eead1e..00000000000 --- a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclTestData.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.vpp.jvpp.acl.test; - - -import io.fd.vpp.jvpp.acl.types.AclRule; -import io.fd.vpp.jvpp.acl.types.MacipAclRule; - -class AclTestData { - - static final byte[] FIRST_RULE_ADDRESS_AS_ARRAY = {-64, -88, 2, 1}; - static final byte[] FIRST_RULE_ADDRESS_2_AS_ARRAY = {-64, -88, 2, 3}; - static final byte[] SECOND_RULE_ADDRESS_AS_ARRAY = - {32, 1, 13, -72, 10, 11, 18, -16, 0, 0, 0, 0, 0, 0, 0, 1}; - static final byte[] SECOND_RULE_ADDRESS_2_AS_ARRAY = - {32, 1, 13, -72, 10, 11, 18, -16, 0, 0, 0, 0, 0, 0, 0, 1}; - static final byte[] FIRST_RULE_MAC = {11, 11, 11, 11, 11, 11}; - static final byte[] FIRST_RULE_MAC_MASK = {0, 0, 0, 0, 0, 0}; - static final byte[] SECOND_RULE_MAC = {11, 12, 11, 11, 12, 11}; - static final byte[] SECOND_RULE_MAC_MASK = {(byte) 170, 0, 0, 0, 0, 0}; - static final int FIRST_RULE_PREFIX = 32; - static final int FIRST_RULE_PREFIX_2 = 24; - static final int SECOND_RULE_PREFIX = 64; - static final int SECOND_RULE_PREFIX_2 = 62; - static final int FIRST_RULE_DST_ICMP_TYPE_START = 0; - static final int FIRST_RULE_DST_ICMP_TYPE_END = 8; - static final int FIRST_RULE_SRC_ICMP_TYPE_START = 1; - static final int FIRST_RULE_SRC_ICMP_TYPE_END = 7; - static final int ICMP_PROTOCOL = 1; - static final int SECOND_RULE_DST_PORT_RANGE_START = 2000; - static final int SECOND_RULE_DST_PORT_RANGE_END = 6000; - static final int SECOND_RULE_SRC_PORT_RANGE_START = 400; - static final int SECOND_RULE_SRC_PORT_RANGE_END = 2047; - static final int UDP_PROTOCOL = 17; - - - static MacipAclRule[] createMacipRules() { - MacipAclRule ruleOne = new MacipAclRule(); - ruleOne.isIpv6 = 0; - ruleOne.isPermit = 1; - ruleOne.srcIpAddr = FIRST_RULE_ADDRESS_AS_ARRAY; - ruleOne.srcIpPrefixLen = FIRST_RULE_PREFIX; - ruleOne.srcMac = FIRST_RULE_MAC; - ruleOne.srcMacMask = FIRST_RULE_MAC_MASK;// no mask - - MacipAclRule ruleTwo = new MacipAclRule(); - ruleTwo.isIpv6 = 1; - ruleTwo.isPermit = 0; - ruleTwo.srcIpAddr = SECOND_RULE_ADDRESS_AS_ARRAY; - ruleTwo.srcIpPrefixLen = SECOND_RULE_PREFIX; - ruleTwo.srcMac = SECOND_RULE_MAC; - ruleTwo.srcMacMask = SECOND_RULE_MAC_MASK; - - return new MacipAclRule[]{ruleOne, ruleTwo}; - } - - static AclRule[] createAclRules() { - AclRule ruleOne = new AclRule(); - - ruleOne.isIpv6 = 0; - ruleOne.isPermit = 1; - ruleOne.srcIpAddr = FIRST_RULE_ADDRESS_AS_ARRAY; - ruleOne.srcIpPrefixLen = FIRST_RULE_PREFIX; - ruleOne.dstIpAddr = FIRST_RULE_ADDRESS_2_AS_ARRAY; - ruleOne.dstIpPrefixLen = FIRST_RULE_PREFIX_2; - ruleOne.dstportOrIcmpcodeFirst = FIRST_RULE_DST_ICMP_TYPE_START; - ruleOne.dstportOrIcmpcodeLast = FIRST_RULE_DST_ICMP_TYPE_END; - ruleOne.srcportOrIcmptypeFirst = FIRST_RULE_SRC_ICMP_TYPE_START; - ruleOne.srcportOrIcmptypeLast = FIRST_RULE_SRC_ICMP_TYPE_END; - ruleOne.proto = ICMP_PROTOCOL; //ICMP - - AclRule ruleTwo = new AclRule(); - ruleTwo.isIpv6 = 1; - ruleTwo.isPermit = 0; - ruleTwo.srcIpAddr = SECOND_RULE_ADDRESS_AS_ARRAY; - ruleTwo.srcIpPrefixLen = SECOND_RULE_PREFIX; - ruleTwo.dstIpAddr = SECOND_RULE_ADDRESS_2_AS_ARRAY; - ruleTwo.dstIpPrefixLen = SECOND_RULE_PREFIX_2; - ruleTwo.dstportOrIcmpcodeFirst = SECOND_RULE_DST_PORT_RANGE_START; - ruleTwo.dstportOrIcmpcodeLast = SECOND_RULE_DST_PORT_RANGE_END; - ruleTwo.srcportOrIcmptypeFirst = SECOND_RULE_SRC_PORT_RANGE_START; - ruleTwo.srcportOrIcmptypeLast = SECOND_RULE_SRC_PORT_RANGE_END; - ruleTwo.proto = UDP_PROTOCOL; //UDP - - return new AclRule[]{ruleOne, ruleTwo}; - } -} diff --git a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclTestRequests.java b/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclTestRequests.java deleted file mode 100644 index b580ee8cfce..00000000000 --- a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/AclTestRequests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.vpp.jvpp.acl.test; - -import static io.fd.vpp.jvpp.acl.test.AclTestData.createAclRules; -import static io.fd.vpp.jvpp.acl.test.AclTestData.createMacipRules; - -import io.fd.vpp.jvpp.VppInvocationException; -import io.fd.vpp.jvpp.acl.dto.AclAddReplace; -import io.fd.vpp.jvpp.acl.dto.AclAddReplaceReply; -import io.fd.vpp.jvpp.acl.dto.AclDel; -import io.fd.vpp.jvpp.acl.dto.AclDelReply; -import io.fd.vpp.jvpp.acl.dto.AclDetailsReplyDump; -import io.fd.vpp.jvpp.acl.dto.AclDump; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDump; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceSetAclList; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceSetAclListReply; -import io.fd.vpp.jvpp.acl.dto.MacipAclAdd; -import io.fd.vpp.jvpp.acl.dto.MacipAclAddReply; -import io.fd.vpp.jvpp.acl.dto.MacipAclDel; -import io.fd.vpp.jvpp.acl.dto.MacipAclDelReply; -import io.fd.vpp.jvpp.acl.dto.MacipAclDetailsReplyDump; -import io.fd.vpp.jvpp.acl.dto.MacipAclDump; -import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; -import java.util.concurrent.ExecutionException; - -class AclTestRequests { - - static MacipAclDetailsReplyDump sendMacIpDumpRequest(final FutureJVppAclFacade jvpp) - throws ExecutionException, InterruptedException { - System.out.println("Sending MacipAclDump request..."); - MacipAclDetailsReplyDump dump = jvpp.macipAclDump(new MacipAclDump()).toCompletableFuture().get(); - System.out.println("MacipAclDump returned"); - return dump; - } - - static void sendMacIpAddRequest(final FutureJVppAclFacade jvpp) throws InterruptedException, ExecutionException { - final MacipAclAdd request = createMacIpAddRequest(); - System.out.printf("Sending MacipAclAdd request %s%n", request.toString()); - final MacipAclAddReply reply = jvpp.macipAclAdd(createMacIpAddRequest()).toCompletableFuture().get(); - System.out.printf("MacipAclAdd send result = %s%n", reply); - } - - static void sendMacIpDelRequest(final FutureJVppAclFacade jvpp) throws InterruptedException, ExecutionException { - final MacipAclDel request = new MacipAclDel(); - request.aclIndex = 0; - System.out.printf("Sending MacipAclDel request %s%n", request.toString()); - final MacipAclDelReply reply = jvpp.macipAclDel(request).toCompletableFuture().get(); - System.out.printf("MacipAclDel send result = %s%n", reply); - } - - static void sendAclAddRequest(final FutureJVppAclFacade jvpp) throws InterruptedException, ExecutionException { - final AclAddReplace request = createAclAddRequest(); - System.out.printf("Sending AclAddReplace request %s%n", request.toString()); - final AclAddReplaceReply reply = jvpp.aclAddReplace(request).toCompletableFuture().get(); - System.out.printf("AclAddReplace send result = %s%n", reply); - } - - static AclDetailsReplyDump sendAclDumpRequest(final FutureJVppAclFacade jvpp) - throws InterruptedException, VppInvocationException, ExecutionException { - System.out.println("Sending AclDump request..."); - final AclDetailsReplyDump dump = jvpp.aclDump(new AclDump()).toCompletableFuture().get(); - System.out.printf("AclDump send result = %s%n", dump); - return dump; - } - - static void sendAclDelRequest(final FutureJVppAclFacade jvpp) throws InterruptedException, ExecutionException { - final AclDel request = new AclDel(); - request.aclIndex = 0; - System.out.printf("Sending AclDel request %s%n", request.toString()); - final AclDelReply reply = jvpp.aclDel(request).toCompletableFuture().get(); - System.out.printf("AclDel send result = %s%n", reply); - } - - static AclInterfaceListDetailsReplyDump sendAclInterfaceListDumpRequest(final FutureJVppAclFacade jvpp) - throws InterruptedException, ExecutionException { - final AclInterfaceListDump request = new AclInterfaceListDump(); - request.swIfIndex = 0; - System.out.printf("Sending AclInterfaceListDump request %s%n", request.toString()); - final AclInterfaceListDetailsReplyDump dump = jvpp.aclInterfaceListDump(request).toCompletableFuture().get(); - System.out.printf("AclInterfaceListDump send result = %s%n", dump); - return dump; - } - - static void sendAclInterfaceSetAclList(final FutureJVppAclFacade jvpp) - throws InterruptedException, ExecutionException { - final AclInterfaceSetAclList request = new AclInterfaceSetAclList(); - request.count = 1; - request.acls = new int[]{1}; - request.swIfIndex = 0; - request.nInput = 0; - System.out.printf("Sending AclInterfaceSetAclList request %s%n", request.toString()); - final AclInterfaceSetAclListReply reply = jvpp.aclInterfaceSetAclList(request).toCompletableFuture().get(); - System.out.printf("AclInterfaceSetAclList send result = %s%n", reply); - } - - static void sendAclInterfaceDeleteList(final FutureJVppAclFacade jvpp) - throws InterruptedException, ExecutionException { - // uses same api but sets list to empty - final AclInterfaceSetAclList request = new AclInterfaceSetAclList(); - request.count = 0; - request.acls = new int[]{}; - request.swIfIndex = 0; - request.nInput = 0; - System.out.printf("Sending AclInterfaceSetAclList(Delete) request %s%n", request.toString()); - final AclInterfaceSetAclListReply reply = jvpp.aclInterfaceSetAclList(request).toCompletableFuture().get(); - System.out.printf("AclInterfaceSetAclList(Delete) send result = %s%n", reply); - } - - private static MacipAclAdd createMacIpAddRequest() { - MacipAclAdd request = new MacipAclAdd(); - - request.count = 2; - request.r = createMacipRules(); - return request; - } - - private static AclAddReplace createAclAddRequest() { - AclAddReplace request = new AclAddReplace(); - - request.aclIndex = -1;// to define new one - request.count = 2; - request.r = createAclRules(); - return request; - } -} diff --git a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/FutureApiTest.java b/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/FutureApiTest.java deleted file mode 100644 index 94490193597..00000000000 --- a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/FutureApiTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.vpp.jvpp.acl.test; - -import static io.fd.vpp.jvpp.acl.test.AclExpectedDumpData.verifyAclDump; -import static io.fd.vpp.jvpp.acl.test.AclExpectedDumpData.verifyAclInterfaceList; -import static io.fd.vpp.jvpp.acl.test.AclExpectedDumpData.verifyMacIpDump; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendAclAddRequest; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendAclDelRequest; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendAclDumpRequest; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendAclInterfaceDeleteList; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendAclInterfaceListDumpRequest; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendAclInterfaceSetAclList; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendMacIpAddRequest; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendMacIpDelRequest; -import static io.fd.vpp.jvpp.acl.test.AclTestRequests.sendMacIpDumpRequest; - -import io.fd.vpp.jvpp.JVppRegistry; -import io.fd.vpp.jvpp.JVppRegistryImpl; -import io.fd.vpp.jvpp.acl.JVppAclImpl; -import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; - -public class FutureApiTest { - - public static void main(String[] args) throws Exception { - testCallbackApi(); - } - - private static void testCallbackApi() throws Exception { - System.out.println("Testing Java callback API for acl plugin"); - try (final JVppRegistry registry = new JVppRegistryImpl("macipAclAddTest"); - final FutureJVppAclFacade jvpp = new FutureJVppAclFacade(registry, new JVppAclImpl())) { - - // adds,dump and verifies Mac-Ip acl - sendMacIpAddRequest(jvpp); - verifyMacIpDump(sendMacIpDumpRequest(jvpp).macipAclDetails.get(0)); - - // adds,dumps and verifies Acl acl - sendAclAddRequest(jvpp); - verifyAclDump(sendAclDumpRequest(jvpp).aclDetails.get(0)); - - // adds,dumps and verifies Interface for acl - sendAclInterfaceSetAclList(jvpp); - verifyAclInterfaceList(sendAclInterfaceListDumpRequest(jvpp).aclInterfaceListDetails.get(0)); - - // deletes all created data - sendAclInterfaceDeleteList(jvpp); - sendAclDelRequest(jvpp); - sendMacIpDelRequest(jvpp); - - System.out.println("Disconnecting..."); - } - } -} diff --git a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/Readme.txt b/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/Readme.txt deleted file mode 100644 index f68e7aba52a..00000000000 --- a/plugins/acl-plugin/acl/jvpp/io/fd/vpp/jvpp/acl/test/Readme.txt +++ /dev/null @@ -1 +0,0 @@ -sudo java -cp build-vpp-native/vpp-api/java/jvpp-registry-17.01.jar:build-vpp-native/plugins/acl-plugin/jvpp-acl-1.0.jar io.fd.vpp.jvpp.acl.test.FutureApiTest diff --git a/plugins/acl-plugin/acl/jvpp_acl.c b/plugins/acl-plugin/acl/jvpp_acl.c deleted file mode 100644 index 0af53bc905b..00000000000 --- a/plugins/acl-plugin/acl/jvpp_acl.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vnet/vnet.h> - -#include <acl/acl_msg_enum.h> -#define vl_typedefs /* define message structures */ -#include <acl/acl_all_api_h.h> -#undef vl_typedefs - -#define vl_endianfun -#include <acl/acl_all_api_h.h> -#undef vl_endianfun - -#define vl_print(handle, ...) -#define vl_printfun -#include <acl/acl_all_api_h.h> -#undef vl_printfun - -/* Get the API version number */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <acl/acl_all_api_h.h> -#undef vl_api_version - -#include <vnet/api_errno.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> - -#if VPPJNI_DEBUG == 1 - #define DEBUG_LOG(...) clib_warning(__VA_ARGS__) -#else - #define DEBUG_LOG(...) -#endif - -#include <jvpp-common/jvpp_common.h> - -#include "acl/jvpp/io_fd_vpp_jvpp_acl_JVppAclImpl.h" -#include "jvpp_acl.h" -#include "acl/jvpp/jvpp_acl_gen.h" - -/* - * Class: io_fd_vpp_jvpp_acl_JVppaclImpl - * Method: init0 - * Signature: (JI)V - */ -JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_acl_JVppAclImpl_init0 - (JNIEnv *env, jclass clazz, jobject callback, jlong queue_address, jint my_client_index) { - acl_main_t * plugin_main = &acl_main; - u8 * name; - clib_warning ("Java_io_fd_vpp_jvpp_acl_JVppAclImpl_init0"); - - plugin_main->my_client_index = my_client_index; - plugin_main->vl_input_queue = (unix_shared_memory_queue_t *)queue_address; - - name = format (0, "acl_%08x%c", api_version, 0); - plugin_main->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name); - - if (plugin_main->msg_id_base == (u16) ~0) { - jclass exClass = (*env)->FindClass(env, "java/lang/IllegalStateException"); - (*env)->ThrowNew(env, exClass, "acl plugin is not loaded in VPP"); - } else { - plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback); - plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback)); - - #define _(N,n) \ - vl_msg_api_set_handlers(VL_API_##N + plugin_main->msg_id_base, #n, \ - vl_api_##n##_t_handler, \ - vl_noop_handler, \ - vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 1); - foreach_api_reply_handler; - #undef _ - } -} - -JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_acl_JVppAclImpl_close0 -(JNIEnv *env, jclass clazz) { - acl_main_t * plugin_main = &acl_main; - - // cleanup: - (*env)->DeleteGlobalRef(env, plugin_main->callbackClass); - (*env)->DeleteGlobalRef(env, plugin_main->callbackObject); - - plugin_main->callbackClass = NULL; - plugin_main->callbackObject = NULL; -} - -/* Attach thread to JVM and cache class references when initiating JVPP ACL */ -jint JNI_OnLoad(JavaVM *vm, void *reserved) { - JNIEnv* env; - - if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) { - return JNI_EVERSION; - } - - if (cache_class_references(env) != 0) { - clib_warning ("Failed to cache class references\n"); - return JNI_ERR; - } - - return JNI_VERSION_1_8; -} - -/* Clean up cached references when disposing JVPP ACL */ -void JNI_OnUnload(JavaVM *vm, void *reserved) { - JNIEnv* env; - if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) { - return; - } - delete_class_references(env); -} diff --git a/plugins/acl-plugin/acl/jvpp_acl.h b/plugins/acl-plugin/acl/jvpp_acl.h deleted file mode 100644 index 2b73d672afa..00000000000 --- a/plugins/acl-plugin/acl/jvpp_acl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __included_jvpp_acl_h__ -#define __included_jvpp_acl_h__ - -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/api_errno.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <jni.h> - -/* Global state for JVPP-acl */ -typedef struct { - /* Base message index for the acl plugin */ - u16 msg_id_base; - - /* Pointer to shared memory queue */ - unix_shared_memory_queue_t * vl_input_queue; - - /* VPP api client index */ - u32 my_client_index; - - /* Callback object and class references enabling asynchronous Java calls */ - jobject callbackObject; - jclass callbackClass; - -} acl_main_t; - -acl_main_t acl_main __attribute__((aligned (64))); - - -#endif /* __included_jvpp_acl_h__ */ diff --git a/plugins/acl-plugin/acl/l2sess.c b/plugins/acl-plugin/acl/l2sess.c deleted file mode 100644 index cc9bde4417d..00000000000 --- a/plugins/acl-plugin/acl/l2sess.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - *------------------------------------------------------------------ - * l2sess.c - simple MAC-swap API / debug CLI handling - *------------------------------------------------------------------ - */ - -#include <vnet/vnet.h> -#include <vnet/plugin/plugin.h> -#include <acl/l2sess.h> - -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vlibsocket/api.h> -#include <vppinfra/timing_wheel.h> - -#include <vnet/l2/l2_output.h> -#include <vnet/l2/l2_input.h> - -void -l2sess_vlib_plugin_register (vlib_main_t * vm, void* hh, - int from_early_init) -{ - l2sess_main_t *sm = &l2sess_main; - vnet_plugin_handoff_t * h = hh; - memset (sm, 0, sizeof (*sm)); - - sm->vlib_main = vm; - sm->vnet_main = h->vnet_main; - sm->ethernet_main = h->ethernet_main; -} - -void -l2sess_init_next_features_input (vlib_main_t * vm, l2sess_main_t * sm) -{ -#define _(node_name, node_var, is_out, is_ip6, is_track) \ - if (!is_out) feat_bitmap_init_next_nodes(vm, node_var.index, L2INPUT_N_FEAT, l2input_get_feat_names (), sm->node_var ## _input_next_node_index); - foreach_l2sess_node -#undef _ -} - -void -l2sess_add_our_next_nodes (vlib_main_t * vm, l2sess_main_t * sm, - u8 * prev_node_name, int add_output_nodes) -{ - vlib_node_t *n; - n = vlib_get_node_by_name (vm, prev_node_name); -#define _(node_name, node_var, is_out, is_ip6, is_track) \ - if (is_out == add_output_nodes) { \ - u32 idx = vlib_node_add_next_with_slot(vm, n->index, node_var.index, ~0); \ - if (is_track) { \ - sm->next_slot_track_node_by_is_ip6_is_out[is_ip6][is_out] = idx; \ - } \ - } - foreach_l2sess_node -#undef _ -} - -void -l2sess_setup_nodes (void) -{ - vlib_main_t *vm = vlib_get_main (); - l2sess_main_t *sm = &l2sess_main; - - l2sess_init_next_features_input (vm, sm); - - l2sess_add_our_next_nodes (vm, sm, (u8 *) "l2-input-classify", 0); - l2sess_add_our_next_nodes (vm, sm, (u8 *) "l2-output-classify", 1); - -} - -static char * -get_l4_proto_str (int is_ip6, uint8_t l4_proto) -{ - switch (l4_proto) - { - case 6: - return "tcp"; - case 17: - return "udp"; - case 1: - return "icmp"; - case 58: - return "icmp6"; - default: - return "<?l4-unknown?>"; - } -} - -static clib_error_t * -l2sess_show_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - l2sess_main_t *sm = &l2sess_main; - clib_time_t *ct = &vm->clib_time; - l2s_session_t *s; - u64 now = clib_cpu_time_now (); - - vlib_cli_output (vm, "Timing wheel info: \n%U", format_timing_wheel, - &sm->timing_wheel, 255); - - pool_foreach (s, sm->sessions, ( - { - f64 ctime = - (now - - s->create_time) * ct->seconds_per_clock; - f64 atime0 = - (now - - s->side[0].active_time) * - ct->seconds_per_clock; - f64 atime1 = - (now - - s->side[1].active_time) * - ct->seconds_per_clock; -/* - f64 ctime = (s->create_time - vm->cpu_time_main_loop_start) * ct->seconds_per_clock; - f64 atime0 = (s->side[0].active_time - vm->cpu_time_main_loop_start) * ct->seconds_per_clock; - f64 atime1 = (s->side[1].active_time - vm->cpu_time_main_loop_start) * ct->seconds_per_clock; -*/ - u8 * out0 = - format (0, - "%5d: create time: %U pkts/bytes/active time: [ %ld %ld %U : %ld %ld %U ]\n", - (s - sm->sessions), - format_time_interval, "h:m:s:u", - ctime, s->side[0].n_packets, - s->side[0].n_bytes, - format_time_interval, "h:m:s:u", - atime0, s->side[1].n_packets, - s->side[1].n_bytes, - format_time_interval, "h:m:s:u", - atime1); u8 * out1 = 0; - if (s->is_ip6) - { - out1 = - format (0, "%s %U :%u <-> %U :%u", - get_l4_proto_str (s->is_ip6, - s->l4_proto), - format_ip6_address, - &s->side[0].addr.ip6, - s->side[0].port, - format_ip6_address, - &s->side[1].addr.ip6, - s->side[1].port);} - else - { - out1 = - format (0, "%s %U :%u <-> %U :%u", - get_l4_proto_str (s->is_ip6, - s->l4_proto), - format_ip4_address, - &s->side[0].addr.ip4, - s->side[0].port, - format_ip4_address, - &s->side[1].addr.ip4, - s->side[1].port);} - vlib_cli_output (vm, "%s %s", out0, - out1); vec_free (out0); - vec_free (out1);} - )); - return 0; -} - -static clib_error_t * -l2sess_show_count_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - l2sess_main_t *sm = &l2sess_main; - - vlib_cli_output (vm, "Timing wheel info: \n%U", format_timing_wheel, - &sm->timing_wheel, 255); - vlib_cli_output (vm, "session pool len: %d, pool elts: %d", - pool_len (sm->sessions), pool_elts (sm->sessions)); - vlib_cli_output (vm, - "attempted to delete sessions which were already free: %d", - sm->counter_attempted_delete_free_session); - return 0; -} - - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (l2sess_show_command, static) = { - .path = "show l2sess", - .short_help = "show l2sess", - .function = l2sess_show_command_fn, -}; - -VLIB_CLI_COMMAND (l2sess_show_count_command, static) = { - .path = "show l2sess count", - .short_help = "show l2sess count", - .function = l2sess_show_count_command_fn, -}; -/* *INDENT-OFF* */ - -static inline u64 -time_sec_to_clock( clib_time_t *ct, f64 sec) -{ - return (u64)(((f64)sec)/ct->seconds_per_clock); -} - -static clib_error_t * l2sess_init (vlib_main_t * vm) -{ - l2sess_main_t * sm = &l2sess_main; - clib_error_t * error = 0; - u64 cpu_time_now = clib_cpu_time_now(); - - - clib_time_t *ct = &vm->clib_time; - sm->udp_session_idle_timeout = time_sec_to_clock(ct, UDP_SESSION_IDLE_TIMEOUT_SEC); - sm->tcp_session_idle_timeout = time_sec_to_clock(ct, TCP_SESSION_IDLE_TIMEOUT_SEC); - sm->tcp_session_transient_timeout = time_sec_to_clock(ct, TCP_SESSION_TRANSIENT_TIMEOUT_SEC); - - /* The min sched time of 10e-1 causes erroneous behavior... */ - sm->timing_wheel.min_sched_time = 10e-2; - sm->timing_wheel.max_sched_time = 3600.0*48.0; - timing_wheel_init (&sm->timing_wheel, cpu_time_now, vm->clib_time.clocks_per_second); - sm->timer_wheel_next_expiring_time = 0; - sm->timer_wheel_tick = time_sec_to_clock(ct, sm->timing_wheel.min_sched_time); - /* Pre-allocate expired nodes. */ - vec_alloc (sm->data_from_advancing_timing_wheel, 32); - - l2sess_setup_nodes(); - l2output_init_output_node_vec (&sm->output_next_nodes.output_node_index_vec); - - return error; -} - -VLIB_INIT_FUNCTION (l2sess_init); - - diff --git a/plugins/acl-plugin/acl/l2sess.h b/plugins/acl-plugin/acl/l2sess.h deleted file mode 100644 index db899917113..00000000000 --- a/plugins/acl-plugin/acl/l2sess.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __included_l2sess_h__ -#define __included_l2sess_h__ - -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/ethernet/ethernet.h> - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vppinfra/elog.h> -#include <vppinfra/timing_wheel.h> - -#include <vnet/l2/l2_output.h> -#include <vnet/l2/l2_input.h> - -#define _(node_name, node_var, is_out, is_ip6, is_track) -#undef _ -#define foreach_l2sess_node \ - _("aclp-l2s-input-ip4-add", l2sess_in_ip4_add, 0, 0, 0) \ - _("aclp-l2s-input-ip6-add", l2sess_in_ip6_add, 0, 1, 0) \ - _("aclp-l2s-output-ip4-add", l2sess_out_ip4_add, 1, 0, 0) \ - _("aclp-l2s-output-ip6-add", l2sess_out_ip6_add, 1, 1, 0) \ - _("aclp-l2s-input-ip4-track", l2sess_in_ip4_track, 0, 0, 1) \ - _("aclp-l2s-input-ip6-track", l2sess_in_ip6_track, 0, 1, 1) \ - _("aclp-l2s-output-ip4-track",l2sess_out_ip4_track, 1, 0, 1) \ - _("aclp-l2s-output-ip6-track", l2sess_out_ip6_track, 1, 1, 1) - -#define _(node_name, node_var, is_out, is_ip6, is_track) \ - extern vlib_node_registration_t node_var; -foreach_l2sess_node -#undef _ - -#define TCP_FLAG_FIN 0x01 -#define TCP_FLAG_SYN 0x02 -#define TCP_FLAG_RST 0x04 -#define TCP_FLAG_PUSH 0x08 -#define TCP_FLAG_ACK 0x10 -#define TCP_FLAG_URG 0x20 -#define TCP_FLAG_ECE 0x40 -#define TCP_FLAG_CWR 0x80 -#define TCP_FLAGS_RSTFINACKSYN (TCP_FLAG_RST + TCP_FLAG_FIN + TCP_FLAG_SYN + TCP_FLAG_ACK) -#define TCP_FLAGS_ACKSYN (TCP_FLAG_SYN + TCP_FLAG_ACK) - -typedef struct { - ip46_address_t addr; - u64 active_time; - u64 n_packets; - u64 n_bytes; - u16 port; -} l2s_session_side_t; - -enum { - L2S_SESSION_SIDE_IN = 0, - L2S_SESSION_SIDE_OUT, - L2S_N_SESSION_SIDES -}; - -typedef struct { - u64 create_time; - l2s_session_side_t side[L2S_N_SESSION_SIDES]; - u8 l4_proto; - u8 is_ip6; - u16 tcp_flags_seen; /* u16 because of two sides */ -} l2s_session_t; - -#define PROD -#ifdef PROD -#define UDP_SESSION_IDLE_TIMEOUT_SEC 600 -#define TCP_SESSION_IDLE_TIMEOUT_SEC (3600*24) -#define TCP_SESSION_TRANSIENT_TIMEOUT_SEC 120 -#else -#define UDP_SESSION_IDLE_TIMEOUT_SEC 15 -#define TCP_SESSION_IDLE_TIMEOUT_SEC 15 -#define TCP_SESSION_TRANSIENT_TIMEOUT_SEC 5 -#endif - -typedef struct { - /* - * the next two fields are present for all nodes, but - * only one of them is used per node - depending - * on whether the node is an input or output one. - */ -#define _(node_name, node_var, is_out, is_ip6, is_track) \ - u32 node_var ## _input_next_node_index[32]; \ - l2_output_next_nodes_st node_var ## _next_nodes; -foreach_l2sess_node -#undef _ - l2_output_next_nodes_st output_next_nodes; - - /* Next indices of the tracker nodes */ - u32 next_slot_track_node_by_is_ip6_is_out[2][2]; - - /* - * Pairing of "forward" and "reverse" tables by table index. - * Each relationship has two entries - for one and the other table, - * so it is bidirectional. - */ - - u32 *fwd_to_rev_by_table_index; - - /* - * The vector of per-interface session pools - */ - - l2s_session_t *sessions; - - /* The session timeouts */ - u64 tcp_session_transient_timeout; - u64 tcp_session_idle_timeout; - u64 udp_session_idle_timeout; - - /* Timing wheel to time out the idle sessions */ - timing_wheel_t timing_wheel; - u32 *data_from_advancing_timing_wheel; - u64 timer_wheel_next_expiring_time; - u64 timer_wheel_tick; - - /* convenience */ - vlib_main_t * vlib_main; - vnet_main_t * vnet_main; - ethernet_main_t * ethernet_main; - - /* Counter(s) */ - u64 counter_attempted_delete_free_session; -} l2sess_main_t; - -l2sess_main_t l2sess_main; - -/* Just exposed for acl.c */ - -void -l2sess_vlib_plugin_register (vlib_main_t * vm, void * hh, - int from_early_init); - - -#endif /* __included_l2sess_h__ */ diff --git a/plugins/acl-plugin/acl/l2sess_node.c b/plugins/acl-plugin/acl/l2sess_node.c deleted file mode 100644 index 520e5929b4b..00000000000 --- a/plugins/acl-plugin/acl/l2sess_node.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <netinet/in.h> -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> -#include <acl/l2sess.h> -#include <vnet/l2/l2_classify.h> - - -typedef struct -{ - u32 next_index; - u32 sw_if_index; - u32 trace_flags; - u32 session_tables[2]; - u32 session_nexts[2]; - u8 l4_proto; -} l2sess_trace_t; - -/* packet trace format function */ - -#define _(node_name, node_var, is_out, is_ip6, is_track) \ -static u8 * format_## node_var ##_trace (u8 * s, va_list * args) \ -{ \ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); \ - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); \ - l2sess_trace_t * t = va_arg (*args, l2sess_trace_t *); \ - \ - s = format (s, node_name ": sw_if_index %d, next index %d trace_flags %08x L4 proto %d\n" \ - " tables [ %d, %d ] nexts [ %d, %d ]", \ - t->sw_if_index, t->next_index, t->trace_flags, t->l4_proto, \ - t->session_tables[0], t->session_tables[1], \ - t->session_nexts[0], t->session_nexts[1]); \ - return s; \ -} -foreach_l2sess_node -#undef _ -#define foreach_l2sess_error \ -_(SWAPPED, "Mac swap packets processed") - typedef enum -{ -#define _(sym,str) L2SESS_ERROR_##sym, - foreach_l2sess_error -#undef _ - L2SESS_N_ERROR, -} l2sess_error_t; - -static char *l2sess_error_strings[] = { -#define _(sym,string) string, - foreach_l2sess_error -#undef _ -}; - -typedef enum -{ - L2SESS_NEXT_DROP, - L2SESS_N_NEXT, -} l2sess_next_t; - -u8 -l2sess_get_l4_proto (vlib_buffer_t * b0, int node_is_ip6) -{ - u8 proto; - int proto_offset; - if (node_is_ip6) - { - proto_offset = 20; - } - else - { - proto_offset = 23; - } - proto = *((u8 *) vlib_buffer_get_current (b0) + proto_offset); - return proto; -} - - -u8 -l2sess_get_tcp_flags (vlib_buffer_t * b0, int node_is_ip6) -{ - u8 flags; - int flags_offset; - if (node_is_ip6) - { - flags_offset = 14 + 40 + 13; /* FIXME: no extension headers assumed */ - } - else - { - flags_offset = 14 + 20 + 13; - } - flags = *((u8 *) vlib_buffer_get_current (b0) + flags_offset); - return flags; -} - -static inline int -l4_tcp_or_udp (u8 proto) -{ - return ((proto == 6) || (proto == 17)); -} - -void -l2sess_get_session_tables (l2sess_main_t * sm, u32 sw_if_index, - int node_is_out, int node_is_ip6, u8 l4_proto, - u32 * session_tables) -{ -/* - * Based on the direction, l3 and l4 protocol, fill a u32[2] array: - * [0] is index for the "direct match" path, [1] is for "mirrored match". - * Store the indices of the tables to add the session to in session_tables[] - */ - l2_output_classify_main_t *l2om = &l2_output_classify_main; - l2_input_classify_main_t *l2im = &l2_input_classify_main; - - u32 output_table_index; - u32 input_table_index; - - if (!l4_tcp_or_udp (l4_proto)) - { - return; - } - - if (node_is_ip6) - { - vec_validate_init_empty (l2im-> - classify_table_index_by_sw_if_index - [L2_INPUT_CLASSIFY_TABLE_IP6], sw_if_index, - ~0); - input_table_index = - l2im-> - classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP6] - [sw_if_index]; - vec_validate_init_empty (l2om-> - classify_table_index_by_sw_if_index - [L2_OUTPUT_CLASSIFY_TABLE_IP6], sw_if_index, - ~0); - output_table_index = - l2om-> - classify_table_index_by_sw_if_index[L2_OUTPUT_CLASSIFY_TABLE_IP6] - [sw_if_index]; - } - else - { - vec_validate_init_empty (l2im-> - classify_table_index_by_sw_if_index - [L2_INPUT_CLASSIFY_TABLE_IP4], sw_if_index, - ~0); - input_table_index = - l2im-> - classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP4] - [sw_if_index]; - vec_validate_init_empty (l2om-> - classify_table_index_by_sw_if_index - [L2_OUTPUT_CLASSIFY_TABLE_IP4], sw_if_index, - ~0); - output_table_index = - l2om-> - classify_table_index_by_sw_if_index[L2_OUTPUT_CLASSIFY_TABLE_IP4] - [sw_if_index]; - } - - if (node_is_out) - { - session_tables[0] = output_table_index; - session_tables[1] = input_table_index; - } - else - { - session_tables[0] = input_table_index; - session_tables[1] = output_table_index; - } -} - -void -l2sess_get_session_nexts (l2sess_main_t * sm, u32 sw_if_index, - int node_is_out, int node_is_ip6, u8 l4_proto, - u32 * session_nexts) -{ -/* - * Based on the direction, l3 and l4 protocol, fill a u32[2] array: - * [0] is the index for the "direct match" path, [1] is for "mirrored match". - * Store the match_next_index in session_nexts[] for a new session entry which is being added to session tables. - */ - u32 input_node_index; - u32 output_node_index; - - if (!l4_tcp_or_udp (l4_proto)) - { - return; - } - - input_node_index = - sm->next_slot_track_node_by_is_ip6_is_out[node_is_ip6][0]; - output_node_index = - sm->next_slot_track_node_by_is_ip6_is_out[node_is_ip6][1]; - - if (node_is_out) - { - session_nexts[0] = output_node_index; - session_nexts[1] = input_node_index; - } - else - { - session_nexts[0] = input_node_index; - session_nexts[1] = output_node_index; - } -} - - -static inline void -swap_bytes (vlib_buffer_t * b0, int off_a, int off_b, int nbytes) -{ - u8 tmp; - u8 *pa = vlib_buffer_get_current (b0) + off_a; - u8 *pb = vlib_buffer_get_current (b0) + off_b; - while (nbytes--) - { - tmp = *pa; - *pa++ = *pb; - *pb++ = tmp; - } -} - -/* - * This quite pro[bv]ably is a terrible idea performance wise. Moreso doing it twice. - * Would having a long (ish) chunk of memory work better for this ? - * We will see when we get to the performance of this. - */ -void -l2sess_flip_l3l4_fields (vlib_buffer_t * b0, int node_is_ip6, u8 l4_proto) -{ - if (!l4_tcp_or_udp (l4_proto)) - { - return; - } - if (node_is_ip6) - { - swap_bytes (b0, 22, 38, 16); /* L3 */ - swap_bytes (b0, 54, 56, 2); /* L4 (when no EH!) */ - } - else - { - swap_bytes (b0, 26, 30, 4); /* L3 */ - swap_bytes (b0, 34, 36, 2); /* L4 */ - } -} - -void -l2sess_add_session (vlib_buffer_t * b0, int node_is_out, int node_is_ip6, - u32 session_table, u32 session_match_next, - u32 opaque_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - u32 action = 0; - u32 metadata = 0; - -#ifdef DEBUG_SESSIONS - printf ("Adding session to table %d with next %d\n", session_table, - session_match_next); -#endif - vnet_classify_add_del_session (cm, session_table, - vlib_buffer_get_current (b0), - session_match_next, opaque_index, 0, action, - metadata, 1); -} - - - -static void * -get_ptr_to_offset (vlib_buffer_t * b0, int offset) -{ - u8 *p = vlib_buffer_get_current (b0) + offset; - return p; -} - - -/* - * FIXME: Hardcoded offsets are ugly, although if casting to structs one - * would need to take care about alignment.. So let's for now be naive and simple. - */ - -void -session_store_ip4_l3l4_info (vlib_buffer_t * b0, l2s_session_t * sess, - int node_is_out) -{ - clib_memcpy (&sess->side[1 - node_is_out].addr.ip4, - get_ptr_to_offset (b0, 26), 4); - clib_memcpy (&sess->side[node_is_out].addr.ip4, get_ptr_to_offset (b0, 30), - 4); - sess->side[1 - node_is_out].port = - ntohs (*(u16 *) get_ptr_to_offset (b0, 34)); - sess->side[node_is_out].port = ntohs (*(u16 *) get_ptr_to_offset (b0, 36)); -} - -void -session_store_ip6_l3l4_info (vlib_buffer_t * b0, l2s_session_t * sess, - int node_is_out) -{ - clib_memcpy (&sess->side[1 - node_is_out].addr.ip6, - get_ptr_to_offset (b0, 22), 16); - clib_memcpy (&sess->side[node_is_out].addr.ip4, get_ptr_to_offset (b0, 38), - 16); - sess->side[1 - node_is_out].port = - ntohs (*(u16 *) get_ptr_to_offset (b0, 54)); - sess->side[node_is_out].port = ntohs (*(u16 *) get_ptr_to_offset (b0, 56)); -} - -static void -build_match_from_session (l2sess_main_t * sm, u8 * match, - l2s_session_t * sess, int is_out) -{ - if (sess->is_ip6) - { - match[20] = sess->l4_proto; - clib_memcpy (&match[22], &sess->side[1 - is_out].addr.ip6, 16); - clib_memcpy (&match[38], &sess->side[is_out].addr.ip4, 16); - *(u16 *) & match[54] = htons (sess->side[1 - is_out].port); - *(u16 *) & match[56] = htons (sess->side[is_out].port); - } - else - { - match[23] = sess->l4_proto; - clib_memcpy (&match[26], &sess->side[1 - is_out].addr.ip6, 4); - clib_memcpy (&match[30], &sess->side[is_out].addr.ip4, 4); - *(u16 *) & match[34] = htons (sess->side[1 - is_out].port); - *(u16 *) & match[36] = htons (sess->side[is_out].port); - } -} - -static void -delete_session (l2sess_main_t * sm, u32 sw_if_index, u32 session_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - u8 match[5 * 16]; /* For building the mock of the packet to delete the classifier session */ - u32 session_tables[2] = { ~0, ~0 }; - l2s_session_t *sess = sm->sessions + session_index; - if (pool_is_free (sm->sessions, sess)) - { - sm->counter_attempted_delete_free_session++; - return; - } - l2sess_get_session_tables (sm, sw_if_index, 0, sess->is_ip6, sess->l4_proto, - session_tables); - if (session_tables[1] != ~0) - { - build_match_from_session (sm, match, sess, 1); - vnet_classify_add_del_session (cm, session_tables[1], match, 0, 0, 0, 0, - 0, 0); - } - if (session_tables[1] != ~0) - { - build_match_from_session (sm, match, sess, 1); - vnet_classify_add_del_session (cm, session_tables[1], match, 0, 0, 0, 0, - 0, 0); - } - pool_put (sm->sessions, sess); -} - -static void -udp_session_account_buffer (vlib_buffer_t * b0, l2s_session_t * s, - int which_side, u64 now) -{ - l2s_session_side_t *ss = &s->side[which_side]; - ss->active_time = now; - ss->n_packets++; - ss->n_bytes += b0->current_data + b0->current_length; -} - -static inline u64 -udp_session_get_timeout (l2sess_main_t * sm, l2s_session_t * sess, u64 now) -{ - return (sm->udp_session_idle_timeout); -} - -static void -tcp_session_account_buffer (vlib_buffer_t * b0, l2s_session_t * s, - int which_side, u64 now) -{ - l2s_session_side_t *ss = &s->side[which_side]; - ss->active_time = now; - ss->n_packets++; - ss->n_bytes += b0->current_data + b0->current_length; - /* Very very lightweight TCP state tracking: just record which flags were seen */ - s->tcp_flags_seen |= - l2sess_get_tcp_flags (b0, s->is_ip6) << (8 * which_side); -} - -/* - * Since we are tracking for the purposes of timing the sessions out, - * we mostly care about two states: established (maximize the idle timeouts) - * and transient (halfopen/halfclosed/reset) - we need to have a reasonably short timeout to - * quickly get rid of sessions but not short enough to violate the TCP specs. - */ - -static inline u64 -tcp_session_get_timeout (l2sess_main_t * sm, l2s_session_t * sess, u64 now) -{ - /* seen both SYNs and ACKs but not FINs means we are in establshed state */ - u16 masked_flags = - sess->tcp_flags_seen & ((TCP_FLAGS_RSTFINACKSYN << 8) + - TCP_FLAGS_RSTFINACKSYN); - if (((TCP_FLAGS_ACKSYN << 8) + TCP_FLAGS_ACKSYN) == masked_flags) - { - return (sm->tcp_session_idle_timeout); - } - else - { - return (sm->tcp_session_transient_timeout); - } -} - -static inline u64 -session_get_timeout (l2sess_main_t * sm, l2s_session_t * sess, u64 now) -{ - u64 timeout; - - switch (sess->l4_proto) - { - case 6: - timeout = tcp_session_get_timeout (sm, sess, now); - break; - case 17: - timeout = udp_session_get_timeout (sm, sess, now); - break; - default: - timeout = 0; - } - - return timeout; -} - -static inline u64 -get_session_last_active_time(l2s_session_t * sess) -{ - u64 last_active = - sess->side[0].active_time > - sess->side[1].active_time ? sess->side[0].active_time : sess->side[1]. - active_time; - return last_active; -} - -static int -session_is_alive (l2sess_main_t * sm, l2s_session_t * sess, u64 now, u64 *last_active_cache) -{ - u64 last_active = get_session_last_active_time(sess); - u64 timeout = session_get_timeout (sm, sess, now); - int is_alive = ((now - last_active) < timeout); - if (last_active_cache) - *last_active_cache = last_active; - return is_alive; -} - -static void -check_idle_sessions (l2sess_main_t * sm, u32 sw_if_index, u64 now) -{ - sm->timer_wheel_next_expiring_time = 0; - sm->data_from_advancing_timing_wheel - = - timing_wheel_advance (&sm->timing_wheel, now, - sm->data_from_advancing_timing_wheel, - &sm->timer_wheel_next_expiring_time); -#ifdef DEBUG_SESSIONS_VERBOSE - { - clib_time_t *ct = &sm->vlib_main->clib_time; - f64 ctime; - ctime = now * ct->seconds_per_clock; - clib_warning ("Now : %U", format_time_interval, "h:m:s:u", ctime); - ctime = sm->timer_wheel_next_expiring_time * ct->seconds_per_clock; - clib_warning ("Next expire: %U", format_time_interval, "h:m:s:u", ctime); - clib_warning ("Expired items: %d", - (int) vec_len (sm->data_from_advancing_timing_wheel)); - } -#endif - - sm->timer_wheel_next_expiring_time = now + sm->timer_wheel_tick; - if (PREDICT_FALSE ( 0 == sm->data_from_advancing_timing_wheel )) { - return; - } - - if (PREDICT_FALSE (_vec_len (sm->data_from_advancing_timing_wheel) > 0)) - { - uword i; - for (i = 0; i < _vec_len (sm->data_from_advancing_timing_wheel); i++) - { - u32 session_index = sm->data_from_advancing_timing_wheel[i]; - if (!pool_is_free_index (sm->sessions, session_index)) - { - l2s_session_t *sess = sm->sessions + session_index; - u64 last_active; - if (session_is_alive (sm, sess, now, &last_active)) - { -#ifdef DEBUG_SESSIONS - clib_warning ("Restarting timer for session %d", (int) session_index); -#endif - /* Pretend we did this in the past, at last_active moment */ - timing_wheel_insert (&sm->timing_wheel, - last_active + session_get_timeout (sm, sess, - last_active), - session_index); - } - else - { -#ifdef DEBUG_SESSIONS - clib_warning ("Deleting session %d", (int) session_index); -#endif - delete_session (sm, sw_if_index, session_index); - } - } - } - _vec_len (sm->data_from_advancing_timing_wheel) = 0; - } -} - -static uword -l2sess_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from, *to_next; - l2sess_next_t next_index; - u32 pkts_swapped = 0; - u32 cached_sw_if_index = (u32) ~ 0; - u32 cached_next_index = (u32) ~ 0; - u32 feature_bitmap0; - u32 trace_flags0; - - l2sess_main_t *sm = &l2sess_main; - - from = vlib_frame_vector_args (frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - - while (n_left_from > 0) - { - u32 n_left_to_next; - - vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); - - /* Only a single loop for now for simplicity */ - - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0; - vlib_buffer_t *b0; - u32 next0 = L2SESS_NEXT_DROP; - u32 sw_if_index0; - //ethernet_header_t *en0; - - /* speculatively enqueue b0 to the current next frame */ - bi0 = from[0]; - to_next[0] = bi0; - from += 1; - to_next += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - //en0 = vlib_buffer_get_current (b0); - -/* - * The non-boilerplate is in the block below. - * Note first a magic macro block that sets up the behavior qualifiers: - * node_is_out : 1 = is output, 0 = is input - * node_is_ip6 : 1 = is ip6, 0 = is ip4 - * node_is_track : 1 = is a state tracking node, 0 - is a session addition node - * - * Subsequently the code adjusts its behavior depending on these variables. - * It's most probably not great performance wise but much easier to work with. - * - */ - { - int node_is_out = -1; - CLIB_UNUSED (int node_is_ip6) = -1; - CLIB_UNUSED (int node_is_track) = -1; - u32 node_index = 0; - u32 session_tables[2] = { ~0, ~0 }; - u32 session_nexts[2] = { ~0, ~0 }; - l2_output_next_nodes_st *next_nodes = 0; - u32 *input_feat_next_node_index; - u8 l4_proto; - u64 now = clib_cpu_time_now (); - -/* - * Set the variables according to which of the 8 nodes we are. - * Hopefully the compiler is smart enough to eliminate the extraneous. - */ -#define _(node_name, node_var, is_out, is_ip6, is_track) \ -if(node_var.index == node->node_index) \ - { \ - node_is_out = is_out; \ - node_is_ip6 = is_ip6; \ - node_is_track = is_track; \ - node_index = node_var.index; \ - next_nodes = &sm->node_var ## _next_nodes; \ - input_feat_next_node_index = sm->node_var ## _input_next_node_index; \ - } - foreach_l2sess_node -#undef _ - trace_flags0 = 0; - if (node_is_out) - { - sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - } - else - { - sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - } - /* potentially also remove the nodes here */ - feature_bitmap0 = vnet_buffer (b0)->l2.feature_bitmap; - - if (node_is_track) - { - u32 sess_index = vnet_buffer (b0)->l2_classify.opaque_index; - l2s_session_t *sess = sm->sessions + sess_index; - l4_proto = sess->l4_proto; - - if (session_is_alive (sm, sess, now, 0)) - { - if (6 == l4_proto) - { - tcp_session_account_buffer (b0, sess, node_is_out, - now); - } - else - { - udp_session_account_buffer (b0, sess, node_is_out, - now); - } - } - else - { - timing_wheel_delete (&sm->timing_wheel, sess_index); - delete_session (sm, sw_if_index0, sess_index); - /* FIXME: drop the packet that hit the obsolete node, for now. We really ought to recycle it. */ - next0 = 0; - } - } - else - { - /* - * "-add" node: take l2opaque which arrived to us, and deduce - * the tables out of that. ~0 means the topmost classifier table - * applied for this AF on the RX(for input)/TX(for output)) sw_if_index. - * Also add the mirrored session to the paired table. - */ - l2s_session_t *sess; - u32 sess_index; - - l4_proto = l2sess_get_l4_proto (b0, node_is_ip6); - - pool_get (sm->sessions, sess); - sess_index = sess - sm->sessions; - sess->create_time = now; - sess->side[node_is_out].active_time = now; - sess->side[1 - node_is_out].active_time = now; - sess->l4_proto = l4_proto; - sess->is_ip6 = node_is_ip6; - if (node_is_ip6) - { - session_store_ip6_l3l4_info (b0, sess, node_is_out); - } - else - { - session_store_ip4_l3l4_info (b0, sess, node_is_out); - } - - l2sess_get_session_tables (sm, sw_if_index0, node_is_out, - node_is_ip6, l4_proto, - session_tables); - l2sess_get_session_nexts (sm, sw_if_index0, node_is_out, - node_is_ip6, l4_proto, - session_nexts); - l2sess_flip_l3l4_fields (b0, node_is_ip6, l4_proto); - if (session_tables[1] != ~0) - { - l2sess_add_session (b0, node_is_out, node_is_ip6, - session_tables[1], session_nexts[1], - sess_index); - } - l2sess_flip_l3l4_fields (b0, node_is_ip6, l4_proto); - if (session_tables[0] != ~0) - { - l2sess_add_session (b0, node_is_out, node_is_ip6, - session_tables[0], session_nexts[0], - sess_index); - } - if (6 == sess->l4_proto) - { - tcp_session_account_buffer (b0, sess, node_is_out, now); - } - else - { - udp_session_account_buffer (b0, sess, node_is_out, now); - } - timing_wheel_insert (&sm->timing_wheel, - now + session_get_timeout (sm, sess, - now), - sess_index); - } - - if (now >= sm->timer_wheel_next_expiring_time) - { - check_idle_sessions (sm, sw_if_index0, now); - } - - if (node_is_out) - { - if (feature_bitmap0) - { - trace_flags0 |= 0x10; - } - if (sw_if_index0 == cached_sw_if_index) - { - trace_flags0 |= 0x20; - } - l2_output_dispatch (sm->vlib_main, - sm->vnet_main, - node, - node_index, - &cached_sw_if_index, - &cached_next_index, - next_nodes, - b0, sw_if_index0, feature_bitmap0, - &next0); - trace_flags0 |= 2; - - } - else - { - next0 = - feat_bitmap_get_next_node_index (input_feat_next_node_index, - feature_bitmap0); - trace_flags0 |= 4; - - } - - - - if (next0 >= node->n_next_nodes) - { - trace_flags0 |= 1; - } - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - l2sess_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->sw_if_index = sw_if_index0; - t->next_index = next0; - t->trace_flags = trace_flags0; - t->l4_proto = l4_proto; - t->session_tables[0] = session_tables[0]; - t->session_tables[1] = session_tables[1]; - t->session_nexts[0] = session_nexts[0]; - t->session_nexts[1] = session_nexts[1]; - } - - } - pkts_swapped += 1; - if (next0 >= node->n_next_nodes) - { - next0 = 0; - } - - /* verify speculative enqueue, maybe switch current next frame */ - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, - bi0, next0); - } - - vlib_put_next_frame (vm, node, next_index, n_left_to_next); - } - vlib_node_increment_counter (vm, node->node_index, - L2SESS_ERROR_SWAPPED, pkts_swapped); - return frame->n_vectors; -} - - -#define _(node_name, node_var, is_out, is_ip6, is_track) \ -static uword \ -node_var ## node_fn (vlib_main_t * vm, \ - vlib_node_runtime_t * node, \ - vlib_frame_t * frame) \ -{ \ - return l2sess_node_fn(vm, node, frame); \ -} \ -VLIB_REGISTER_NODE (node_var) = { \ - .function = node_var ## node_fn, \ - .name = node_name, \ - .vector_size = sizeof (u32), \ - .format_trace = format_ ## node_var ## _trace, \ - .type = VLIB_NODE_TYPE_INTERNAL, \ - \ - .n_errors = ARRAY_LEN(l2sess_error_strings), \ - .error_strings = l2sess_error_strings, \ - \ - .n_next_nodes = L2SESS_N_NEXT, \ - .next_nodes = { \ - [L2SESS_NEXT_DROP] = "error-drop", \ - }, \ -}; -foreach_l2sess_node -#undef _ diff --git a/plugins/acl-plugin/acl/node_in.c b/plugins/acl-plugin/acl/node_in.c deleted file mode 100644 index 2a5199a9ab8..00000000000 --- a/plugins/acl-plugin/acl/node_in.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> -#include <acl/acl.h> -#include "node_in.h" - -typedef struct -{ - u32 next_index; - u32 sw_if_index; - u32 match_acl_index; - u32 match_rule_index; - u32 trace_bitmap; -} acl_in_trace_t; - -/* packet trace format function */ -static u8 * -format_acl_in_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - acl_in_trace_t *t = va_arg (*args, acl_in_trace_t *); - - s = - format (s, - "ACL_IN: sw_if_index %d, next index %d, match: inacl %d rule %d trace_bits %08x", - t->sw_if_index, t->next_index, t->match_acl_index, - t->match_rule_index, t->trace_bitmap); - return s; -} - -vlib_node_registration_t acl_in_node; - -#define foreach_acl_in_error \ -_(ACL_CHECK, "InACL check packets processed") - -typedef enum -{ -#define _(sym,str) ACL_IN_ERROR_##sym, - foreach_acl_in_error -#undef _ - ACL_IN_N_ERROR, -} acl_in_error_t; - -static char *acl_in_error_strings[] = { -#define _(sym,string) string, - foreach_acl_in_error -#undef _ -}; - -static uword -acl_in_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from, *to_next; - acl_in_next_t next_index; - u32 pkts_acl_checked = 0; - u32 feature_bitmap0; - u32 trace_bitmap = 0; - u32 *input_feat_next_node_index = - acl_main.acl_in_node_input_next_node_index; - - from = vlib_frame_vector_args (frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - - while (n_left_from > 0) - { - u32 n_left_to_next; - - vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); - - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0; - vlib_buffer_t *b0; - u32 next0 = ~0; - u32 sw_if_index0; - u32 next = ~0; - u32 match_acl_index = ~0; - u32 match_rule_index = ~0; - - /* speculatively enqueue b0 to the current next frame */ - bi0 = from[0]; - to_next[0] = bi0; - from += 1; - to_next += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - - - sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - feature_bitmap0 = vnet_buffer (b0)->l2.feature_bitmap; - - input_acl_packet_match (sw_if_index0, b0, &next, &match_acl_index, - &match_rule_index, &trace_bitmap); - if (next != ~0) - { - next0 = next; - } - if (next0 == ~0) - { - next0 = - feat_bitmap_get_next_node_index (input_feat_next_node_index, - feature_bitmap0); - } - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - acl_in_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); - t->sw_if_index = sw_if_index0; - t->next_index = next0; - t->match_acl_index = match_acl_index; - t->match_rule_index = match_rule_index; - t->trace_bitmap = trace_bitmap; - } - - next0 = next0 < node->n_next_nodes ? next0 : 0; - - pkts_acl_checked += 1; - - /* verify speculative enqueue, maybe switch current next frame */ - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, - bi0, next0); - } - - vlib_put_next_frame (vm, node, next_index, n_left_to_next); - } - - vlib_node_increment_counter (vm, acl_in_node.index, - ACL_IN_ERROR_ACL_CHECK, pkts_acl_checked); - return frame->n_vectors; -} - -VLIB_REGISTER_NODE (acl_in_node) = -{ - .function = acl_in_node_fn,.name = "acl-plugin-in",.vector_size = - sizeof (u32),.format_trace = format_acl_in_trace,.type = - VLIB_NODE_TYPE_INTERNAL,.n_errors = - ARRAY_LEN (acl_in_error_strings),.error_strings = - acl_in_error_strings,.n_next_nodes = ACL_IN_N_NEXT, - /* edit / add dispositions here */ - .next_nodes = - { - [ACL_IN_ERROR_DROP] = "error-drop", - [ACL_IN_ETHERNET_INPUT] = "ethernet-input", - [ACL_IN_L2S_INPUT_IP4_ADD] = "aclp-l2s-input-ip4-add", - [ACL_IN_L2S_INPUT_IP6_ADD] = "aclp-l2s-input-ip6-add",} -,}; diff --git a/plugins/acl-plugin/acl/node_in.h b/plugins/acl-plugin/acl/node_in.h deleted file mode 100644 index 502bbf8dd1d..00000000000 --- a/plugins/acl-plugin/acl/node_in.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _NODE_IN_H_ -#define _NODE_IN_H_ - -typedef enum { - ACL_IN_ERROR_DROP, - ACL_IN_ETHERNET_INPUT, - ACL_IN_L2S_INPUT_IP4_ADD, - ACL_IN_L2S_INPUT_IP6_ADD, - ACL_IN_N_NEXT, -} acl_in_next_t; - -#endif diff --git a/plugins/acl-plugin/acl/node_out.c b/plugins/acl-plugin/acl/node_out.c deleted file mode 100644 index 50af3679b6e..00000000000 --- a/plugins/acl-plugin/acl/node_out.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> -#include <acl/acl.h> - -#include "node_out.h" - -typedef struct -{ - u32 next_index; - u32 sw_if_index; - u32 match_acl_index; - u32 match_rule_index; - u32 trace_bitmap; -} acl_out_trace_t; - -/* packet trace format function */ -static u8 * -format_acl_out_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - acl_out_trace_t *t = va_arg (*args, acl_out_trace_t *); - s = - format (s, - "ACL_OUT: sw_if_index %d, next index %d, match: outacl %d rule %d trace_bits %08x", - t->sw_if_index, t->next_index, t->match_acl_index, - t->match_rule_index, t->trace_bitmap); - return s; -} - -vlib_node_registration_t acl_out_node; - -#define foreach_acl_out_error \ -_(ACL_CHECK, "OutACL check packets processed") - -typedef enum -{ -#define _(sym,str) ACL_OUT_ERROR_##sym, - foreach_acl_out_error -#undef _ - ACL_OUT_N_ERROR, -} acl_out_error_t; - -static char *acl_out_error_strings[] = { -#define _(sym,string) string, - foreach_acl_out_error -#undef _ -}; - -static uword -acl_out_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - acl_main_t *am = &acl_main; - l2_output_next_nodes_st *next_nodes = &am->acl_out_output_next_nodes; - u32 n_left_from, *from, *to_next; - acl_out_next_t next_index; - u32 pkts_acl_checked = 0; - u32 feature_bitmap0; - u32 cached_sw_if_index = (u32) ~ 0; - u32 cached_next_index = (u32) ~ 0; - u32 match_acl_index = ~0; - u32 match_rule_index = ~0; - u32 trace_bitmap = 0; - - from = vlib_frame_vector_args (frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - - while (n_left_from > 0) - { - u32 n_left_to_next; - - vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); - - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0; - vlib_buffer_t *b0; - u32 next0 = ~0; - u32 next = 0; - u32 sw_if_index0; - - /* speculatively enqueue b0 to the current next frame */ - bi0 = from[0]; - to_next[0] = bi0; - from += 1; - to_next += 1; - n_left_from -= 1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - - - sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - feature_bitmap0 = vnet_buffer (b0)->l2.feature_bitmap; - - output_acl_packet_match (sw_if_index0, b0, &next, &match_acl_index, - &match_rule_index, &trace_bitmap); - if (next != ~0) - { - next0 = next; - } - if (next0 == ~0) - { - l2_output_dispatch (vm, - am->vnet_main, - node, - acl_out_node.index, - &cached_sw_if_index, - &cached_next_index, - next_nodes, - b0, sw_if_index0, feature_bitmap0, &next0); - } - - - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - acl_out_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); - t->sw_if_index = sw_if_index0; - t->next_index = next0; - t->match_acl_index = match_acl_index; - t->match_rule_index = match_rule_index; - t->trace_bitmap = trace_bitmap; - } - - pkts_acl_checked += 1; - - /* verify speculative enqueue, maybe switch current next frame */ - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, - to_next, n_left_to_next, - bi0, next0); - } - - vlib_put_next_frame (vm, node, next_index, n_left_to_next); - } - - vlib_node_increment_counter (vm, acl_out_node.index, - ACL_OUT_ERROR_ACL_CHECK, pkts_acl_checked); - return frame->n_vectors; -} - -VLIB_REGISTER_NODE (acl_out_node) = -{ - .function = acl_out_node_fn,.name = "acl-plugin-out",.vector_size = - sizeof (u32),.format_trace = format_acl_out_trace,.type = - VLIB_NODE_TYPE_INTERNAL,.n_errors = - ARRAY_LEN (acl_out_error_strings),.error_strings = - acl_out_error_strings,.n_next_nodes = ACL_OUT_N_NEXT, - /* edit / add dispositions here */ - .next_nodes = - { - [ACL_OUT_ERROR_DROP] = "error-drop", - [ACL_OUT_INTERFACE_OUTPUT] = "interface-output", - [ACL_OUT_L2S_OUTPUT_IP4_ADD] = "aclp-l2s-output-ip4-add", - [ACL_OUT_L2S_OUTPUT_IP6_ADD] = "aclp-l2s-output-ip6-add",} -,}; diff --git a/plugins/acl-plugin/acl/node_out.h b/plugins/acl-plugin/acl/node_out.h deleted file mode 100644 index c919f3b701c..00000000000 --- a/plugins/acl-plugin/acl/node_out.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _NODE_OUT_H_ -#define _NODE_OUT_H_ - -typedef enum { - ACL_OUT_ERROR_DROP, - ACL_OUT_INTERFACE_OUTPUT, - ACL_OUT_L2S_OUTPUT_IP4_ADD, - ACL_OUT_L2S_OUTPUT_IP6_ADD, - ACL_OUT_N_NEXT, -} acl_out_next_t; - -#endif |