FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
ip6_hop_by_hop.h
Go to the documentation of this file.
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 
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 {
40  u8 flow_name[64];
41 } flow_data_t;
42 
43 typedef struct
44 {
45  u8 next_index_by_protocol[256];
47 
48 typedef struct
49 {
50  /* The current rewrite we're using */
52 
53  /* Trace data processing callback */
55  /* 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
62  /* time scale transform. Joy. */
65 
66 
67  /* Trace option */
69 
70  /* Pot option */
72 
73  /* Per Packet Counter option */
75 
76  /* Enabling analyis of iOAM data on decap node */
78 
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,
82  u8 * rewrite_size);
83  int (*pop_options[MAX_IP6_HBH_OPTION]) (vlib_buffer_t * b,
84  ip6_header_t * ip,
86  int (*get_sizeof_options[MAX_IP6_HBH_OPTION]) (u32 * rewrite_size);
87  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 */
90  u32 (*flow_handler[MAX_IP6_HBH_OPTION]) (u32 flow_ctx, u8 add);
92 
94 
95  /* convenience */
99 
101 
102 extern 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);
106 
107 extern 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);
110 
111 extern clib_error_t *clear_ioam_rewrite_fn (void);
112 
113 static inline u8
115 {
116  return (a->as_u32 == 0);
117 }
118 
119 static inline void
120 copy_ip6_address (ip6_address_t * dst, ip6_address_t * src)
121 {
122  dst->as_u64[0] = src->as_u64[0];
123  dst->as_u64[1] = src->as_u64[1];
124 }
125 
126 static inline void
127 set_zero_ip6_address (ip6_address_t * a)
128 {
129  a->as_u64[0] = 0;
130  a->as_u64[1] = 0;
131 }
132 
133 static inline u8
134 cmp_ip6_address (ip6_address_t * a1, ip6_address_t * a2)
135 {
136  return ((a1->as_u64[0] == a2->as_u64[0])
137  && (a1->as_u64[1] == a2->as_u64[1]));
138 }
139 
140 static inline u8
141 is_zero_ip6_address (ip6_address_t * a)
142 {
143  return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0));
144 }
145 
146 int ip6_hbh_add_register_option (u8 option,
147  u8 size,
148  int rewrite_options (u8 * rewrite_string,
149  u8 * size));
150 int ip6_hbh_add_unregister_option (u8 option);
151 
152 int ip6_hbh_pop_register_option (u8 option,
153  int options (vlib_buffer_t * b,
154  ip6_header_t * ip,
155  ip6_hop_by_hop_option_t * opt));
156 int ip6_hbh_pop_unregister_option (u8 option);
157 
158 int
160  int get_sizeof_hdr_options (u32 *
161  rewrite_size));
162 
163 int
164 ip6_ioam_set_rewrite (u8 ** rwp, int has_trace_option,
165  int has_pot_option, int has_seq_no);
166 
167 int
169  int config_handler (void *data, u8 disable));
170 
172 
174  u32 ioam_flow_handler (u32 flow_ctx,
175  u8 add));
176 
178 
180 
181 static inline flow_data_t *
183 {
184  flow_data_t *flow = NULL;
186 
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 
194 static inline u32
196 {
197  flow_data_t *flow = NULL;
199  u32 index;
200 
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]);
205 }
206 
207 static inline u8
209 {
210  return (ip6_hop_by_hop_ioam_main.has_seqno_option);
211 }
212 
214 
215 static inline u32
216 ioam_flow_add (u8 encap, u8 * flow_name)
217 {
219  flow_data_t *flow = 0;
220  u32 index = 0;
221  u8 i;
222 
223  pool_get (hm->flows, flow);
224  clib_memset (flow, 0, sizeof (flow_data_t));
225 
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 
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 
276 #endif /* __included_ip6_hop_by_hop_ioam_h__ */
277 
278 /*
279  * fd.io coding-style-patch-verification: ON
280  *
281  * Local Variables:
282  * eval: (c-set-style "gnu")
283  * End:
284  */
a
Definition: bitmap.h:538
int ip6_ioam_set_rewrite(u8 **rwp, int has_trace_option, int has_pot_option, int has_seq_no)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
int ip6_hbh_flow_handler_unregister(u8 option)
int ip6_hbh_get_sizeof_register_option(u8 option, int get_sizeof_hdr_options(u32 *rewrite_size))
vl_api_address_t src
Definition: gre.api:54
u32 ctx[MAX_IP6_HBH_OPTION]
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
vhost_vring_addr_t addr
Definition: vhost_user.h:111
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:89
double f64
Definition: types.h:142
int ip6_hbh_config_handler_register(u8 option, int config_handler(void *data, u8 disable))
int ip6_hbh_add_register_option(u8 option, u8 size, int rewrite_options(u8 *rewrite_string, u8 *size))
int ip6_trace_profile_setup()
int ip6_ioam_set_destination(ip6_address_t *addr, u32 mask_width, u32 vrf_id, int is_add, int is_pop, int is_none)
unsigned int u32
Definition: types.h:88
int ip6_hbh_config_handler_unregister(u8 option)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
clib_error_t * ip6_ioam_enable(int has_trace_option, int has_pot_option, int has_seqno_option, int has_analyse_option)
long ctx[MAX_CONNS]
Definition: main.c:144
u32 size
Definition: vhost_user.h:106
static u32 get_flow_data_from_flow_ctx(u32 flow_ctx, u8 option)
static flow_data_t * get_flow(u32 index)
static void set_zero_ip6_address(ip6_address_t *a)
clib_error_t * clear_ioam_rewrite_fn(void)
#define always_inline
Definition: ipsec.h:28
u8 * get_flow_name_from_flow_ctx(u32 flow_ctx)
static u8 cmp_ip6_address(ip6_address_t *a1, ip6_address_t *a2)
vl_api_address_t dst
Definition: gre.api:55
ip6_local_hop_by_hop_runtime_t * ip6_local_hbh_runtime
static u8 is_seqno_enabled(void)
static u8 is_zero_ip4_address(ip4_address_t *a)
u8 flow_name[64]
u32(* flow_handler[MAX_IP6_HBH_OPTION])(u32 flow_ctx, u8 add)
u8 mask_width
Definition: dhcp.api:204
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
static u32 ioam_flow_add(u8 encap, u8 *flow_name)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:299
ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main
static u8 is_zero_ip6_address(ip6_address_t *a)
int ip6_hbh_flow_handler_register(u8 option, u32 ioam_flow_handler(u32 flow_ctx, u8 add))
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))
#define IOAM_SET_DECAP(opaque_data)
vl_api_flow_t flow
Definition: flow_types.api:240
vl_api_address_t ip
Definition: l2.api:501
VLIB buffer representation.
Definition: buffer.h:102
static ip6_hop_by_hop_option_t * ip6_hbh_get_option(ip6_hop_by_hop_header_t *hbh0, u8 option_to_search)
u32 index
Definition: flow_types.api:221
static struct option options[]
Definition: main.c:52
#define IOAM_MASK_DECAP_BIT(x)
u32 vrf_id
Definition: nat.api:944
static void copy_ip6_address(ip6_address_t *dst, ip6_address_t *src)
int ip6_hbh_pop_unregister_option(u8 option)
#define MAX_IP6_HBH_OPTION
int ip6_hbh_add_unregister_option(u8 option)