fib: Register multicast MAC with interface for accepting interfaces
[vpp.git] / src / vnet / pg / pg.h
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>
48 #include <vnet/ethernet/mac_address.h>
49 #include <vnet/gso/gro.h>
50
51 extern vnet_device_class_t pg_dev_class;
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. */
59   pg_edit_t *edits;
60
61   /* Vector of non-fixed edits for this group. */
62   pg_edit_t *non_fixed_edits;
63
64   /* Fixed edits for this group. */
65   u8 *fixed_packet_data;
66   u8 *fixed_packet_data_mask;
67
68   /* Byte offset where packet data begins. */
69   u32 start_byte_offset;
70
71   /* Number of packet bytes for this edit group. */
72   u32 n_packet_bytes;
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. */
81   uword edit_function_opaque;
82 } pg_edit_group_t;
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. */
89   pg_edit_t *edits;
90
91   /* Buffers pre-initialized with fixed buffer data for this stream. */
92   u32 *buffer_fifo;
93
94 } pg_buffer_index_t;
95
96 typedef struct pg_stream_t
97 {
98   /* Stream name. */
99   u8 *name;
100
101   u32 flags;
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, ...). */
108   pg_edit_group_t *edit_groups;
109
110   pg_edit_type_t packet_size_edit_type;
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. */
117   pg_edit_t *non_fixed_edits;
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. */
122   u8 *fixed_packet_data, *fixed_packet_data_mask;
123
124   /* Size to use for buffers.  0 means use buffers big enough
125      for max_packet_bytes. */
126   u32 buffer_bytes;
127
128   /* Buffer flags to set in each packet e.g. checksum offload flags */
129   u32 buffer_flags;
130
131   /* Last packet length if packet size edit type is increment. */
132   u32 last_increment_packet_size;
133
134   /* Index into main interface pool for this stream. */
135   u32 pg_if_index;
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. */
143   u32 sw_if_index[VLIB_N_RX_TX];
144
145   /* Node where stream's buffers get put. */
146   u32 node_index;
147
148   /* Worker thread index */
149   u32 worker_index;
150
151   /* Output next index to reach output node from stream input node. */
152   u32 next_index;
153
154   u32 if_id;
155
156   /* Number of packets currently generated. */
157   u64 n_packets_generated;
158
159   /* Stream is disabled when packet limit is reached.
160      Zero means no packet limit. */
161   u64 n_packets_limit;
162
163   /* Only generate up to n_max_frame per frame. */
164   u32 n_max_frame;
165
166   /* Rate for this stream in packets/second.
167      Zero means unlimited rate. */
168   f64 rate_packets_per_second;
169
170   f64 time_last_generate;
171
172   f64 packet_accumulator;
173
174   pg_buffer_index_t *buffer_indices;
175
176   u8 **replay_packet_templates;
177   u64 *replay_packet_timestamps;
178   u32 current_replay_packet_index;
179 } pg_stream_t;
180
181 always_inline void
182 pg_buffer_index_free (pg_buffer_index_t * bi)
183 {
184   vec_free (bi->edits);
185   clib_fifo_free (bi->buffer_fifo);
186 }
187
188 always_inline void
189 pg_edit_group_free (pg_edit_group_t * g)
190 {
191   pg_edit_t *e;
192   vec_foreach (e, g->edits) pg_edit_free (e);
193   vec_free (g->edits);
194   vec_free (g->fixed_packet_data);
195   vec_free (g->fixed_packet_data_mask);
196 }
197
198 always_inline void
199 pg_stream_free (pg_stream_t * s)
200 {
201   int i;
202   pg_edit_group_t *g;
203   pg_edit_t *e;
204   vec_foreach (e, s->non_fixed_edits) pg_edit_free (e);
205   vec_free (s->non_fixed_edits);
206   vec_foreach (g, s->edit_groups) pg_edit_group_free (g);
207   vec_free (s->edit_groups);
208   vec_free (s->fixed_packet_data);
209   vec_free (s->fixed_packet_data_mask);
210   vec_free (s->name);
211   for (i = 0; i < vec_len (s->replay_packet_templates); i++)
212     vec_free (s->replay_packet_templates[i]);
213   vec_free (s->replay_packet_templates);
214   vec_free (s->replay_packet_timestamps);
215
216   {
217     pg_buffer_index_t *bi;
218     vec_foreach (bi, s->buffer_indices) pg_buffer_index_free (bi);
219     vec_free (s->buffer_indices);
220   }
221 }
222
223 always_inline int
224 pg_stream_is_enabled (pg_stream_t * s)
225 {
226   return (s->flags & PG_STREAM_FLAGS_IS_ENABLED) != 0;
227 }
228
229 always_inline pg_edit_group_t *
230 pg_stream_get_group (pg_stream_t * s, u32 group_index)
231 {
232   return vec_elt_at_index (s->edit_groups, group_index);
233 }
234
235 always_inline void *
236 pg_create_edit_group (pg_stream_t * s,
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
250   g->n_packet_bytes = n_packet_bytes;
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);
265   g->n_packet_bytes += n_packet_bytes;
266   return e;
267 }
268
269 always_inline void *
270 pg_get_edit_group (pg_stream_t * s, u32 group_index)
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. */
277 always_inline uword
278 pg_edit_group_n_bytes (pg_stream_t * s, u32 group_index)
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
289 pg_free_edit_group (pg_stream_t * s)
290 {
291   uword i = vec_len (s->edit_groups) - 1;
292   pg_edit_group_t *g = pg_stream_get_group (s, i);
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. */
308   u32 id;
309
310   u8 coalesce_enabled;
311   gro_flow_table_t *flow_table;
312   u8 gso_enabled;
313   u32 gso_size;
314   pcap_main_t pcap_main;
315   char *pcap_file_name;
316
317   mac_address_t *allowed_mcast_macs;
318 } pg_interface_t;
319
320 /* Per VLIB node data. */
321 typedef struct
322 {
323   /* Parser function indexed by node index. */
324   unformat_function_t *unformat_edit;
325 } pg_node_t;
326
327 typedef struct pg_main_t
328 {
329   /* Pool of streams. */
330   pg_stream_t *streams;
331
332   /* Bitmap indicating which streams are currently enabled. */
333   uword **enabled_streams;
334
335   /* Hash mapping name -> stream index. */
336   uword *stream_index_by_name;
337
338   /* Pool of interfaces. */
339   pg_interface_t *interfaces;
340   uword *if_index_by_if_id;
341   uword *if_id_by_sw_if_index;
342
343   /* Vector of buffer indices for use in pg_stream_fill_replay, per thread */
344   u32 **replay_buffers_by_thread;
345
346   /* Per VLIB node information. */
347   pg_node_t *nodes;
348 } pg_main_t;
349
350 /* Global main structure. */
351 extern pg_main_t pg_main;
352
353 /* Global node. */
354 extern vlib_node_registration_t pg_input_node;
355
356 /* Buffer generator input, output node functions. */
357 vlib_node_function_t pg_input, pg_output;
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. */
365 void pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s,
366                                int is_enable);
367
368 /* Enable/disable packet coalesce on given interface */
369 void pg_interface_enable_disable_coalesce (pg_interface_t * pi, u8 enable,
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
377 always_inline pg_node_t *
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
385 void pg_edit_group_get_fixed_packet_data (pg_stream_t * s,
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 {
394   u32 hw_if_index;
395   u32 dev_instance;
396   u8 is_enabled;
397   char *pcap_file_name;
398   u32 count;
399 } pg_capture_args_t;
400
401 clib_error_t *pg_capture (pg_capture_args_t * a);
402
403 typedef struct
404 {
405   vlib_buffer_t buffer;
406   u32 buffer_index;
407 }
408 pg_output_trace_t;
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  */