FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
udp_ping_export.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 
18 #include <vnet/api_errno.h>
19 #include <vnet/ip/ip4.h>
20 #include <vnet/udp/udp_local.h>
21 #include <ioam/udp-ping/udp_ping.h>
22 
23 #define UDP_PING_EXPORT_RECORD_SIZE 400
24 
25 static u8 *
27  ip4_address_t * collector_address,
28  ip4_address_t * src_address, u16 collector_port,
30  u32 n_elts, u32 * stream_index)
31 {
32  return ioam_template_rewrite (frm, fr, collector_address,
33  src_address, collector_port, elts, n_elts,
34  stream_index);
35 }
36 
37 static vlib_frame_t *
39  vlib_frame_t * f, u32 * to_next, u32 node_index)
40 {
41  vlib_buffer_t *b0 = NULL;
42  u32 next_offset = 0;
43  u32 bi0 = ~0;
44  int i, j;
47  ipfix_set_header_t *s = NULL;
49  udp_header_t *udp;
50  u32 records_this_buffer;
51  u16 new_l0, old_l0;
52  ip_csum_t sum0;
53  vlib_main_t *vm = frm->vlib_main;
54  flow_report_stream_t *stream;
56  ip46_udp_ping_flow *ip46_flow;
58  u16 data_len;
59 
60  stream = &frm->streams[fr->stream_index];
62 
63  for (i = 0; i < data_len; i++)
64  {
66  continue;
67 
69  j = 0;
70  for (src_port = ip46_flow->udp_data.start_src_port;
71  src_port <= ip46_flow->udp_data.end_src_port; src_port++)
72  {
73  for (dst_port = ip46_flow->udp_data.start_dst_port;
74  dst_port <= ip46_flow->udp_data.end_dst_port; dst_port++, j++)
75  {
76  stats = ip46_flow->udp_data.stats + j;
77  if (PREDICT_FALSE (b0 == NULL))
78  {
79  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
80  break;
81 
82 
83  b0 = vlib_get_buffer (vm, bi0);
84  memcpy (b0->data, fr->rewrite, vec_len (fr->rewrite));
85  b0->current_data = 0;
86  b0->current_length = vec_len (fr->rewrite);
87  b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
88  vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
89  vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
90 
91  tp = vlib_buffer_get_current (b0);
92  ip = &tp->ip4;
93  h = &tp->ipfix.h;
94  s = &tp->ipfix.s;
95 
96  /* FIXUP: message header export_time */
97  h->export_time = clib_host_to_net_u32 (((u32) time (NULL)));
98 
99  /* FIXUP: message header sequence_number */
100  h->sequence_number = stream->sequence_number++;
101  h->sequence_number =
102  clib_host_to_net_u32 (h->sequence_number);
103  next_offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
104  records_this_buffer = 0;
105  }
106 
107  next_offset = ioam_analyse_add_ipfix_record (fr,
108  &stats->analyse_data,
109  b0, next_offset,
110  &ip46_flow->
111  src.ip6,
112  &ip46_flow->
113  dst.ip6, src_port,
114  dst_port);
115 
116  //u32 pak_sent = clib_host_to_net_u32(stats->pak_sent);
117  //memcpy (b0->data + next_offset, &pak_sent, sizeof(u32));
118  //next_offset += sizeof(u32);
119 
120  records_this_buffer++;
121 
122  /* Flush data if packet len is about to reach path mtu */
123  if (next_offset > (frm->path_mtu - UDP_PING_EXPORT_RECORD_SIZE))
124  {
125  b0->current_length = next_offset;
126  b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
127  tp = vlib_buffer_get_current (b0);
128  ip = (ip4_header_t *) & tp->ip4;
129  udp = (udp_header_t *) (ip + 1);
130  h = &tp->ipfix.h;
131  s = &tp->ipfix.s;
132 
133  s->set_id_length =
135  next_offset - (sizeof (*ip) +
136  sizeof (*udp) +
137  sizeof (*h)));
138  h->version_length =
139  version_length (next_offset -
140  (sizeof (*ip) + sizeof (*udp)));
141 
142  sum0 = ip->checksum;
143  old_l0 = ip->length;
144  new_l0 = clib_host_to_net_u16 ((u16) next_offset);
145  sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
146  length /* changed member */ );
147 
148  ip->checksum = ip_csum_fold (sum0);
149  ip->length = new_l0;
150  udp->length =
151  clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
152 
154  if (udp->checksum == 0)
155  udp->checksum = 0xffff;
156 
158 
159  to_next[0] = bi0;
160  f->n_vectors++;
161  to_next++;
162 
163  if (f->n_vectors == VLIB_FRAME_SIZE)
164  {
167  f->n_vectors = 0;
168  to_next = vlib_frame_vector_args (f);
169  }
170  b0 = 0;
171  bi0 = ~0;
172  }
173  }
174  }
175  }
176 
177  if (b0)
178  {
179  b0->current_length = next_offset;
180  b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
181  tp = vlib_buffer_get_current (b0);
182  ip = (ip4_header_t *) & tp->ip4;
183  udp = (udp_header_t *) (ip + 1);
184  h = &tp->ipfix.h;
185  s = &tp->ipfix.s;
186 
188  next_offset - (sizeof (*ip) +
189  sizeof (*udp) +
190  sizeof (*h)));
191  h->version_length =
192  version_length (next_offset - (sizeof (*ip) + sizeof (*udp)));
193 
194  sum0 = ip->checksum;
195  old_l0 = ip->length;
196  new_l0 = clib_host_to_net_u16 ((u16) next_offset);
197  sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
198  length /* changed member */ );
199 
200  ip->checksum = ip_csum_fold (sum0);
201  ip->length = new_l0;
202  udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
203 
205  if (udp->checksum == 0)
206  udp->checksum = 0xffff;
207 
209 
210  to_next[0] = bi0;
211  f->n_vectors++;
212  to_next++;
213 
214  if (f->n_vectors == VLIB_FRAME_SIZE)
215  {
218  f->n_vectors = 0;
219  to_next = vlib_frame_vector_args (f);
220  }
221  b0 = 0;
222  bi0 = ~0;
223  }
224  return f;
225 }
226 
227 clib_error_t *
229 {
231  int rv;
232  u32 domain_id = 0;
234  u16 template_id;
235 
236  clib_memset (&args, 0, sizeof (args));
239  del ? (args.is_add = 0) : (args.is_add = 1);
240  args.domain_id = domain_id;
241  args.src_port = UDP_DST_PORT_ipfix;
242 
243  rv = vnet_flow_report_add_del (frm, &args, &template_id);
244 
245  switch (rv)
246  {
247  case 0:
248  break;
249  case VNET_API_ERROR_NO_SUCH_ENTRY:
250  return clib_error_return (0, "registration not found...");
251  default:
252  return clib_error_return (0, "vnet_flow_report_add_del returned %d",
253  rv);
254  }
255 
256  return 0;
257 }
258 
259 static clib_error_t *
261  vlib_cli_command_t * cmd)
262 {
263  //int rv;
264  int is_add = 1;
265 
267  {
268  if (unformat (input, "export-ipfix"))
269  is_add = 1;
270  else if (unformat (input, "disable"))
271  is_add = 0;
272  else
273  break;
274  }
275 
276  if (is_add)
277  (void) udp_ping_flow_create (0);
278  else
279  (void) udp_ping_flow_create (1);
280 
281  return 0;
282 }
283 
284 /* *INDENT-OFF* */
286  .path = "set udp-ping export-ipfix",
287  .short_help = "set udp-ping export-ipfix [disable]",
288  .function = set_udp_ping_export_command_fn,
289 };
290 /* *INDENT-ON* */
291 
292 clib_error_t *
294 {
295  return 0;
296 }
297 
298 /* *INDENT-OFF* */
300 {
301  .runs_after = VLIB_INITS ("flow_report_init"),
302 };
303 /* *INDENT-ON* */
304 
305 
306 /*
307  * fd.io coding-style-patch-verification: ON
308  *
309  * Local Variables:
310  * eval: (c-set-style "gnu")
311  * End:
312  */
vlib_frame_t::n_vectors
u16 n_vectors
Definition: node.h:387
vnet_flow_report_add_del_args_t::domain_id
u32 domain_id
Definition: flow_report.h:154
flow_report_stream_t::sequence_number
u32 sequence_number
Definition: flow_report.h:80
udp_header_t::length
u16 length
Definition: udp_packet.h:51
flow_report_main
flow_report_main_t flow_report_main
Definition: flow_report.c:22
dst_port
vl_api_ip_port_and_mask_t dst_port
Definition: flow_types.api:92
flow_report_main::vlib_main
vlib_main_t * vlib_main
Definition: flow_report.h:136
udp_ping_main_t::ip46_flow
ip46_udp_ping_flow * ip46_flow
Vector od udp-ping data.
Definition: udp_ping.h:108
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
f
vlib_frame_t * f
Definition: interface_output.c:1080
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
ipfix_set_header_t
Definition: ipfix_packet.h:115
flow_report::stream_index
u32 stream_index
Definition: flow_report.h:91
ip4_header_checksum_is_valid
static uword ip4_header_checksum_is_valid(ip4_header_t *i)
Definition: ip4_packet.h:396
udp_ping_flow::stats
udp_ping_flow_data * stats
Ping statistics.
Definition: udp_ping.h:79
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
set_udp_ping_export_command
static vlib_cli_command_t set_udp_ping_export_command
(constructor) VLIB_CLI_COMMAND (set_udp_ping_export_command)
Definition: udp_ping_export.c:285
flow_report
Definition: flow_report.h:86
u16
unsigned short u16
Definition: types.h:57
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
node_index
node node_index
Definition: interface_output.c:420
stats
vl_api_ikev2_sa_stats_t stats
Definition: ikev2_types.api:162
unformat_input_t
struct _unformat_input_t unformat_input_t
vlib_frame_t
Definition: node.h:372
vlib_get_frame_to_node
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:184
udp_header_t
Definition: udp_packet.h:45
ip4_header_t
Definition: ip4_packet.h:87
udp_ping_flow::start_src_port
u16 start_src_port
Defines start port of the src port range.
Definition: udp_ping.h:67
h
h
Definition: flowhash_template.h:372
ip4_ipfix_template_packet_t
Definition: flow_report.h:42
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
udp_ping_flow_report_init
clib_error_t * udp_ping_flow_report_init(vlib_main_t *vm)
Definition: udp_ping_export.c:293
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
vlib_put_frame_to_node
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:218
ipfix_template_packet_t::h
ipfix_message_header_t h
Definition: ipfix_packet.h:192
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
udp_ping_send_flows
static vlib_frame_t * udp_ping_send_flows(flow_report_main_t *frm, flow_report_t *fr, vlib_frame_t *f, u32 *to_next, u32 node_index)
Definition: udp_ping_export.c:38
vlib_buffer_alloc
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:708
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
ip4_tcp_udp_compute_checksum
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
Definition: pnat_test_stubs.h:59
udp_ping_main
udp_ping_main_t udp_ping_main
Definition: udp_ping_node.c:58
vnet_flow_report_add_del_args_t::src_port
u16 src_port
Definition: flow_report.h:155
udp_local.h
ipfix_report_element_t
Definition: flow_report.h:35
vnet_flow_report_add_del_args_t::flow_data_callback
vnet_flow_data_callback_t * flow_data_callback
Definition: flow_report.h:148
src_port
vl_api_ip_port_and_mask_t src_port
Definition: flow_types.api:91
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
IOAM_FLOW_TEMPLATE_ID
#define IOAM_FLOW_TEMPLATE_ID
Definition: ioam_analyse.h:27
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
src
vl_api_address_t src
Definition: gre.api:54
flow_report_main
Definition: flow_report.h:111
ip4_address_t
Definition: ip4_packet.h:50
version_length
static u32 version_length(u16 length)
Definition: ipfix_packet.h:33
flow_report_main::streams
flow_report_stream_t * streams
Definition: flow_report.h:114
ipfix_message_header_t
Definition: ipfix_packet.h:24
ioam_template_rewrite
u8 * ioam_template_rewrite(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
Definition: ioam_summary_export.c:23
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
flow_report.h
flow_report_main::path_mtu
u32 path_mtu
Definition: flow_report.h:123
udp_ping_flow_data
udp-ping session data.
Definition: udp_ping.h:28
udp_header_t::checksum
u16 checksum
Definition: udp_packet.h:55
ip4_ipfix_template_packet_t::ip4
ip4_header_t ip4
Definition: flow_report.h:44
ioam_analyse_add_ipfix_record
u16 ioam_analyse_add_ipfix_record(flow_report_t *fr, ioam_analyser_data_t *record, vlib_buffer_t *b0, u16 offset, ip6_address_t *src, ip6_address_t *dst, u16 src_port, u16 dst_port)
Definition: ioam_summary_export.c:148
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
data_len
u8 data_len
Definition: ikev2_types.api:24
ip46_udp_ping_flow::udp_data
udp_ping_flow udp_data
Per flow data.
Definition: udp_ping.h:97
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
flow_report_stream_t
Definition: flow_report.h:77
vnet_flow_report_add_del_args_t
Definition: flow_report.h:146
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
ioam_summary_export.h
ip46_udp_ping_flow
udp-ping data.
Definition: udp_ping.h:85
ip4.h
length
char const int length
Definition: cJSON.h:163
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
ip_csum_update
#define ip_csum_update(sum, old, new, type, field)
Definition: ip_packet.h:295
VLIB_INITS
#define VLIB_INITS(...)
Definition: init.h:352
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
ip
vl_api_address_t ip
Definition: l2.api:558
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ip_csum_t
uword ip_csum_t
Definition: ip_packet.h:245
vlib_buffer_t::data
u8 data[]
Packet data.
Definition: buffer.h:204
ipfix_set_id_length
static u32 ipfix_set_id_length(u16 set_id, u16 length)
Definition: ipfix_packet.h:121
rv
int __clib_unused rv
Definition: application.c:491
udp_ping.h
vnet_flow_report_add_del
int vnet_flow_report_add_del(flow_report_main_t *frm, vnet_flow_report_add_del_args_t *a, u16 *template_id)
Definition: flow_report.c:344
api_errno.h
src_address
vl_api_address_union_t src_address
Definition: ip_types.api:122
vlib_cli_command_t
Definition: cli.h:92
udp_ping_template_rewrite
static u8 * udp_ping_template_rewrite(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
Definition: udp_ping_export.c:26
ip_csum_fold
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:301
flow_report::rewrite
u8 * rewrite
Definition: flow_report.h:89
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
ipfix_set_header_t::set_id_length
u32 set_id_length
Definition: ipfix_packet.h:117
udp_ping_flow::start_dst_port
u16 start_dst_port
Defines start port of the dest port range.
Definition: udp_ping.h:73
vnet_flow_report_add_del_args_t::rewrite_callback
vnet_flow_rewrite_callback_t * rewrite_callback
Definition: flow_report.h:149
udp_ping_flow_create
clib_error_t * udp_ping_flow_create(u8 del)
Definition: udp_ping_export.c:228
ipfix_template_packet_t::s
ipfix_set_header_t s
Definition: ipfix_packet.h:193
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
UDP_PING_EXPORT_RECORD_SIZE
#define UDP_PING_EXPORT_RECORD_SIZE
Definition: udp_ping_export.c:23
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vnet_flow_report_add_del_args_t::is_add
int is_add
Definition: flow_report.h:153
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
ip4_ipfix_template_packet_t::ipfix
ipfix_template_packet_t ipfix
Definition: flow_report.h:46
set_udp_ping_export_command_fn
static clib_error_t * set_udp_ping_export_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: udp_ping_export.c:260