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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 * pg.h: VLIB packet generator
18 * Copyright (c) 2008 Eliot Dresselhaus
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:
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
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.
40 #ifndef included_vlib_pg_h
41 #define included_vlib_pg_h
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>
48 #include <vnet/ethernet/mac_address.h>
49 #include <vnet/gso/gro.h>
51 extern vnet_device_class_t pg_dev_class;
56 typedef struct pg_edit_group_t
58 /* Edits in this group. */
61 /* Vector of non-fixed edits for this group. */
62 pg_edit_t *non_fixed_edits;
64 /* Fixed edits for this group. */
65 u8 *fixed_packet_data;
66 u8 *fixed_packet_data_mask;
68 /* Byte offset where packet data begins. */
69 u32 start_byte_offset;
71 /* Number of packet bytes for this edit group. */
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);
80 /* Opaque data for edit function's use. */
81 uword edit_function_opaque;
84 /* Packets are made of multiple buffers chained together.
85 This struct keeps track of data per-chain index. */
88 /* Vector of buffer edits for this stream and buffer index. */
91 /* Buffers pre-initialized with fixed buffer data for this stream. */
96 typedef struct pg_stream_t
103 /* Stream is currently enabled. */
104 #define PG_STREAM_FLAGS_IS_ENABLED (1 << 0)
106 /* Edit groups are created by each protocol level (e.g. ethernet,
108 pg_edit_group_t *edit_groups;
110 pg_edit_type_t packet_size_edit_type;
112 /* Min/max packet size. */
113 u32 min_packet_bytes, max_packet_bytes;
115 /* Vector of non-fixed edits for this stream.
116 All fixed edits are performed and placed into fixed_packet_data. */
117 pg_edit_t *non_fixed_edits;
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. */
122 u8 *fixed_packet_data, *fixed_packet_data_mask;
124 /* Size to use for buffers. 0 means use buffers big enough
125 for max_packet_bytes. */
128 /* Buffer flags to set in each packet e.g. l2 valid flags */
131 /* Buffer offload flags to set in each packet e.g. checksum offload flags */
134 /* Last packet length if packet size edit type is increment. */
135 u32 last_increment_packet_size;
137 /* Index into main interface pool for this stream. */
140 /* Interface used to mark packets for this stream. May be different
141 than hw/sw index from pg main interface pool. They will be
142 different if this stream is being used generate buffers as if
143 they were received on a non-pg interface. For example, suppose you
144 are trying to test vlan code and you want to generate buffers that
145 appear to come from an ethernet interface. */
146 u32 sw_if_index[VLIB_N_RX_TX];
148 /* Node where stream's buffers get put. */
151 /* Worker thread index */
154 /* Output next index to reach output node from stream input node. */
159 /* Number of packets currently generated. */
160 u64 n_packets_generated;
162 /* Stream is disabled when packet limit is reached.
163 Zero means no packet limit. */
166 /* Only generate up to n_max_frame per frame. */
169 /* Rate for this stream in packets/second.
170 Zero means unlimited rate. */
171 f64 rate_packets_per_second;
173 f64 time_last_generate;
175 f64 packet_accumulator;
177 pg_buffer_index_t *buffer_indices;
179 u8 **replay_packet_templates;
180 u64 *replay_packet_timestamps;
181 u32 current_replay_packet_index;
185 pg_buffer_index_free (pg_buffer_index_t * bi)
187 vec_free (bi->edits);
188 clib_fifo_free (bi->buffer_fifo);
192 pg_edit_group_free (pg_edit_group_t * g)
195 vec_foreach (e, g->edits) pg_edit_free (e);
197 vec_free (g->fixed_packet_data);
198 vec_free (g->fixed_packet_data_mask);
202 pg_stream_free (pg_stream_t * s)
207 vec_foreach (e, s->non_fixed_edits) pg_edit_free (e);
208 vec_free (s->non_fixed_edits);
209 vec_foreach (g, s->edit_groups) pg_edit_group_free (g);
210 vec_free (s->edit_groups);
211 vec_free (s->fixed_packet_data);
212 vec_free (s->fixed_packet_data_mask);
214 for (i = 0; i < vec_len (s->replay_packet_templates); i++)
215 vec_free (s->replay_packet_templates[i]);
216 vec_free (s->replay_packet_templates);
217 vec_free (s->replay_packet_timestamps);
220 pg_buffer_index_t *bi;
221 vec_foreach (bi, s->buffer_indices) pg_buffer_index_free (bi);
222 vec_free (s->buffer_indices);
227 pg_stream_is_enabled (pg_stream_t * s)
229 return (s->flags & PG_STREAM_FLAGS_IS_ENABLED) != 0;
232 always_inline pg_edit_group_t *
233 pg_stream_get_group (pg_stream_t * s, u32 group_index)
235 return vec_elt_at_index (s->edit_groups, group_index);
239 pg_create_edit_group (pg_stream_t * s,
240 int n_edit_bytes, int n_packet_bytes, u32 * group_index)
245 vec_add2 (s->edit_groups, g, 1);
247 *group_index = g - s->edit_groups;
249 ASSERT (n_edit_bytes % sizeof (pg_edit_t) == 0);
250 n_edits = n_edit_bytes / sizeof (pg_edit_t);
251 vec_resize (g->edits, n_edits);
253 g->n_packet_bytes = n_packet_bytes;
259 pg_add_edits (pg_stream_t * s, int n_edit_bytes, int n_packet_bytes,
262 pg_edit_group_t *g = pg_stream_get_group (s, group_index);
265 ASSERT (n_edit_bytes % sizeof (pg_edit_t) == 0);
266 n_edits = n_edit_bytes / sizeof (pg_edit_t);
267 vec_add2 (g->edits, e, n_edits);
268 g->n_packet_bytes += n_packet_bytes;
273 pg_get_edit_group (pg_stream_t * s, u32 group_index)
275 pg_edit_group_t *g = pg_stream_get_group (s, group_index);
279 /* Number of bytes for all groups >= given group. */
281 pg_edit_group_n_bytes (pg_stream_t * s, u32 group_index)
286 for (g = s->edit_groups + group_index; g < vec_end (s->edit_groups); g++)
287 n_bytes += g->n_packet_bytes;
292 pg_free_edit_group (pg_stream_t * s)
294 uword i = vec_len (s->edit_groups) - 1;
295 pg_edit_group_t *g = pg_stream_get_group (s, i);
297 pg_edit_group_free (g);
298 clib_memset (g, 0, sizeof (g[0]));
299 vec_set_len (s->edit_groups, i);
302 typedef enum pg_interface_mode_t_
307 } pg_interface_mode_t;
314 /* VLIB interface indices. */
315 u32 hw_if_index, sw_if_index;
317 /* Identifies stream for this interface. */
321 gro_flow_table_t *flow_table;
324 pcap_main_t pcap_main;
325 char *pcap_file_name;
326 pg_interface_mode_t mode;
328 mac_address_t *allowed_mcast_macs;
331 /* Per VLIB node data. */
334 /* Parser function indexed by node index. */
335 unformat_function_t *unformat_edit;
338 typedef struct pg_main_t
340 /* Pool of streams. */
341 pg_stream_t *streams;
343 /* Bitmap indicating which streams are currently enabled. */
344 uword **enabled_streams;
346 /* Hash mapping name -> stream index. */
347 uword *stream_index_by_name;
349 /* Pool of interfaces. */
350 pg_interface_t *interfaces;
351 uword *if_index_by_if_id;
352 uword *if_id_by_sw_if_index;
354 /* Vector of buffer indices for use in pg_stream_fill_replay, per thread */
355 u32 **replay_buffers_by_thread;
357 /* Per VLIB node information. */
363 /* Global main structure. */
364 extern pg_main_t pg_main;
367 extern vlib_node_registration_t pg_input_node;
369 /* Buffer generator input, output node functions. */
370 vlib_node_function_t pg_input, pg_output;
372 /* Stream add/delete. */
373 void pg_stream_del (pg_main_t * pg, uword index);
374 void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init);
375 void pg_stream_change (pg_main_t * pg, pg_stream_t * s);
377 /* Enable/disable stream. */
378 void pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s,
381 /* Enable/disable packet coalesce on given interface */
382 void pg_interface_enable_disable_coalesce (pg_interface_t * pi, u8 enable,
385 /* Find/create free packet-generator interface index. */
386 u32 pg_interface_add_or_get (pg_main_t *pg, uword stream_index, u8 gso_enabled,
387 u32 gso_size, u8 coalesce_enabled,
388 pg_interface_mode_t mode);
390 always_inline pg_node_t *
391 pg_get_node (uword node_index)
393 pg_main_t *pg = &pg_main;
394 vec_validate (pg->nodes, node_index);
395 return pg->nodes + node_index;
398 void pg_edit_group_get_fixed_packet_data (pg_stream_t * s,
400 void *fixed_packet_data,
401 void *fixed_packet_data_mask);
403 void pg_enable_disable (u32 stream_index, int is_enable);
410 char *pcap_file_name;
414 clib_error_t *pg_capture (pg_capture_args_t * a);
419 vlib_buffer_t buffer;
423 #endif /* included_vlib_pg_h */
426 * fd.io coding-style-patch-verification: ON
429 * eval: (c-set-style "gnu")