diff options
author | Damjan Marion <damarion@cisco.com> | 2016-12-19 23:05:39 +0100 |
---|---|---|
committer | Damjan Marion <damarion@cisco.com> | 2016-12-28 12:25:14 +0100 |
commit | 7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 (patch) | |
tree | 5de62f8dbd3a752f5a676ca600e43d2652d1ff1a /plugins | |
parent | 696f1adec0df3b8f161862566dd9c86174302658 (diff) |
Reorganize source tree to use single autotools instance
Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'plugins')
25 files changed, 0 insertions, 4552 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 100f089e0fe..a101e47f5d7 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -28,10 +28,6 @@ if ENABLE_sample_PLUGIN SUBDIRS += sample-plugin endif -if ENABLE_sixrd_PLUGIN -SUBDIRS += sixrd-plugin -endif - if ENABLE_ioam_PLUGIN SUBDIRS += ioam-plugin endif @@ -44,18 +40,10 @@ if ENABLE_snat_PLUGIN SUBDIRS += snat-plugin endif -if ENABLE_ila_PLUGIN -SUBDIRS += ila-plugin -endif - if ENABLE_lb_PLUGIN SUBDIRS += lb-plugin endif -if ENABLE_flowperpkt_PLUGIN -SUBDIRS += flowperpkt-plugin -endif - if ENABLE_acl_PLUGIN SUBDIRS += acl-plugin endif diff --git a/plugins/configure.ac b/plugins/configure.ac index 6e7d5b8ad1e..9c631634ff6 100644 --- a/plugins/configure.ac +++ b/plugins/configure.ac @@ -53,12 +53,9 @@ AM_CONDITIONAL(ENABLE_$1_PLUGIN, test "$enable_the_plugin" = "1") # SUBDIRS += new-plugin # endif -PLUGIN_ENABLED(sixrd) PLUGIN_ENABLED(ioam) PLUGIN_ENABLED(snat) -PLUGIN_ENABLED(ila) PLUGIN_ENABLED(lb) -PLUGIN_ENABLED(flowperpkt) PLUGIN_ENABLED(acl) # Disabled plugins, require --enable-XXX-plugin diff --git a/plugins/flowperpkt-plugin/Makefile.am b/plugins/flowperpkt-plugin/Makefile.am deleted file mode 100644 index 9354e26faa2..00000000000 --- a/plugins/flowperpkt-plugin/Makefile.am +++ /dev/null @@ -1,64 +0,0 @@ - -# Copyright (c) <current-year> <your-organization> -# 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. - -AUTOMAKE_OPTIONS = foreign subdir-objects - -AM_CFLAGS = -Wall -AM_LDFLAGS = -module -shared -avoid-version - -vppapitestpluginsdir = ${libdir}/vpp_api_test_plugins -vpppluginsdir = ${libdir}/vpp_plugins - -vppplugins_LTLIBRARIES = flowperpkt_plugin.la -vppapitestplugins_LTLIBRARIES = flowperpkt_test_plugin.la - -flowperpkt_plugin_la_SOURCES = flowperpkt/flowperpkt.c \ - flowperpkt/l2_node.c \ - flowperpkt/node.c \ - flowperpkt/flowperpkt_plugin.api.h -flowperpkt_plugin_la_LDFLAGS = -module - -BUILT_SOURCES = \ - flowperpkt/flowperpkt.api.h \ - flowperpkt/flowperpkt.api.json - -SUFFIXES = .api.h .api .api.json - -%.api.h: %.api - mkdir -p `dirname $@` ; \ - $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ - | vppapigen --input - --output $@ --show-name $@ - -%.api.json: %.api - @echo " JSON APIGEN " $@ ; \ - mkdir -p `dirname $@` ; \ - $(CC) $(CPPFLAGS) -E -P -C -x c $^ \ - | vppapigen --input - --json $@ - -apidir = $(prefix)/flowperpkt/ -api_DATA = flowperpkt/flowperpkt.api.json - -noinst_HEADERS = \ - flowperpkt/flowperpkt_all_api_h.h \ - flowperpkt/flowperpkt_msg_enum.h \ - flowperpkt/flowperpkt.api.h - -flowperpkt_test_plugin_la_SOURCES = \ - flowperpkt/flowperpkt_test.c flowperpkt/flowperpkt_plugin.api.h - -# Remove *.la files -install-data-hook: - @(cd $(vpppluginsdir) && $(RM) $(vppplugins_LTLIBRARIES)) - @(cd $(vppapitestpluginsdir) && $(RM) $(vppapitestplugins_LTLIBRARIES)) - diff --git a/plugins/flowperpkt-plugin/configure.ac b/plugins/flowperpkt-plugin/configure.ac deleted file mode 100644 index 80546169efd..00000000000 --- a/plugins/flowperpkt-plugin/configure.ac +++ /dev/null @@ -1,9 +0,0 @@ - -AC_INIT(flowperpkt_plugin, 1.0) -AM_INIT_AUTOMAKE -AM_SILENT_RULES([yes]) - -AC_PROG_LIBTOOL -AC_PROG_CC - -AC_OUTPUT([Makefile]) diff --git a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.api b/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.api deleted file mode 100644 index fa878f21ed3..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.api +++ /dev/null @@ -1,42 +0,0 @@ -/* Define a simple enable-disable binary API to control the feature */ - -/** \file - This file defines the vpp control-plane API messages - used to control the flowperpkt plugin -*/ - -/** \brief Enable / disable per-packet IPFIX recording on an interface - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add address if non-zero, else delete - @param is_ipv6 - if non-zero the address is ipv6, else ipv4 - @param sw_if_index - index of the interface -*/ -manual_print define flowperpkt_tx_interface_add_del -{ - /* Client identifier, set from api_main.my_client_index */ - u32 client_index; - - /* Arbitrary context, so client can match reply to request */ - u32 context; - - /* Enable / disable the feature */ - u8 is_add; - u8 which; /* 0 = ipv4, 1 = l2, 2 = ipv6 (not yet implemented) */ - - /* Interface handle */ - u32 sw_if_index; -}; - -/** \brief Reply to enable/disable per-packet IPFIX recording messages - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define flowperpkt_tx_interface_add_del_reply -{ - /* From the request */ - u32 context; - - /* Return value, zero means all OK */ - i32 retval; -}; diff --git a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.c b/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.c deleted file mode 100644 index fb71d5b0ffc..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * flowperpkt.c - per-packet data capture flow report plugin - * - * Copyright (c) <current-year> <your-organization> - * 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 - * @brief Per-packet IPFIX flow record generator plugin - * - * This file implements vpp plugin registration mechanics, - * debug CLI, and binary API handling. - */ - -#include <vnet/vnet.h> -#include <vnet/plugin/plugin.h> -#include <flowperpkt/flowperpkt.h> - -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vlibsocket/api.h> - -/* define message IDs */ -#include <flowperpkt/flowperpkt_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_typedefs - -/* define generated endian-swappers */ -#define vl_endianfun -#include <flowperpkt/flowperpkt_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 <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_printfun - -flowperpkt_main_t flowperpkt_main; - -/* Get the API version number */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_api_version - -/* Define the per-interface configurable features */ -/* *INDENT-OFF* */ -VNET_FEATURE_INIT (flow_perpacket_ipv4, static) = -{ - .arc_name = "ip4-output", - .node_name = "flowperpkt-ipv4", - .runs_before = VNET_FEATURES ("interface-output"), -}; - -VNET_FEATURE_INIT (flow_perpacket_l2, static) = -{ - .arc_name = "interface-output", - .node_name = "flowperpkt-l2", - .runs_before = VNET_FEATURES ("interface-tx"), -}; -/* *INDENT-ON* */ - -/* - * 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)+fm->msg_id_base); \ - rmp->context = mp->context; \ - rmp->retval = ntohl(rv); \ - \ - vl_msg_api_send_shmem (q, (u8 *)&rmp); \ -} while(0); - -/* Macro to finish up custom dump fns */ -#define FINISH \ - vec_add1 (s, 0); \ - vl_print (handle, (char *)s); \ - vec_free (s); \ - return handle; - -#define VALIDATE_SW_IF_INDEX(mp) \ - do { u32 __sw_if_index = ntohl(mp->sw_if_index); \ - vnet_main_t *__vnm = vnet_get_main(); \ - if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \ - __sw_if_index)) { \ - rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \ - goto bad_sw_if_index; \ - } \ -} while(0); - -#define BAD_SW_IF_INDEX_LABEL \ -do { \ -bad_sw_if_index: \ - ; \ -} while (0); - -/** - * @brief Create an IPFIX template packet rewrite string - * @param frm flow_report_main_t * - * @param fr flow_report_t * - * @param collector_address ip4_address_t * the IPFIX collector address - * @param src_address ip4_address_t * the source address we should use - * @param collector_port u16 the collector port we should use, host byte order - * @returns u8 * vector containing the indicated IPFIX template packet - */ -static inline u8 * -flowperpkt_template_rewrite_inline (flow_report_main_t * frm, - flow_report_t * fr, - ip4_address_t * collector_address, - ip4_address_t * src_address, - u16 collector_port, int variant) -{ - ip4_header_t *ip; - udp_header_t *udp; - ipfix_message_header_t *h; - ipfix_set_header_t *s; - ipfix_template_header_t *t; - ipfix_field_specifier_t *f; - ipfix_field_specifier_t *first_field; - u8 *rewrite = 0; - ip4_ipfix_template_packet_t *tp; - u32 field_count = 0; - flow_report_stream_t *stream; - flowperpkt_main_t *fm = &flowperpkt_main; - - stream = &frm->streams[fr->stream_index]; - - if (variant == FLOW_VARIANT_IPV4) - { - /* - * ip4 Supported Fields: - * - * ingressInterface, TLV type 10, u32 - * egressInterface, TLV type 14, u32 - * sourceIpv4Address, TLV type 8, u32 - * destinationIPv4Address, TLV type 12, u32 - * ipClassOfService, TLV type 5, u8 - * flowStartNanoseconds, TLV type 156, dateTimeNanoseconds (f64) - * Implementation: f64 nanoseconds since VPP started - * warning: wireshark doesn't really understand this TLV - * dataLinkFrameSize, TLV type 312, u16 - * warning: wireshark doesn't understand this TLV at all - */ - - /* Currently 7 fields */ - field_count += 7; - - /* allocate rewrite space */ - vec_validate_aligned - (rewrite, - sizeof (ip4_ipfix_template_packet_t) - + field_count * sizeof (ipfix_field_specifier_t) - 1, - CLIB_CACHE_LINE_BYTES); - } - else if (variant == FLOW_VARIANT_L2) - { - /* - * L2 Supported Fields: - * - * ingressInterface, TLV type 10, u32 - * egressInterface, TLV type 14, u32 - * sourceMacAddress, TLV type 56, u8[6] we hope - * destinationMacAddress, TLV type 57, u8[6] we hope - * ethernetType, TLV type 256, u16 - * flowStartNanoseconds, TLV type 156, dateTimeNanoseconds (f64) - * Implementation: f64 nanoseconds since VPP started - * warning: wireshark doesn't really understand this TLV - * dataLinkFrameSize, TLV type 312, u16 - * warning: wireshark doesn't understand this TLV at all - */ - - /* Currently 7 fields */ - field_count += 7; - - /* allocate rewrite space */ - vec_validate_aligned - (rewrite, - sizeof (ip4_ipfix_template_packet_t) - + field_count * sizeof (ipfix_field_specifier_t) - 1, - CLIB_CACHE_LINE_BYTES); - } - - tp = (ip4_ipfix_template_packet_t *) rewrite; - ip = (ip4_header_t *) & tp->ip4; - udp = (udp_header_t *) (ip + 1); - h = (ipfix_message_header_t *) (udp + 1); - s = (ipfix_set_header_t *) (h + 1); - t = (ipfix_template_header_t *) (s + 1); - first_field = f = (ipfix_field_specifier_t *) (t + 1); - - ip->ip_version_and_header_length = 0x45; - ip->ttl = 254; - ip->protocol = IP_PROTOCOL_UDP; - ip->src_address.as_u32 = src_address->as_u32; - ip->dst_address.as_u32 = collector_address->as_u32; - udp->src_port = clib_host_to_net_u16 (stream->src_port); - udp->dst_port = clib_host_to_net_u16 (collector_port); - udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip)); - - /* FIXUP: message header export_time */ - /* FIXUP: message header sequence_number */ - h->domain_id = clib_host_to_net_u32 (stream->domain_id); - - /* Add TLVs to the template */ - if (variant == FLOW_VARIANT_IPV4) - { - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , ingressInterface, - 4); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , egressInterface, - 4); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , sourceIPv4Address, - 4); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , destinationIPv4Address, 4); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , ipClassOfService, - 1); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , flowStartNanoseconds, - 8); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , dataLinkFrameSize, - 2); - f++; - } - else if (variant == FLOW_VARIANT_L2) - { - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , ingressInterface, - 4); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , egressInterface, - 4); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , sourceMacAddress, - 6); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , destinationMacAddress, 6); - f++; - f->e_id_length = ipfix_e_id_length (0 /* enterprise */ , ethernetType, - 2); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , flowStartNanoseconds, - 8); - f++; - f->e_id_length = - ipfix_e_id_length (0 /* enterprise */ , dataLinkFrameSize, - 2); - f++; - } - - /* Extend in the obvious way, right here... */ - - /* Back to the template packet... */ - ip = (ip4_header_t *) & tp->ip4; - udp = (udp_header_t *) (ip + 1); - - ASSERT (f - first_field); - /* Field count in this template */ - t->id_count = ipfix_id_count (fr->template_id, f - first_field); - - if (variant == FLOW_VARIANT_IPV4) - fm->ipv4_report_id = fr->template_id; - else if (variant == FLOW_VARIANT_L2) - fm->l2_report_id = fr->template_id; - - /* set length in octets */ - s->set_id_length = - ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s); - - /* message length in octets */ - h->version_length = version_length ((u8 *) f - (u8 *) h); - - ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip); - ip->checksum = ip4_header_checksum (ip); - - return rewrite; -} - -u8 * -flowperpkt_template_rewrite_ipv4 (flow_report_main_t * frm, - flow_report_t * fr, - ip4_address_t * collector_address, - ip4_address_t * src_address, - u16 collector_port) -{ - return flowperpkt_template_rewrite_inline - (frm, fr, collector_address, src_address, collector_port, - FLOW_VARIANT_IPV4); -} - -u8 * -flowperpkt_template_rewrite_l2 (flow_report_main_t * frm, - flow_report_t * fr, - ip4_address_t * collector_address, - ip4_address_t * src_address, - u16 collector_port) -{ - return flowperpkt_template_rewrite_inline - (frm, fr, collector_address, src_address, collector_port, - FLOW_VARIANT_L2); -} - - -/** - * @brief Flush accumulated data - * @param frm flow_report_main_t * - * @param fr flow_report_t * - * @param f vlib_frame_t * - * - * <em>Notes:</em> - * This function must simply return the incoming frame, or no template packets - * will be sent. - */ -vlib_frame_t * -flowperpkt_data_callback_ipv4 (flow_report_main_t * frm, - flow_report_t * fr, - vlib_frame_t * f, u32 * to_next, - u32 node_index) -{ - flowperpkt_flush_callback_ipv4 (); - return f; -} - -vlib_frame_t * -flowperpkt_data_callback_l2 (flow_report_main_t * frm, - flow_report_t * fr, - vlib_frame_t * f, u32 * to_next, u32 node_index) -{ - flowperpkt_flush_callback_l2 (); - return f; -} - -/** - * @brief configure / deconfigure the IPFIX flow-per-packet - * @param fm flowperpkt_main_t * fm - * @param sw_if_index u32 the desired interface - * @param is_add int 1 to enable the feature, 0 to disable it - * @returns 0 if successful, non-zero otherwise - */ - -static int flowperpkt_tx_interface_add_del_feature - (flowperpkt_main_t * fm, u32 sw_if_index, int which, int is_add) -{ - flow_report_main_t *frm = &flow_report_main; - vnet_flow_report_add_del_args_t _a, *a = &_a; - int rv; - - if (which == FLOW_VARIANT_IPV4 && !fm->ipv4_report_created) - { - memset (a, 0, sizeof (*a)); - a->rewrite_callback = flowperpkt_template_rewrite_ipv4; - a->flow_data_callback = flowperpkt_data_callback_ipv4; - a->is_add = 1; - a->domain_id = 1; /*$$$$ config parameter */ - a->src_port = 4739; /*$$$$ config parameter */ - fm->ipv4_report_created = 1; - - rv = vnet_flow_report_add_del (frm, a); - if (rv) - { - clib_warning ("vnet_flow_report_add_del returned %d", rv); - return -1; - } - } - else if (which == FLOW_VARIANT_L2 && !fm->l2_report_created) - { - memset (a, 0, sizeof (*a)); - a->rewrite_callback = flowperpkt_template_rewrite_l2; - a->flow_data_callback = flowperpkt_data_callback_l2; - a->is_add = 1; - a->domain_id = 1; /*$$$$ config parameter */ - a->src_port = 4739; /*$$$$ config parameter */ - fm->l2_report_created = 1; - - rv = vnet_flow_report_add_del (frm, a); - if (rv) - { - clib_warning ("vnet_flow_report_add_del returned %d", rv); - return -1; - } - } - - if (which == FLOW_VARIANT_IPV4) - vnet_feature_enable_disable ("ip4-output", "flowperpkt-ipv4", - sw_if_index, is_add, 0, 0); - else if (which == FLOW_VARIANT_L2) - vnet_feature_enable_disable ("interface-output", "flowperpkt-l2", - sw_if_index, is_add, 0, 0); - - return 0; -} - -/** - * @brief API message handler - * @param mp vl_api_flowperpkt_tx_interface_add_del_t * mp the api message - */ -void vl_api_flowperpkt_tx_interface_add_del_t_handler - (vl_api_flowperpkt_tx_interface_add_del_t * mp) -{ - flowperpkt_main_t *fm = &flowperpkt_main; - vl_api_flowperpkt_tx_interface_add_del_reply_t *rmp; - u32 sw_if_index = ntohl (mp->sw_if_index); - int rv = 0; - - VALIDATE_SW_IF_INDEX (mp); - - if (mp->which != FLOW_VARIANT_IPV4 && mp->which != FLOW_VARIANT_L2) - { - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - - rv = flowperpkt_tx_interface_add_del_feature (fm, sw_if_index, mp->which, - mp->is_add); -out: - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_FLOWPERPKT_TX_INTERFACE_ADD_DEL_REPLY); -} - -/** - * @brief API message custom-dump function - * @param mp vl_api_flowperpkt_tx_interface_add_del_t * mp the api message - * @param handle void * print function handle - * @returns u8 * output string - */ -static void *vl_api_flowperpkt_tx_interface_add_del_t_print - (vl_api_flowperpkt_tx_interface_add_del_t * mp, void *handle) -{ - u8 *s; - - s = format (0, "SCRIPT: flowperpkt_tx_interface_add_del "); - s = format (s, "sw_if_index %d is_add %d which %d ", - clib_host_to_net_u32 (mp->sw_if_index), - (int) mp->is_add, (int) mp->which); - FINISH; -} - -/* List of message types that this plugin understands */ -#define foreach_flowperpkt_plugin_api_msg \ -_(FLOWPERPKT_TX_INTERFACE_ADD_DEL, flowperpkt_tx_interface_add_del) - -/** - * @brief plugin-api required function - * @param vm vlib_main_t * vlib main data structure pointer - * @param h vlib_plugin_handoff_t * handoff structure - * @param from_early_init int notused - * - * <em>Notes:</em> - * 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) -{ - flowperpkt_main_t *fm = &flowperpkt_main; - clib_error_t *error = 0; - - fm->vlib_main = vm; - fm->vnet_main = h->vnet_main; - - return error; -} - -static clib_error_t * -flowperpkt_tx_interface_add_del_feature_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - flowperpkt_main_t *fm = &flowperpkt_main; - u32 sw_if_index = ~0; - int is_add = 1; - u8 which = FLOW_VARIANT_IPV4; - - int rv; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "disable")) - is_add = 0; - else if (unformat (input, "%U", unformat_vnet_sw_interface, - fm->vnet_main, &sw_if_index)); - else if (unformat (input, "l2")) - which = FLOW_VARIANT_L2; - else - break; - } - - if (sw_if_index == ~0) - return clib_error_return (0, "Please specify an interface..."); - - rv = - flowperpkt_tx_interface_add_del_feature (fm, sw_if_index, which, is_add); - switch (rv) - { - case 0: - break; - - case VNET_API_ERROR_INVALID_SW_IF_INDEX: - return clib_error_return - (0, "Invalid interface, only works on physical ports"); - break; - - case VNET_API_ERROR_UNIMPLEMENTED: - return clib_error_return (0, "ip6 not supported"); - break; - - default: - return clib_error_return (0, "flowperpkt_enable_disable returned %d", - rv); - } - return 0; -} - -/*? - * '<em>flowperpkt feature add-del</em>' commands to enable/disable - * per-packet IPFIX flow record generation on an interface - * - * @cliexpar - * @parblock - * To enable per-packet IPFIX flow-record generation on an interface: - * @cliexcmd{flowperpkt feature add-del GigabitEthernet2/0/0} - * - * To disable per-packet IPFIX flow-record generation on an interface: - * @cliexcmd{flowperpkt feature add-del GigabitEthernet2/0/0 disable} - * @cliexend - * @endparblock -?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (flowperpkt_enable_disable_command, static) = { - .path = "flowperpkt feature add-del", - .short_help = - "flowperpkt feature add-del <interface-name> [disable]", - .function = flowperpkt_tx_interface_add_del_feature_command_fn, -}; -/* *INDENT-ON* */ - -/** - * @brief Set up the API message handling tables - * @param vm vlib_main_t * vlib main data structure pointer - * @returns 0 to indicate all is well - */ -static clib_error_t * -flowperpkt_plugin_api_hookup (vlib_main_t * vm) -{ - flowperpkt_main_t *fm = &flowperpkt_main; -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + fm->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_flowperpkt_plugin_api_msg; -#undef _ - - return 0; -} - -#define vl_msg_name_crc_list -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (flowperpkt_main_t * fm, api_main_t * am) -{ -#define _(id,n,crc) \ - vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + fm->msg_id_base); - foreach_vl_msg_name_crc_flowperpkt; -#undef _ -} - -/** - * @brief Set up the API message handling tables - * @param vm vlib_main_t * vlib main data structure pointer - * @returns 0 to indicate all is well, or a clib_error_t - */ -static clib_error_t * -flowperpkt_init (vlib_main_t * vm) -{ - flowperpkt_main_t *fm = &flowperpkt_main; - vlib_thread_main_t *tm = &vlib_thread_main; - clib_error_t *error = 0; - u32 num_threads; - u8 *name; - - /* Construct the API name */ - name = format (0, "flowperpkt_%08x%c", api_version, 0); - - /* Ask for a correctly-sized block of API message decode slots */ - fm->msg_id_base = vl_msg_api_get_msg_ids - ((char *) name, VL_MSG_FIRST_AVAILABLE); - - /* Hook up message handlers */ - error = flowperpkt_plugin_api_hookup (vm); - - /* Add our API messages to the global name_crc hash table */ - setup_message_id_table (fm, &api_main); - - vec_free (name); - - /* Decide how many worker threads we have */ - num_threads = 1 /* main thread */ + tm->n_eal_threads; - - /* Allocate per worker thread vectors */ - vec_validate (fm->ipv4_buffers_per_worker, num_threads - 1); - vec_validate (fm->l2_buffers_per_worker, num_threads - 1); - vec_validate (fm->ipv4_frames_per_worker, num_threads - 1); - vec_validate (fm->l2_frames_per_worker, num_threads - 1); - vec_validate (fm->ipv4_next_record_offset_per_worker, num_threads - 1); - vec_validate (fm->l2_next_record_offset_per_worker, num_threads - 1); - - /* Set up time reference pair */ - fm->vlib_time_0 = vlib_time_now (vm); - fm->nanosecond_time_0 = unix_time_now_nsec (); - - return error; -} - -VLIB_INIT_FUNCTION (flowperpkt_init); - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.h b/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.h deleted file mode 100644 index 20f6939dda5..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * flowperpkt.h - skeleton vpp engine plug-in header file - * - * Copyright (c) <current-year> <your-organization> - * 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_flowperpkt_h__ -#define __included_flowperpkt_h__ - -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/ethernet/ethernet.h> - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vnet/flow/flow_report.h> -#include <vnet/flow/flow_report_classify.h> - -/** - * @file - * @brief flow-per-packet plugin header file - */ -typedef struct -{ - /** API message ID base */ - u16 msg_id_base; - - /** Have the reports [templates] been created? */ - int ipv4_report_created; - int l2_report_created; - - /** stream/template IDs */ - u16 ipv4_report_id; - u16 l2_report_id; - - /** ipfix buffers under construction, per-worker thread */ - vlib_buffer_t **ipv4_buffers_per_worker; - vlib_buffer_t **l2_buffers_per_worker; - - /** frames containing ipfix buffers, per-worker thread */ - vlib_frame_t **ipv4_frames_per_worker; - vlib_frame_t **l2_frames_per_worker; - - /** next record offset, per worker thread */ - u16 *ipv4_next_record_offset_per_worker; - u16 *l2_next_record_offset_per_worker; - - /** Time reference pair */ - u64 nanosecond_time_0; - f64 vlib_time_0; - - /** convenience vlib_main_t pointer */ - vlib_main_t *vlib_main; - /** convenience vnet_main_t pointer */ - vnet_main_t *vnet_main; -} flowperpkt_main_t; - -typedef enum -{ - FLOW_VARIANT_IPV4, - FLOW_VARIANT_L2, - FLOW_N_VARIANTS, -} flowperpkt_variant_t; - -extern flowperpkt_main_t flowperpkt_main; - -extern vlib_node_registration_t flowperpkt_ipv4_node; - -void flowperpkt_flush_callback_ipv4 (void); -void flowperpkt_flush_callback_l2 (void); - -#endif /* __included_flowperpkt_h__ */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_all_api_h.h b/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_all_api_h.h deleted file mode 100644 index 329c375abca..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_all_api_h.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * flowperpkt_all_api_h.h - plug-in api #include file - * - * Copyright (c) <current-year> <your-organization> - * 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 <flowperpkt/flowperpkt.api.h> diff --git a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_msg_enum.h b/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_msg_enum.h deleted file mode 100644 index 3177e77a63b..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_msg_enum.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * flowperpkt_msg_enum.h - vpp engine plug-in message enumeration - * - * Copyright (c) <current-year> <your-organization> - * 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_flowperpkt_msg_enum_h -#define included_flowperpkt_msg_enum_h - -#include <vppinfra/byte_order.h> - -#define vl_msg_id(n,h) n, -typedef enum -{ -#include <flowperpkt/flowperpkt_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 /* included_flowperpkt_msg_enum_h */ diff --git a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_test.c b/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_test.c deleted file mode 100644 index 716818ffe0a..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/flowperpkt_test.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * flowperpkt.c - skeleton vpp-api-test plug-in - * - * Copyright (c) <current-year> <your-organization> - * 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 <vat/vat.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vlibsocket/api.h> -#include <vppinfra/error.h> - -/** - * @file vpp_api_test plugin - */ - -uword unformat_sw_if_index (unformat_input_t * input, va_list * args); - -/* Declare message IDs */ -#include <flowperpkt/flowperpkt_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_typedefs - -/* declare message handlers for each api */ - -#define vl_endianfun /* define message structures */ -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) -#define vl_printfun -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_printfun - -/* Get the API version number. */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <flowperpkt/flowperpkt_all_api_h.h> -#undef vl_api_version - -typedef struct -{ - /** API message ID base */ - u16 msg_id_base; - /** vat_main_t pointer */ - vat_main_t *vat_main; -} flowperpkt_test_main_t; - -flowperpkt_test_main_t flowperpkt_test_main; - -#define foreach_standard_reply_retval_handler \ -_(flowperpkt_tx_interface_add_del_reply) - -#define _(n) \ - static void vl_api_##n##_t_handler \ - (vl_api_##n##_t * mp) \ - { \ - vat_main_t * vam = flowperpkt_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 _ - -/* - * Table of message reply handlers, must include boilerplate handlers - * we just generated - */ -#define foreach_vpe_api_reply_msg \ -_(FLOWPERPKT_TX_INTERFACE_ADD_DEL_REPLY, \ - flowperpkt_tx_interface_add_del_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_flowperpkt_tx_interface_add_del (vat_main_t * vam) -{ - flowperpkt_test_main_t *sm = &flowperpkt_test_main; - unformat_input_t *i = vam->input; - f64 timeout; - int enable_disable = 1; - u8 which = 0; /* ipv4 by default */ - u32 sw_if_index = ~0; - vl_api_flowperpkt_tx_interface_add_del_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 if (unformat (i, "disable")) - enable_disable = 0; - else if (unformat (i, "l2")) - which = 1; - else - break; - } - - if (sw_if_index == ~0) - { - errmsg ("missing interface name / explicit sw_if_index number \n"); - return -99; - } - - /* Construct the API message */ - M (FLOWPERPKT_TX_INTERFACE_ADD_DEL, flowperpkt_tx_interface_add_del); - mp->sw_if_index = ntohl (sw_if_index); - mp->is_add = enable_disable; - mp->which = which; - - /* 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 \ -_(flowperpkt_tx_interface_add_del, "<intfc> [disable]") - -void -vat_api_hookup (vat_main_t * vam) -{ - flowperpkt_test_main_t *sm = &flowperpkt_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) -{ - flowperpkt_test_main_t *sm = &flowperpkt_test_main; - u8 *name; - - sm->vat_main = vam; - - /* Ask the vpp engine for the first assigned message-id */ - name = format (0, "flowperpkt_%08x%c", api_version, 0); - sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name); - - /* Don't attempt to hook up API messages if the data plane plugin is AWOL */ - if (sm->msg_id_base != (u16) ~ 0) - vat_api_hookup (vam); - - vec_free (name); - - return 0; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/plugins/flowperpkt-plugin/flowperpkt/l2_node.c b/plugins/flowperpkt-plugin/flowperpkt/l2_node.c deleted file mode 100644 index 1c2f681e1e1..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/l2_node.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - * l2_node.c - l2 ipfix-per-packet graph node - * - * Copyright (c) <current-year> <your-organization> - * 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 <flowperpkt/flowperpkt.h> - -/** - * @file l2 flow record generator graph node - */ - -typedef struct -{ - /** interface handle */ - u32 rx_sw_if_index; - u32 tx_sw_if_index; - /** src and dst L2 addresses */ - u8 src_mac[6]; - u8 dst_mac[6]; - /** Ethertype */ - u16 ethertype; - /** packet timestamp */ - u64 timestamp; - /** size of the buffer */ - u16 buffer_size; -} flowperpkt_l2_trace_t; - -/* packet trace format function */ -static u8 * -format_flowperpkt_l2_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 *); - flowperpkt_l2_trace_t *t = va_arg (*args, flowperpkt_l2_trace_t *); - - s = format (s, - "FLOWPERPKT-L2: rx_sw_if_index %d, tx_sw_if_index %d, src %U dst %U ethertype %0x2, timestamp %lld, size %d", - t->rx_sw_if_index, t->tx_sw_if_index, - format_ethernet_address, &t->src_mac, - format_ethernet_address, &t->dst_mac, - t->ethertype, t->timestamp, t->buffer_size); - return s; -} - -vlib_node_registration_t flowperpkt_l2_node; - -/* No counters at the moment */ -#define foreach_flowperpkt_l2_error - -typedef enum -{ -#define _(sym,str) FLOWPERPKT_ERROR_##sym, - foreach_flowperpkt_l2_error -#undef _ - FLOWPERPKT_N_ERROR, -} flowperpkt_l2_error_t; - -static char *flowperpkt_l2_error_strings[] = { -#define _(sym,string) string, - foreach_flowperpkt_l2_error -#undef _ -}; - -typedef enum -{ - FLOWPERPKT_L2_NEXT_DROP, - FLOWPERPKT_L2_NEXT_IP4_LOOKUP, - FLOWPERPKT_L2_N_NEXT, -} flowperpkt_l2_next_t; - -/** - * @brief add an entry to the flow record under construction - * @param vm vlib_main_t * current worker thread main structure pointer - * @param fm flowperpkt_main_t * flow-per-packet main structure pointer - * @param sw_if_index u32 interface handle - * @param tos u8 ToS bits from the packet - * @param timestamp u64 timestamp, nanoseconds since 1/1/70 - * @param length u16 ip length of the packet - * @param do_flush int 1 = flush all cached records, 0 = construct a record - */ - -static inline void -add_to_flow_record_l2 (vlib_main_t * vm, - vlib_node_runtime_t * node, - flowperpkt_main_t * fm, - u32 rx_sw_if_index, u32 tx_sw_if_index, - u8 * src_mac, u8 * dst_mac, - u16 ethertype, u64 timestamp, u16 length, int do_flush) -{ - u32 my_cpu_number = vm->cpu_index; - flow_report_main_t *frm = &flow_report_main; - ip4_header_t *ip; - udp_header_t *udp; - ip4_ipfix_template_packet_t *tp; - ipfix_message_header_t *h; - ipfix_set_header_t *s; - vlib_frame_t *f; - vlib_buffer_t *b0; - u16 offset; - u32 bi0; - vlib_buffer_free_list_t *fl; - - /* Find or allocate a buffer */ - b0 = fm->l2_buffers_per_worker[my_cpu_number]; - - /* Need to allocate a buffer? */ - if (PREDICT_FALSE (b0 == 0)) - { - /* Nothing to flush */ - if (do_flush) - return; - - /* $$$$ drop counter? */ - if (vlib_buffer_alloc (vm, &bi0, 1) != 1) - return; - - /* Initialize the buffer */ - b0 = fm->l2_buffers_per_worker[my_cpu_number] = - vlib_get_buffer (vm, bi0); - fl = - vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX); - vlib_buffer_init_for_free_list (b0, fl); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - offset = 0; - } - else - { - /* use the current buffer */ - bi0 = vlib_get_buffer_index (vm, b0); - offset = fm->l2_next_record_offset_per_worker[my_cpu_number]; - } - - /* Find or allocate a frame */ - f = fm->l2_frames_per_worker[my_cpu_number]; - if (PREDICT_FALSE (f == 0)) - { - u32 *to_next; - f = vlib_get_frame_to_node (vm, ip4_lookup_node.index); - fm->l2_frames_per_worker[my_cpu_number] = f; - - /* Enqueue the buffer */ - to_next = vlib_frame_vector_args (f); - to_next[0] = bi0; - f->n_vectors = 1; - } - - /* Fresh packet, construct header */ - if (PREDICT_FALSE (offset == 0)) - { - flow_report_stream_t *stream; - - stream = &frm->streams[0]; - - b0->current_data = 0; - b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) + - sizeof (*s); - b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_FLOW_REPORT); - vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index; - - tp = vlib_buffer_get_current (b0); - ip = (ip4_header_t *) & tp->ip4; - udp = (udp_header_t *) (ip + 1); - h = (ipfix_message_header_t *) (udp + 1); - s = (ipfix_set_header_t *) (h + 1); - - ip->ip_version_and_header_length = 0x45; - ip->ttl = 254; - ip->protocol = IP_PROTOCOL_UDP; - ip->flags_and_fragment_offset = 0; - ip->src_address.as_u32 = frm->src_address.as_u32; - ip->dst_address.as_u32 = frm->ipfix_collector.as_u32; - udp->src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix); - udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix); - udp->checksum = 0; - - /* FIXUP: message header export_time */ - h->export_time = (u32) - (((f64) frm->unix_time_0) + - (vlib_time_now (frm->vlib_main) - frm->vlib_time_0)); - h->export_time = clib_host_to_net_u32 (h->export_time); - h->domain_id = clib_host_to_net_u32 (stream->domain_id); - - /* FIXUP: message header sequence_number */ - h->sequence_number = stream->sequence_number++; - h->sequence_number = clib_host_to_net_u32 (h->sequence_number); - - offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp); - } - - /* Add data, unless we're flushing stale data */ - if (PREDICT_TRUE (do_flush == 0)) - { - - /* Add data */ - /* Ingress interface */ - { - u32 ingress_interface = clib_host_to_net_u32 (rx_sw_if_index); - clib_memcpy (b0->data + offset, &ingress_interface, - sizeof (ingress_interface)); - offset += sizeof (ingress_interface); - } - /* Egress interface */ - { - u32 egress_interface = clib_host_to_net_u32 (tx_sw_if_index); - clib_memcpy (b0->data + offset, &egress_interface, - sizeof (egress_interface)); - offset += sizeof (egress_interface); - } - /* src mac address */ - { - clib_memcpy (b0->data + offset, src_mac, 6); - offset += 6; - } - /* dst mac address */ - { - clib_memcpy (b0->data + offset, dst_mac, 6); - offset += 6; - } - - /* ethertype */ - b0->data[offset++] = ethertype >> 8; - b0->data[offset++] = ethertype & 0xFF; - - /* Timestamp */ - clib_memcpy (b0->data + offset, ×tamp, sizeof (f64)); - offset += sizeof (f64); - - /* pkt size */ - { - u16 pkt_size = clib_host_to_net_u16 (length); - clib_memcpy (b0->data + offset, &pkt_size, sizeof (pkt_size)); - offset += sizeof (pkt_size); - } - - b0->current_length += - /* 2*sw_if_index + 2*mac + ethertype + timestamp + length = 32 */ - 2 * sizeof (u32) + 12 + sizeof (u16) + sizeof (f64) + sizeof (u16); - - } - /* Time to flush the buffer? */ - if (PREDICT_FALSE - (do_flush || (offset + 2 * sizeof (u32) + 12 + sizeof (u16) + - +sizeof (f64) + sizeof (u16)) > frm->path_mtu)) - { - tp = vlib_buffer_get_current (b0); - ip = (ip4_header_t *) & tp->ip4; - udp = (udp_header_t *) (ip + 1); - h = (ipfix_message_header_t *) (udp + 1); - s = (ipfix_set_header_t *) (h + 1); - - s->set_id_length = ipfix_set_id_length (fm->l2_report_id, - b0->current_length - - (sizeof (*ip) + sizeof (*udp) + - sizeof (*h))); - h->version_length = version_length (b0->current_length - - (sizeof (*ip) + sizeof (*udp))); - - ip->length = clib_host_to_net_u16 (b0->current_length); - - ip->checksum = ip4_header_checksum (ip); - udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip)); - - if (frm->udp_checksum) - { - /* RFC 7011 section 10.3.2. */ - udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip); - if (udp->checksum == 0) - udp->checksum = 0xffff; - } - - ASSERT (ip->checksum == ip4_header_checksum (ip)); - - if (PREDICT_FALSE (vlib_get_trace_count (vm, node) > 0)) - { - vlib_trace_buffer (vm, node, FLOWPERPKT_L2_NEXT_IP4_LOOKUP, b0, - 0 /* follow chain */ ); - flowperpkt_l2_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - memset (t, 0, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - t->buffer_size = b0->current_length; - } - - vlib_put_frame_to_node (vm, ip4_lookup_node.index, - fm->l2_frames_per_worker[my_cpu_number]); - fm->l2_frames_per_worker[my_cpu_number] = 0; - fm->l2_buffers_per_worker[my_cpu_number] = 0; - offset = 0; - } - - fm->l2_next_record_offset_per_worker[my_cpu_number] = offset; -} - -void -flowperpkt_flush_callback_l2 (void) -{ - vlib_main_t *vm = vlib_get_main (); - flowperpkt_main_t *fm = &flowperpkt_main; - vlib_node_runtime_t *node; - node = vlib_node_get_runtime (vm, flowperpkt_l2_node.index); - - add_to_flow_record_l2 (vm, node, fm, 0 /* rx_sw_if_index */ , - 0 /* tx_sw_if_index */ , - 0 /* src mac */ , - 0 /* dst mac */ , - 0 /* ethertype */ , - 0ULL /* timestamp */ , - 0 /* length */ , - 1 /* do_flush */ ); -} - - -static uword -flowperpkt_l2_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from, *to_next; - flowperpkt_l2_next_t next_index; - flowperpkt_main_t *fm = &flowperpkt_main; - u64 now; - - now = (u64) ((vlib_time_now (vm) - fm->vlib_time_0) * 1e9); - now += fm->nanosecond_time_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 >= 4 && n_left_to_next >= 2) - { - u32 next0 = FLOWPERPKT_L2_NEXT_DROP; - u32 next1 = FLOWPERPKT_L2_NEXT_DROP; - ethernet_header_t *eh0, *eh1; - u16 len0, len1; - u32 bi0, bi1; - vlib_buffer_t *b0, *b1; - - /* Prefetch next iteration. */ - { - vlib_buffer_t *p2, *p3; - - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); - - vlib_prefetch_buffer_header (p2, LOAD); - vlib_prefetch_buffer_header (p3, LOAD); - - CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE); - } - - /* speculatively enqueue b0 and b1 to the current next frame */ - to_next[0] = bi0 = from[0]; - to_next[1] = bi1 = from[1]; - from += 2; - to_next += 2; - n_left_from -= 2; - n_left_to_next -= 2; - - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); - - vnet_feature_next (vnet_buffer (b0)->sw_if_index[VLIB_TX], - &next0, b0); - vnet_feature_next (vnet_buffer (b1)->sw_if_index[VLIB_TX], - &next1, b1); - - eh0 = vlib_buffer_get_current (b0); - len0 = vlib_buffer_length_in_chain (vm, b0); - - if (PREDICT_TRUE ((b0->flags & VLIB_BUFFER_FLOW_REPORT) == 0)) - add_to_flow_record_l2 (vm, node, fm, - vnet_buffer (b0)->sw_if_index[VLIB_RX], - vnet_buffer (b0)->sw_if_index[VLIB_TX], - eh0->src_address, - eh0->dst_address, - eh0->type, now, len0, 0 /* flush */ ); - - eh1 = vlib_buffer_get_current (b0); - len1 = vlib_buffer_length_in_chain (vm, b0); - - if (PREDICT_TRUE ((b1->flags & VLIB_BUFFER_FLOW_REPORT) == 0)) - add_to_flow_record_l2 (vm, node, fm, - vnet_buffer (b1)->sw_if_index[VLIB_RX], - vnet_buffer (b1)->sw_if_index[VLIB_TX], - eh1->src_address, - eh1->dst_address, - eh1->type, now, len1, 0 /* flush */ ); - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) - { - if (b0->flags & VLIB_BUFFER_IS_TRACED) - { - flowperpkt_l2_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - clib_memcpy (t->src_mac, eh0->src_address, 6); - clib_memcpy (t->dst_mac, eh0->dst_address, 6); - t->ethertype = clib_net_to_host_u16 (eh0->type); - t->timestamp = now; - t->buffer_size = len0; - } - if (b1->flags & VLIB_BUFFER_IS_TRACED) - { - flowperpkt_l2_trace_t *t = - vlib_add_trace (vm, node, b1, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX]; - clib_memcpy (t->src_mac, eh1->src_address, 6); - clib_memcpy (t->dst_mac, eh1->dst_address, 6); - t->ethertype = clib_net_to_host_u16 (eh1->type); - t->timestamp = now; - t->buffer_size = len1; - } - } - - /* verify speculative enqueues, maybe switch current next frame */ - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, - to_next, n_left_to_next, - bi0, bi1, next0, next1); - } - - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0; - vlib_buffer_t *b0; - u32 next0 = FLOWPERPKT_L2_NEXT_DROP; - ethernet_header_t *eh0; - u16 len0; - - /* 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); - - vnet_feature_next (vnet_buffer (b0)->sw_if_index[VLIB_TX], - &next0, b0); - - eh0 = vlib_buffer_get_current (b0); - len0 = vlib_buffer_length_in_chain (vm, b0); - - if (PREDICT_TRUE ((b0->flags & VLIB_BUFFER_FLOW_REPORT) == 0)) - add_to_flow_record_l2 (vm, node, fm, - vnet_buffer (b0)->sw_if_index[VLIB_RX], - vnet_buffer (b0)->sw_if_index[VLIB_TX], - eh0->src_address, - eh0->dst_address, - eh0->type, now, len0, 0 /* flush */ ); - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - flowperpkt_l2_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - clib_memcpy (t->src_mac, eh0->src_address, 6); - clib_memcpy (t->dst_mac, eh0->dst_address, 6); - t->ethertype = clib_net_to_host_u16 (eh0->type); - t->timestamp = now; - t->buffer_size = len0; - } - - /* 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); - } - return frame->n_vectors; -} - -/** - * @brief IPFIX l2 flow-per-packet graph node - * @node flowperpkt-l2 - * - * This is the IPFIX flow-record-per-packet node. - * - * @param vm vlib_main_t corresponding to the current thread. - * @param node vlib_node_runtime_t data for this node. - * @param frame vlib_frame_t whose contents should be dispatched. - * - * @par Graph mechanics: buffer metadata, next index usage - * - * <em>Uses:</em> - * - <code>vnet_buffer(b)->ip.save_rewrite_length</code> - * - tells the node the length of the rewrite which was applied in - * ip4/6_rewrite_inline, allows the code to find the IP header without - * having to parse L2 headers, or make stupid assumptions about their - * length. - * - <code>vnet_buffer(b)->flags & VLIB_BUFFER_FLOW_REPORT</code> - * - Used to suppress flow record generation for flow record packets. - * - * <em>Sets:</em> - * - <code>vnet_buffer(b)->flags & VLIB_BUFFER_FLOW_REPORT</code> - * - To suppress flow record generation for flow record packets - * - * <em>Next Index:</em> - * - Next configured output feature on the interface, usually - * "interface-output." Generated flow records head for ip4-lookup - */ - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (flowperpkt_l2_node) = { - .function = flowperpkt_l2_node_fn, - .name = "flowperpkt-l2", - .vector_size = sizeof (u32), - .format_trace = format_flowperpkt_l2_trace, - .type = VLIB_NODE_TYPE_INTERNAL, - - .n_errors = ARRAY_LEN(flowperpkt_l2_error_strings), - .error_strings = flowperpkt_l2_error_strings, - - .n_next_nodes = FLOWPERPKT_L2_N_NEXT, - - /* edit / add dispositions here */ - .next_nodes = { - [FLOWPERPKT_L2_NEXT_DROP] = "error-drop", - [FLOWPERPKT_L2_NEXT_IP4_LOOKUP] = "ip4-lookup", - }, -}; -/* *INDENT-ON* */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/plugins/flowperpkt-plugin/flowperpkt/node.c b/plugins/flowperpkt-plugin/flowperpkt/node.c deleted file mode 100644 index f77f087dc78..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt/node.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * node.c - ipv4 ipfix-per-packet graph node - * - * Copyright (c) <current-year> <your-organization> - * 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 <flowperpkt/flowperpkt.h> - -/** - * @file ipv4 flow record generator graph node - */ - -typedef struct -{ - /** interface handle */ - u32 rx_sw_if_index; - u32 tx_sw_if_index; - u32 src_address; - u32 dst_address; - /** ToS bits */ - u8 tos; - /** packet timestamp */ - u64 timestamp; - /** size of the buffer */ - u16 buffer_size; -} flowperpkt_ipv4_trace_t; - -/* packet trace format function */ -static u8 * -format_flowperpkt_ipv4_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 *); - flowperpkt_ipv4_trace_t *t = va_arg (*args, flowperpkt_ipv4_trace_t *); - - s = format (s, - "FLOWPERPKT-V4: rx_sw_if_index %d, tx_sw_if_index %d, src %U dst %U tos %0x2, timestamp %lld, size %d", - t->rx_sw_if_index, t->tx_sw_if_index, - format_ip4_address, &t->src_address, - format_ip4_address, &t->dst_address, - t->tos, t->timestamp, t->buffer_size); - return s; -} - -vlib_node_registration_t flowperpkt_ipv4_node; - -/* No counters at the moment */ -#define foreach_flowperpkt_ipv4_error - -typedef enum -{ -#define _(sym,str) FLOWPERPKT_ERROR_##sym, - foreach_flowperpkt_ipv4_error -#undef _ - FLOWPERPKT_N_ERROR, -} flowperpkt_ipv4_error_t; - -static char *flowperpkt_ipv4_error_strings[] = { -#define _(sym,string) string, - foreach_flowperpkt_ipv4_error -#undef _ -}; - -typedef enum -{ - FLOWPERPKT_IPV4_NEXT_DROP, - FLOWPERPKT_IPV4_NEXT_LOOKUP, - FLOWPERPKT_IPV4_N_NEXT, -} flowperpkt_ipv4_next_t; - -/** - * @brief add an entry to the flow record under construction - * @param vm vlib_main_t * current worker thread main structure pointer - * @param fm flowperpkt_main_t * flow-per-packet main structure pointer - * @param sw_if_index u32 interface handle - * @param tos u8 ToS bits from the packet - * @param timestamp u64 timestamp, nanoseconds since 1/1/70 - * @param length u16 ip length of the packet - * @param do_flush int 1 = flush all cached records, 0 = construct a record - */ - -static inline void -add_to_flow_record_ipv4 (vlib_main_t * vm, - vlib_node_runtime_t * node, - flowperpkt_main_t * fm, - u32 rx_sw_if_index, u32 tx_sw_if_index, - u32 src_address, u32 dst_address, - u8 tos, u64 timestamp, u16 length, int do_flush) -{ - u32 my_cpu_number = vm->cpu_index; - flow_report_main_t *frm = &flow_report_main; - ip4_header_t *ip; - udp_header_t *udp; - ip4_ipfix_template_packet_t *tp; - ipfix_message_header_t *h; - ipfix_set_header_t *s; - vlib_frame_t *f; - vlib_buffer_t *b0; - u16 offset; - u32 bi0; - vlib_buffer_free_list_t *fl; - - /* Find or allocate a buffer */ - b0 = fm->ipv4_buffers_per_worker[my_cpu_number]; - - /* Need to allocate a buffer? */ - if (PREDICT_FALSE (b0 == 0)) - { - /* Nothing to flush */ - if (do_flush) - return; - - /* $$$$ drop counter? */ - if (vlib_buffer_alloc (vm, &bi0, 1) != 1) - return; - - /* Initialize the buffer */ - b0 = fm->ipv4_buffers_per_worker[my_cpu_number] = - vlib_get_buffer (vm, bi0); - fl = - vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX); - vlib_buffer_init_for_free_list (b0, fl); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - offset = 0; - } - else - { - /* use the current buffer */ - bi0 = vlib_get_buffer_index (vm, b0); - offset = fm->ipv4_next_record_offset_per_worker[my_cpu_number]; - } - - /* Find or allocate a frame */ - f = fm->ipv4_frames_per_worker[my_cpu_number]; - if (PREDICT_FALSE (f == 0)) - { - u32 *to_next; - f = vlib_get_frame_to_node (vm, ip4_lookup_node.index); - fm->ipv4_frames_per_worker[my_cpu_number] = f; - - /* Enqueue the buffer */ - to_next = vlib_frame_vector_args (f); - to_next[0] = bi0; - f->n_vectors = 1; - } - - /* Fresh packet, construct header */ - if (PREDICT_FALSE (offset == 0)) - { - flow_report_stream_t *stream; - - stream = &frm->streams[0]; - - b0->current_data = 0; - b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) + - sizeof (*s); - b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_FLOW_REPORT); - vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index; - - tp = vlib_buffer_get_current (b0); - ip = (ip4_header_t *) & tp->ip4; - udp = (udp_header_t *) (ip + 1); - h = (ipfix_message_header_t *) (udp + 1); - s = (ipfix_set_header_t *) (h + 1); - - ip->ip_version_and_header_length = 0x45; - ip->ttl = 254; - ip->protocol = IP_PROTOCOL_UDP; - ip->flags_and_fragment_offset = 0; - ip->src_address.as_u32 = frm->src_address.as_u32; - ip->dst_address.as_u32 = frm->ipfix_collector.as_u32; - udp->src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix); - udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipfix); - udp->checksum = 0; - - /* FIXUP: message header export_time */ - h->export_time = (u32) - (((f64) frm->unix_time_0) + - (vlib_time_now (frm->vlib_main) - frm->vlib_time_0)); - h->export_time = clib_host_to_net_u32 (h->export_time); - h->domain_id = clib_host_to_net_u32 (stream->domain_id); - - /* FIXUP: message header sequence_number */ - h->sequence_number = stream->sequence_number++; - h->sequence_number = clib_host_to_net_u32 (h->sequence_number); - - offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp); - } - - /* Add data, unless we're flushing stale data */ - if (PREDICT_TRUE (do_flush == 0)) - { - - /* Add data */ - /* Ingress interface */ - { - u32 ingress_interface = clib_host_to_net_u32 (rx_sw_if_index); - clib_memcpy (b0->data + offset, &ingress_interface, - sizeof (ingress_interface)); - offset += sizeof (ingress_interface); - } - /* Egress interface */ - { - u32 egress_interface = clib_host_to_net_u32 (tx_sw_if_index); - clib_memcpy (b0->data + offset, &egress_interface, - sizeof (egress_interface)); - offset += sizeof (egress_interface); - } - /* ip4 src address */ - { - clib_memcpy (b0->data + offset, &src_address, sizeof (src_address)); - offset += sizeof (src_address); - } - /* ip4 dst address */ - { - clib_memcpy (b0->data + offset, &dst_address, sizeof (dst_address)); - offset += sizeof (dst_address); - } - - /* ToS */ - b0->data[offset++] = tos; - - /* Timestamp */ - clib_memcpy (b0->data + offset, ×tamp, sizeof (f64)); - offset += sizeof (f64); - - /* pkt size */ - { - u16 pkt_size = clib_host_to_net_u16 (length); - clib_memcpy (b0->data + offset, &pkt_size, sizeof (pkt_size)); - offset += sizeof (pkt_size); - } - - b0->current_length += - /* sw_if_index + tos + timestamp + length = 15 */ - 4 * sizeof (u32) + sizeof (u8) + sizeof (f64) + sizeof (u16); - - } - /* Time to flush the buffer? */ - if (PREDICT_FALSE - (do_flush || (offset + 4 * sizeof (u32) + sizeof (u8) - + sizeof (f64) + sizeof (u16)) > frm->path_mtu)) - { - tp = vlib_buffer_get_current (b0); - ip = (ip4_header_t *) & tp->ip4; - udp = (udp_header_t *) (ip + 1); - h = (ipfix_message_header_t *) (udp + 1); - s = (ipfix_set_header_t *) (h + 1); - - s->set_id_length = ipfix_set_id_length (fm->ipv4_report_id, - b0->current_length - - (sizeof (*ip) + sizeof (*udp) + - sizeof (*h))); - h->version_length = version_length (b0->current_length - - (sizeof (*ip) + sizeof (*udp))); - - ip->length = clib_host_to_net_u16 (b0->current_length); - - ip->checksum = ip4_header_checksum (ip); - udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip)); - - if (frm->udp_checksum) - { - /* RFC 7011 section 10.3.2. */ - udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip); - if (udp->checksum == 0) - udp->checksum = 0xffff; - } - - ASSERT (ip->checksum == ip4_header_checksum (ip)); - - if (PREDICT_FALSE (vlib_get_trace_count (vm, node) > 0)) - { - vlib_trace_buffer (vm, node, FLOWPERPKT_IPV4_NEXT_LOOKUP, b0, - 0 /* follow chain */ ); - flowperpkt_ipv4_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - t->src_address = 0; - t->dst_address = 0; - t->tos = 0; - t->timestamp = 0; - t->buffer_size = b0->current_length; - } - - vlib_put_frame_to_node (vm, ip4_lookup_node.index, - fm->ipv4_frames_per_worker[my_cpu_number]); - fm->ipv4_frames_per_worker[my_cpu_number] = 0; - fm->ipv4_buffers_per_worker[my_cpu_number] = 0; - offset = 0; - } - - fm->ipv4_next_record_offset_per_worker[my_cpu_number] = offset; -} - -void -flowperpkt_flush_callback_ipv4 (void) -{ - vlib_main_t *vm = vlib_get_main (); - flowperpkt_main_t *fm = &flowperpkt_main; - vlib_node_runtime_t *node; - node = vlib_node_get_runtime (vm, flowperpkt_ipv4_node.index); - - add_to_flow_record_ipv4 (vm, node, fm, 0 /* rx_sw_if_index */ , - 0 /* tx_sw_if_index */ , - 0 /* src_address */ , - 0 /* dst_address */ , - 0 /* ToS */ , - 0ULL /* timestamp */ , - 0 /* length */ , - 1 /* do_flush */ ); -} - - -static uword -flowperpkt_ipv4_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from, *to_next; - flowperpkt_ipv4_next_t next_index; - flowperpkt_main_t *fm = &flowperpkt_main; - u64 now; - - now = (u64) ((vlib_time_now (vm) - fm->vlib_time_0) * 1e9); - now += fm->nanosecond_time_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 >= 4 && n_left_to_next >= 2) - { - u32 next0 = FLOWPERPKT_IPV4_NEXT_DROP; - u32 next1 = FLOWPERPKT_IPV4_NEXT_DROP; - ip4_header_t *ip0, *ip1; - u16 len0, len1; - u32 bi0, bi1; - vlib_buffer_t *b0, *b1; - - /* Prefetch next iteration. */ - { - vlib_buffer_t *p2, *p3; - - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); - - vlib_prefetch_buffer_header (p2, LOAD); - vlib_prefetch_buffer_header (p3, LOAD); - - CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE); - } - - /* speculatively enqueue b0 and b1 to the current next frame */ - to_next[0] = bi0 = from[0]; - to_next[1] = bi1 = from[1]; - from += 2; - to_next += 2; - n_left_from -= 2; - n_left_to_next -= 2; - - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); - - vnet_feature_next (vnet_buffer (b0)->sw_if_index[VLIB_TX], - &next0, b0); - vnet_feature_next (vnet_buffer (b1)->sw_if_index[VLIB_TX], - &next1, b1); - - ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) + - vnet_buffer (b0)->ip.save_rewrite_length); - - len0 = vlib_buffer_length_in_chain (vm, b0); - - if (PREDICT_TRUE ((b0->flags & VLIB_BUFFER_FLOW_REPORT) == 0)) - add_to_flow_record_ipv4 (vm, node, fm, - vnet_buffer (b0)->sw_if_index[VLIB_RX], - vnet_buffer (b0)->sw_if_index[VLIB_TX], - ip0->src_address.as_u32, - ip0->dst_address.as_u32, - ip0->tos, now, len0, 0 /* flush */ ); - - ip1 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b1) + - vnet_buffer (b1)->ip.save_rewrite_length); - len1 = vlib_buffer_length_in_chain (vm, b1); - - if (PREDICT_TRUE ((b1->flags & VLIB_BUFFER_FLOW_REPORT) == 0)) - add_to_flow_record_ipv4 (vm, node, fm, - vnet_buffer (b1)->sw_if_index[VLIB_RX], - vnet_buffer (b1)->sw_if_index[VLIB_TX], - ip1->src_address.as_u32, - ip1->dst_address.as_u32, - ip1->tos, now, len1, 0 /* flush */ ); - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) - { - if (b0->flags & VLIB_BUFFER_IS_TRACED) - { - flowperpkt_ipv4_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - t->src_address = ip0->src_address.as_u32; - t->dst_address = ip0->dst_address.as_u32; - t->tos = ip0->tos; - t->timestamp = now; - t->buffer_size = len0; - } - if (b1->flags & VLIB_BUFFER_IS_TRACED) - { - flowperpkt_ipv4_trace_t *t = - vlib_add_trace (vm, node, b1, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX]; - t->src_address = ip1->src_address.as_u32; - t->dst_address = ip1->dst_address.as_u32; - t->tos = ip1->tos; - t->timestamp = now; - t->buffer_size = len1; - } - } - - /* verify speculative enqueues, maybe switch current next frame */ - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, - to_next, n_left_to_next, - bi0, bi1, next0, next1); - } - - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 bi0; - vlib_buffer_t *b0; - u32 next0 = FLOWPERPKT_IPV4_NEXT_DROP; - ip4_header_t *ip0; - u16 len0; - - /* 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); - - vnet_feature_next (vnet_buffer (b0)->sw_if_index[VLIB_TX], - &next0, b0); - - ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0) + - vnet_buffer (b0)->ip.save_rewrite_length); - /* - * egressInterface, TLV type 14, u32 - * ipClassOfService, TLV type 5, u8 - * flowStartNanoseconds, TLV type 156, dateTimeNanoseconds (f64) - * Implementation: f64 nanoseconds since VPP started - * dataLinkFrameSize, TLV type 312, u16 - */ - len0 = vlib_buffer_length_in_chain (vm, b0); - - if (PREDICT_TRUE ((b0->flags & VLIB_BUFFER_FLOW_REPORT) == 0)) - add_to_flow_record_ipv4 (vm, node, fm, - vnet_buffer (b0)->sw_if_index[VLIB_RX], - vnet_buffer (b0)->sw_if_index[VLIB_TX], - ip0->src_address.as_u32, - ip0->dst_address.as_u32, - ip0->tos, now, len0, 0 /* flush */ ); - - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) - && (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - flowperpkt_ipv4_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->tx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - t->src_address = ip0->src_address.as_u32; - t->dst_address = ip0->dst_address.as_u32; - t->tos = ip0->tos; - t->timestamp = now; - t->buffer_size = len0; - } - - /* 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); - } - return frame->n_vectors; -} - -/** - * @brief IPFIX ipv4 flow-per-packet graph node - * @node flowperpkt-ipv4 - * - * This is the IPFIX flow-record-per-packet node. - * - * @param vm vlib_main_t corresponding to the current thread. - * @param node vlib_node_runtime_t data for this node. - * @param frame vlib_frame_t whose contents should be dispatched. - * - * @par Graph mechanics: buffer metadata, next index usage - * - * <em>Uses:</em> - * - <code>vnet_buffer(b)->ip.save_rewrite_length</code> - * - tells the node the length of the rewrite which was applied in - * ip4/6_rewrite_inline, allows the code to find the IP header without - * having to parse L2 headers, or make stupid assumptions about their - * length. - * - <code>vnet_buffer(b)->flags & VLIB_BUFFER_FLOW_REPORT</code> - * - Used to suppress flow record generation for flow record packets. - * - * <em>Sets:</em> - * - <code>vnet_buffer(b)->flags & VLIB_BUFFER_FLOW_REPORT</code> - * - To suppress flow record generation for flow record packets - * - * <em>Next Index:</em> - * - Next configured output feature on the interface, usually - * "interface-output." Generated flow records head for ip4-lookup - */ - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (flowperpkt_ipv4_node) = { - .function = flowperpkt_ipv4_node_fn, - .name = "flowperpkt-ipv4", - .vector_size = sizeof (u32), - .format_trace = format_flowperpkt_ipv4_trace, - .type = VLIB_NODE_TYPE_INTERNAL, - - .n_errors = ARRAY_LEN(flowperpkt_ipv4_error_strings), - .error_strings = flowperpkt_ipv4_error_strings, - - .n_next_nodes = FLOWPERPKT_IPV4_N_NEXT, - - /* edit / add dispositions here */ - .next_nodes = { - [FLOWPERPKT_IPV4_NEXT_DROP] = "error-drop", - /* Used only to trace ipfix data packets */ - [FLOWPERPKT_IPV4_NEXT_LOOKUP] = "ip4-lookup", - }, -}; -/* *INDENT-ON* */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/plugins/flowperpkt-plugin/flowperpkt_plugin_doc.md b/plugins/flowperpkt-plugin/flowperpkt_plugin_doc.md deleted file mode 100644 index ed76c45c2dc..00000000000 --- a/plugins/flowperpkt-plugin/flowperpkt_plugin_doc.md +++ /dev/null @@ -1,13 +0,0 @@ -Per-packet IPFIX flow record plugin {#flowperpkt_plugin_doc} -=================================== - -## Introduction - -This plugin generates one ipfix record entry per packet transmitted -on interfaces which have the feature enabled - -## Sample configuration - -set ipfix exporter collector 192.168.6.2 src 192.168.6.1 template-interval 20 port 4739 path-mtu 1500 - -flowperpkt feature add-del GigabitEthernet2/3/0 diff --git a/plugins/ila-plugin/Makefile.am b/plugins/ila-plugin/Makefile.am deleted file mode 100644 index fe785df9bc3..00000000000 --- a/plugins/ila-plugin/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2016 Cisco Systems, Inc. -# 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. - -AUTOMAKE_OPTIONS = foreign subdir-objects - -AM_CFLAGS = -Wall -AM_LDFLAGS = -module -shared -avoid-version - -vpppluginsdir = ${libdir}/vpp_plugins - -vppplugins_LTLIBRARIES = ila_plugin.la - -ila_plugin_la_SOURCES = ila/ila.c - -noinst_HEADERS = ila/ila.h - -# Remove *.la files -install-data-hook: - @(cd $(vpppluginsdir) && $(RM) $(vppplugins_LTLIBRARIES)) diff --git a/plugins/ila-plugin/configure.ac b/plugins/ila-plugin/configure.ac deleted file mode 100644 index 56016b4d22d..00000000000 --- a/plugins/ila-plugin/configure.ac +++ /dev/null @@ -1,9 +0,0 @@ -AC_INIT(ila_plugin, 1.0) -AM_INIT_AUTOMAKE -AM_SILENT_RULES([yes]) -AC_PREFIX_DEFAULT([/usr]) - -AC_PROG_LIBTOOL -AC_PROG_CC - -AC_OUTPUT([Makefile]) diff --git a/plugins/ila-plugin/ila/ila.c b/plugins/ila-plugin/ila/ila.c deleted file mode 100644 index 336f4cf560c..00000000000 --- a/plugins/ila-plugin/ila/ila.c +++ /dev/null @@ -1,1070 +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 <ila/ila.h> -#include <vnet/plugin/plugin.h> -#include <vnet/ip/lookup.h> -#include <vnet/dpo/dpo.h> -#include <vnet/fib/fib_table.h> - -static ila_main_t ila_main; - -#define ILA_TABLE_DEFAULT_HASH_NUM_BUCKETS (64 * 1024) -#define ILA_TABLE_DEFAULT_HASH_MEMORY_SIZE (32<<20) - -#define foreach_ila_error \ - _(NONE, "valid ILA packets") - -typedef enum { -#define _(sym,str) ILA_ERROR_##sym, - foreach_ila_error -#undef _ - ILA_N_ERROR, -} ila_error_t; - -static char *ila_error_strings[] = { -#define _(sym,string) string, - foreach_ila_error -#undef _ -}; - -typedef enum { - ILA_ILA2SIR_NEXT_DROP, - ILA_ILA2SIR_N_NEXT, -} ila_ila2sir_next_t; - -typedef struct { - u32 ila_index; - ip6_address_t initial_dst; - u32 adj_index; -} ila_ila2sir_trace_t; - -static ila_entry_t ila_sir2ila_default_entry = { - .csum_mode = ILA_CSUM_MODE_NO_ACTION, - .type = ILA_TYPE_IID, - .dir = ILA_DIR_ILA2SIR, //Will pass the packet with no -}; - -/** - * @brief Dynamically registered DPO Type for ILA - */ -static dpo_type_t ila_dpo_type; - -/** - * @brief Dynamically registered FIB node type for ILA - */ -static fib_node_type_t ila_fib_node_type; - -u8 * -format_half_ip6_address (u8 * s, va_list * va) -{ - u64 v = clib_net_to_host_u64 (va_arg (*va, u64)); - - return format (s, "%04x:%04x:%04x:%04x", - v >> 48, (v >> 32) & 0xffff, (v >> 16) & 0xffff, v & 0xffff); - -} - -u8 * -format_ila_direction (u8 * s, va_list * args) -{ - ila_direction_t t = va_arg (*args, ila_direction_t); -#define _(i,n,st) \ - if (t == ILA_DIR_##i) \ - return format(s, st); - ila_foreach_direction -#undef _ - return format (s, "invalid_ila_direction"); -} - -static u8 * -format_csum_mode (u8 * s, va_list * va) -{ - ila_csum_mode_t csum_mode = va_arg (*va, ila_csum_mode_t); - char *txt; - - switch (csum_mode) - { -#define _(i,n,st) \ - case ILA_CSUM_MODE_##i: \ - txt = st; \ - break; - ila_csum_foreach_type -#undef _ - default: - txt = "invalid_ila_csum_mode"; - break; - } - return format (s, txt); -} - -u8 * -format_ila_type (u8 * s, va_list * args) -{ - ila_type_t t = va_arg (*args, ila_type_t); -#define _(i,n,st) \ - if (t == ILA_TYPE_##i) \ - return format(s, st); - ila_foreach_type -#undef _ - return format (s, "invalid_ila_type"); -} - -static u8 * -format_ila_entry (u8 * s, va_list * va) -{ - vnet_main_t *vnm = va_arg (*va, vnet_main_t *); - ila_entry_t *e = va_arg (*va, ila_entry_t *); - - if (!e) - { - return format (s, "%-15s%=40s%=40s%+16s%+18s%+11s", "Type", "SIR Address", - "ILA Address", "Checksum Mode", "Direction", "Next DPO"); - } - else if (vnm) - { - if (ip6_address_is_zero(&e->next_hop)) - { - return format (s, "%-15U%=40U%=40U%18U%11U%s", - format_ila_type, e->type, - format_ip6_address, &e->sir_address, - format_ip6_address, &e->ila_address, - format_csum_mode, e->csum_mode, - format_ila_direction, e->dir, - "n/a"); - } - else - { - return format (s, "%-15U%=40U%=40U%18U%11U%U", - format_ila_type, e->type, - format_ip6_address, &e->sir_address, - format_ip6_address, &e->ila_address, - format_csum_mode, e->csum_mode, - format_ila_direction, e->dir, - format_dpo_id, &e->ila_dpo, 0); - } - } - - return NULL; -} - -u8 * -format_ila_ila2sir_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 *); - ila_ila2sir_trace_t *t = va_arg (*args, ila_ila2sir_trace_t *); - return format (s, - "ILA -> SIR adj index: %d entry index: %d initial_dst: %U", - t->adj_index, t->ila_index, format_ip6_address, - &t->initial_dst); -} - -static uword -unformat_ila_direction (unformat_input_t * input, va_list * args) -{ - ila_direction_t *result = va_arg (*args, ila_direction_t *); -#define _(i,n,s) \ - if (unformat(input, s)) \ - { \ - *result = ILA_DIR_##i; \ - return 1;\ - } - - ila_foreach_direction -#undef _ - return 0; -} - -static uword -unformat_ila_type (unformat_input_t * input, va_list * args) -{ - ila_type_t *result = va_arg (*args, ila_type_t *); -#define _(i,n,s) \ - if (unformat(input, s)) \ - { \ - *result = ILA_TYPE_##i; \ - return 1;\ - } - - ila_foreach_type -#undef _ - return 0; -} - -static uword -unformat_ila_csum_mode (unformat_input_t * input, va_list * args) -{ - ila_csum_mode_t *result = va_arg (*args, ila_csum_mode_t *); - if (unformat (input, "none") || unformat (input, "no-action")) - { - *result = ILA_CSUM_MODE_NO_ACTION; - return 1; - } - if (unformat (input, "neutral-map")) - { - *result = ILA_CSUM_MODE_NEUTRAL_MAP; - return 1; - } - if (unformat (input, "adjust-transport")) - { - *result = ILA_CSUM_MODE_ADJUST_TRANSPORT; - return 1; - } - return 0; -} - -static uword -unformat_half_ip6_address (unformat_input_t * input, va_list * args) -{ - u64 *result = va_arg (*args, u64 *); - u32 a[4]; - - if (!unformat (input, "%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3])) - return 0; - - if (a[0] > 0xFFFF || a[1] > 0xFFFF || a[2] > 0xFFFF || a[3] > 0xFFFF) - return 0; - - *result = clib_host_to_net_u64 ((((u64) a[0]) << 48) | - (((u64) a[1]) << 32) | - (((u64) a[2]) << 16) | (((u64) a[3]))); - - return 1; -} - -static vlib_node_registration_t ila_ila2sir_node; - -static uword -ila_ila2sir (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from, next_index, *to_next, n_left_to_next; - ila_main_t *ilm = &ila_main; - - from = vlib_frame_vector_args (frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - - while (n_left_from > 0) - { - vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); - - while (n_left_from >= 4 && n_left_to_next >= 2) - { - u32 pi0, pi1; - vlib_buffer_t *p0, *p1; - ila_entry_t *ie0, *ie1; - ip6_header_t *ip60, *ip61; - ip6_address_t *sir_address0, *sir_address1; - - { - vlib_buffer_t *p2, *p3; - - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); - - vlib_prefetch_buffer_header (p2, LOAD); - vlib_prefetch_buffer_header (p3, LOAD); - CLIB_PREFETCH (p2->data, sizeof (ip6_header_t), LOAD); - CLIB_PREFETCH (p3->data, sizeof (ip6_header_t), LOAD); - } - - pi0 = to_next[0] = from[0]; - pi1 = to_next[1] = from[1]; - from += 2; - n_left_from -= 2; - to_next += 2; - n_left_to_next -= 2; - - p0 = vlib_get_buffer (vm, pi0); - p1 = vlib_get_buffer (vm, pi1); - ip60 = vlib_buffer_get_current (p0); - ip61 = vlib_buffer_get_current (p1); - sir_address0 = &ip60->dst_address; - sir_address1 = &ip61->dst_address; - ie0 = pool_elt_at_index (ilm->entries, - vnet_buffer (p0)->ip.adj_index[VLIB_TX]); - ie1 = pool_elt_at_index (ilm->entries, - vnet_buffer (p1)->ip.adj_index[VLIB_TX]); - - if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED)) - { - ila_ila2sir_trace_t *tr = - vlib_add_trace (vm, node, p0, sizeof (*tr)); - tr->ila_index = ie0 - ilm->entries; - tr->initial_dst = ip60->dst_address; - tr->adj_index = vnet_buffer (p0)->ip.adj_index[VLIB_TX]; - } - - if (PREDICT_FALSE (p1->flags & VLIB_BUFFER_IS_TRACED)) - { - ila_ila2sir_trace_t *tr = - vlib_add_trace (vm, node, p1, sizeof (*tr)); - tr->ila_index = ie1 - ilm->entries; - tr->initial_dst = ip61->dst_address; - tr->adj_index = vnet_buffer (p1)->ip.adj_index[VLIB_TX]; - } - - sir_address0 = (ie0->dir != ILA_DIR_SIR2ILA) ? &ie0->sir_address : sir_address0; - sir_address1 = (ie1->dir != ILA_DIR_SIR2ILA) ? &ie1->sir_address : sir_address1; - ip60->dst_address.as_u64[0] = sir_address0->as_u64[0]; - ip60->dst_address.as_u64[1] = sir_address0->as_u64[1]; - ip61->dst_address.as_u64[0] = sir_address1->as_u64[0]; - ip61->dst_address.as_u64[1] = sir_address1->as_u64[1]; - - vnet_buffer (p0)->ip.adj_index[VLIB_TX] = ie0->ila_dpo.dpoi_index; - vnet_buffer (p1)->ip.adj_index[VLIB_TX] = ie1->ila_dpo.dpoi_index; - - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, - n_left_to_next, pi0, pi1, - ie0->ila_dpo.dpoi_next_node, - ie1->ila_dpo.dpoi_next_node); - } - - /* Single loop */ - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 pi0; - vlib_buffer_t *p0; - ila_entry_t *ie0; - ip6_header_t *ip60; - ip6_address_t *sir_address0; - - pi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next += 1; - n_left_to_next -= 1; - - p0 = vlib_get_buffer (vm, pi0); - ip60 = vlib_buffer_get_current (p0); - sir_address0 = &ip60->dst_address; - ie0 = pool_elt_at_index (ilm->entries, - vnet_buffer (p0)->ip.adj_index[VLIB_TX]); - - if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED)) - { - ila_ila2sir_trace_t *tr = - vlib_add_trace (vm, node, p0, sizeof (*tr)); - tr->ila_index = ie0 ? (ie0 - ilm->entries) : ~0; - tr->initial_dst = ip60->dst_address; - tr->adj_index = vnet_buffer (p0)->ip.adj_index[VLIB_TX]; - } - - sir_address0 = (ie0->dir != ILA_DIR_SIR2ILA) ? &ie0->sir_address : sir_address0; - ip60->dst_address.as_u64[0] = sir_address0->as_u64[0]; - ip60->dst_address.as_u64[1] = sir_address0->as_u64[1]; - vnet_buffer (p0)->ip.adj_index[VLIB_TX] = ie0->ila_dpo.dpoi_index; - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, pi0, - ie0->ila_dpo.dpoi_next_node); - } - vlib_put_next_frame (vm, node, next_index, n_left_to_next); - } - - return frame->n_vectors; -} - -/** *INDENT-OFF* */ -VLIB_REGISTER_NODE (ila_ila2sir_node, static) = -{ - .function = ila_ila2sir, - .name = "ila-to-sir", - .vector_size = sizeof (u32), - .format_trace = format_ila_ila2sir_trace, - .n_errors = ILA_N_ERROR, - .error_strings = ila_error_strings, - .n_next_nodes = ILA_ILA2SIR_N_NEXT, - .next_nodes = - { - [ILA_ILA2SIR_NEXT_DROP] = "error-drop" - }, -}; -/** *INDENT-ON* */ - -typedef enum -{ - ILA_SIR2ILA_NEXT_DROP, - ILA_SIR2ILA_N_NEXT, -} ila_sir2ila_next_t; - -typedef struct -{ - u32 ila_index; - ip6_address_t initial_dst; -} ila_sir2ila_trace_t; - -u8 * -format_ila_sir2ila_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 *); - ila_sir2ila_trace_t *t = va_arg (*args, ila_sir2ila_trace_t *); - - return format (s, "SIR -> ILA entry index: %d initial_dst: %U", - t->ila_index, format_ip6_address, &t->initial_dst); -} - -static vlib_node_registration_t ila_sir2ila_node; - -static uword -ila_sir2ila (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from, next_index, *to_next, n_left_to_next; - ila_main_t *ilm = &ila_main; - - from = vlib_frame_vector_args (frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - - while (n_left_from > 0) - { - vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); - - while (n_left_from >= 4 && n_left_to_next >= 2) - { - u32 pi0, pi1; - vlib_buffer_t *p0, *p1; - ip6_header_t *ip60, *ip61; - u32 next0 = ILA_SIR2ILA_NEXT_DROP; - u32 next1 = ILA_SIR2ILA_NEXT_DROP; - BVT (clib_bihash_kv) kv0, value0; - BVT (clib_bihash_kv) kv1, value1; - ila_entry_t *ie0 = &ila_sir2ila_default_entry; - ila_entry_t *ie1 = &ila_sir2ila_default_entry; - ip6_address_t *ila_address0, *ila_address1; - - { - vlib_buffer_t *p2, *p3; - - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); - - vlib_prefetch_buffer_header (p2, LOAD); - vlib_prefetch_buffer_header (p3, LOAD); - CLIB_PREFETCH (p2->data, sizeof (ip6_header_t), LOAD); - CLIB_PREFETCH (p3->data, sizeof (ip6_header_t), LOAD); - } - - pi0 = to_next[0] = from[0]; - pi1 = to_next[1] = from[1]; - from += 2; - n_left_from -= 2; - to_next += 2; - n_left_to_next -= 2; - - p0 = vlib_get_buffer (vm, pi0); - p1 = vlib_get_buffer (vm, pi1); - ip60 = vlib_buffer_get_current (p0); - ip61 = vlib_buffer_get_current (p1); - ila_address0 = &ip60->dst_address; - ila_address1 = &ip61->dst_address; - kv0.key[0] = ip60->dst_address.as_u64[0]; - kv0.key[1] = ip60->dst_address.as_u64[1]; - kv0.key[2] = 0; - kv1.key[0] = ip61->dst_address.as_u64[0]; - kv1.key[1] = ip61->dst_address.as_u64[1]; - kv1.key[2] = 0; - - if (PREDICT_TRUE((BV (clib_bihash_search) - (&ilm->id_to_entry_table, &kv0, &value0)) == 0)) { - ie0 = &ilm->entries[value0.value]; - ila_address0 = (ie0->dir != ILA_DIR_ILA2SIR) ? &ie0->ila_address : ila_address0; - } - - if ((BV (clib_bihash_search) - (&ilm->id_to_entry_table, &kv1, &value1)) == 0) { - ie1 = &ilm->entries[value1.value]; - ila_address1 = (ie1->dir != ILA_DIR_ILA2SIR) ? &ie1->ila_address : ila_address1; - } - - if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED)) - { - ila_sir2ila_trace_t *tr = - vlib_add_trace (vm, node, p0, sizeof (*tr)); - tr->ila_index = - (ie0 != &ila_sir2ila_default_entry) ? (ie0 - ilm->entries) : ~0; - tr->initial_dst = ip60->dst_address; - } - - if (PREDICT_FALSE (p1->flags & VLIB_BUFFER_IS_TRACED)) - { - ila_sir2ila_trace_t *tr = - vlib_add_trace (vm, node, p1, sizeof (*tr)); - tr->ila_index = - (ie1 != &ila_sir2ila_default_entry) ? (ie1 - ilm->entries) : ~0; - tr->initial_dst = ip61->dst_address; - } - - ip60->dst_address.as_u64[0] = ila_address0->as_u64[0]; - ip60->dst_address.as_u64[1] = ila_address0->as_u64[1]; - ip61->dst_address.as_u64[0] = ila_address1->as_u64[0]; - ip61->dst_address.as_u64[1] = ila_address1->as_u64[1]; - - vnet_feature_next (vnet_buffer (p0)->sw_if_index[VLIB_RX], &next0, p0); - vnet_feature_next (vnet_buffer (p1)->sw_if_index[VLIB_RX], &next1, p1); - - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, - n_left_to_next, pi0, pi1, next0, - next1); - } - - /* Single loop */ - while (n_left_from > 0 && n_left_to_next > 0) - { - u32 pi0; - vlib_buffer_t *p0; - ip6_header_t *ip60; - u32 next0 = ILA_SIR2ILA_NEXT_DROP; - BVT (clib_bihash_kv) kv0, value0; - ila_entry_t *ie0 = &ila_sir2ila_default_entry; - ip6_address_t *ila_address0; - - pi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next += 1; - n_left_to_next -= 1; - - p0 = vlib_get_buffer (vm, pi0); - ip60 = vlib_buffer_get_current (p0); - ila_address0 = &ip60->dst_address; - - kv0.key[0] = ip60->dst_address.as_u64[0]; - kv0.key[1] = ip60->dst_address.as_u64[1]; - kv0.key[2] = 0; - - if (PREDICT_TRUE((BV (clib_bihash_search) - (&ilm->id_to_entry_table, &kv0, &value0)) == 0)) { - ie0 = &ilm->entries[value0.value]; - ila_address0 = (ie0->dir != ILA_DIR_ILA2SIR) ? &ie0->ila_address : ila_address0; - } - - if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED)) - { - ila_sir2ila_trace_t *tr = - vlib_add_trace (vm, node, p0, sizeof (*tr)); - tr->ila_index = - (ie0 != &ila_sir2ila_default_entry) ? (ie0 - ilm->entries) : ~0; - tr->initial_dst = ip60->dst_address; - } - - //This operation should do everything for any type (except vnid4 obviously) - ip60->dst_address.as_u64[0] = ila_address0->as_u64[0]; - ip60->dst_address.as_u64[1] = ila_address0->as_u64[1]; - - vnet_feature_next (vnet_buffer (p0)->sw_if_index[VLIB_RX], &next0, p0); - - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, pi0, next0); - } - vlib_put_next_frame (vm, node, next_index, n_left_to_next); - } - - return frame->n_vectors; -} - -/** *INDENT-OFF* */ -VLIB_REGISTER_NODE (ila_sir2ila_node, static) = -{ - .function = ila_sir2ila,.name = "sir-to-ila", - .vector_size = sizeof (u32), - .format_trace = format_ila_sir2ila_trace, - .n_errors = ILA_N_ERROR, - .error_strings = ila_error_strings, - .n_next_nodes = ILA_SIR2ILA_N_NEXT, - .next_nodes = - { - [ILA_SIR2ILA_NEXT_DROP] = "error-drop" - }, -}; -/** *INDENT-ON* */ - -/** *INDENT-OFF* */ -VNET_FEATURE_INIT (ila_sir2ila, static) = -{ - .arc_name = "ip6-unicast", - .node_name = "sir-to-ila", - .runs_before = VNET_FEATURES ("ip6-lookup"), -}; -/** *INDENT-ON* */ - -static void -ila_entry_stack (ila_entry_t *ie) -{ - /* - * restack on the next-hop's FIB entry - */ - dpo_stack(ila_dpo_type, - DPO_PROTO_IP6, - &ie->ila_dpo, - fib_entry_contribute_ip_forwarding( - ie->next_hop_fib_entry_index)); -} - -int -ila_add_del_entry (ila_add_del_entry_args_t * args) -{ - ila_main_t *ilm = &ila_main; - BVT (clib_bihash_kv) kv, value; - - //Sanity check - if (args->type == ILA_TYPE_IID || args->type == ILA_TYPE_LUID) - { - if ((args->sir_address.as_u8[8] >> 5) != args->type) - { - clib_warning ("Incorrect SIR address (ILA type mismatch %d %d)", - args->sir_address.as_u8[8] >> 1, args->type); - return -1; - } - if (args->sir_address.as_u8[8] & 0x10) - { - clib_warning ("Checksum bit should not be set in SIR address"); - return -1; - } - } - else if (args->type == ILA_TYPE_VNIDM) - { - if (args->sir_address.as_u8[0] != 0xff || - (args->sir_address.as_u8[1] & 0xf0) != 0xf0) - { - clib_warning ("SIR multicast address must start with fff"); - return -1; - } - if (args->sir_address.as_u16[1] || args->sir_address.as_u16[2] || - args->sir_address.as_u16[3] || args->sir_address.as_u16[4] || - args->sir_address.as_u16[5] || (args->sir_address.as_u8[12] & 0xf0)) - { - clib_warning ("SIR multicast address must start with fff"); - return -1; - } - } - - if (!args->is_del) - { - ila_entry_t *e; - pool_get (ilm->entries, e); - e->type = args->type; - e->sir_address = args->sir_address; - e->next_hop = args->next_hop_address; - e->csum_mode = args->csum_mode; - e->dir = args->dir; - - //Construct ILA address - switch (e->type) - { - case ILA_TYPE_IID: - e->ila_address = e->sir_address; - break; - case ILA_TYPE_LUID: - e->ila_address.as_u64[0] = args->locator; - e->ila_address.as_u64[1] = args->sir_address.as_u64[1]; - break; - case ILA_TYPE_VNID6: - e->ila_address.as_u64[0] = args->locator; - e->ila_address.as_u8[8] = (ILA_TYPE_VNID6 << 1); - e->ila_address.as_u32[2] |= args->vnid; - e->ila_address.as_u32[3] = args->sir_address.as_u32[3]; - break; - case ILA_TYPE_VNIDM: - e->ila_address.as_u64[0] = args->locator; - e->ila_address.as_u8[8] = (ILA_TYPE_VNIDM << 1); - e->ila_address.as_u32[2] |= args->vnid; - e->ila_address.as_u32[3] = args->sir_address.as_u32[3]; - e->ila_address.as_u8[12] |= args->sir_address.as_u8[2] << 4; - break; - case ILA_TYPE_VNID4: - clib_warning ("ILA type '%U' is not supported", format_ila_type, - e->type); - return -1; - } - - //Modify ILA checksum if necessary - if (e->csum_mode == ILA_CSUM_MODE_NEUTRAL_MAP) - { - ip_csum_t csum = e->ila_address.as_u16[7]; - int i; - for (i = 0; i < 4; i++) - { - csum = ip_csum_sub_even (csum, e->sir_address.as_u32[i]); - csum = ip_csum_add_even (csum, e->ila_address.as_u32[i]); - } - csum = ip_csum_add_even (csum, clib_host_to_net_u16 (0x1000)); - e->ila_address.as_u16[7] = ip_csum_fold (csum); - e->ila_address.as_u8[8] |= 0x10; - } - - //Create entry with the sir address - kv.key[0] = e->sir_address.as_u64[0]; - kv.key[1] = e->sir_address.as_u64[1]; - kv.key[2] = 0; - kv.value = e - ilm->entries; - BV (clib_bihash_add_del) (&ilm->id_to_entry_table, &kv, - 1 /* is_add */ ); - - if (!ip6_address_is_zero(&e->next_hop)) - { - /* - * become a child of the FIB netry for the next-hop - * so we are informed when its forwarding changes - */ - fib_prefix_t next_hop = { - .fp_addr = { - .ip6 = e->next_hop, - }, - .fp_len = 128, - .fp_proto = FIB_PROTOCOL_IP6, - }; - - e->next_hop_fib_entry_index = - fib_table_entry_special_add(0, - &next_hop, - FIB_SOURCE_RR, - FIB_ENTRY_FLAG_NONE, - ADJ_INDEX_INVALID); - e->next_hop_child_index = - fib_entry_child_add(e->next_hop_fib_entry_index, - ila_fib_node_type, - e - ilm->entries); - - /* - * Create a route that results in the ILA entry - */ - dpo_id_t dpo = DPO_INVALID; - fib_prefix_t pfx = { - .fp_addr = { - .ip6 = e->ila_address, - }, - .fp_len = 128, - .fp_proto = FIB_PROTOCOL_IP6, - }; - - dpo_set(&dpo, ila_dpo_type, DPO_PROTO_IP6, e - ilm->entries); - - fib_table_entry_special_dpo_add(0, - &pfx, - FIB_SOURCE_PLUGIN_HI, - FIB_ENTRY_FLAG_EXCLUSIVE, - &dpo); - dpo_reset(&dpo); - - /* - * finally stack the ILA entry so it will forward to the next-hop - */ - ila_entry_stack (e); - } - } - else - { - ila_entry_t *e; - kv.key[0] = args->sir_address.as_u64[0]; - kv.key[1] = args->sir_address.as_u64[1]; - kv.key[2] = 0; - - if ((BV (clib_bihash_search) (&ilm->id_to_entry_table, &kv, &value) < - 0)) - { - return -1; - } - - e = &ilm->entries[value.value]; - - if (!ip6_address_is_zero(&e->next_hop)) - { - fib_prefix_t pfx = { - .fp_addr = { - .ip6 = e->ila_address, - }, - .fp_len = 128, - .fp_proto = FIB_PROTOCOL_IP6, - }; - - fib_table_entry_special_remove(0, &pfx, FIB_SOURCE_PLUGIN_HI); - /* - * remove this ILA entry as child of the FIB netry for the next-hop - */ - fib_entry_child_remove(e->next_hop_fib_entry_index, - e->next_hop_child_index); - fib_table_entry_delete_index(e->next_hop_fib_entry_index, - FIB_SOURCE_RR); - e->next_hop_fib_entry_index = FIB_NODE_INDEX_INVALID; - } - dpo_reset (&e->ila_dpo); - - BV (clib_bihash_add_del) (&ilm->id_to_entry_table, &kv, - 0 /* is_add */ ); - pool_put (ilm->entries, e); - } - return 0; -} - -int -ila_interface (u32 sw_if_index, u8 disable) -{ - vnet_feature_enable_disable ("ip4-unicast", "sir-to-ila", sw_if_index, - !disable, 0, 0); - return 0; -} - -clib_error_t * -vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h, - int from_early_init) -{ - clib_error_t *error = 0; - - return error; -} - -u8 *format_ila_dpo (u8 * s, va_list * va) -{ - index_t index = va_arg (*va, index_t); - CLIB_UNUSED(u32 indent) = va_arg (*va, u32); - ila_main_t *ilm = &ila_main; - ila_entry_t *ie = pool_elt_at_index (ilm->entries, index); - return format(s, "ILA: idx:%d sir:%U", - index, - format_ip6_address, &ie->sir_address); -} - -/** - * @brief no-op lock function. - * The lifetime of the ILA entry is managed by the control plane - */ -static void -ila_dpo_lock (dpo_id_t *dpo) -{ -} - -/** - * @brief no-op unlock function. - * The lifetime of the ILA entry is managed by the control plane - */ -static void -ila_dpo_unlock (dpo_id_t *dpo) -{ -} - -const static dpo_vft_t ila_vft = { - .dv_lock = ila_dpo_lock, - .dv_unlock = ila_dpo_unlock, - .dv_format = format_ila_dpo, -}; -const static char* const ila_ip6_nodes[] = -{ - "ila-to-sir", - NULL, -}; -const static char* const * const ila_nodes[DPO_PROTO_NUM] = -{ - [DPO_PROTO_IP6] = ila_ip6_nodes, -}; - -static fib_node_t * -ila_fib_node_get_node (fib_node_index_t index) -{ - ila_main_t *ilm = &ila_main; - ila_entry_t *ie = pool_elt_at_index (ilm->entries, index); - - return (&ie->ila_fib_node); -} - -/** - * @brief no-op unlock function. - * The lifetime of the ILA entry is managed by the control plane - */ -static void -ila_fib_node_last_lock_gone (fib_node_t *node) -{ -} - -static ila_entry_t * -ila_entry_from_fib_node (fib_node_t *node) -{ - return ((ila_entry_t*)(((char*)node) - - STRUCT_OFFSET_OF(ila_entry_t, ila_fib_node))); -} - -/** - * @brief - * Callback function invoked when the forwarding changes for the ILA next-hop - */ -static fib_node_back_walk_rc_t -ila_fib_node_back_walk_notify (fib_node_t *node, - fib_node_back_walk_ctx_t *ctx) -{ - ila_entry_stack(ila_entry_from_fib_node(node)); - - return (FIB_NODE_BACK_WALK_CONTINUE); -} - -/* - * ILA's FIB graph node virtual function table - */ -static const fib_node_vft_t ila_fib_node_vft = { - .fnv_get = ila_fib_node_get_node, - .fnv_last_lock = ila_fib_node_last_lock_gone, - .fnv_back_walk = ila_fib_node_back_walk_notify, -}; - -clib_error_t * -ila_init (vlib_main_t * vm) -{ - ila_main_t *ilm = &ila_main; - ilm->entries = NULL; - - ilm->lookup_table_nbuckets = ILA_TABLE_DEFAULT_HASH_NUM_BUCKETS; - ilm->lookup_table_nbuckets = 1 << max_log2 (ilm->lookup_table_nbuckets); - ilm->lookup_table_size = ILA_TABLE_DEFAULT_HASH_MEMORY_SIZE; - - BV (clib_bihash_init) (&ilm->id_to_entry_table, - "ila id to entry index table", - ilm->lookup_table_nbuckets, ilm->lookup_table_size); - - ila_dpo_type = dpo_register_new_type(&ila_vft, ila_nodes); - ila_fib_node_type = fib_node_register_new_type(&ila_fib_node_vft); - - return NULL; -} - -VLIB_INIT_FUNCTION (ila_init); - -static clib_error_t * -ila_entry_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - unformat_input_t _line_input, *line_input = &_line_input; - ila_add_del_entry_args_t args = { 0 }; - u8 next_hop_set = 0; - int ret; - - args.type = ILA_TYPE_IID; - args.csum_mode = ILA_CSUM_MODE_NO_ACTION; - args.local_adj_index = ~0; - args.dir = ILA_DIR_BIDIR; - - if (!unformat_user (input, unformat_line_input, line_input)) - return 0; - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "type %U", unformat_ila_type, &args.type)) - ; - else if (unformat - (line_input, "sir-address %U", unformat_ip6_address, - &args.sir_address)) - ; - else if (unformat - (line_input, "locator %U", unformat_half_ip6_address, - &args.locator)) - ; - else if (unformat - (line_input, "csum-mode %U", unformat_ila_csum_mode, - &args.csum_mode)) - ; - else if (unformat (line_input, "vnid %x", &args.vnid)) - ; - else if (unformat - (line_input, "next-hop %U", unformat_ip6_address, - &args.next_hop_address)) - ; - else if (unformat - (line_input, "direction %U", unformat_ila_direction, &args.dir)) - next_hop_set = 1; - else if (unformat (line_input, "del")) - args.is_del = 1; - else - return clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - } - - unformat_free (line_input); - - if (!next_hop_set) - return clib_error_return (0, "Specified a next hop"); - - if ((ret = ila_add_del_entry (&args))) - return clib_error_return (0, "ila_add_del_entry returned error %d", ret); - - return NULL; -} - -VLIB_CLI_COMMAND (ila_entry_command, static) = -{ - .path = "ila entry", - .short_help = "ila entry [type <type>] [sir-address <address>] [locator <locator>] [vnid <hex-vnid>]" - " [adj-index <adj-index>] [next-hop <next-hop>] [direction (bidir|sir2ila|ila2sir)]" - " [csum-mode (no-action|neutral-map|transport-adjust)] [del]", - .function = ila_entry_command_fn, -}; - -static clib_error_t * -ila_interface_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - u32 sw_if_index = ~0; - u8 disable = 0; - - if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) - { - return clib_error_return (0, "Invalid interface name"); - } - - if (unformat (input, "disable")) - { - disable = 1; - } - - int ret; - if ((ret = ila_interface (sw_if_index, disable))) - return clib_error_return (0, "ila_interface returned error %d", ret); - - return NULL; -} - -VLIB_CLI_COMMAND (ila_interface_command, static) = -{ - .path = "ila interface", - .short_help = "ila interface <interface-name> [disable]", - .function = ila_interface_command_fn, -}; - -static clib_error_t * -ila_show_entries_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - ila_main_t *ilm = &ila_main; - ila_entry_t *e; - - vlib_cli_output (vm, " %U\n", format_ila_entry, vnm, NULL); - pool_foreach (e, ilm->entries, - ({ - vlib_cli_output (vm, " %U\n", format_ila_entry, vnm, e); - })); - - return NULL; -} - -VLIB_CLI_COMMAND (ila_show_entries_command, static) = -{ - .path = "show ila entries", - .short_help = "show ila entries", - .function = ila_show_entries_command_fn, -}; diff --git a/plugins/ila-plugin/ila/ila.h b/plugins/ila-plugin/ila/ila.h deleted file mode 100644 index 26620983823..00000000000 --- a/plugins/ila-plugin/ila/ila.h +++ /dev/null @@ -1,116 +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 ILA_H -#define ILA_H - -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/fib/fib_node.h> - -#include <vppinfra/bihash_24_8.h> -#include <vppinfra/bihash_template.h> - -#define ila_foreach_type \ - _(IID, 0, "iid") \ - _(LUID, 1, "luid") \ - _(VNID4, 2, "vnid-ip4") \ - _(VNID6, 3, "vnid-ip6") \ - _(VNIDM, 4, "vnid-multicast") - -typedef enum { -#define _(i,n,s) ILA_TYPE_##i = n, - ila_foreach_type -#undef _ -} ila_type_t; - -#define ila_csum_foreach_type \ -_(NO_ACTION, 0, "no-action") \ -_(NEUTRAL_MAP, 1, "neutral-map") \ -_(ADJUST_TRANSPORT, 2, "adjust-transport") - -typedef enum { -#define _(i,n,s) ILA_CSUM_MODE_##i = n, - ila_csum_foreach_type -#undef _ - ILA_CSUM_N_TYPES -} ila_csum_mode_t; - -#define ila_foreach_direction \ -_(BIDIR, 0, "bidir") \ -_(SIR2ILA, 1, "sir2ila") \ -_(ILA2SIR, 2, "ila2sir") - -typedef enum { -#define _(i,n,s) ILA_DIR_##i = n, - ila_foreach_direction -#undef _ -} ila_direction_t; - -typedef struct { - /** - * Fib Node base class - */ - fib_node_t ila_fib_node; - ila_type_t type; - ip6_address_t sir_address; - ip6_address_t ila_address; - ip6_address_t next_hop; - ila_csum_mode_t csum_mode; - ila_direction_t dir; - - /** - * The FIB entry index for the next-hop - */ - fib_node_index_t next_hop_fib_entry_index; - - /** - * The child index on the FIB entry - */ - u32 next_hop_child_index; - - /** - * The next DPO in the grpah to follow - */ - dpo_id_t ila_dpo; -} ila_entry_t; - -typedef struct { - ila_entry_t *entries; //Pool of ILA entries - - u64 lookup_table_nbuckets; - u64 lookup_table_size; - clib_bihash_24_8_t id_to_entry_table; - - u32 ip6_lookup_next_index; -} ila_main_t; - - -typedef struct { - ila_type_t type; - ip6_address_t sir_address; - ip6_address_t next_hop_address; - u64 locator; - u32 vnid; - u32 local_adj_index; - ila_csum_mode_t csum_mode; - ila_direction_t dir; - u8 is_del; -} ila_add_del_entry_args_t; - -int ila_add_del_entry (ila_add_del_entry_args_t * args); -int ila_interface (u32 sw_if_index, u8 disable); - -#endif //ILA_H diff --git a/plugins/sixrd-plugin/Makefile.am b/plugins/sixrd-plugin/Makefile.am deleted file mode 100644 index eb0d806aa6a..00000000000 --- a/plugins/sixrd-plugin/Makefile.am +++ /dev/null @@ -1,38 +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. - -AUTOMAKE_OPTIONS = foreign subdir-objects - -AM_CFLAGS = -Wall -AM_LDFLAGS = -module -shared -avoid-version - -libsixrd_plugin_la_SOURCES = \ - sixrd/sixrd.c \ - sixrd/sixrd_dpo.c \ - sixrd/ip4_sixrd.c \ - sixrd/ip6_sixrd.c - -noinst_HEADERS = \ - sixrd/sixrd.h \ - sixrd/sixrd_dpo.h - -BUILT_SOURCES = - -vpppluginsdir = ${libdir}/vpp_plugins - -vppplugins_LTLIBRARIES = libsixrd_plugin.la - - -# Remove *.la files -install-data-hook: - @(cd $(vpppluginsdir) && $(RM) $(vppplugins_LTLIBRARIES)) diff --git a/plugins/sixrd-plugin/configure.ac b/plugins/sixrd-plugin/configure.ac deleted file mode 100644 index 3aa4c425158..00000000000 --- a/plugins/sixrd-plugin/configure.ac +++ /dev/null @@ -1,9 +0,0 @@ -AC_INIT(sixrd_plugin, 1.0) -LT_INIT -AM_INIT_AUTOMAKE -AM_SILENT_RULES([yes]) -AC_PREFIX_DEFAULT([/usr]) - -AC_PROG_CC - -AC_OUTPUT([Makefile]) diff --git a/plugins/sixrd-plugin/sixrd/ip4_sixrd.c b/plugins/sixrd-plugin/sixrd/ip4_sixrd.c deleted file mode 100644 index 2fb8015d994..00000000000 --- a/plugins/sixrd-plugin/sixrd/ip4_sixrd.c +++ /dev/null @@ -1,127 +0,0 @@ -/*--------------------------------------------------------------------------- - * Copyright (c) 2009-2014 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 "sixrd.h" - -static vlib_node_registration_t ip4_sixrd_node; - -typedef enum { - IP4_SIXRD_NEXT_IP6_LOOKUP, - IP4_SIXRD_NEXT_DROP, - IP4_SIXRD_N_NEXT, -} ip4_sixrd_next_t; - -/* - * ip4_sixrd_sec_check - */ -static_always_inline void -ip4_sixrd_sec_check (sixrd_domain_t *d, ip4_address_t sa4, ip6_address_t sa6, u8 *error) -{ - u32 a = sixrd_get_addr(d, sa6.as_u64[0]); - clib_warning("Security check: %U %U", format_ip4_address, &a, format_ip4_address, &sa4); - if (PREDICT_FALSE(sixrd_get_addr(d, sa6.as_u64[0]) != sa4.as_u32)) - *error = SIXRD_ERROR_SEC_CHECK; -} - -/* - * ip4_sixrd - */ -static uword -ip4_sixrd (vlib_main_t *vm, - vlib_node_runtime_t *node, - vlib_frame_t *frame) -{ - u32 n_left_from, *from, next_index, *to_next, n_left_to_next; - vlib_node_runtime_t *error_node = vlib_node_get_runtime(vm, ip4_sixrd_node.index); - u32 decap = 0; - - from = vlib_frame_vector_args(frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - while (n_left_from > 0) { - vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next); - - /* Single loop */ - while (n_left_from > 0 && n_left_to_next > 0) { - u32 pi0; - vlib_buffer_t *p0; - u8 error0 = SIXRD_ERROR_NONE; - sixrd_domain_t *d0 = 0; - ip4_header_t *ip40; - ip6_header_t *ip60; - u32 sixrd_domain_index0 = ~0; - u32 next0; - - pi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next +=1; - n_left_to_next -= 1; - - p0 = vlib_get_buffer(vm, pi0); - ip40 = vlib_buffer_get_current(p0); - - /* Throw away anything that isn't IP in IP. */ - if (PREDICT_TRUE(ip40->protocol == IP_PROTOCOL_IPV6 && clib_net_to_host_u16(ip40->length) >= 60)) { - vlib_buffer_advance(p0, sizeof(ip4_header_t)); - ip60 = vlib_buffer_get_current(p0); - d0 = ip4_sixrd_get_domain(vnet_buffer(p0)->ip.adj_index[VLIB_TX], (ip6_address_t *)&ip60->src_address, - &sixrd_domain_index0, &error0); - } else { - error0 = SIXRD_ERROR_BAD_PROTOCOL; - } - if (d0) { - /* SIXRD inbound security check */ - ip4_sixrd_sec_check(d0, ip40->src_address, ip60->src_address, &error0); - } - - next0 = error0 == SIXRD_ERROR_NONE ? IP4_SIXRD_NEXT_IP6_LOOKUP : IP4_SIXRD_NEXT_DROP; - - if (PREDICT_FALSE(p0->flags & VLIB_BUFFER_IS_TRACED)) { - sixrd_trace_t *tr = vlib_add_trace(vm, node, p0, sizeof(*tr)); - tr->sixrd_domain_index = sixrd_domain_index0; - } - - p0->error = error_node->errors[error0]; - if (PREDICT_TRUE(error0 == SIXRD_ERROR_NONE)) decap++; - vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, pi0, next0); - - } - vlib_put_next_frame(vm, node, next_index, n_left_to_next); - } - vlib_node_increment_counter(vm, ip4_sixrd_node.index, SIXRD_ERROR_DECAPSULATED, decap); - - return frame->n_vectors; -} - -static char *sixrd_error_strings[] = { -#define _(sym,string) string, - foreach_sixrd_error -#undef _ -}; - -VLIB_REGISTER_NODE(ip4_sixrd_node,static) = { - .function = ip4_sixrd, - .name = "ip4-sixrd", - .vector_size = sizeof(u32), - .format_trace = format_sixrd_trace, - .n_errors = SIXRD_N_ERROR, - .error_strings = sixrd_error_strings, - .n_next_nodes = IP4_SIXRD_N_NEXT, - .next_nodes = { - [IP4_SIXRD_NEXT_IP6_LOOKUP] = "ip6-lookup", - [IP4_SIXRD_NEXT_DROP] = "error-drop", - }, -}; diff --git a/plugins/sixrd-plugin/sixrd/ip6_sixrd.c b/plugins/sixrd-plugin/sixrd/ip6_sixrd.c deleted file mode 100644 index 36f3fab320b..00000000000 --- a/plugins/sixrd-plugin/sixrd/ip6_sixrd.c +++ /dev/null @@ -1,129 +0,0 @@ -/*--------------------------------------------------------------------------- - * Copyright (c) 2009-2014 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. - *--------------------------------------------------------------------------- - */ -/* - * Defines used for testing various optimisation schemes - */ -#define SIXRD_ENCAP_DUAL 0 - -#include "sixrd.h" - -static vlib_node_registration_t ip6_sixrd_node; - -typedef enum { - IP6_SIXRD_NEXT_IP4_LOOKUP, - IP6_SIXRD_NEXT_DROP, - IP6_SIXRD_N_NEXT, -} ip6_sixrd_next_t; - -/* - * ip6_sixrd - */ -static uword -ip6_sixrd (vlib_main_t *vm, - vlib_node_runtime_t *node, - vlib_frame_t *frame) -{ - u32 n_left_from, *from, next_index, *to_next, n_left_to_next; - vlib_node_runtime_t *error_node = vlib_node_get_runtime(vm, ip6_sixrd_node.index); - u32 encap = 0; - from = vlib_frame_vector_args(frame); - n_left_from = frame->n_vectors; - next_index = node->cached_next_index; - - while (n_left_from > 0) { - 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 pi0; - vlib_buffer_t *p0; - sixrd_domain_t *d0; - u8 error0 = SIXRD_ERROR_NONE; - ip6_header_t *ip60; - ip4_header_t *ip4h0; - u32 next0 = IP6_SIXRD_NEXT_IP4_LOOKUP; - u32 sixrd_domain_index0 = ~0; - - pi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next +=1; - n_left_to_next -= 1; - - p0 = vlib_get_buffer(vm, pi0); - ip60 = vlib_buffer_get_current(p0); - // p0->current_length = clib_net_to_host_u16(ip40->length); - d0 = ip6_sixrd_get_domain(vnet_buffer(p0)->ip.adj_index[VLIB_TX], &sixrd_domain_index0); - ASSERT(d0); - - /* SIXRD calc */ - u64 dal60 = clib_net_to_host_u64(ip60->dst_address.as_u64[0]); - u32 da40 = sixrd_get_addr(d0, dal60); - u16 len = clib_net_to_host_u16(ip60->payload_length) + 60; - if (da40 == 0) error0 = SIXRD_ERROR_UNKNOWN; - - /* construct ipv4 header */ - vlib_buffer_advance(p0, - (sizeof(ip4_header_t))); - ip4h0 = vlib_buffer_get_current(p0); - vnet_buffer(p0)->sw_if_index[VLIB_TX] = (u32)~0; - ip4h0->ip_version_and_header_length = 0x45; - ip4h0->tos = 0; - ip4h0->length = clib_host_to_net_u16(len); - ip4h0->fragment_id = 0; - ip4h0->flags_and_fragment_offset = 0; - ip4h0->ttl = 0x40; - ip4h0->protocol = IP_PROTOCOL_IPV6; - ip4h0->src_address = d0->ip4_src; - ip4h0->dst_address.as_u32 = clib_host_to_net_u32(da40); - ip4h0->checksum = ip4_header_checksum(ip4h0); - - next0 = error0 == SIXRD_ERROR_NONE ? IP6_SIXRD_NEXT_IP4_LOOKUP : IP6_SIXRD_NEXT_DROP; - - if (PREDICT_FALSE(p0->flags & VLIB_BUFFER_IS_TRACED)) { - sixrd_trace_t *tr = vlib_add_trace(vm, node, p0, sizeof(*tr)); - tr->sixrd_domain_index = sixrd_domain_index0; - } - - p0->error = error_node->errors[error0]; - if (PREDICT_TRUE(error0 == SIXRD_ERROR_NONE)) encap++; - - vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, pi0, next0); - } - vlib_put_next_frame(vm, node, next_index, n_left_to_next); - } - vlib_node_increment_counter(vm, ip6_sixrd_node.index, SIXRD_ERROR_ENCAPSULATED, encap); - - return frame->n_vectors; -} - -static char *sixrd_error_strings[] = { -#define _(sym,string) string, - foreach_sixrd_error -#undef _ -}; - -VLIB_REGISTER_NODE(ip6_sixrd_node,static) = { - .function = ip6_sixrd, - .name = "ip6-sixrd", - .vector_size = sizeof(u32), - .format_trace = format_sixrd_trace, - .n_errors = SIXRD_N_ERROR, - .error_strings = sixrd_error_strings, - .n_next_nodes = IP6_SIXRD_N_NEXT, - .next_nodes = { - [IP6_SIXRD_NEXT_IP4_LOOKUP] = "ip4-lookup", - [IP6_SIXRD_NEXT_DROP] = "error-drop", - }, -}; diff --git a/plugins/sixrd-plugin/sixrd/sixrd.c b/plugins/sixrd-plugin/sixrd/sixrd.c deleted file mode 100644 index 66e631a2b6a..00000000000 --- a/plugins/sixrd-plugin/sixrd/sixrd.c +++ /dev/null @@ -1,369 +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. - */ - -#include "sixrd.h" -#include <vnet/plugin/plugin.h> - -#include <vnet/fib/fib_table.h> -#include <vnet/fib/ip6_fib.h> -#include <vnet/adj/adj.h> - -/* - * This code supports the following sixrd modes: - * - * 32 EA bits (Complete IPv4 address is embedded): - * ea_bits_len = 32 - * IPv4 suffix is embedded: - * ea_bits_len = < 32 - * No embedded address bits (1:1 mode): - * ea_bits_len = 0 - */ - -int -sixrd_create_domain (ip6_address_t *ip6_prefix, - u8 ip6_prefix_len, - ip4_address_t *ip4_prefix, - u8 ip4_prefix_len, - ip4_address_t *ip4_src, - u32 *sixrd_domain_index, - u16 mtu) -{ - dpo_id_t dpo_v6 = DPO_INVALID, dpo_v4 = DPO_INVALID; - sixrd_main_t *mm = &sixrd_main; - fib_node_index_t fei; - sixrd_domain_t *d; - - /* Get domain index */ - pool_get_aligned(mm->domains, d, CLIB_CACHE_LINE_BYTES); - memset(d, 0, sizeof (*d)); - *sixrd_domain_index = d - mm->domains; - - /* Init domain struct */ - d->ip4_prefix.as_u32 = ip4_prefix->as_u32; - d->ip4_prefix_len = ip4_prefix_len; - d->ip6_prefix = *ip6_prefix; - d->ip6_prefix_len = ip6_prefix_len; - d->ip4_src = *ip4_src; - d->mtu = mtu; - - if (ip4_prefix_len < 32) - d->shift = 64 - ip6_prefix_len + (32 - ip4_prefix_len); - - /* Create IPv6 route/adjacency */ - fib_prefix_t pfx6 = { - .fp_proto = FIB_PROTOCOL_IP6, - .fp_len = d->ip6_prefix_len, - .fp_addr = { - .ip6 = d->ip6_prefix, - }, - }; - sixrd_dpo_create(DPO_PROTO_IP6, - *sixrd_domain_index, - &dpo_v6); - fib_table_entry_special_dpo_add(0, &pfx6, - FIB_SOURCE_SIXRD, - FIB_ENTRY_FLAG_EXCLUSIVE, - &dpo_v6); - dpo_reset (&dpo_v6); - - /* - * Multiple SIXRD domains may share same source IPv4 TEP - * In this case the route will exist and be SixRD sourced. - * Find the adj (if any) already contributed and modify it - */ - fib_prefix_t pfx4 = { - .fp_proto = FIB_PROTOCOL_IP4, - .fp_len = 32, - .fp_addr = { - .ip4 = d->ip4_src, - }, - }; - fei = fib_table_lookup_exact_match(0, &pfx4); - - if (FIB_NODE_INDEX_INVALID != fei) - { - dpo_id_t dpo = DPO_INVALID; - - if (fib_entry_get_dpo_for_source (fei, FIB_SOURCE_SIXRD, &dpo)) - { - /* - * modify the existing adj to indicate it's shared - * skip to route add. - * It is locked to pair with the unlock below. - */ - const dpo_id_t *sd_dpo; - sixrd_dpo_t *sd; - - ASSERT(DPO_LOAD_BALANCE == dpo.dpoi_type); - - sd_dpo = load_balance_get_bucket(dpo.dpoi_index, 0); - sd = sixrd_dpo_get (sd_dpo->dpoi_index); - - sd->sd_domain = ~0; - dpo_copy (&dpo_v4, sd_dpo); - dpo_reset (&dpo); - - goto route_add; - } - } - /* first time addition of the route */ - sixrd_dpo_create(DPO_PROTO_IP4, - *sixrd_domain_index, - &dpo_v4); - -route_add: - /* - * Create ip4 route. This is a reference counted add. If the prefix - * already exists and is SixRD sourced, it is now SixRD source n+1 times - * and will need to be removed n+1 times. - */ - fib_table_entry_special_dpo_add(0, &pfx4, - FIB_SOURCE_SIXRD, - FIB_ENTRY_FLAG_EXCLUSIVE, - &dpo_v4); - dpo_reset (&dpo_v4); - - return 0; -} - -/* - * sixrd_delete_domain - */ -int -sixrd_delete_domain (u32 sixrd_domain_index) -{ - sixrd_main_t *mm = &sixrd_main; - sixrd_domain_t *d; - - if (pool_is_free_index(mm->domains, sixrd_domain_index)) { - clib_warning("SIXRD domain delete: domain does not exist: %d", - sixrd_domain_index); - return -1; - } - - d = pool_elt_at_index(mm->domains, sixrd_domain_index); - - fib_prefix_t pfx = { - .fp_proto = FIB_PROTOCOL_IP4, - .fp_len = 32, - .fp_addr = { - .ip4 = d->ip4_src, - }, - }; - fib_table_entry_special_remove(0, &pfx, FIB_SOURCE_SIXRD); - - fib_prefix_t pfx6 = { - .fp_proto = FIB_PROTOCOL_IP6, - .fp_len = d->ip6_prefix_len, - .fp_addr = { - .ip6 = d->ip6_prefix, - }, - }; - fib_table_entry_special_remove(0, &pfx6, FIB_SOURCE_SIXRD); - - pool_put(mm->domains, d); - - return 0; -} - -static clib_error_t * -sixrd_add_domain_command_fn (vlib_main_t *vm, - unformat_input_t *input, - vlib_cli_command_t *cmd) -{ - unformat_input_t _line_input, *line_input = &_line_input; - ip4_address_t ip4_prefix; - ip6_address_t ip6_prefix; - ip4_address_t ip4_src; - u32 ip6_prefix_len=0, ip4_prefix_len=0, sixrd_domain_index; - u32 num_m_args = 0; - /* Optional arguments */ - u32 mtu = 0; - - /* Get a line of input. */ - if (!unformat_user(input, unformat_line_input, line_input)) - return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat(line_input, "ip6-pfx %U/%d", unformat_ip6_address, &ip6_prefix, &ip6_prefix_len)) - num_m_args++; - else if (unformat(line_input, "ip4-pfx %U/%d", unformat_ip4_address, &ip4_prefix, &ip4_prefix_len)) - num_m_args++; - else if (unformat(line_input, "ip4-src %U", unformat_ip4_address, &ip4_src)) - num_m_args++; - else if (unformat(line_input, "mtu %d", &mtu)) - num_m_args++; - else - return clib_error_return(0, "unknown input `%U'", - format_unformat_error, input); - } - unformat_free(line_input); - - if (num_m_args < 3) - return clib_error_return(0, "mandatory argument(s) missing"); - - sixrd_create_domain(&ip6_prefix, ip6_prefix_len, &ip4_prefix, ip4_prefix_len, - &ip4_src, &sixrd_domain_index, mtu); - - return 0; -} - -static clib_error_t * -sixrd_del_domain_command_fn (vlib_main_t *vm, - unformat_input_t *input, - vlib_cli_command_t *cmd) -{ - unformat_input_t _line_input, *line_input = &_line_input; - u32 num_m_args = 0; - u32 sixrd_domain_index; - - /* Get a line of input. */ - if (! unformat_user(input, unformat_line_input, line_input)) - return 0; - - while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat(line_input, "index %d", &sixrd_domain_index)) - num_m_args++; - else - return clib_error_return(0, "unknown input `%U'", - format_unformat_error, input); - } - unformat_free(line_input); - - if (num_m_args != 1) - return clib_error_return(0, "mandatory argument(s) missing"); - - sixrd_delete_domain(sixrd_domain_index); - - return 0; -} - -static u8 * -format_sixrd_domain (u8 *s, va_list *args) -{ - sixrd_domain_t *d = va_arg(*args, sixrd_domain_t *); - sixrd_main_t *mm = &sixrd_main; - - s = format(s, - "[%d] ip6-pfx %U/%d ip4-pfx %U/%d ip4-src %U mtu %d", - d - mm->domains, - format_ip6_address, &d->ip6_prefix, d->ip6_prefix_len, - format_ip4_address, &d->ip4_prefix, d->ip4_prefix_len, - format_ip4_address, &d->ip4_src, d->mtu); - - return s; -} - -static clib_error_t * -show_sixrd_domain_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd) -{ - sixrd_main_t *mm = &sixrd_main; - sixrd_domain_t *d; - - if (pool_elts(mm->domains) == 0) - vlib_cli_output(vm, "No SIXRD domains are configured..."); - - pool_foreach(d, mm->domains, ({vlib_cli_output(vm, "%U", format_sixrd_domain, d);})); - - return 0; - -} - -static clib_error_t * -show_sixrd_stats_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd) -{ - sixrd_main_t *mm = &sixrd_main; - sixrd_domain_t *d; - int domains = 0, domaincount = 0; - if (pool_elts (mm->domains) == 0) - vlib_cli_output (vm, "No SIXRD domains are configured..."); - - pool_foreach(d, mm->domains, ({ - domains += sizeof(*d); - domaincount++; - })); - - vlib_cli_output(vm, "SIXRD domains structure: %d\n", sizeof (sixrd_domain_t)); - vlib_cli_output(vm, "SIXRD domains: %d (%d bytes)\n", domaincount, domains); - - return 0; -} - -/* - * packet trace format function - */ -u8 * -format_sixrd_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 *); - sixrd_trace_t *t = va_arg (*args, sixrd_trace_t *); - u32 sixrd_domain_index = t->sixrd_domain_index; - - s = format(s, "SIXRD domain index: %d", sixrd_domain_index); - - return s; -} - -VLIB_CLI_COMMAND(sixrd_add_domain_command, static) = { - .path = "sixrd add domain", - .short_help = - "sixrd add domain ip6-pfx <ip6-pfx> ip4-pfx <ip4-pfx> ip4-src <ip4-addr>", - .function = sixrd_add_domain_command_fn, -}; - -VLIB_CLI_COMMAND(sixrd_del_command, static) = { - .path = "sixrd del domain", - .short_help = - "sixrd del domain index <domain>", - .function = sixrd_del_domain_command_fn, -}; - -VLIB_CLI_COMMAND(show_sixrd_domain_command, static) = { - .path = "show sixrd domain", - .function = show_sixrd_domain_command_fn, -}; - -VLIB_CLI_COMMAND(show_sixrd_stats_command, static) = { - .path = "show sixrd stats", - .function = show_sixrd_stats_command_fn, -}; - -/* - * 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) -{ - clib_error_t * error = 0; - sixrd_main_t *mm = &sixrd_main; - - mm->vnet_main = vnet_get_main(); - mm->vlib_main = vm; - - return error; -} - -static clib_error_t * sixrd_init (vlib_main_t * vm) -{ - sixrd_dpo_module_init (); - - return (NULL); -} - -VLIB_INIT_FUNCTION (sixrd_init); diff --git a/plugins/sixrd-plugin/sixrd/sixrd.h b/plugins/sixrd-plugin/sixrd/sixrd.h deleted file mode 100644 index 56714c9e3bd..00000000000 --- a/plugins/sixrd-plugin/sixrd/sixrd.h +++ /dev/null @@ -1,141 +0,0 @@ -/*--------------------------------------------------------------------------- - * Copyright (c) 2009-2014 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 <stdbool.h> -#include <vppinfra/error.h> -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vnet/fib/ip6_fib.h> - -#include "sixrd_dpo.h" - -int sixrd_create_domain(ip6_address_t *ip6_prefix, u8 ip6_prefix_len, - ip4_address_t *ip4_prefix, u8 ip4_prefix_len, - ip4_address_t *ip4_src, u32 *sixrd_domain_index, u16 mtu); -int sixrd_delete_domain(u32 sixrd_domain_index); -u8 *format_sixrd_trace(u8 *s, va_list *args); - -typedef struct { - ip6_address_t ip6_prefix; - ip4_address_t ip4_prefix; - ip4_address_t ip4_src; - u8 ip6_prefix_len; - u8 ip4_prefix_len; - - /* helpers */ - u8 shift; - - u16 mtu; -} sixrd_domain_t; - -typedef struct { - /* pool of SIXRD domains */ - sixrd_domain_t *domains; - - /* convenience */ - vlib_main_t *vlib_main; - vnet_main_t *vnet_main; -} sixrd_main_t; - -#define foreach_sixrd_error \ - /* Must be first. */ \ - _(NONE, "valid SIXRD packets") \ - _(BAD_PROTOCOL, "bad protocol") \ - _(WRONG_ICMP_TYPE, "wrong icmp type") \ - _(SEC_CHECK, "security check failed") \ - _(ICMP, "unable to translate ICMP") \ - _(UNKNOWN, "unknown") \ - _(NO_DOMAIN, "no domain") \ - _(ENCAPSULATED, "encapsulated") \ - _(DECAPSULATED, "decapsulated") \ - _(TRANSLATED_4TO6, "translated 4 to 6") \ - _(TRANSLATED_6TO4, "translated 6 to 4") \ - _(FRAGMENT, "fragment handling error") \ - _(FRAGMENT_QUEUED, "dropped, missing first fragment") \ - _(FRAGMENTED, "packets requiring fragmentation") \ - _(FRAGMENT_PARTS, "fragment parts") \ - _(MALFORMED, "malformed packet") - -typedef enum { -#define _(sym,str) SIXRD_ERROR_##sym, - foreach_sixrd_error -#undef _ - SIXRD_N_ERROR, - } sixrd_error_t; - -typedef struct { - u32 sixrd_domain_index; -} sixrd_trace_t; - -sixrd_main_t sixrd_main; - -/* - * sixrd_get_addr - */ -static_always_inline u32 -sixrd_get_addr (sixrd_domain_t *d, u64 dal) -{ - - /* 1:1 mode */ - if (d->ip4_prefix_len == 32) return (d->ip4_prefix.as_u32); - - /* Grab 32 - ip4_prefix_len bits out of IPv6 address from offset ip6_prefix_len */ - return (d->ip4_prefix.as_u32 | (u32)(dal >> d->shift)); -} - -/* - * Get the SIXRD domain from an IPv6 lookup adjacency. - */ -static_always_inline sixrd_domain_t * -ip6_sixrd_get_domain (u32 sdi, u32 *sixrd_domain_index) -{ - sixrd_main_t *mm = &sixrd_main; - sixrd_dpo_t *sd; - - sd = sixrd_dpo_get(sdi); - - ASSERT(sd); - *sixrd_domain_index = sd->sd_domain; - return pool_elt_at_index(mm->domains, *sixrd_domain_index); -} - -/* - * Get the SIXRD domain from an IPv4 lookup adjacency. - * If the IPv4 address is not shared, no lookup is required. - * The IPv6 address is used otherwise. - */ -static_always_inline sixrd_domain_t * -ip4_sixrd_get_domain (u32 sdi, ip6_address_t *addr, - u32 *sixrd_domain_index, u8 *error) -{ - sixrd_main_t *mm = &sixrd_main; - sixrd_dpo_t *sd; - - sd = sixrd_dpo_get(sdi); - *sixrd_domain_index = sd->sd_domain; - if (*sixrd_domain_index != ~0) - return pool_elt_at_index(mm->domains, *sixrd_domain_index); - - u32 lbi = ip6_fib_table_fwding_lookup(&ip6_main, 0, addr); - const dpo_id_t *dpo = load_balance_get_bucket(lbi, 0); - if (PREDICT_TRUE(dpo->dpoi_type == sixrd_dpo_type)) - { - sd = sixrd_dpo_get(dpo->dpoi_index); - *sixrd_domain_index = sd->sd_domain; - return pool_elt_at_index(mm->domains, *sixrd_domain_index); - } - *error = SIXRD_ERROR_NO_DOMAIN; - return NULL; -} diff --git a/plugins/sixrd-plugin/sixrd/sixrd_dpo.c b/plugins/sixrd-plugin/sixrd/sixrd_dpo.c deleted file mode 100644 index 88a079350a3..00000000000 --- a/plugins/sixrd-plugin/sixrd/sixrd_dpo.c +++ /dev/null @@ -1,132 +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 "sixrd_dpo.h" -#include <vnet/ip/ip.h> - -/** - * pool of all MPLS Label DPOs - */ -sixrd_dpo_t *sixrd_dpo_pool; - -/** - * The register SIXRD DPO type - */ -dpo_type_t sixrd_dpo_type; - -static sixrd_dpo_t * -sixrd_dpo_alloc (void) -{ - sixrd_dpo_t *sd; - - pool_get_aligned(sixrd_dpo_pool, sd, CLIB_CACHE_LINE_BYTES); - memset(sd, 0, sizeof(*sd)); - - return (sd); -} - -static index_t -sixrd_dpo_get_index (sixrd_dpo_t *sd) -{ - return (sd - sixrd_dpo_pool); -} - -void -sixrd_dpo_create (dpo_proto_t dproto, - u32 domain_index, - dpo_id_t *dpo) -{ - sixrd_dpo_t *sd; - - sd = sixrd_dpo_alloc(); - sd->sd_domain = domain_index; - sd->sd_proto = dproto; - - dpo_set(dpo, - sixrd_dpo_type, - dproto, - sixrd_dpo_get_index(sd)); -} - -u8* -format_sixrd_dpo (u8 *s, va_list *args) -{ - index_t index = va_arg (*args, index_t); - CLIB_UNUSED(u32 indent) = va_arg (*args, u32); - sixrd_dpo_t *sd; - - sd = sixrd_dpo_get(index); - - return (format(s, "sixrd:[%d]:%U domain:%d", - index, - format_dpo_proto, sd->sd_proto, - sd->sd_domain)); -} - - -static void -sixrd_dpo_lock (dpo_id_t *dpo) -{ - sixrd_dpo_t *sd; - - sd = sixrd_dpo_get(dpo->dpoi_index); - - sd->sd_locks++; -} - -static void -sixrd_dpo_unlock (dpo_id_t *dpo) -{ - sixrd_dpo_t *sd; - - sd = sixrd_dpo_get(dpo->dpoi_index); - - sd->sd_locks--; - - if (0 == sd->sd_locks) - { - pool_put(sixrd_dpo_pool, sd); - } -} - -const static dpo_vft_t sd_vft = { - .dv_lock = sixrd_dpo_lock, - .dv_unlock = sixrd_dpo_unlock, - .dv_format = format_sixrd_dpo, -}; - -const static char* const sixrd_ip4_nodes[] = -{ - "ip4-sixrd", - NULL, -}; -const static char* const sixrd_ip6_nodes[] = -{ - "ip6-sixrd", - NULL, -}; - -const static char* const * const sixrd_nodes[DPO_PROTO_NUM] = -{ - [DPO_PROTO_IP4] = sixrd_ip4_nodes, - [DPO_PROTO_IP6] = sixrd_ip6_nodes, - [DPO_PROTO_MPLS] = NULL, -}; - -void -sixrd_dpo_module_init (void) -{ - sixrd_dpo_type = dpo_register_new_type(&sd_vft, sixrd_nodes); -} diff --git a/plugins/sixrd-plugin/sixrd/sixrd_dpo.h b/plugins/sixrd-plugin/sixrd/sixrd_dpo.h deleted file mode 100644 index 17142288451..00000000000 --- a/plugins/sixrd-plugin/sixrd/sixrd_dpo.h +++ /dev/null @@ -1,61 +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 __SIXRD_DPO_H__ -#define __SIXRD_DPO_H__ - -#include <vnet/vnet.h> -#include <vnet/dpo/dpo.h> - -/** - * A representation of a 6RD DPO - */ -typedef struct sixrd_dpo_t -{ - /** - * The dat-plane protocol - */ - dpo_proto_t sd_proto; - - /** - * the SIXRD domain index - */ - u32 sd_domain; - - /** - * Number of locks/users of the label - */ - u16 sd_locks; -} sixrd_dpo_t; - -extern void sixrd_dpo_create (dpo_proto_t dproto, - u32 domain_index, - dpo_id_t *dpo); - -/* - * Encapsulation violation for fast data-path access - */ -extern sixrd_dpo_t *sixrd_dpo_pool; -extern dpo_type_t sixrd_dpo_type; - -static inline sixrd_dpo_t * -sixrd_dpo_get (index_t index) -{ - return (pool_elt_at_index(sixrd_dpo_pool, index)); -} - -extern void sixrd_dpo_module_init(void); - -#endif |