blob: e8ecab6c6d567d9e285f5c111e1049ae51f834cc [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +05302 * Copyright (c) 2016 Cisco and/or its affiliates.
Ed Warnickecb9cada2015-12-08 15:45:58 -07003 * 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:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
Ole Troan944f5482016-05-24 11:56:58 +020015#ifndef __included_ip6_hop_by_hop_ioam_h__
16#define __included_ip6_hop_by_hop_ioam_h__
Ed Warnickecb9cada2015-12-08 15:45:58 -070017
18#include <vnet/ip/ip6_hop_by_hop_packet.h>
Shwetha Bhandari05866a12016-05-04 08:12:57 +020019#include <vnet/ip/ip.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070020
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +053021
22#define MAX_IP6_HBH_OPTION 256
23
24/* To determine whether a node is decap MS bit is set */
25#define IOAM_DECAP_BIT 0x80000000
26
27#define IOAM_DEAP_ENABLED(opaque_data) (opaque_data & IOAM_DECAP_BIT)
28
29#define IOAM_SET_DECAP(opaque_data) \
30 (opaque_data |= IOAM_DECAP_BIT)
31
32#define IOAM_MASK_DECAP_BIT(x) (x & ~IOAM_DECAP_BIT)
33
34/*
35 * Stores the run time flow data of hbh options
36 */
Dave Barachd7cb1b52016-12-09 09:52:16 -050037typedef struct
38{
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +053039 u32 ctx[MAX_IP6_HBH_OPTION];
40 u8 flow_name[64];
41} flow_data_t;
42
Dave Barachd7cb1b52016-12-09 09:52:16 -050043typedef struct
44{
Dave Barach90800962019-05-24 13:03:01 -040045 u8 next_index_by_protocol[256];
46} ip6_local_hop_by_hop_runtime_t;
47
48typedef struct
49{
Ed Warnickecb9cada2015-12-08 15:45:58 -070050 /* The current rewrite we're using */
Dave Barachd7cb1b52016-12-09 09:52:16 -050051 u8 *rewrite;
Ed Warnickecb9cada2015-12-08 15:45:58 -070052
53 /* Trace data processing callback */
54 void *ioam_end_of_path_cb;
rangan4f810852016-03-18 03:31:17 +053055 /* Configuration data */
56 /* Adjacency */
57 ip6_address_t adj;
58#define IOAM_HBYH_ADD 0
59#define IOAM_HBYH_MOD 1
60#define IOAM_HBYH_POP 2
61 u8 ioam_flag;
62 /* time scale transform. Joy. */
63 u32 unix_time_0;
64 f64 vlib_time_0;
65
66
67 /* Trace option */
Vengada Govindan07d2f842016-08-25 10:34:34 -070068 u8 has_trace_option;
rangan4f810852016-03-18 03:31:17 +053069
Shwetha85b528e2016-06-15 16:34:16 +010070 /* Pot option */
71 u8 has_pot_option;
rangan4f810852016-03-18 03:31:17 +053072
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +053073 /* Per Packet Counter option */
74 u8 has_seqno_option;
75
76 /* Enabling analyis of iOAM data on decap node */
77 u8 has_analyse_option;
rangan4f810852016-03-18 03:31:17 +053078
Shwetha85b528e2016-06-15 16:34:16 +010079 /* Array of function pointers to ADD and POP HBH option handling routines */
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +053080 u8 options_size[MAX_IP6_HBH_OPTION];
Dave Barachd7cb1b52016-12-09 09:52:16 -050081 int (*add_options[MAX_IP6_HBH_OPTION]) (u8 * rewrite_string,
82 u8 * rewrite_size);
83 int (*pop_options[MAX_IP6_HBH_OPTION]) (vlib_buffer_t * b,
84 ip6_header_t * ip,
85 ip6_hop_by_hop_option_t * opt);
86 int (*get_sizeof_options[MAX_IP6_HBH_OPTION]) (u32 * rewrite_size);
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +053087 int (*config_handler[MAX_IP6_HBH_OPTION]) (void *data, u8 disable);
88
89 /* Array of function pointers to handle hbh options being used with classifier */
Dave Barachd7cb1b52016-12-09 09:52:16 -050090 u32 (*flow_handler[MAX_IP6_HBH_OPTION]) (u32 flow_ctx, u8 add);
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +053091 flow_data_t *flows;
92
Dave Barach90800962019-05-24 13:03:01 -040093 ip6_local_hop_by_hop_runtime_t *ip6_local_hbh_runtime;
94
Ed Warnickecb9cada2015-12-08 15:45:58 -070095 /* convenience */
Dave Barachd7cb1b52016-12-09 09:52:16 -050096 vlib_main_t *vlib_main;
97 vnet_main_t *vnet_main;
Ole Troan944f5482016-05-24 11:56:58 +020098} ip6_hop_by_hop_ioam_main_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -070099
Ole Troan944f5482016-05-24 11:56:58 +0200100extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
rangan4f810852016-03-18 03:31:17 +0530101
Dave Barachd7cb1b52016-12-09 09:52:16 -0500102extern clib_error_t *ip6_ioam_enable (int has_trace_option,
103 int has_pot_option,
104 int has_seqno_option,
105 int has_analyse_option);
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530106
Dave Barachd7cb1b52016-12-09 09:52:16 -0500107extern int ip6_ioam_set_destination (ip6_address_t * addr, u32 mask_width,
108 u32 vrf_id, int is_add, int is_pop,
109 int is_none);
rangan4f810852016-03-18 03:31:17 +0530110
Dave Barachd7cb1b52016-12-09 09:52:16 -0500111extern clib_error_t *clear_ioam_rewrite_fn (void);
rangan4f810852016-03-18 03:31:17 +0530112
Dave Barachd7cb1b52016-12-09 09:52:16 -0500113static inline u8
114is_zero_ip4_address (ip4_address_t * a)
rangan4f810852016-03-18 03:31:17 +0530115{
116 return (a->as_u32 == 0);
117}
118
Dave Barachd7cb1b52016-12-09 09:52:16 -0500119static inline void
120copy_ip6_address (ip6_address_t * dst, ip6_address_t * src)
rangan4f810852016-03-18 03:31:17 +0530121{
122 dst->as_u64[0] = src->as_u64[0];
123 dst->as_u64[1] = src->as_u64[1];
124}
125
Dave Barachd7cb1b52016-12-09 09:52:16 -0500126static inline void
127set_zero_ip6_address (ip6_address_t * a)
rangan4f810852016-03-18 03:31:17 +0530128{
129 a->as_u64[0] = 0;
130 a->as_u64[1] = 0;
131}
132
Dave Barachd7cb1b52016-12-09 09:52:16 -0500133static inline u8
134cmp_ip6_address (ip6_address_t * a1, ip6_address_t * a2)
rangan4f810852016-03-18 03:31:17 +0530135{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500136 return ((a1->as_u64[0] == a2->as_u64[0])
137 && (a1->as_u64[1] == a2->as_u64[1]));
rangan4f810852016-03-18 03:31:17 +0530138}
Dave Barachd7cb1b52016-12-09 09:52:16 -0500139
140static inline u8
141is_zero_ip6_address (ip6_address_t * a)
rangan4f810852016-03-18 03:31:17 +0530142{
143 return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0));
144}
145
Shwetha85b528e2016-06-15 16:34:16 +0100146int ip6_hbh_add_register_option (u8 option,
147 u8 size,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500148 int rewrite_options (u8 * rewrite_string,
149 u8 * size));
Shwetha85b528e2016-06-15 16:34:16 +0100150int ip6_hbh_add_unregister_option (u8 option);
151
152int ip6_hbh_pop_register_option (u8 option,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500153 int options (vlib_buffer_t * b,
154 ip6_header_t * ip,
155 ip6_hop_by_hop_option_t * opt));
Shwetha85b528e2016-06-15 16:34:16 +0100156int ip6_hbh_pop_unregister_option (u8 option);
157
Vengada Govindan07d2f842016-08-25 10:34:34 -0700158int
159ip6_hbh_get_sizeof_register_option (u8 option,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500160 int get_sizeof_hdr_options (u32 *
161 rewrite_size));
Shwetha85b528e2016-06-15 16:34:16 +0100162
Vengada Govindan07d2f842016-08-25 10:34:34 -0700163int
Dave Barachd7cb1b52016-12-09 09:52:16 -0500164ip6_ioam_set_rewrite (u8 ** rwp, int has_trace_option,
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530165 int has_pot_option, int has_seq_no);
166
167int
168ip6_hbh_config_handler_register (u8 option,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500169 int config_handler (void *data, u8 disable));
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530170
171int ip6_hbh_config_handler_unregister (u8 option);
172
Dave Barachd7cb1b52016-12-09 09:52:16 -0500173int ip6_hbh_flow_handler_register (u8 option,
174 u32 ioam_flow_handler (u32 flow_ctx,
175 u8 add));
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530176
Dave Barachd7cb1b52016-12-09 09:52:16 -0500177int ip6_hbh_flow_handler_unregister (u8 option);
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530178
Dave Barachd7cb1b52016-12-09 09:52:16 -0500179u8 *get_flow_name_from_flow_ctx (u32 flow_ctx);
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530180
Dave Barachd7cb1b52016-12-09 09:52:16 -0500181static inline flow_data_t *
182get_flow (u32 index)
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530183{
184 flow_data_t *flow = NULL;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500185 ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530186
187 if (pool_is_free_index (hm->flows, index))
188 return NULL;
189
190 flow = pool_elt_at_index (hm->flows, index);
191 return flow;
192}
193
Dave Barachd7cb1b52016-12-09 09:52:16 -0500194static inline u32
195get_flow_data_from_flow_ctx (u32 flow_ctx, u8 option)
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530196{
197 flow_data_t *flow = NULL;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500198 ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530199 u32 index;
200
Dave Barachd7cb1b52016-12-09 09:52:16 -0500201 index = IOAM_MASK_DECAP_BIT (flow_ctx);
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530202 //flow = pool_elt_at_index (hm->flows, index);
203 flow = &hm->flows[index];
204 return (flow->ctx[option]);
205}
206
Dave Barachd7cb1b52016-12-09 09:52:16 -0500207static inline u8
208is_seqno_enabled (void)
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +0530209{
210 return (ip6_hop_by_hop_ioam_main.has_seqno_option);
211}
212
Dave Barachd7cb1b52016-12-09 09:52:16 -0500213int ip6_trace_profile_setup ();
AkshayaNadahallifdd81af2016-12-01 16:33:51 +0530214
215static inline u32
216ioam_flow_add (u8 encap, u8 * flow_name)
217{
218 ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
219 flow_data_t *flow = 0;
220 u32 index = 0;
221 u8 i;
222
223 pool_get (hm->flows, flow);
Dave Barachb7b92992018-10-17 10:38:51 -0400224 clib_memset (flow, 0, sizeof (flow_data_t));
AkshayaNadahallifdd81af2016-12-01 16:33:51 +0530225
226 index = flow - hm->flows;
227 strncpy ((char *) flow->flow_name, (char *) flow_name, 31);
228
229 if (!encap)
230 IOAM_SET_DECAP (index);
231
232 for (i = 0; i < 255; i++)
233 {
234 if (hm->flow_handler[i])
235 flow->ctx[i] = hm->flow_handler[i] (index, 1);
236 }
237 return (index);
238}
239
AkshayaNadahalli1b563522017-01-23 22:05:35 +0530240always_inline ip6_hop_by_hop_option_t *
241ip6_hbh_get_option (ip6_hop_by_hop_header_t * hbh0, u8 option_to_search)
242{
243 ip6_hop_by_hop_option_t *opt0, *limit0;
244 u8 type0;
245
246 if (!hbh0)
247 return NULL;
248
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));
252
253 /* Scan the set of h-b-h options, process ones that we understand */
254 while (opt0 < limit0)
255 {
256 type0 = opt0->type;
257 switch (type0)
258 {
259 case 0: /* Pad1 */
260 opt0 = (ip6_hop_by_hop_option_t *) ((u8 *) opt0) + 1;
261 continue;
262 case 1: /* PadN */
263 break;
264 default:
265 if (type0 == option_to_search)
266 return opt0;
267 break;
268 }
269 opt0 =
270 (ip6_hop_by_hop_option_t *) (((u8 *) opt0) + opt0->length +
271 sizeof (ip6_hop_by_hop_option_t));
272 }
273 return NULL;
274}
275
Ole Troan944f5482016-05-24 11:56:58 +0200276#endif /* __included_ip6_hop_by_hop_ioam_h__ */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500277
278/*
279 * fd.io coding-style-patch-verification: ON
280 *
281 * Local Variables:
282 * eval: (c-set-style "gnu")
283 * End:
284 */