FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
ip6_ioam_e2e.c
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 
16 #include <vlib/vlib.h>
17 #include <vnet/vnet.h>
18 #include <vnet/pg/pg.h>
19 #include <vppinfra/error.h>
20 
21 #include <vnet/ip/ip.h>
22 
23 #include <vppinfra/hash.h>
24 #include <vppinfra/error.h>
25 #include <vppinfra/elog.h>
26 
27 #include <vnet/ip/ip6_hop_by_hop.h>
28 #include <vnet/plugin/plugin.h>
29 
30 #include "ip6_ioam_e2e.h"
31 
33 
36 {
37  ioam_e2e_option_t * e2e = (ioam_e2e_option_t *)opt;
38  u32 seqno = 0;
39 
40  if (e2e)
41  {
42  seqno = clib_net_to_host_u32 (e2e->e2e_data);
43  }
44 
45  s = format (s, "SeqNo = 0x%Lx", seqno);
46  return s;
47 }
48 
49 int
50 ioam_e2e_config_handler (void *data, u8 disable)
51 {
52  int *analyse = data;
53 
54  /* Register hanlders if enabled */
55  if (!disable)
56  {
57  /* If encap node register for encap handler */
58  if (0 == *analyse)
59  {
63  {
64  return (-1);
65  }
66  }
67  /* If analyze node then register for decap handler */
68  else
69  {
72  {
73  return (-1);
74  }
75  }
76  return 0;
77  }
78 
79  /* UnRegister handlers */
82  return 0;
83 }
84 
85 int
86 ioam_e2e_rewrite_handler (u8 *rewrite_string,
87  u8 *rewrite_size)
88 {
89  ioam_e2e_option_t *e2e_option;
90 
91  if (rewrite_string && *rewrite_size == sizeof(ioam_e2e_option_t))
92  {
93  e2e_option = (ioam_e2e_option_t *)rewrite_string;
94  e2e_option->hdr.type = HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE
96  e2e_option->hdr.length = sizeof (ioam_e2e_option_t) -
97  sizeof (ip6_hop_by_hop_option_t);
98  return(0);
99  }
100  return(-1);
101 }
102 
103 u32
105 {
106  ioam_e2e_data_t *data;
107  u16 i;
108 
109  if (add)
110  {
111  pool_get(ioam_e2e_main.e2e_data, data);
112  data->flow_ctx = ctx;
114  return ((u32) (data - ioam_e2e_main.e2e_data));
115  }
116 
117  /* Delete case */
118  for (i = 0; i < vec_len(ioam_e2e_main.e2e_data); i++)
119  {
120  if (pool_is_free_index(ioam_e2e_main.e2e_data, i))
121  continue;
122 
123  data = pool_elt_at_index(ioam_e2e_main.e2e_data, i);
124  if (data && (data->flow_ctx == ctx))
125  {
126  pool_put_index(ioam_e2e_main.e2e_data, i);
127  return (0);
128  }
129  }
130  return 0;
131 }
132 
133 static clib_error_t *
135  unformat_input_t * input,
136  vlib_cli_command_t * cmd)
137 {
138  ioam_e2e_data_t *e2e_data;
139  u8 *s = 0;
140  int i;
141 
142  vec_reset_length(s);
143 
144  s = format(0, "IOAM E2E information: \n");
145  for (i = 0; i < vec_len(ioam_e2e_main.e2e_data); i++)
146  {
147  if (pool_is_free_index(ioam_e2e_main.e2e_data, i))
148  continue;
149 
150  e2e_data = pool_elt_at_index(ioam_e2e_main.e2e_data, i);
151  s = format(s, "Flow name: %s\n", get_flow_name_from_flow_ctx(e2e_data->flow_ctx));
152 
154  &e2e_data->seqno_data,
155  !IOAM_DEAP_ENABLED(e2e_data->flow_ctx));
156  }
157 
158  vlib_cli_output(vm, "%v", s);
159  return 0;
160 }
161 
162 
163 VLIB_CLI_COMMAND (ioam_show_e2e_cmd, static) = {
164  .path = "show ioam e2e ",
165  .short_help = "show ioam e2e information",
166  .function = ioam_show_e2e_cmd_fn,
167 };
168 
169 /*
170  * This routine exists to convince the vlib plugin framework that
171  * we haven't accidentally copied a random .dll into the plugin directory.
172  *
173  * Also collects global variable pointers passed from the vpp engine
174  */
175 clib_error_t *
177  int from_early_init)
178 {
179  clib_error_t * error = 0;
180 
181  ioam_e2e_main.vlib_main = vm;
182  ioam_e2e_main.vnet_main = h->vnet_main;
183  return error;
184 }
185 
186 /*
187  * Init handler E2E headet handling.
188  * Init hanlder registers encap, decap, trace and Rewrite handlers.
189  */
190 static clib_error_t *
192 {
193  clib_error_t * error;
194 
195  if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init)))
196  {
197  return(error);
198  }
199 
200  /*
201  * As of now we have only PPC under E2E header.
202  */
205  {
206  return (clib_error_create("Registration of "
207  "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE for rewrite failed"));
208  }
209 
211  sizeof(ioam_e2e_option_t),
213  {
214  return (clib_error_create("Registration of "
215  "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE for rewrite failed"));
216  }
217 
220  {
221  return (clib_error_create("Registration of "
222  "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE Flow handler failed"));
223  }
224 
225  return (0);
226 }
227 
228 /*
229  * Init function for the E2E lib.
230  * ip6_hop_by_hop_ioam_e2e_init gets called during init.
231  */
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
int ioam_seqno_encap_handler(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt)
int ip6_hbh_register_option(u8 option, int options(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt), u8 *trace(u8 *s, ip6_hop_by_hop_option_t *opt))
Definition: ip6_forward.c:2602
int ioam_seqno_decap_handler(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
int ip6_hbh_flow_handler_register(u8 option, u32 ioam_flow_handler(u32 flow_ctx, u8 add))
int ip6_hbh_pop_unregister_option(u8 option)
static u8 * ioam_e2e_trace_handler(u8 *s, ip6_hop_by_hop_option_t *opt)
Definition: ip6_ioam_e2e.c:34
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE
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))
vnet_main_t * vnet_main
Definition: ip6_ioam_e2e.h:30
#define vlib_call_init_function(vm, x)
Definition: init.h:161
int ip6_hbh_unregister_option(u8 option)
Definition: ip6_forward.c:2625
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
add
Definition: vector_sse2.h:285
#define clib_error_create(args...)
Definition: error.h:108
static clib_error_t * ioam_e2e_init(vlib_main_t *vm)
Definition: ip6_ioam_e2e.c:191
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
vlib_main_t * vlib_main
Definition: ip6_ioam_e2e.h:29
u32 ioam_e2e_flow_handler(u32 ctx, u8 add)
Definition: ip6_ioam_e2e.c:104
int ip6_hbh_config_handler_register(u8 option, int config_handler(void *data, u8 disable))
clib_error_t * vlib_plugin_register(vlib_main_t *vm, vnet_plugin_handoff_t *h, int from_early_init)
Definition: ip6_ioam_e2e.c:176
u8 * show_ioam_seqno_cmd_fn(u8 *s, ioam_seqno_data *seqno_data, u8 enc)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:211
ioam_seqno_data seqno_data
Definition: ip6_ioam_e2e.h:24
ioam_e2e_main_t ioam_e2e_main
Definition: ip6_ioam_e2e.c:32
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:228
unsigned int u32
Definition: types.h:88
u8 * get_flow_name_from_flow_ctx(u32 flow_ctx)
unsigned short u16
Definition: types.h:57
int ioam_e2e_config_handler(void *data, u8 disable)
Definition: ip6_ioam_e2e.c:50
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static clib_error_t * ioam_show_e2e_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip6_ioam_e2e.c:134
vnet_main_t * vnet_main
Definition: plugin.h:26
ioam_e2e_data_t * e2e_data
Definition: ip6_ioam_e2e.h:28
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
int ioam_e2e_rewrite_handler(u8 *rewrite_string, u8 *rewrite_size)
Definition: ip6_ioam_e2e.c:86
#define HBH_OPTION_TYPE_SKIP_UNKNOWN
#define IOAM_DEAP_ENABLED(opaque_data)
int ip6_hbh_add_register_option(u8 option, u8 size, int rewrite_options(u8 *rewrite_string, u8 *rewrite_size))
struct _unformat_input_t unformat_input_t
void ioam_seqno_init_bitmap(ioam_seqno_data *data)