1cb9cadadSEd Warnicke/*
2cb9cadadSEd Warnicke * Copyright (c) 2015 Cisco and/or its affiliates.
3cb9cadadSEd Warnicke * Licensed under the Apache License, Version 2.0 (the "License");
4cb9cadadSEd Warnicke * you may not use this file except in compliance with the License.
5cb9cadadSEd Warnicke * You may obtain a copy of the License at:
6cb9cadadSEd Warnicke *
7cb9cadadSEd Warnicke *     http://www.apache.org/licenses/LICENSE-2.0
8cb9cadadSEd Warnicke *
9cb9cadadSEd Warnicke * Unless required by applicable law or agreed to in writing, software
10cb9cadadSEd Warnicke * distributed under the License is distributed on an "AS IS" BASIS,
11cb9cadadSEd Warnicke * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cb9cadadSEd Warnicke * See the License for the specific language governing permissions and
13cb9cadadSEd Warnicke * limitations under the License.
14cb9cadadSEd Warnicke */
15cb9cadadSEd Warnicke/*
16cb9cadadSEd Warnicke * pg.h: VLIB packet generator
17cb9cadadSEd Warnicke *
18cb9cadadSEd Warnicke * Copyright (c) 2008 Eliot Dresselhaus
19cb9cadadSEd Warnicke *
20cb9cadadSEd Warnicke * Permission is hereby granted, free of charge, to any person obtaining
21cb9cadadSEd Warnicke * a copy of this software and associated documentation files (the
22cb9cadadSEd Warnicke * "Software"), to deal in the Software without restriction, including
23cb9cadadSEd Warnicke * without limitation the rights to use, copy, modify, merge, publish,
24cb9cadadSEd Warnicke * distribute, sublicense, and/or sell copies of the Software, and to
25cb9cadadSEd Warnicke * permit persons to whom the Software is furnished to do so, subject to
26cb9cadadSEd Warnicke * the following conditions:
27cb9cadadSEd Warnicke *
28cb9cadadSEd Warnicke * The above copyright notice and this permission notice shall be
29cb9cadadSEd Warnicke * included in all copies or substantial portions of the Software.
30cb9cadadSEd Warnicke *
31cb9cadadSEd Warnicke *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32cb9cadadSEd Warnicke *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33cb9cadadSEd Warnicke *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34cb9cadadSEd Warnicke *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35cb9cadadSEd Warnicke *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36cb9cadadSEd Warnicke *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37cb9cadadSEd Warnicke *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38cb9cadadSEd Warnicke */
39cb9cadadSEd Warnicke
40cb9cadadSEd Warnicke#ifndef included_vlib_pg_h
41cb9cadadSEd Warnicke#define included_vlib_pg_h
42cb9cadadSEd Warnicke
43cb9cadadSEd Warnicke#include <vlib/vlib.h>		/* for VLIB_N_RX_TX */
44cb9cadadSEd Warnicke#include <vnet/pg/edit.h>
4571e97c63SCalvin#include <vppinfra/fifo.h>	/* for buffer_fifo */
463ae2873eSDave Barach#include <vppinfra/pcap.h>
473d9c86e9SDamjan Marion#include <vnet/interface.h>
483d9c86e9SDamjan Marion
493d9c86e9SDamjan Marionextern vnet_device_class_t pg_dev_class;
50cb9cadadSEd Warnicke
51cb9cadadSEd Warnickestruct pg_main_t;
52cb9cadadSEd Warnickestruct pg_stream_t;
53cb9cadadSEd Warnicke
5471e97c63SCalvintypedef struct pg_edit_group_t
5571e97c63SCalvin{
56cb9cadadSEd Warnicke  /* Edits in this group. */
5771e97c63SCalvin  pg_edit_t *edits;
58cb9cadadSEd Warnicke
59cb9cadadSEd Warnicke  /* Vector of non-fixed edits for this group. */
6071e97c63SCalvin  pg_edit_t *non_fixed_edits;
61cb9cadadSEd Warnicke
62cb9cadadSEd Warnicke  /* Fixed edits for this group. */
6371e97c63SCalvin  u8 *fixed_packet_data;
6471e97c63SCalvin  u8 *fixed_packet_data_mask;
65cb9cadadSEd Warnicke
66cb9cadadSEd Warnicke  /* Byte offset where packet data begins. */
67cb9cadadSEd Warnicke  u32 start_byte_offset;
68cb9cadadSEd Warnicke
69cb9cadadSEd Warnicke  /* Number of packet bytes for this edit group. */
70cb9cadadSEd Warnicke  u32 n_packet_bytes;
71cb9cadadSEd Warnicke
72cb9cadadSEd Warnicke  /* Function to perform miscellaneous edits (e.g. set IP checksum, ...). */
7371e97c63SCalvin  void (*edit_function) (struct pg_main_t * pg,
7471e97c63SCalvin			 struct pg_stream_t * s,
7571e97c63SCalvin			 struct pg_edit_group_t * g,
7671e97c63SCalvin			 u32 * buffers, u32 n_buffers);
77cb9cadadSEd Warnicke
78cb9cadadSEd Warnicke  /* Opaque data for edit function's use. */
79cb9cadadSEd Warnicke  uword edit_function_opaque;
80cb9cadadSEd Warnicke} pg_edit_group_t;
81cb9cadadSEd Warnicke
82cb9cadadSEd Warnicke/* Packets are made of multiple buffers chained together.
83cb9cadadSEd Warnicke   This struct keeps track of data per-chain index. */
8471e97c63SCalvintypedef struct
8571e97c63SCalvin{
86cb9cadadSEd Warnicke  /* Vector of buffer edits for this stream and buffer index. */
8771e97c63SCalvin  pg_edit_t *edits;
88cb9cadadSEd Warnicke
89cb9cadadSEd Warnicke  /* Buffers pre-initialized with fixed buffer data for this stream. */
9071e97c63SCalvin  u32 *buffer_fifo;
91cb9cadadSEd Warnicke
92cb9cadadSEd Warnicke} pg_buffer_index_t;
93cb9cadadSEd Warnicke
9471e97c63SCalvintypedef struct pg_stream_t
9571e97c63SCalvin{
96cb9cadadSEd Warnicke  /* Stream name. */
9771e97c63SCalvin  u8 *name;
98cb9cadadSEd Warnicke
99cb9cadadSEd Warnicke  u32 flags;
100cb9cadadSEd Warnicke
101cb9cadadSEd Warnicke  /* Stream is currently enabled. */
102cb9cadadSEd Warnicke#define PG_STREAM_FLAGS_IS_ENABLED (1 << 0)
103cb9cadadSEd Warnicke
104cb9cadadSEd Warnicke  /* Edit groups are created by each protocol level (e.g. ethernet,
105cb9cadadSEd Warnicke     ip4, tcp, ...). */
10671e97c63SCalvin  pg_edit_group_t *edit_groups;
107cb9cadadSEd Warnicke
108cb9cadadSEd Warnicke  pg_edit_type_t packet_size_edit_type;
109cb9cadadSEd Warnicke
110cb9cadadSEd Warnicke  /* Min/max packet size. */
111cb9cadadSEd Warnicke  u32 min_packet_bytes, max_packet_bytes;
112cb9cadadSEd Warnicke
113cb9cadadSEd Warnicke  /* Vector of non-fixed edits for this stream.
114cb9cadadSEd Warnicke     All fixed edits are performed and placed into fixed_packet_data. */
11571e97c63SCalvin  pg_edit_t *non_fixed_edits;
116cb9cadadSEd Warnicke
117cb9cadadSEd Warnicke  /* Packet data with all fixed edits performed.
118cb9cadadSEd Warnicke     All packets in stream are initialized according with this data.
119cb9cadadSEd Warnicke     Mask specifies which bits of packet data are covered by fixed edits. */
12071e97c63SCalvin  u8 *fixed_packet_data, *fixed_packet_data_mask;
121cb9cadadSEd Warnicke
122cb9cadadSEd Warnicke  /* Size to use for buffers.  0 means use buffers big enough
123cb9cadadSEd Warnicke     for max_packet_bytes. */
124cb9cadadSEd Warnicke  u32 buffer_bytes;
125cb9cadadSEd Warnicke
12608eb2bb2SDave Barach  /* Buffer flags to set in each packet e.g. checksum offload flags */
12708eb2bb2SDave Barach  u32 buffer_flags;
12808eb2bb2SDave Barach
129cb9cadadSEd Warnicke  /* Last packet length if packet size edit type is increment. */
130cb9cadadSEd Warnicke  u32 last_increment_packet_size;
131cb9cadadSEd Warnicke
132cb9cadadSEd Warnicke  /* Index into main interface pool for this stream. */
133cb9cadadSEd Warnicke  u32 pg_if_index;
134cb9cadadSEd Warnicke
135cb9cadadSEd Warnicke  /* Interface used to mark packets for this stream.  May be different
136cb9cadadSEd Warnicke     than hw/sw index from pg main interface pool.  They will be
137cb9cadadSEd Warnicke     different if this stream is being used generate buffers as if
138cb9cadadSEd Warnicke     they were received on a non-pg interface.  For example, suppose you
139cb9cadadSEd Warnicke     are trying to test vlan code and you want to generate buffers that
140cb9cadadSEd Warnicke     appear to come from an ethernet interface. */
141cb9cadadSEd Warnicke  u32 sw_if_index[VLIB_N_RX_TX];
142cb9cadadSEd Warnicke
143cb9cadadSEd Warnicke  /* Node where stream's buffers get put. */
144cb9cadadSEd Warnicke  u32 node_index;
145cb9cadadSEd Warnicke
14664034367SDamjan Marion  /* Worker thread index */
14764034367SDamjan Marion  u32 worker_index;
14864034367SDamjan Marion
149cb9cadadSEd Warnicke  /* Output next index to reach output node from stream input node. */
150cb9cadadSEd Warnicke  u32 next_index;
151cb9cadadSEd Warnicke
1523d9c86e9SDamjan Marion  u32 if_id;
1533d9c86e9SDamjan Marion
154cb9cadadSEd Warnicke  /* Number of packets currently generated. */
155cb9cadadSEd Warnicke  u64 n_packets_generated;
156cb9cadadSEd Warnicke
157cb9cadadSEd Warnicke  /* Stream is disabled when packet limit is reached.
158cb9cadadSEd Warnicke     Zero means no packet limit. */
159cb9cadadSEd Warnicke  u64 n_packets_limit;
160cb9cadadSEd Warnicke
16187d7bac5SChristian E. Hopps  /* Only generate up to n_max_frame per frame. */
16287d7bac5SChristian E. Hopps  u32 n_max_frame;
16387d7bac5SChristian E. Hopps
164cb9cadadSEd Warnicke  /* Rate for this stream in packets/second.
165cb9cadadSEd Warnicke     Zero means unlimited rate. */
166cb9cadadSEd Warnicke  f64 rate_packets_per_second;
167cb9cadadSEd Warnicke
168cb9cadadSEd Warnicke  f64 time_last_generate;
169cb9cadadSEd Warnicke
170cb9cadadSEd Warnicke  f64 packet_accumulator;
171cb9cadadSEd Warnicke
17271e97c63SCalvin  pg_buffer_index_t *buffer_indices;
173cb9cadadSEd Warnicke
17471e97c63SCalvin  u8 **replay_packet_templates;
17578c56890SDave Barach  u64 *replay_packet_timestamps;
176cb9cadadSEd Warnicke  u32 current_replay_packet_index;
177cb9cadadSEd Warnicke} pg_stream_t;
178cb9cadadSEd Warnicke
179cb9cadadSEd Warnickealways_inline void
180cb9cadadSEd Warnickepg_buffer_index_free (pg_buffer_index_t * bi)
181cb9cadadSEd Warnicke{
182cb9cadadSEd Warnicke  vec_free (bi->edits);
183cb9cadadSEd Warnicke  clib_fifo_free (bi->buffer_fifo);
184cb9cadadSEd Warnicke}
185cb9cadadSEd Warnicke
186cb9cadadSEd Warnickealways_inline void
187cb9cadadSEd Warnickepg_edit_group_free (pg_edit_group_t * g)
188cb9cadadSEd Warnicke{
18971e97c63SCalvin  pg_edit_t *e;
19071e97c63SCalvin  vec_foreach (e, g->edits) pg_edit_free (e);
191cb9cadadSEd Warnicke  vec_free (g->edits);
192cb9cadadSEd Warnicke  vec_free (g->fixed_packet_data);
193cb9cadadSEd Warnicke  vec_free (g->fixed_packet_data_mask);
194cb9cadadSEd Warnicke}
195cb9cadadSEd Warnicke
196cb9cadadSEd Warnickealways_inline void
197cb9cadadSEd Warnickepg_stream_free (pg_stream_t * s)
198cb9cadadSEd Warnicke{
19978c56890SDave Barach  int i;
20071e97c63SCalvin  pg_edit_group_t *g;
20171e97c63SCalvin  pg_edit_t *e;
20271e97c63SCalvin  vec_foreach (e, s->non_fixed_edits) pg_edit_free (e);
203cb9cadadSEd Warnicke  vec_free (s->non_fixed_edits);
20471e97c63SCalvin  vec_foreach (g, s->edit_groups) pg_edit_group_free (g);
205cb9cadadSEd Warnicke  vec_free (s->edit_groups);
206cb9cadadSEd Warnicke  vec_free (s->fixed_packet_data);
207cb9cadadSEd Warnicke  vec_free (s->fixed_packet_data_mask);
208cb9cadadSEd Warnicke  vec_free (s->name);
20978c56890SDave Barach  for (i = 0; i < vec_len (s->replay_packet_templates); i++)
21078c56890SDave Barach    vec_free (s->replay_packet_templates[i]);
21178c56890SDave Barach  vec_free (s->replay_packet_templates);
21278c56890SDave Barach  vec_free (s->replay_packet_timestamps);
213cb9cadadSEd Warnicke
214cb9cadadSEd Warnicke  {
21571e97c63SCalvin    pg_buffer_index_t *bi;
21671e97c63SCalvin    vec_foreach (bi, s->buffer_indices) pg_buffer_index_free (bi);
217cb9cadadSEd Warnicke    vec_free (s->buffer_indices);
218cb9cadadSEd Warnicke  }
219cb9cadadSEd Warnicke}
220cb9cadadSEd Warnicke
221cb9cadadSEd Warnickealways_inline int
222cb9cadadSEd Warnickepg_stream_is_enabled (pg_stream_t * s)
22371e97c63SCalvin{
22471e97c63SCalvin  return (s->flags & PG_STREAM_FLAGS_IS_ENABLED) != 0;
22571e97c63SCalvin}
226cb9cadadSEd Warnicke
227cb9cadadSEd Warnickealways_inline pg_edit_group_t *
228cb9cadadSEd Warnickepg_stream_get_group (pg_stream_t * s, u32 group_index)
22971e97c63SCalvin{
23071e97c63SCalvin  return vec_elt_at_index (s->edit_groups, group_index);
23171e97c63SCalvin}
232cb9cadadSEd Warnicke
233cb9cadadSEd Warnickealways_inline void *
234cb9cadadSEd Warnickepg_create_edit_group (pg_stream_t * s,
23571e97c63SCalvin		      int n_edit_bytes, int n_packet_bytes, u32 * group_index)
236cb9cadadSEd Warnicke{
23771e97c63SCalvin  pg_edit_group_t *g;
238cb9cadadSEd Warnicke  int n_edits;
239cb9cadadSEd Warnicke
240cb9cadadSEd Warnicke  vec_add2 (s->edit_groups, g, 1);
241cb9cadadSEd Warnicke  if (group_index)
242cb9cadadSEd Warnicke    *group_index = g - s->edit_groups;
243cb9cadadSEd Warnicke
244cb9cadadSEd Warnicke  ASSERT (n_edit_bytes % sizeof (pg_edit_t) == 0);
245cb9cadadSEd Warnicke  n_edits = n_edit_bytes / sizeof (pg_edit_t);
246cb9cadadSEd Warnicke  vec_resize (g->edits, n_edits);
247cb9cadadSEd Warnicke
248cb9cadadSEd Warnicke  g->n_packet_bytes = n_packet_bytes;
249cb9cadadSEd Warnicke
250cb9cadadSEd Warnicke  return g->edits;
251cb9cadadSEd Warnicke}
252cb9cadadSEd Warnicke
253cb9cadadSEd Warnickealways_inline void *
254cb9cadadSEd Warnickepg_add_edits (pg_stream_t * s, int n_edit_bytes, int n_packet_bytes,
255cb9cadadSEd Warnicke	      u32 group_index)
256cb9cadadSEd Warnicke{
25771e97c63SCalvin  pg_edit_group_t *g = pg_stream_get_group (s, group_index);
25871e97c63SCalvin  pg_edit_t *e;
259cb9cadadSEd Warnicke  int n_edits;
260cb9cadadSEd Warnicke  ASSERT (n_edit_bytes % sizeof (pg_edit_t) == 0);
261cb9cadadSEd Warnicke  n_edits = n_edit_bytes / sizeof (pg_edit_t);
262cb9cadadSEd Warnicke  vec_add2 (g->edits, e, n_edits);
263cb9cadadSEd Warnicke  g->n_packet_bytes += n_packet_bytes;
264cb9cadadSEd Warnicke  return e;
265cb9cadadSEd Warnicke}
266cb9cadadSEd Warnicke
267cb9cadadSEd Warnickealways_inline void *
268cb9cadadSEd Warnickepg_get_edit_group (pg_stream_t * s, u32 group_index)
269cb9cadadSEd Warnicke{
27071e97c63SCalvin  pg_edit_group_t *g = pg_stream_get_group (s, group_index);
271cb9cadadSEd Warnicke  return g->edits;
272cb9cadadSEd Warnicke}
273cb9cadadSEd Warnicke
274cb9cadadSEd Warnicke/* Number of bytes for all groups >= given group. */
275cb9cadadSEd Warnickealways_inline uword
276cb9cadadSEd Warnickepg_edit_group_n_bytes (pg_stream_t * s, u32 group_index)
277cb9cadadSEd Warnicke{
27871e97c63SCalvin  pg_edit_group_t *g;
279cb9cadadSEd Warnicke  uword n_bytes = 0;
280cb9cadadSEd Warnicke
281cb9cadadSEd Warnicke  for (g = s->edit_groups + group_index; g < vec_end (s->edit_groups); g++)
282cb9cadadSEd Warnicke    n_bytes += g->n_packet_bytes;
283cb9cadadSEd Warnicke  return n_bytes;
284cb9cadadSEd Warnicke}
285cb9cadadSEd Warnicke
286cb9cadadSEd Warnickealways_inline void
287cb9cadadSEd Warnickepg_free_edit_group (pg_stream_t * s)
288cb9cadadSEd Warnicke{
289cb9cadadSEd Warnicke  uword i = vec_len (s->edit_groups) - 1;
29071e97c63SCalvin  pg_edit_group_t *g = pg_stream_get_group (s, i);
291cb9cadadSEd Warnicke
292cb9cadadSEd Warnicke  pg_edit_group_free (g);
293b7b92993SDave Barach  clib_memset (g, 0, sizeof (g[0]));
294cb9cadadSEd Warnicke  _vec_len (s->edit_groups) = i;
295cb9cadadSEd Warnicke}
296cb9cadadSEd Warnicke
29771e97c63SCalvintypedef struct
29871e97c63SCalvin{
29964034367SDamjan Marion  /* TX lock */
30064034367SDamjan Marion  volatile u32 *lockp;
30164034367SDamjan Marion
302cb9cadadSEd Warnicke  /* VLIB interface indices. */
303cb9cadadSEd Warnicke  u32 hw_if_index, sw_if_index;
304cb9cadadSEd Warnicke
305cb9cadadSEd Warnicke  /* Identifies stream for this interface. */
3063d9c86e9SDamjan Marion  u32 id;
3073d9c86e9SDamjan Marion
30822e9cfd7SMohsin Kazmi  u8 gso_enabled;
30922e9cfd7SMohsin Kazmi  u32 gso_size;
3103d9c86e9SDamjan Marion  pcap_main_t pcap_main;
311db86329aSJakub Grajciar  char *pcap_file_name;
312cb9cadadSEd Warnicke} pg_interface_t;
313cb9cadadSEd Warnicke
314cb9cadadSEd Warnicke/* Per VLIB node data. */
31571e97c63SCalvintypedef struct
31671e97c63SCalvin{
317cb9cadadSEd Warnicke  /* Parser function indexed by node index. */
31871e97c63SCalvin  unformat_function_t *unformat_edit;
319cb9cadadSEd Warnicke} pg_node_t;
320cb9cadadSEd Warnicke
32171e97c63SCalvintypedef struct pg_main_t
32271e97c63SCalvin{
323cb9cadadSEd Warnicke  /* Pool of streams. */
32471e97c63SCalvin  pg_stream_t *streams;
325cb9cadadSEd Warnicke
326cb9cadadSEd Warnicke  /* Bitmap indicating which streams are currently enabled. */
3273a4ed393SDamjan Marion  uword **enabled_streams;
328cb9cadadSEd Warnicke
329cb9cadadSEd Warnicke  /* Hash mapping name -> stream index. */
33071e97c63SCalvin  uword *stream_index_by_name;
331cb9cadadSEd Warnicke
3323d9c86e9SDamjan Marion  /* Pool of interfaces. */
33371e97c63SCalvin  pg_interface_t *interfaces;
33471e97c63SCalvin  uword *if_index_by_if_id;
335cb9cadadSEd Warnicke
3363c8e1468SDave Barach  /* Vector of buffer indices for use in pg_stream_fill_replay, per thread */
3373c8e1468SDave Barach  u32 **replay_buffers_by_thread;
3383c8e1468SDave Barach
339cb9cadadSEd Warnicke  /* Per VLIB node information. */
34071e97c63SCalvin  pg_node_t *nodes;
341cb9cadadSEd Warnicke} pg_main_t;
342cb9cadadSEd Warnicke
343cb9cadadSEd Warnicke/* Global main structure. */
344cb9cadadSEd Warnickeextern pg_main_t pg_main;
345cb9cadadSEd Warnicke
346cb9cadadSEd Warnicke/* Global node. */
347cb9cadadSEd Warnickeextern vlib_node_registration_t pg_input_node;
348cb9cadadSEd Warnicke
349cb9cadadSEd Warnicke/* Buffer generator input, output node functions. */
350cb9cadadSEd Warnickevlib_node_function_t pg_input, pg_output;
351cb9cadadSEd Warnicke
352cb9cadadSEd Warnicke/* Stream add/delete. */
353cb9cadadSEd Warnickevoid pg_stream_del (pg_main_t * pg, uword index);
354cb9cadadSEd Warnickevoid pg_stream_add (pg_main_t * pg, pg_stream_t * s_init);
3554222347aSKingwel Xievoid pg_stream_change (pg_main_t * pg, pg_stream_t * s);
356cb9cadadSEd Warnicke
357cb9cadadSEd Warnicke/* Enable/disable stream. */
35871e97c63SCalvinvoid pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s,
35971e97c63SCalvin			       int is_enable);
360cb9cadadSEd Warnicke
361cb9cadadSEd Warnicke/* Find/create free packet-generator interface index. */
36222e9cfd7SMohsin Kazmiu32 pg_interface_add_or_get (pg_main_t * pg, uword stream_index,
36322e9cfd7SMohsin Kazmi			     u8 gso_enabled, u32 gso_size);
364cb9cadadSEd Warnicke
365cb9cadadSEd Warnickealways_inline pg_node_t *
366cb9cadadSEd Warnickepg_get_node (uword node_index)
367cb9cadadSEd Warnicke{
36871e97c63SCalvin  pg_main_t *pg = &pg_main;
369cb9cadadSEd Warnicke  vec_validate (pg->nodes, node_index);
370cb9cadadSEd Warnicke  return pg->nodes + node_index;
371cb9cadadSEd Warnicke}
372cb9cadadSEd Warnicke
373cb9cadadSEd Warnickevoid pg_edit_group_get_fixed_packet_data (pg_stream_t * s,
374cb9cadadSEd Warnicke					  u32 group_index,
37571e97c63SCalvin					  void *fixed_packet_data,
37671e97c63SCalvin					  void *fixed_packet_data_mask);
377cb9cadadSEd Warnicke
3789e6ed6e2SPavel Kotucekvoid pg_enable_disable (u32 stream_index, int is_enable);
3799e6ed6e2SPavel Kotucek
38071e97c63SCalvintypedef struct
38171e97c63SCalvin{
38271e97c63SCalvin  u32 hw_if_index;
38371e97c63SCalvin  u32 dev_instance;
38471e97c63SCalvin  u8 is_enabled;
385db86329aSJakub Grajciar  char *pcap_file_name;
38671e97c63SCalvin  u32 count;
3879e6ed6e2SPavel Kotucek} pg_capture_args_t;
3889e6ed6e2SPavel Kotucek
38971e97c63SCalvinclib_error_t *pg_capture (pg_capture_args_t * a);
3909e6ed6e2SPavel Kotucek
391bfe4dfa7SDamjan Mariontypedef struct
392bfe4dfa7SDamjan Marion{
393bfe4dfa7SDamjan Marion  vlib_buffer_t buffer;
394bfe4dfa7SDamjan Marion  u32 buffer_index;
395bfe4dfa7SDamjan Marion}
396bfe4dfa7SDamjan Marionpg_output_trace_t;
397bfe4dfa7SDamjan Marion
398cb9cadadSEd Warnicke#endif /* included_vlib_pg_h */
39971e97c63SCalvin
40071e97c63SCalvin/*
40171e97c63SCalvin * fd.io coding-style-patch-verification: ON
40271e97c63SCalvin *
40371e97c63SCalvin * Local Variables:
40471e97c63SCalvin * eval: (c-set-style "gnu")
40571e97c63SCalvin * End:
40671e97c63SCalvin */
407