diff options
Diffstat (limited to 'plugins/ioam-plugin/ioam/encap')
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.c | 232 | ||||
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.h | 47 | ||||
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_pot.c | 276 | ||||
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.c | 109 | ||||
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.h | 70 | ||||
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno_analyse.c | 141 | ||||
-rw-r--r-- | plugins/ioam-plugin/ioam/encap/ip6_ioam_trace.c | 438 |
7 files changed, 0 insertions, 1313 deletions
diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.c b/plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.c deleted file mode 100644 index 0839cdceca7..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> - -#include <vnet/ip/ip.h> - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vppinfra/elog.h> - -#include <vnet/ip/ip6_hop_by_hop.h> -#include <vnet/plugin/plugin.h> - -#include "ip6_ioam_e2e.h" - -ioam_e2e_main_t ioam_e2e_main; - -static u8 * ioam_e2e_trace_handler (u8 * s, - ip6_hop_by_hop_option_t *opt) -{ - ioam_e2e_option_t * e2e = (ioam_e2e_option_t *)opt; - u32 seqno = 0; - - if (e2e) - { - seqno = clib_net_to_host_u32 (e2e->e2e_data); - } - - s = format (s, "SeqNo = 0x%Lx", seqno); - return s; -} - -int -ioam_e2e_config_handler (void *data, u8 disable) -{ - int *analyse = data; - - /* Register hanlders if enabled */ - if (!disable) - { - /* If encap node register for encap handler */ - if (0 == *analyse) - { - if (ip6_hbh_register_option(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE, - ioam_seqno_encap_handler, - ioam_e2e_trace_handler) < 0) - { - return (-1); - } - } - /* If analyze node then register for decap handler */ - else - { - if (ip6_hbh_pop_register_option(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE, - ioam_seqno_decap_handler) < 0) - { - return (-1); - } - } - return 0; - } - - /* UnRegister handlers */ - (void) ip6_hbh_unregister_option(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE); - (void) ip6_hbh_pop_unregister_option(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE); - return 0; -} - -int -ioam_e2e_rewrite_handler (u8 *rewrite_string, - u8 *rewrite_size) -{ - ioam_e2e_option_t *e2e_option; - - if (rewrite_string && *rewrite_size == sizeof(ioam_e2e_option_t)) - { - e2e_option = (ioam_e2e_option_t *)rewrite_string; - e2e_option->hdr.type = HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE - | HBH_OPTION_TYPE_SKIP_UNKNOWN; - e2e_option->hdr.length = sizeof (ioam_e2e_option_t) - - sizeof (ip6_hop_by_hop_option_t); - return(0); - } - return(-1); -} - -u32 -ioam_e2e_flow_handler (u32 ctx, u8 add) -{ - ioam_e2e_data_t *data; - u16 i; - - if (add) - { - pool_get(ioam_e2e_main.e2e_data, data); - data->flow_ctx = ctx; - ioam_seqno_init_bitmap(&data->seqno_data); - return ((u32) (data - ioam_e2e_main.e2e_data)); - } - - /* Delete case */ - for (i = 0; i < vec_len(ioam_e2e_main.e2e_data); i++) - { - if (pool_is_free_index(ioam_e2e_main.e2e_data, i)) - continue; - - data = pool_elt_at_index(ioam_e2e_main.e2e_data, i); - if (data && (data->flow_ctx == ctx)) - { - pool_put_index(ioam_e2e_main.e2e_data, i); - return (0); - } - } - return 0; -} - -static clib_error_t * -ioam_show_e2e_cmd_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - ioam_e2e_data_t *e2e_data; - u8 *s = 0; - int i; - - vec_reset_length(s); - - s = format(0, "IOAM E2E information: \n"); - for (i = 0; i < vec_len(ioam_e2e_main.e2e_data); i++) - { - if (pool_is_free_index(ioam_e2e_main.e2e_data, i)) - continue; - - e2e_data = pool_elt_at_index(ioam_e2e_main.e2e_data, i); - s = format(s, "Flow name: %s\n", get_flow_name_from_flow_ctx(e2e_data->flow_ctx)); - - s = show_ioam_seqno_cmd_fn(s, - &e2e_data->seqno_data, - !IOAM_DEAP_ENABLED(e2e_data->flow_ctx)); - } - - vlib_cli_output(vm, "%v", s); - return 0; -} - - -VLIB_CLI_COMMAND (ioam_show_e2e_cmd, static) = { - .path = "show ioam e2e ", - .short_help = "show ioam e2e information", - .function = ioam_show_e2e_cmd_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; - - ioam_e2e_main.vlib_main = vm; - ioam_e2e_main.vnet_main = h->vnet_main; - return error; -} - -/* - * Init handler E2E headet handling. - * Init hanlder registers encap, decap, trace and Rewrite handlers. - */ -static clib_error_t * -ioam_e2e_init (vlib_main_t * vm) -{ - clib_error_t * error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init))) - { - return(error); - } - - /* - * As of now we have only PPC under E2E header. - */ - if (ip6_hbh_config_handler_register(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE, - ioam_e2e_config_handler) < 0) - { - return (clib_error_create("Registration of " - "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE for rewrite failed")); - } - - if (ip6_hbh_add_register_option(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE, - sizeof(ioam_e2e_option_t), - ioam_e2e_rewrite_handler) < 0) - { - return (clib_error_create("Registration of " - "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE for rewrite failed")); - } - - if (ip6_hbh_flow_handler_register(HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE, - ioam_e2e_flow_handler) < 0) - { - return (clib_error_create("Registration of " - "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE Flow handler failed")); - } - - return (0); -} - -/* - * Init function for the E2E lib. - * ip6_hop_by_hop_ioam_e2e_init gets called during init. - */ -VLIB_INIT_FUNCTION (ioam_e2e_init); diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.h b/plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.h deleted file mode 100644 index 18f35f80c60..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_e2e.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __included_ip6_ioam_e2e_h__ -#define __included_ip6_ioam_e2e_h__ - -#include "ip6_ioam_seqno.h" - -typedef struct ioam_e2e_data_t_ { - u32 flow_ctx; - u32 pad; - ioam_seqno_data seqno_data; -} ioam_e2e_data_t; - -typedef struct { - ioam_e2e_data_t *e2e_data; - vlib_main_t *vlib_main; - vnet_main_t *vnet_main; -} ioam_e2e_main_t; - -extern ioam_e2e_main_t ioam_e2e_main; - -static inline ioam_seqno_data * -ioam_e2ec_get_seqno_data_from_flow_ctx (u32 flow_ctx) -{ - ioam_e2e_data_t *data = NULL; - u32 index; - - index = get_flow_data_from_flow_ctx(flow_ctx, - HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE); - data = &ioam_e2e_main.e2e_data[index]; - return &(data->seqno_data); -} - -#endif /* __included_ioam_e2e_h__ */ diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_pot.c b/plugins/ioam-plugin/ioam/encap/ip6_ioam_pot.c deleted file mode 100644 index 05f42c91d0f..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_pot.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> - -#include <vnet/ip/ip6.h> -#include <vnet/ip/ip6_hop_by_hop.h> -#include <vnet/ip/ip6_hop_by_hop_packet.h> - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vppinfra/elog.h> - -#include <ioam/lib-pot/pot_util.h> - -typedef CLIB_PACKED(struct { - ip6_hop_by_hop_option_t hdr; - u8 pot_type; -#define PROFILE_ID_MASK 0xF - u8 reserved_profile_id; /* 4 bits reserved, 4 bits to carry profile id */ - u64 random; - u64 cumulative; -}) ioam_pot_option_t; - -#define foreach_ip6_hop_by_hop_ioam_pot_stats \ - _(PROCESSED, "Pkts with ip6 hop-by-hop pot options") \ - _(PROFILE_MISS, "Pkts with ip6 hop-by-hop pot options but no profile set") \ - _(PASSED, "Pkts with POT in Policy") \ - _(FAILED, "Pkts with POT out of Policy") - -static char * ip6_hop_by_hop_ioam_pot_stats_strings[] = { -#define _(sym,string) string, - foreach_ip6_hop_by_hop_ioam_pot_stats -#undef _ -}; - -typedef enum { -#define _(sym,str) IP6_IOAM_POT_##sym, - foreach_ip6_hop_by_hop_ioam_pot_stats -#undef _ - IP6_IOAM_POT_N_STATS, -} ip6_ioam_pot_stats_t; - -typedef struct { - /* stats */ - u64 counters[ARRAY_LEN(ip6_hop_by_hop_ioam_pot_stats_strings)]; - - /* convenience */ - vlib_main_t * vlib_main; - vnet_main_t * vnet_main; -} ip6_hop_by_hop_ioam_pot_main_t; - -ip6_hop_by_hop_ioam_pot_main_t ip6_hop_by_hop_ioam_pot_main; - -always_inline void -ip6_ioam_stats_increment_counter (u32 counter_index, u64 increment) -{ - ip6_hop_by_hop_ioam_pot_main_t *hm = &ip6_hop_by_hop_ioam_pot_main; - - hm->counters[counter_index] += increment; -} - - -static u8 * format_ioam_pot (u8 * s, va_list * args) -{ - ioam_pot_option_t * pot0 = va_arg (*args, ioam_pot_option_t *); - u64 random, cumulative; - random = cumulative = 0; - if (pot0) - { - random = clib_net_to_host_u64 (pot0->random); - cumulative = clib_net_to_host_u64 (pot0->cumulative); - } - - s = format (s, "random = 0x%Lx, Cumulative = 0x%Lx, Index = 0x%x", - random, cumulative, pot0 ? pot0->reserved_profile_id : ~0); - return s; -} - -u8 * -ip6_hbh_ioam_proof_of_transit_trace_handler (u8 *s, ip6_hop_by_hop_option_t *opt) -{ - ioam_pot_option_t *pot; - - s = format (s, " POT opt present\n"); - pot = (ioam_pot_option_t *) opt; - s = format (s, " %U\n", format_ioam_pot, pot); - return (s); -} - -int -ip6_hbh_ioam_proof_of_transit_handler (vlib_buffer_t *b, - ip6_header_t *ip, - ip6_hop_by_hop_option_t *opt0) -{ - ioam_pot_option_t * pot0; - u64 random = 0, cumulative = 0; - int rv = 0; - u8 pot_profile_index; - pot_profile *pot_profile = 0, *new_profile = 0; - u8 pot_encap = 0; - - pot0 = (ioam_pot_option_t *) opt0; - pot_encap = (pot0->random == 0); - pot_profile_index = pot_profile_get_active_id(); - pot_profile = pot_profile_get_active(); - if (pot_encap && PREDICT_FALSE(!pot_profile)) - { - ip6_ioam_stats_increment_counter (IP6_IOAM_POT_PROFILE_MISS, 1); - return(-1); - } - if (pot_encap) - { - pot0->reserved_profile_id = - pot_profile_index & PROFILE_ID_MASK; - pot_profile_incr_usage_stats(pot_profile); - } - else - { /* Non encap node */ - if (PREDICT_FALSE(pot0->reserved_profile_id != - pot_profile_index || pot_profile == 0)) - { - /* New profile announced by encap node. */ - new_profile = - pot_profile_find(pot0->reserved_profile_id); - if (PREDICT_FALSE(new_profile == 0 || - new_profile->valid == 0)) - { - ip6_ioam_stats_increment_counter (IP6_IOAM_POT_PROFILE_MISS, 1); - return(-1); - } - else - { - pot_profile_index = pot0->reserved_profile_id; - pot_profile = new_profile; - pot_profile_set_active(pot_profile_index); - pot_profile_reset_usage_stats(pot_profile); - } - } - pot_profile_incr_usage_stats(pot_profile); - } - - if (pot0->random == 0) - { - pot0->random = clib_host_to_net_u64(pot_generate_random(pot_profile)); - pot0->cumulative = 0; - } - random = clib_net_to_host_u64(pot0->random); - cumulative = clib_net_to_host_u64(pot0->cumulative); - pot0->cumulative = clib_host_to_net_u64( - pot_update_cumulative(pot_profile, - cumulative, - random)); - ip6_ioam_stats_increment_counter (IP6_IOAM_POT_PROCESSED, 1); - - return (rv); -} - -int -ip6_hbh_ioam_proof_of_transit_pop_handler (vlib_buffer_t *b, ip6_header_t *ip, - ip6_hop_by_hop_option_t *opt0) -{ - ioam_pot_option_t * pot0; - u64 random = 0; - u64 cumulative = 0; - int rv = 0; - pot_profile *pot_profile = 0; - u8 result = 0; - - pot0 = (ioam_pot_option_t *) opt0; - random = clib_net_to_host_u64(pot0->random); - cumulative = clib_net_to_host_u64(pot0->cumulative); - pot_profile = pot_profile_get_active(); - result = pot_validate (pot_profile, - cumulative, random); - - if (result == 1) - { - ip6_ioam_stats_increment_counter (IP6_IOAM_POT_PASSED, 1); - } - else - { - ip6_ioam_stats_increment_counter (IP6_IOAM_POT_FAILED, 1); - } - return (rv); -} - -int ip6_hop_by_hop_ioam_pot_rewrite_handler (u8 *rewrite_string, u8 *rewrite_size) -{ - ioam_pot_option_t * pot_option; - if (rewrite_string && *rewrite_size == sizeof(ioam_pot_option_t)) - { - pot_option = (ioam_pot_option_t *)rewrite_string; - pot_option->hdr.type = HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT - | HBH_OPTION_TYPE_DATA_CHANGE_ENROUTE; - pot_option->hdr.length = sizeof (ioam_pot_option_t) - - sizeof (ip6_hop_by_hop_option_t); - return(0); - } - return(-1); -} - -static clib_error_t * -ip6_show_ioam_pot_cmd_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - ip6_hop_by_hop_ioam_pot_main_t *hm = &ip6_hop_by_hop_ioam_pot_main; - u8 *s = 0; - int i = 0; - - for ( i = 0; i < IP6_IOAM_POT_N_STATS; i++) - { - s = format(s, " %s - %lu\n", ip6_hop_by_hop_ioam_pot_stats_strings[i], - hm->counters[i]); - } - - vlib_cli_output(vm, "%v", s); - vec_free(s); - return 0; -} - - -VLIB_CLI_COMMAND (ip6_show_ioam_pot_cmd, static) = { - .path = "show ioam pot", - .short_help = "iOAM pot statistics", - .function = ip6_show_ioam_pot_cmd_fn, -}; - - -static clib_error_t * -ip6_hop_by_hop_ioam_pot_init (vlib_main_t * vm) -{ - ip6_hop_by_hop_ioam_pot_main_t * hm = &ip6_hop_by_hop_ioam_pot_main; - clib_error_t * error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init))) - return(error); - - hm->vlib_main = vm; - hm->vnet_main = vnet_get_main(); - memset(hm->counters, 0, sizeof(hm->counters)); - - if (ip6_hbh_register_option(HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT, ip6_hbh_ioam_proof_of_transit_handler, - ip6_hbh_ioam_proof_of_transit_trace_handler) < 0) - return (clib_error_create("registration of HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT failed")); - - if (ip6_hbh_add_register_option(HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT, - sizeof(ioam_pot_option_t), - ip6_hop_by_hop_ioam_pot_rewrite_handler) < 0) - return (clib_error_create("registration of HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT for rewrite failed")); - - if (ip6_hbh_pop_register_option(HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT, - ip6_hbh_ioam_proof_of_transit_pop_handler) < 0) - return (clib_error_create("registration of HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT POP failed")); - - return (0); -} - -VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_pot_init); - - diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.c b/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.c deleted file mode 100644 index 0b4d4192975..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> - -#include <vnet/ip/ip.h> - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vppinfra/elog.h> - -#include "ip6_ioam_seqno.h" -#include "ip6_ioam_e2e.h" - -ioam_seqno_data_main_t ioam_seqno_main; - -void ioam_seqno_init_bitmap (ioam_seqno_data *data) -{ - seqno_bitmap *bitmap = &data->seqno_rx.bitmap; - bitmap->window_size = SEQNO_WINDOW_SIZE; - bitmap->array_size = SEQNO_WINDOW_ARRAY_SIZE; - bitmap->mask = 32 * SEQNO_WINDOW_ARRAY_SIZE - 1; - bitmap->array[0] = 0x00000000;/* pretend we haven seen sequence numbers 0*/ - bitmap->highest = 0; - - data->seq_num = 0; - return ; -} - -/* - * This Routine gets called from IPv6 hop-by-hop option handling. - * Only if we are encap node, then add PPC data. - * On a Transit(MID) node we dont do anything with E2E headers. - * On decap node decap is handled by seperate function. - */ -int -ioam_seqno_encap_handler (vlib_buffer_t *b, ip6_header_t *ip, - ip6_hop_by_hop_option_t *opt) -{ - u32 opaque_index = vnet_buffer(b)->l2_classify.opaque_index; - ioam_e2e_option_t * e2e; - int rv = 0; - ioam_seqno_data *data; - - data = ioam_e2ec_get_seqno_data_from_flow_ctx(opaque_index); - e2e = (ioam_e2e_option_t *) opt; - e2e->e2e_data = clib_host_to_net_u32(++data->seq_num); - - return (rv); -} - -/* - * This Routine gets called on POP/Decap node. - */ -int -ioam_seqno_decap_handler (vlib_buffer_t *b, ip6_header_t *ip, - ip6_hop_by_hop_option_t *opt) -{ - u32 opaque_index = vnet_buffer(b)->l2_classify.opaque_index; - ioam_e2e_option_t * e2e; - int rv = 0; - ioam_seqno_data *data; - - data = ioam_e2ec_get_seqno_data_from_flow_ctx(opaque_index); - e2e = (ioam_e2e_option_t *) opt; - ioam_analyze_seqno(&data->seqno_rx, (u64) clib_net_to_host_u32(e2e->e2e_data)); - - return (rv); -} - -u8 * -show_ioam_seqno_cmd_fn (u8 *s, ioam_seqno_data *seqno_data, u8 enc) -{ - seqno_rx_info *rx; - - s = format(s, "SeqNo Data:\n"); - if (enc) - { - s = format(s, " Current Seq. Number : %llu\n", seqno_data->seq_num); - } - else - { - rx = &seqno_data->seqno_rx; - s = format(s, " Highest Seq. Number : %llu\n", rx->bitmap.highest); - s = format(s, " Packets received : %llu\n", rx->rx_packets); - s = format(s, " Lost packets : %llu\n", rx->lost_packets); - s = format(s, " Reordered packets : %llu\n", rx->reordered_packets); - s = format(s, " Duplicate packets : %llu\n", rx->dup_packets); - } - - format(s, "\n"); - return s; -} diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.h b/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.h deleted file mode 100644 index 13a84db0d71..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __included_ip6_ioam_seqno_h__ -#define __included_ip6_ioam_seqno_h__ - -#include <vnet/ip/ip6_packet.h> -#include <vnet/ip/ip6_hop_by_hop.h> - -#define SEQ_CHECK_VALUE 0x80000000 /* for seq number wraparound detection */ - -#define SEQNO_WINDOW_SIZE 2048 -#define SEQNO_WINDOW_ARRAY_SIZE 64 - -typedef struct seqno_bitmap_ { - u32 window_size; - u32 array_size; - u32 mask; - u32 pad; - u64 highest; - u64 array[SEQNO_WINDOW_ARRAY_SIZE]; /* Will be alloc to array_size */ -} seqno_bitmap; - -typedef struct seqno_rx_info_ { - u64 rx_packets; - u64 lost_packets; - u64 reordered_packets; - u64 dup_packets; - seqno_bitmap bitmap; -} seqno_rx_info; - -/* This structure is 64-byte aligned */ -typedef struct ioam_seqno_data_ { - union { - u32 seq_num; /* Useful only for encap node */ - seqno_rx_info seqno_rx; - }; -} ioam_seqno_data; - -typedef struct ioam_seqno_data_main_t_ { - ioam_seqno_data *seqno_data; -} ioam_seqno_data_main_t; - -void ioam_seqno_init_bitmap(ioam_seqno_data *data); - -int ioam_seqno_encap_handler(vlib_buffer_t *b, ip6_header_t *ip, - ip6_hop_by_hop_option_t *opt); - -int -ioam_seqno_decap_handler(vlib_buffer_t *b, ip6_header_t *ip, - ip6_hop_by_hop_option_t *opt); - -void ioam_analyze_seqno(seqno_rx_info *ppc_rx, u64 seqno); - -u8 * -show_ioam_seqno_cmd_fn(u8 *s, ioam_seqno_data *seqno_data, u8 enc); - -#endif diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno_analyse.c b/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno_analyse.c deleted file mode 100644 index 4638871c224..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_seqno_analyse.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vnet/vnet.h> -#include "ip6_ioam_seqno.h" - -static inline void BIT_SET (u64 *p, u32 n) -{ - p[ n>>5 ] |= (1 << (n&31)); -} - -static inline int BIT_TEST (u64 *p, u32 n) -{ - return p[ n>>5 ] & (1 << (n&31)); -} - -static void BIT_CLEAR (u64 *p, u64 start, int num_bits, u32 mask) -{ - int n, t; - int start_index = (start >> 5); - int mask_index = (mask >> 5); - - start_index &= mask_index; - if (start & 0x1f) - { - int start_bit = (start & 0x1f); - - n = (1 << start_bit)-1; - t = start_bit + num_bits; - if (t < 32) - { - n |= ~((1 << t)-1); - p[ start_index ] &= n; - return; - } - p[ start_index ] &= n; - start_index = (start_index + 1) & mask_index; - num_bits -= (32 - start_bit); - } - while (num_bits >= 32) - { - p[ start_index ] = 0; - start_index = (start_index + 1) & mask_index; - num_bits -= 32; - } - n = ~((1 << num_bits) - 1); - p[ start_index ] &= n; -} - -static inline u8 seqno_check_wraparound(u32 a, u32 b) -{ - if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE)) - { - return 1; - } - return 0; -} - -/* - * Function to analyze the PPC value recevied. - * - Updates the bitmap with received sequence number - * - counts the received/lost/duplicate/reordered packets - */ -void ioam_analyze_seqno (seqno_rx_info *seqno_rx, u64 seqno) -{ - int diff; - static int peer_dead_count; - seqno_bitmap *bitmap = &seqno_rx->bitmap; - - seqno_rx->rx_packets++; - - if (seqno > bitmap->highest) - { /* new larger sequence number */ - peer_dead_count = 0; - diff = seqno - bitmap->highest; - if (diff < bitmap->window_size) - { - if (diff > 1) - { /* diff==1 is *such* a common case it's a win to optimize it */ - BIT_CLEAR(bitmap->array, bitmap->highest+1, diff-1, bitmap->mask); - seqno_rx->lost_packets += diff -1; - } - } - else - { - seqno_rx->lost_packets += diff -1; - memset( bitmap->array, 0, bitmap->array_size * sizeof(u64) ); - } - BIT_SET(bitmap->array, seqno & bitmap->mask); - bitmap->highest = seqno; - return; - } - - /* we've seen a bigger seq number before */ - diff = bitmap->highest - seqno; - if (diff >= bitmap->window_size) - { - if (seqno_check_wraparound(bitmap->highest, seqno)) - { - memset( bitmap->array, 0, bitmap->array_size * sizeof(u64)); - BIT_SET(bitmap->array, seqno & bitmap->mask); - bitmap->highest = seqno; - return; - } - else - { - peer_dead_count++; - if (peer_dead_count > 25) - { - peer_dead_count = 0; - memset( bitmap->array, 0, bitmap->array_size * sizeof(u64) ); - BIT_SET(bitmap->array, seqno & bitmap->mask); - bitmap->highest = seqno; - } - //ppc_rx->reordered_packets++; - } - return; - } - - if (BIT_TEST(bitmap->array, seqno & bitmap->mask)) - { - seqno_rx->dup_packets++; - return; /* Already seen */ - } - seqno_rx->reordered_packets++; - seqno_rx->lost_packets--; - BIT_SET(bitmap->array, seqno & bitmap->mask); - return; -} diff --git a/plugins/ioam-plugin/ioam/encap/ip6_ioam_trace.c b/plugins/ioam-plugin/ioam/encap/ip6_ioam_trace.c deleted file mode 100644 index e63db6e4ec5..00000000000 --- a/plugins/ioam-plugin/ioam/encap/ip6_ioam_trace.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vlib/vlib.h> -#include <vnet/vnet.h> -#include <vnet/pg/pg.h> -#include <vppinfra/error.h> - -#include <vnet/ip/ip6.h> -#include <vnet/ip/ip6_hop_by_hop.h> -#include <vnet/ip/ip6_hop_by_hop_packet.h> - -#include <vppinfra/hash.h> -#include <vppinfra/error.h> -#include <vppinfra/elog.h> - -#include <ioam/lib-trace/trace_util.h> - -/* Timestamp precision multipliers for seconds, milliseconds, microseconds - * and nanoseconds respectively. - */ -static f64 trace_tsp_mul[4] = { 1, 1e3, 1e6, 1e9 }; - -typedef union -{ - u64 as_u64; - u32 as_u32[2]; -} time_u64_t; - -/* *INDENT-OFF* */ -typedef CLIB_PACKED(struct { - ip6_hop_by_hop_option_t hdr; - u8 ioam_trace_type; - u8 data_list_elts_left; - u32 elts[0]; /* Variable type. So keep it generic */ -}) ioam_trace_option_t; -/* *INDENT-ON* */ - - -extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main; -extern ip6_main_t ip6_main; - -#define foreach_ip6_hop_by_hop_ioam_trace_stats \ - _(PROCESSED, "Pkts with ip6 hop-by-hop trace options") \ - _(PROFILE_MISS, "Pkts with ip6 hop-by-hop trace options but no profile set") \ - _(UPDATED, "Pkts with trace updated") \ - _(FULL, "Pkts with trace options but no space") - -static char *ip6_hop_by_hop_ioam_trace_stats_strings[] = { -#define _(sym,string) string, - foreach_ip6_hop_by_hop_ioam_trace_stats -#undef _ -}; - -typedef enum -{ -#define _(sym,str) IP6_IOAM_TRACE_##sym, - foreach_ip6_hop_by_hop_ioam_trace_stats -#undef _ - IP6_IOAM_TRACE_N_STATS, -} ip6_ioam_trace_stats_t; - - -typedef struct -{ - /* stats */ - u64 counters[ARRAY_LEN (ip6_hop_by_hop_ioam_trace_stats_strings)]; - - /* convenience */ - vlib_main_t *vlib_main; - vnet_main_t *vnet_main; -} ip6_hop_by_hop_ioam_trace_main_t; - -ip6_hop_by_hop_ioam_trace_main_t ip6_hop_by_hop_ioam_trace_main; - -always_inline void -ip6_ioam_trace_stats_increment_counter (u32 counter_index, u64 increment) -{ - ip6_hop_by_hop_ioam_trace_main_t *hm = &ip6_hop_by_hop_ioam_trace_main; - - hm->counters[counter_index] += increment; -} - - -static u8 * -format_ioam_data_list_element (u8 * s, va_list * args) -{ - u32 *elt = va_arg (*args, u32 *); - u8 *trace_type_p = va_arg (*args, u8 *); - u8 trace_type = *trace_type_p; - - - if (trace_type & BIT_TTL_NODEID) - { - u32 ttl_node_id_host_byte_order = clib_net_to_host_u32 (*elt); - s = format (s, "ttl 0x%x node id 0x%x ", - ttl_node_id_host_byte_order >> 24, - ttl_node_id_host_byte_order & 0x00FFFFFF); - - elt++; - } - - if (trace_type & BIT_ING_INTERFACE && trace_type & BIT_ING_INTERFACE) - { - u32 ingress_host_byte_order = clib_net_to_host_u32 (*elt); - s = format (s, "ingress 0x%x egress 0x%x ", - ingress_host_byte_order >> 16, - ingress_host_byte_order & 0xFFFF); - elt++; - } - - if (trace_type & BIT_TIMESTAMP) - { - u32 ts_in_host_byte_order = clib_net_to_host_u32 (*elt); - s = format (s, "ts 0x%x \n", ts_in_host_byte_order); - elt++; - } - - if (trace_type & BIT_APPDATA) - { - u32 appdata_in_host_byte_order = clib_net_to_host_u32 (*elt); - s = format (s, "app 0x%x ", appdata_in_host_byte_order); - elt++; - } - - return s; -} - - -int -ip6_ioam_trace_get_sizeof_handler (u32 * result) -{ - u16 size = 0; - u8 trace_data_size = 0; - trace_profile *profile = NULL; - - *result = 0; - - profile = trace_profile_find (); - - if (PREDICT_FALSE (!profile)) - { - ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_PROFILE_MISS, 1); - return (-1); - } - - trace_data_size = fetch_trace_data_size (profile->trace_type); - if (PREDICT_FALSE (trace_data_size == 0)) - return VNET_API_ERROR_INVALID_VALUE; - - if (PREDICT_FALSE (profile->num_elts * trace_data_size > 254)) - return VNET_API_ERROR_INVALID_VALUE; - - size += - sizeof (ioam_trace_option_t) + (profile->num_elts * trace_data_size); - *result = size; - - return 0; -} - - - -int -ip6_hop_by_hop_ioam_trace_rewrite_handler (u8 * rewrite_string, - u8 * rewrite_size) -{ - ioam_trace_option_t *trace_option = NULL; - u8 trace_data_size = 0; - u8 trace_option_elts = 0; - trace_profile *profile = NULL; - - - profile = trace_profile_find (); - - if (PREDICT_FALSE (!profile)) - { - ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_PROFILE_MISS, 1); - return (-1); - } - - if (PREDICT_FALSE (!rewrite_string)) - return -1; - - trace_option_elts = profile->num_elts; - trace_data_size = fetch_trace_data_size (profile->trace_type); - trace_option = (ioam_trace_option_t *) rewrite_string; - trace_option->hdr.type = HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST | - HBH_OPTION_TYPE_DATA_CHANGE_ENROUTE; - trace_option->hdr.length = 2 /*ioam_trace_type,data_list_elts_left */ + - trace_option_elts * trace_data_size; - trace_option->ioam_trace_type = profile->trace_type & TRACE_TYPE_MASK; - trace_option->data_list_elts_left = trace_option_elts; - *rewrite_size = - sizeof (ioam_trace_option_t) + (trace_option_elts * trace_data_size); - - return 0; -} - - -int -ip6_hbh_ioam_trace_data_list_handler (vlib_buffer_t * b, ip6_header_t * ip, - ip6_hop_by_hop_option_t * opt) -{ - ip6_main_t *im = &ip6_main; - ip_lookup_main_t *lm = &im->lookup_main; - ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main; - u8 elt_index = 0; - ioam_trace_option_t *trace = (ioam_trace_option_t *) opt; - u32 adj_index = vnet_buffer (b)->ip.adj_index[VLIB_TX]; - ip_adjacency_t *adj = ip_get_adjacency (lm, adj_index); - time_u64_t time_u64; - u32 *elt; - int rv = 0; - trace_profile *profile = NULL; - - - profile = trace_profile_find (); - - if (PREDICT_FALSE (!profile)) - { - ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_PROFILE_MISS, 1); - return (-1); - } - - - time_u64.as_u64 = 0; - - if (PREDICT_TRUE (trace->data_list_elts_left)) - { - trace->data_list_elts_left--; - /* fetch_trace_data_size returns in bytes. Convert it to 4-bytes - * to skip to this node's location. - */ - elt_index = - trace->data_list_elts_left * - fetch_trace_data_size (trace->ioam_trace_type) / 4; - elt = &trace->elts[elt_index]; - if (trace->ioam_trace_type & BIT_TTL_NODEID) - { - *elt = - clib_host_to_net_u32 ((ip->hop_limit << 24) | profile->node_id); - elt++; - } - - if (trace->ioam_trace_type & BIT_ING_INTERFACE) - { - *elt = - (vnet_buffer (b)->sw_if_index[VLIB_RX] & 0xFFFF) << 16 | - (adj->rewrite_header.sw_if_index & 0xFFFF); - *elt = clib_host_to_net_u32 (*elt); - elt++; - } - - if (trace->ioam_trace_type & BIT_TIMESTAMP) - { - /* Send least significant 32 bits */ - f64 time_f64 = - (f64) (((f64) hm->unix_time_0) + - (vlib_time_now (hm->vlib_main) - hm->vlib_time_0)); - - time_u64.as_u64 = time_f64 * trace_tsp_mul[profile->trace_tsp]; - *elt = clib_host_to_net_u32 (time_u64.as_u32[0]); - elt++; - } - - if (trace->ioam_trace_type & BIT_APPDATA) - { - /* $$$ set elt0->app_data */ - *elt = clib_host_to_net_u32 (profile->app_data); - elt++; - } - ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_UPDATED, 1); - } - else - { - ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_FULL, 1); - } - return (rv); -} - -u8 * -ip6_hbh_ioam_trace_data_list_trace_handler (u8 * s, - ip6_hop_by_hop_option_t * opt) -{ - ioam_trace_option_t *trace; - u8 trace_data_size_in_words = 0; - u32 *elt; - int elt_index = 0; - - trace = (ioam_trace_option_t *) opt; - s = - format (s, " Trace Type 0x%x , %d elts left\n", trace->ioam_trace_type, - trace->data_list_elts_left); - trace_data_size_in_words = - fetch_trace_data_size (trace->ioam_trace_type) / 4; - elt = &trace->elts[0]; - while ((u8 *) elt < ((u8 *) (&trace->elts[0]) + trace->hdr.length - 2 - /* -2 accounts for ioam_trace_type,elts_left */ )) - { - s = format (s, " [%d] %U\n", elt_index, - format_ioam_data_list_element, - elt, &trace->ioam_trace_type); - elt_index++; - elt += trace_data_size_in_words; - } - return (s); -} - - -static clib_error_t * -ip6_show_ioam_trace_cmd_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - ip6_hop_by_hop_ioam_trace_main_t *hm = &ip6_hop_by_hop_ioam_trace_main; - u8 *s = 0; - int i = 0; - - for (i = 0; i < IP6_IOAM_TRACE_N_STATS; i++) - { - s = - format (s, " %s - %lu\n", ip6_hop_by_hop_ioam_trace_stats_strings[i], - hm->counters[i]); - } - - vlib_cli_output (vm, "%v", s); - vec_free (s); - return 0; -} - - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (ip6_show_ioam_trace_cmd, static) = { - .path = "show ioam trace", - .short_help = "iOAM trace statistics", - .function = ip6_show_ioam_trace_cmd_fn, -}; -/* *INDENT-ON* */ - - -static clib_error_t * -ip6_hop_by_hop_ioam_trace_init (vlib_main_t * vm) -{ - ip6_hop_by_hop_ioam_trace_main_t *hm = &ip6_hop_by_hop_ioam_trace_main; - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, ip_main_init))) - return (error); - - if ((error = vlib_call_init_function (vm, ip6_lookup_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init))) - return (error); - - hm->vlib_main = vm; - hm->vnet_main = vnet_get_main (); - memset (hm->counters, 0, sizeof (hm->counters)); - - - if (ip6_hbh_register_option - (HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST, - ip6_hbh_ioam_trace_data_list_handler, - ip6_hbh_ioam_trace_data_list_trace_handler) < 0) - return (clib_error_create - ("registration of HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST failed")); - - - if (ip6_hbh_add_register_option (HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST, - sizeof (ioam_trace_option_t), - ip6_hop_by_hop_ioam_trace_rewrite_handler) - < 0) - return (clib_error_create - ("registration of HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST for rewrite failed")); - - - return (0); -} - -int -ip6_trace_profile_cleanup (void) -{ - ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main; - - hm->options_size[HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST] = 0; - - return 0; - -} - - -int -ip6_trace_profile_setup (void) -{ - u32 trace_size = 0; - ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main; - - trace_profile *profile = NULL; - - - profile = trace_profile_find (); - - if (PREDICT_FALSE (!profile)) - { - ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_PROFILE_MISS, 1); - return (-1); - } - - - if (ip6_ioam_trace_get_sizeof_handler (&trace_size) < 0) - return (-1); - - hm->options_size[HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST] = trace_size; - - return (0); -} - - -VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_trace_init); - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |