2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
15 #ifndef __included_ip6_hop_by_hop_ioam_h__
16 #define __included_ip6_hop_by_hop_ioam_h__
18 #include <vnet/ip/ip6_hop_by_hop_packet.h>
19 #include <vnet/ip/ip.h>
22 #define MAX_IP6_HBH_OPTION 256
24 /* To determine whether a node is decap MS bit is set */
25 #define IOAM_DECAP_BIT 0x80000000
27 #define IOAM_DEAP_ENABLED(opaque_data) (opaque_data & IOAM_DECAP_BIT)
29 #define IOAM_SET_DECAP(opaque_data) \
30 (opaque_data |= IOAM_DECAP_BIT)
32 #define IOAM_MASK_DECAP_BIT(x) (x & ~IOAM_DECAP_BIT)
35 * Stores the run time flow data of hbh options
39 u32 ctx[MAX_IP6_HBH_OPTION];
45 u8 next_index_by_protocol[256];
46 } ip6_local_hop_by_hop_runtime_t;
50 /* The current rewrite we're using */
53 /* Trace data processing callback */
54 void *ioam_end_of_path_cb;
55 /* Configuration data */
58 #define IOAM_HBYH_ADD 0
59 #define IOAM_HBYH_MOD 1
60 #define IOAM_HBYH_POP 2
62 /* time scale transform. Joy. */
73 /* Per Packet Counter option */
76 /* Enabling analyis of iOAM data on decap node */
77 u8 has_analyse_option;
79 /* Array of function pointers to ADD and POP HBH option handling routines */
80 u8 options_size[MAX_IP6_HBH_OPTION];
81 int (*add_options[MAX_IP6_HBH_OPTION]) (u8 * rewrite_string,
83 int (*pop_options[MAX_IP6_HBH_OPTION]) (vlib_buffer_t * b,
85 ip6_hop_by_hop_option_t * opt);
86 int (*get_sizeof_options[MAX_IP6_HBH_OPTION]) (u32 * rewrite_size);
87 int (*config_handler[MAX_IP6_HBH_OPTION]) (void *data, u8 disable);
89 /* Array of function pointers to handle hbh options being used with classifier */
90 u32 (*flow_handler[MAX_IP6_HBH_OPTION]) (u32 flow_ctx, u8 add);
93 ip6_local_hop_by_hop_runtime_t *ip6_local_hbh_runtime;
96 vlib_main_t *vlib_main;
97 vnet_main_t *vnet_main;
98 } ip6_hop_by_hop_ioam_main_t;
100 extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
102 extern clib_error_t *ip6_ioam_enable (int has_trace_option,
104 int has_seqno_option,
105 int has_analyse_option);
107 extern int ip6_ioam_set_destination (ip6_address_t * addr, u32 mask_width,
108 u32 vrf_id, int is_add, int is_pop,
111 extern clib_error_t *clear_ioam_rewrite_fn (void);
114 is_zero_ip4_address (ip4_address_t * a)
116 return (a->as_u32 == 0);
120 copy_ip6_address (ip6_address_t * dst, ip6_address_t * src)
122 dst->as_u64[0] = src->as_u64[0];
123 dst->as_u64[1] = src->as_u64[1];
127 set_zero_ip6_address (ip6_address_t * a)
134 cmp_ip6_address (ip6_address_t * a1, ip6_address_t * a2)
136 return ((a1->as_u64[0] == a2->as_u64[0])
137 && (a1->as_u64[1] == a2->as_u64[1]));
141 is_zero_ip6_address (ip6_address_t * a)
143 return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0));
146 int ip6_hbh_add_register_option (u8 option,
148 int rewrite_options (u8 * rewrite_string,
150 int ip6_hbh_add_unregister_option (u8 option);
152 int ip6_hbh_pop_register_option (u8 option,
153 int options (vlib_buffer_t * b,
155 ip6_hop_by_hop_option_t * opt));
156 int ip6_hbh_pop_unregister_option (u8 option);
159 ip6_hbh_get_sizeof_register_option (u8 option,
160 int get_sizeof_hdr_options (u32 *
164 ip6_ioam_set_rewrite (u8 ** rwp, int has_trace_option,
165 int has_pot_option, int has_seq_no);
168 ip6_hbh_config_handler_register (u8 option,
169 int config_handler (void *data, u8 disable));
171 int ip6_hbh_config_handler_unregister (u8 option);
173 int ip6_hbh_flow_handler_register (u8 option,
174 u32 ioam_flow_handler (u32 flow_ctx,
177 int ip6_hbh_flow_handler_unregister (u8 option);
179 u8 *get_flow_name_from_flow_ctx (u32 flow_ctx);
181 static inline flow_data_t *
184 flow_data_t *flow = NULL;
185 ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
187 if (pool_is_free_index (hm->flows, index))
190 flow = pool_elt_at_index (hm->flows, index);
195 get_flow_data_from_flow_ctx (u32 flow_ctx, u8 option)
197 flow_data_t *flow = NULL;
198 ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
201 index = IOAM_MASK_DECAP_BIT (flow_ctx);
202 //flow = pool_elt_at_index (hm->flows, index);
203 flow = &hm->flows[index];
204 return (flow->ctx[option]);
208 is_seqno_enabled (void)
210 return (ip6_hop_by_hop_ioam_main.has_seqno_option);
213 int ip6_trace_profile_setup ();
216 ioam_flow_add (u8 encap, u8 * flow_name)
218 ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
219 flow_data_t *flow = 0;
223 pool_get (hm->flows, flow);
224 clib_memset (flow, 0, sizeof (flow_data_t));
226 index = flow - hm->flows;
227 strncpy ((char *) flow->flow_name, (char *) flow_name, 31);
230 IOAM_SET_DECAP (index);
232 for (i = 0; i < 255; i++)
234 if (hm->flow_handler[i])
235 flow->ctx[i] = hm->flow_handler[i] (index, 1);
240 always_inline ip6_hop_by_hop_option_t *
241 ip6_hbh_get_option (ip6_hop_by_hop_header_t * hbh0, u8 option_to_search)
243 ip6_hop_by_hop_option_t *opt0, *limit0;
249 opt0 = (ip6_hop_by_hop_option_t *) (hbh0 + 1);
250 limit0 = (ip6_hop_by_hop_option_t *)
251 ((u8 *) hbh0 + ((hbh0->length + 1) << 3));
253 /* Scan the set of h-b-h options, process ones that we understand */
254 while (opt0 < limit0)
260 opt0 = (ip6_hop_by_hop_option_t *) ((u8 *) opt0) + 1;
265 if (type0 == option_to_search)
270 (ip6_hop_by_hop_option_t *) (((u8 *) opt0) + opt0->length +
271 sizeof (ip6_hop_by_hop_option_t));
276 #endif /* __included_ip6_hop_by_hop_ioam_h__ */
279 * fd.io coding-style-patch-verification: ON
282 * eval: (c-set-style "gnu")