e86a6d05f8229b148e1a8a4ab466c75504e4b3e5
[vpp.git] / vnet / vnet / ip / ip6_hop_by_hop.h
1 /*
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:
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  */
15 #ifndef __included_ip6_hop_by_hop_ioam_h__
16 #define __included_ip6_hop_by_hop_ioam_h__
17
18 #include <vnet/ip/ip6_hop_by_hop_packet.h>
19 #include <vnet/ip/ip.h>
20
21
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  */
37 typedef struct {
38   u32 ctx[MAX_IP6_HBH_OPTION];
39   u8 flow_name[64];
40 } flow_data_t;
41
42 typedef struct {
43   /* The current rewrite we're using */
44   u8 * rewrite;
45
46   /* Trace data processing callback */
47   void *ioam_end_of_path_cb;
48   /* Configuration data */
49   /* Adjacency */
50   ip6_address_t adj;
51 #define IOAM_HBYH_ADD  0
52 #define IOAM_HBYH_MOD  1
53 #define IOAM_HBYH_POP  2
54   u8 ioam_flag;
55   /* time scale transform. Joy. */
56   u32 unix_time_0;
57   f64 vlib_time_0;
58
59
60   /* Trace option */
61   u8 has_trace_option;
62
63   /* Pot option */
64   u8 has_pot_option;
65
66   /* Per Packet Counter option */
67   u8 has_seqno_option;
68
69   /* Enabling analyis of iOAM data on decap node */
70   u8 has_analyse_option;
71
72   /* Array of function pointers to ADD and POP HBH option handling routines */
73   u8 options_size[MAX_IP6_HBH_OPTION];
74   int (*add_options[MAX_IP6_HBH_OPTION])(u8 *rewrite_string, u8 *rewrite_size);
75   int (*pop_options[MAX_IP6_HBH_OPTION])(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt);
76   int (*get_sizeof_options[MAX_IP6_HBH_OPTION])(u32 *rewrite_size);
77   int (*config_handler[MAX_IP6_HBH_OPTION]) (void *data, u8 disable);
78
79   /* Array of function pointers to handle hbh options being used with classifier */
80   u32 (*flow_handler[MAX_IP6_HBH_OPTION])(u32 flow_ctx, u8 add);
81   flow_data_t *flows;
82
83   /* convenience */
84   vlib_main_t * vlib_main;
85   vnet_main_t * vnet_main;
86 } ip6_hop_by_hop_ioam_main_t;
87
88 extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
89
90 extern u8 * format_path_map(u8 * s, va_list * args);
91
92 extern clib_error_t *
93 ip6_ioam_enable(int has_trace_option, int has_pot_option,
94                            int has_seqno_option, int has_analyse_option);
95
96 extern int ip6_ioam_set_destination (ip6_address_t *addr, u32 mask_width,
97                   u32 vrf_id, int is_add, int is_pop, int is_none);
98
99 extern clib_error_t * clear_ioam_rewrite_fn(void);
100
101 static inline u8 is_zero_ip4_address (ip4_address_t *a)
102 {
103   return (a->as_u32 == 0);
104 }
105
106 static inline void copy_ip6_address (ip6_address_t *dst, ip6_address_t *src)
107 {
108   dst->as_u64[0] = src->as_u64[0];
109   dst->as_u64[1] = src->as_u64[1];
110 }
111
112 static inline void set_zero_ip6_address (ip6_address_t *a)
113 {
114   a->as_u64[0] = 0;
115   a->as_u64[1] = 0;
116 }
117
118 static inline u8 cmp_ip6_address (ip6_address_t *a1, ip6_address_t *a2)
119 {
120   return ((a1->as_u64[0] == a2->as_u64[0]) && (a1->as_u64[1] == a2->as_u64[1]));
121 }
122 static inline u8 is_zero_ip6_address (ip6_address_t *a)
123 {
124   return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0));
125 }
126
127 int ip6_hbh_add_register_option (u8 option,
128                                  u8 size,
129                                  int rewrite_options(u8 *rewrite_string, u8 *size));
130 int ip6_hbh_add_unregister_option (u8 option);
131
132 int ip6_hbh_pop_register_option (u8 option,
133                                  int options(vlib_buffer_t *b,
134                                              ip6_header_t *ip, ip6_hop_by_hop_option_t *opt));
135 int ip6_hbh_pop_unregister_option (u8 option);
136
137 int
138 ip6_hbh_get_sizeof_register_option (u8 option,
139                             int get_sizeof_hdr_options(u32 *rewrite_size));
140
141 int
142 ip6_ioam_set_rewrite (u8 **rwp, int has_trace_option,
143                       int has_pot_option, int has_seq_no);
144
145 int
146 ip6_hbh_config_handler_register (u8 option,
147                                  int config_handler(void *data, u8 disable));
148
149 int ip6_hbh_config_handler_unregister (u8 option);
150
151 int ip6_hbh_flow_handler_register(u8 option,
152                                   u32 ioam_flow_handler(u32 flow_ctx, u8 add));
153
154 int ip6_hbh_flow_handler_unregister(u8 option);
155
156 u8 * get_flow_name_from_flow_ctx(u32 flow_ctx);
157
158 static inline flow_data_t * get_flow (u32 index)
159 {
160   flow_data_t *flow = NULL;
161   ip6_hop_by_hop_ioam_main_t * hm = &ip6_hop_by_hop_ioam_main;
162
163   if (pool_is_free_index (hm->flows, index))
164     return NULL;
165
166   flow = pool_elt_at_index (hm->flows, index);
167   return flow;
168 }
169
170 static inline u32 get_flow_data_from_flow_ctx (u32 flow_ctx, u8 option)
171 {
172   flow_data_t *flow = NULL;
173   ip6_hop_by_hop_ioam_main_t * hm = &ip6_hop_by_hop_ioam_main;
174   u32 index;
175
176   index = IOAM_MASK_DECAP_BIT(flow_ctx);
177   //flow = pool_elt_at_index (hm->flows, index);
178   flow = &hm->flows[index];
179   return (flow->ctx[option]);
180 }
181
182 static inline u8 is_seqno_enabled (void)
183 {
184   return (ip6_hop_by_hop_ioam_main.has_seqno_option);
185 }
186
187 int
188 ip6_trace_profile_setup ();
189 #endif /* __included_ip6_hop_by_hop_ioam_h__ */