FD.io VPP  v21.01.1
Vector Packet Processing
pg.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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  * pg.h: VLIB packet generator
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #ifndef included_vlib_pg_h
41 #define included_vlib_pg_h
42 
43 #include <vlib/vlib.h> /* for VLIB_N_RX_TX */
44 #include <vnet/pg/edit.h>
45 #include <vppinfra/fifo.h> /* for buffer_fifo */
46 #include <vppinfra/pcap.h>
47 #include <vnet/interface.h>
49 #include <vnet/gso/gro.h>
50 
52 
53 struct pg_main_t;
54 struct pg_stream_t;
55 
56 typedef struct pg_edit_group_t
57 {
58  /* Edits in this group. */
60 
61  /* Vector of non-fixed edits for this group. */
63 
64  /* Fixed edits for this group. */
67 
68  /* Byte offset where packet data begins. */
70 
71  /* Number of packet bytes for this edit group. */
73 
74  /* Function to perform miscellaneous edits (e.g. set IP checksum, ...). */
75  void (*edit_function) (struct pg_main_t * pg,
76  struct pg_stream_t * s,
77  struct pg_edit_group_t * g,
78  u32 * buffers, u32 n_buffers);
79 
80  /* Opaque data for edit function's use. */
83 
84 /* Packets are made of multiple buffers chained together.
85  This struct keeps track of data per-chain index. */
86 typedef struct
87 {
88  /* Vector of buffer edits for this stream and buffer index. */
90 
91  /* Buffers pre-initialized with fixed buffer data for this stream. */
93 
95 
96 typedef struct pg_stream_t
97 {
98  /* Stream name. */
99  u8 *name;
100 
102 
103  /* Stream is currently enabled. */
104 #define PG_STREAM_FLAGS_IS_ENABLED (1 << 0)
105 
106  /* Edit groups are created by each protocol level (e.g. ethernet,
107  ip4, tcp, ...). */
109 
111 
112  /* Min/max packet size. */
113  u32 min_packet_bytes, max_packet_bytes;
114 
115  /* Vector of non-fixed edits for this stream.
116  All fixed edits are performed and placed into fixed_packet_data. */
118 
119  /* Packet data with all fixed edits performed.
120  All packets in stream are initialized according with this data.
121  Mask specifies which bits of packet data are covered by fixed edits. */
123 
124  /* Size to use for buffers. 0 means use buffers big enough
125  for max_packet_bytes. */
127 
128  /* Buffer flags to set in each packet e.g. checksum offload flags */
130 
131  /* Last packet length if packet size edit type is increment. */
133 
134  /* Index into main interface pool for this stream. */
136 
137  /* Interface used to mark packets for this stream. May be different
138  than hw/sw index from pg main interface pool. They will be
139  different if this stream is being used generate buffers as if
140  they were received on a non-pg interface. For example, suppose you
141  are trying to test vlan code and you want to generate buffers that
142  appear to come from an ethernet interface. */
144 
145  /* Node where stream's buffers get put. */
147 
148  /* Worker thread index */
150 
151  /* Output next index to reach output node from stream input node. */
153 
155 
156  /* Number of packets currently generated. */
158 
159  /* Stream is disabled when packet limit is reached.
160  Zero means no packet limit. */
162 
163  /* Only generate up to n_max_frame per frame. */
165 
166  /* Rate for this stream in packets/second.
167  Zero means unlimited rate. */
169 
171 
173 
175 
179 } pg_stream_t;
180 
181 always_inline void
183 {
184  vec_free (bi->edits);
186 }
187 
188 always_inline void
190 {
191  pg_edit_t *e;
192  vec_foreach (e, g->edits) pg_edit_free (e);
193  vec_free (g->edits);
196 }
197 
198 always_inline void
200 {
201  int i;
202  pg_edit_group_t *g;
203  pg_edit_t *e;
207  vec_free (s->edit_groups);
210  vec_free (s->name);
211  for (i = 0; i < vec_len (s->replay_packet_templates); i++)
215 
216  {
217  pg_buffer_index_t *bi;
220  }
221 }
222 
223 always_inline int
225 {
226  return (s->flags & PG_STREAM_FLAGS_IS_ENABLED) != 0;
227 }
228 
231 {
232  return vec_elt_at_index (s->edit_groups, group_index);
233 }
234 
235 always_inline void *
237  int n_edit_bytes, int n_packet_bytes, u32 * group_index)
238 {
239  pg_edit_group_t *g;
240  int n_edits;
241 
242  vec_add2 (s->edit_groups, g, 1);
243  if (group_index)
244  *group_index = g - s->edit_groups;
245 
246  ASSERT (n_edit_bytes % sizeof (pg_edit_t) == 0);
247  n_edits = n_edit_bytes / sizeof (pg_edit_t);
248  vec_resize (g->edits, n_edits);
249 
251 
252  return g->edits;
253 }
254 
255 always_inline void *
256 pg_add_edits (pg_stream_t * s, int n_edit_bytes, int n_packet_bytes,
257  u32 group_index)
258 {
259  pg_edit_group_t *g = pg_stream_get_group (s, group_index);
260  pg_edit_t *e;
261  int n_edits;
262  ASSERT (n_edit_bytes % sizeof (pg_edit_t) == 0);
263  n_edits = n_edit_bytes / sizeof (pg_edit_t);
264  vec_add2 (g->edits, e, n_edits);
266  return e;
267 }
268 
269 always_inline void *
271 {
272  pg_edit_group_t *g = pg_stream_get_group (s, group_index);
273  return g->edits;
274 }
275 
276 /* Number of bytes for all groups >= given group. */
279 {
280  pg_edit_group_t *g;
281  uword n_bytes = 0;
282 
283  for (g = s->edit_groups + group_index; g < vec_end (s->edit_groups); g++)
284  n_bytes += g->n_packet_bytes;
285  return n_bytes;
286 }
287 
288 always_inline void
290 {
291  uword i = vec_len (s->edit_groups) - 1;
293 
294  pg_edit_group_free (g);
295  clib_memset (g, 0, sizeof (g[0]));
296  _vec_len (s->edit_groups) = i;
297 }
298 
299 typedef struct
300 {
301  /* TX lock */
302  volatile u32 *lockp;
303 
304  /* VLIB interface indices. */
305  u32 hw_if_index, sw_if_index;
306 
307  /* Identifies stream for this interface. */
309 
316 
319 
320 /* Per VLIB node data. */
321 typedef struct
322 {
323  /* Parser function indexed by node index. */
325 } pg_node_t;
326 
327 typedef struct pg_main_t
328 {
329  /* Pool of streams. */
331 
332  /* Bitmap indicating which streams are currently enabled. */
334 
335  /* Hash mapping name -> stream index. */
337 
338  /* Pool of interfaces. */
342 
343  /* Vector of buffer indices for use in pg_stream_fill_replay, per thread */
345 
346  /* Per VLIB node information. */
348 } pg_main_t;
349 
350 /* Global main structure. */
351 extern pg_main_t pg_main;
352 
353 /* Global node. */
355 
356 /* Buffer generator input, output node functions. */
358 
359 /* Stream add/delete. */
360 void pg_stream_del (pg_main_t * pg, uword index);
361 void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init);
362 void pg_stream_change (pg_main_t * pg, pg_stream_t * s);
363 
364 /* Enable/disable stream. */
366  int is_enable);
367 
368 /* Enable/disable packet coalesce on given interface */
370  u32 tx_node_index);
371 
372 /* Find/create free packet-generator interface index. */
373 u32 pg_interface_add_or_get (pg_main_t * pg, uword stream_index,
374  u8 gso_enabled, u32 gso_size,
375  u8 coalesce_enabled);
376 
378 pg_get_node (uword node_index)
379 {
380  pg_main_t *pg = &pg_main;
381  vec_validate (pg->nodes, node_index);
382  return pg->nodes + node_index;
383 }
384 
386  u32 group_index,
387  void *fixed_packet_data,
388  void *fixed_packet_data_mask);
389 
390 void pg_enable_disable (u32 stream_index, int is_enable);
391 
392 typedef struct
393 {
400 
402 
403 typedef struct
404 {
407 }
409 
410 #endif /* included_vlib_pg_h */
411 
412 /*
413  * fd.io coding-style-patch-verification: ON
414  *
415  * Local Variables:
416  * eval: (c-set-style "gnu")
417  * End:
418  */
u32 sw_if_index
Definition: pg.h:305
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
Definition: edit.h:64
static int pg_stream_is_enabled(pg_stream_t *s)
Definition: pg.h:224
u32 next_index
Definition: pg.h:152
u64 n_packets_limit
Definition: pg.h:161
void pg_stream_add(pg_main_t *pg, pg_stream_t *s_init)
Definition: stream.c:450
u32 pg_interface_add_or_get(pg_main_t *pg, uword stream_index, u8 gso_enabled, u32 gso_size, u8 coalesce_enabled)
Definition: stream.c:233
void pg_interface_enable_disable_coalesce(pg_interface_t *pi, u8 enable, u32 tx_node_index)
Definition: stream.c:216
u8 * fixed_packet_data
Definition: pg.h:122
static void * pg_get_edit_group(pg_stream_t *s, u32 group_index)
Definition: pg.h:270
mac_address_t * allowed_mcast_macs
Definition: pg.h:317
a
Definition: bitmap.h:544
vlib_buffer_t buffer
Definition: pg.h:406
Definition: pg.h:327
unsigned long u64
Definition: types.h:89
pg_edit_group_t * edit_groups
Definition: pg.h:108
char * pcap_file_name
Definition: pg.h:397
PCAP utility definitions.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
pg_edit_type_t
Definition: edit.h:46
void(* edit_function)(struct pg_main_t *pg, struct pg_stream_t *s, struct pg_edit_group_t *g, u32 *buffers, u32 n_buffers)
Definition: pg.h:75
uword * stream_index_by_name
Definition: pg.h:336
u8 coalesce_enabled
Definition: pg.h:310
u32 worker_index
Definition: pg.h:149
u32 n_max_frame
Definition: pg.h:164
char * pcap_file_name
Definition: pg.h:315
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:630
u32 buffer_index
Definition: pg.h:405
u32 hw_if_index
Definition: pg.h:394
pg_buffer_index_t * buffer_indices
Definition: pg.h:174
struct _vnet_device_class vnet_device_class_t
pg_edit_type_t packet_size_edit_type
Definition: pg.h:110
void pg_stream_del(pg_main_t *pg, uword index)
Definition: stream.c:534
unsigned char u8
Definition: types.h:56
u8 * fixed_packet_data_mask
Definition: pg.h:122
u32 start_byte_offset
Definition: pg.h:69
static pg_edit_group_t * pg_stream_get_group(pg_stream_t *s, u32 group_index)
Definition: pg.h:230
gro_flow_table_t * flow_table
Definition: pg.h:311
double f64
Definition: types.h:142
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:378
u32 gso_size
Definition: pg.h:313
PCAP main state data structure.
Definition: pcap.h:156
static void * pg_add_edits(pg_stream_t *s, int n_edit_bytes, int n_packet_bytes, u32 group_index)
Definition: pg.h:256
u8 * fixed_packet_data_mask
Definition: pg.h:66
pg_edit_t * edits
Definition: pg.h:89
u32 n_packet_bytes
Definition: pg.h:72
u8 * fixed_packet_data
Definition: pg.h:65
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:281
uword * if_id_by_sw_if_index
Definition: pg.h:341
unsigned int u32
Definition: types.h:88
#define vec_end(v)
End (last data address) of vector.
static void * pg_create_edit_group(pg_stream_t *s, int n_edit_bytes, int n_packet_bytes, u32 *group_index)
Definition: pg.h:236
#define PG_STREAM_FLAGS_IS_ENABLED
Definition: pg.h:104
uword * if_index_by_if_id
Definition: pg.h:340
clib_error_t * pg_capture(pg_capture_args_t *a)
Definition: cli.c:81
pg_main_t pg_main
Definition: init.c:44
u32 buffer_bytes
Definition: pg.h:126
volatile u32 * lockp
Definition: pg.h:302
void pg_edit_group_get_fixed_packet_data(pg_stream_t *s, u32 group_index, void *fixed_packet_data, void *fixed_packet_data_mask)
Definition: stream.c:391
f64 packet_accumulator
Definition: pg.h:172
u32 last_increment_packet_size
Definition: pg.h:132
u32 pg_if_index
Definition: pg.h:135
u32 current_replay_packet_index
Definition: pg.h:178
pg_edit_t * non_fixed_edits
Definition: pg.h:62
u32 ** replay_buffers_by_thread
Definition: pg.h:344
u8 * name
Definition: pg.h:99
static void pg_stream_free(pg_stream_t *s)
Definition: pg.h:199
pcap_main_t pcap_main
Definition: pg.h:314
vlib_node_registration_t pg_input_node
(constructor) VLIB_REGISTER_NODE (pg_input_node)
Definition: input.c:1821
#define always_inline
Definition: ipsec.h:28
vlib_node_function_t pg_output
Definition: pg.h:357
pg_node_t * nodes
Definition: pg.h:347
uword() unformat_function_t(unformat_input_t *input, va_list *args)
Definition: format.h:232
uword ** enabled_streams
Definition: pg.h:333
u8 gso_enabled
Definition: pg.h:312
u64 * replay_packet_timestamps
Definition: pg.h:177
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
u32 min_packet_bytes
Definition: pg.h:113
static uword pg_edit_group_n_bytes(pg_stream_t *s, u32 group_index)
Definition: pg.h:278
struct pg_stream_t pg_stream_t
void pg_stream_change(pg_main_t *pg, pg_stream_t *s)
Definition: stream.c:554
unformat_function_t * unformat_edit
Definition: pg.h:324
vlib_node_function_t pg_input
Definition: pg.h:357
pg_edit_t * non_fixed_edits
Definition: pg.h:117
u8 ** replay_packet_templates
Definition: pg.h:176
pg_stream_t * streams
Definition: pg.h:330
#define ASSERT(truth)
uword() vlib_node_function_t(struct vlib_main_t *vm, struct vlib_node_runtime_t *node, struct vlib_frame_t *frame)
Definition: node.h:54
static void pg_free_edit_group(pg_stream_t *s)
Definition: pg.h:289
void pg_stream_enable_disable(pg_main_t *pg, pg_stream_t *s, int is_enable)
Definition: stream.c:49
uword edit_function_opaque
Definition: pg.h:81
#define clib_fifo_free(f)
Definition: fifo.h:257
Definition: pg.h:96
struct _vlib_node_registration vlib_node_registration_t
static void pg_buffer_index_free(pg_buffer_index_t *bi)
Definition: pg.h:182
u32 node_index
Definition: pg.h:146
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 id
Definition: pg.h:308
struct pg_edit_group_t pg_edit_group_t
VLIB buffer representation.
Definition: buffer.h:102
u32 if_id
Definition: pg.h:154
u64 uword
Definition: types.h:112
u32 index
Definition: flow_types.api:221
pg_edit_t * edits
Definition: pg.h:59
u32 dev_instance
Definition: pg.h:395
f64 rate_packets_per_second
Definition: pg.h:168
u32 buffer_flags
Definition: pg.h:129
u64 n_packets_generated
Definition: pg.h:157
u8 is_enabled
Definition: pg.h:396
#define vec_foreach(var, vec)
Vector iterator.
static void pg_edit_free(pg_edit_t *e)
Definition: edit.h:91
vnet_device_class_t pg_dev_class
struct pg_main_t pg_main_t
f64 time_last_generate
Definition: pg.h:170
Definition: pg.h:321
pg_interface_t * interfaces
Definition: pg.h:339
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
static void pg_edit_group_free(pg_edit_group_t *g)
Definition: pg.h:189
void pg_enable_disable(u32 stream_index, int is_enable)
Definition: cli.c:58
u32 flags
Definition: pg.h:101
u32 * buffer_fifo
Definition: pg.h:92