/*
- * Copyright (c) 2015 Cisco and/or its affiliates.
+ * 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:
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef __included_ip6_hop_by_hop_h__
-#define __included_ip6_hop_by_hop_h__
+#ifndef __included_ip6_hop_by_hop_ioam_h__
+#define __included_ip6_hop_by_hop_ioam_h__
#include <vnet/ip/ip6_hop_by_hop_packet.h>
#include <vnet/ip/ip.h>
+
+#define MAX_IP6_HBH_OPTION 256
+
+/* To determine whether a node is decap MS bit is set */
+#define IOAM_DECAP_BIT 0x80000000
+
+#define IOAM_DEAP_ENABLED(opaque_data) (opaque_data & IOAM_DECAP_BIT)
+
+#define IOAM_SET_DECAP(opaque_data) \
+ (opaque_data |= IOAM_DECAP_BIT)
+
+#define IOAM_MASK_DECAP_BIT(x) (x & ~IOAM_DECAP_BIT)
+
+/*
+ * Stores the run time flow data of hbh options
+ */
+typedef struct {
+ u32 ctx[MAX_IP6_HBH_OPTION];
+ u8 flow_name[64];
+} flow_data_t;
+
typedef struct {
/* The current rewrite we're using */
u8 * rewrite;
/* Trace option */
- u8 trace_type;
- u8 trace_option_elts;
+ u8 has_trace_option;
- /* Configured node-id */
- u32 node_id;
- u32 app_data;
+ /* Pot option */
+ u8 has_pot_option;
- /* PoW option */
- u8 has_pow_option;
+ /* Per Packet Counter option */
+ u8 has_seqno_option;
-#define PPC_NONE 0
-#define PPC_ENCAP 1
-#define PPC_DECAP 2
- u8 has_ppc_option;
+ /* Enabling analyis of iOAM data on decap node */
+ u8 has_analyse_option;
#define TSP_SECONDS 0
#define TSP_MILLISECONDS 1
#define TSP_MICROSECONDS 2
#define TSP_NANOSECONDS 3
- /* Time stamp precision. This is enumerated to above four options */
- u32 trace_tsp;
+
+ /* Array of function pointers to ADD and POP HBH option handling routines */
+ u8 options_size[MAX_IP6_HBH_OPTION];
+ int (*add_options[MAX_IP6_HBH_OPTION])(u8 *rewrite_string, u8 *rewrite_size);
+ int (*pop_options[MAX_IP6_HBH_OPTION])(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt);
+ int (*get_sizeof_options[MAX_IP6_HBH_OPTION])(u32 *rewrite_size);
+ int (*config_handler[MAX_IP6_HBH_OPTION]) (void *data, u8 disable);
+
+ /* Array of function pointers to handle hbh options being used with classifier */
+ u32 (*flow_handler[MAX_IP6_HBH_OPTION])(u32 flow_ctx, u8 add);
+ flow_data_t *flows;
/* convenience */
vlib_main_t * vlib_main;
vnet_main_t * vnet_main;
-} ip6_hop_by_hop_main_t;
+} ip6_hop_by_hop_ioam_main_t;
-extern ip6_hop_by_hop_main_t ip6_hop_by_hop_main;
+extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
extern u8 * format_path_map(u8 * s, va_list * args);
+
extern clib_error_t *
-ip6_ioam_trace_profile_set(u32 trace_option_elts, u32 trace_type, u32 node_id,
- u32 app_data, int has_pow_option, u32 trace_tsp,
- int has_e2e_option);
+ip6_ioam_enable(int has_trace_option, int has_pot_option,
+ int has_seqno_option, int has_analyse_option);
+
extern int ip6_ioam_set_destination (ip6_address_t *addr, u32 mask_width,
u32 vrf_id, int is_add, int is_pop, int is_none);
return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0));
}
-extern ip6_hop_by_hop_main_t * hm;
-#endif /* __included_ip6_hop_by_hop_h__ */
+int ip6_hbh_add_register_option (u8 option,
+ u8 size,
+ int rewrite_options(u8 *rewrite_string, u8 *size));
+int ip6_hbh_add_unregister_option (u8 option);
+
+int ip6_hbh_pop_register_option (u8 option,
+ int options(vlib_buffer_t *b,
+ ip6_header_t *ip, ip6_hop_by_hop_option_t *opt));
+int ip6_hbh_pop_unregister_option (u8 option);
+
+int
+ip6_hbh_get_sizeof_register_option (u8 option,
+ int get_sizeof_hdr_options(u32 *rewrite_size));
+
+int
+ip6_ioam_set_rewrite (u8 **rwp, int has_trace_option,
+ int has_pot_option, int has_seq_no);
+
+int
+ip6_hbh_config_handler_register (u8 option,
+ int config_handler(void *data, u8 disable));
+
+int ip6_hbh_config_handler_unregister (u8 option);
+
+int ip6_hbh_flow_handler_register(u8 option,
+ u32 ioam_flow_handler(u32 flow_ctx, u8 add));
+
+int ip6_hbh_flow_handler_unregister(u8 option);
+
+u8 * get_flow_name_from_flow_ctx(u32 flow_ctx);
+
+static inline flow_data_t * get_flow (u32 index)
+{
+ flow_data_t *flow = NULL;
+ ip6_hop_by_hop_ioam_main_t * hm = &ip6_hop_by_hop_ioam_main;
+
+ if (pool_is_free_index (hm->flows, index))
+ return NULL;
+
+ flow = pool_elt_at_index (hm->flows, index);
+ return flow;
+}
+
+static inline u32 get_flow_data_from_flow_ctx (u32 flow_ctx, u8 option)
+{
+ flow_data_t *flow = NULL;
+ ip6_hop_by_hop_ioam_main_t * hm = &ip6_hop_by_hop_ioam_main;
+ u32 index;
+
+ index = IOAM_MASK_DECAP_BIT(flow_ctx);
+ //flow = pool_elt_at_index (hm->flows, index);
+ flow = &hm->flows[index];
+ return (flow->ctx[option]);
+}
+
+static inline u8 is_seqno_enabled (void)
+{
+ return (ip6_hop_by_hop_ioam_main.has_seqno_option);
+}
+
+#endif /* __included_ip6_hop_by_hop_ioam_h__ */