1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
.. (c) OPNFV, Intel Corporation, AT&T and others.
===================================
Traffic Generator Integration Guide
===================================
Intended Audience
=================
This document is intended to aid those who want to integrate new traffic
generator into the vsperf code. It is expected, that reader has already
read generic part of :ref:`vsperf-design`.
Let us create a sample traffic generator called **sample_tg**, step by step.
Step 1 - create a directory
===========================
Implementation of trafficgens is located at tools/pkt_gen/ directory,
where every implementation has its dedicated sub-directory. It is
required to create a new directory for new traffic generator
implementations.
E.g.
.. code-block:: console
$ mkdir tools/pkt_gen/sample_tg
Step 2 - create a trafficgen module
===================================
Every trafficgen class must inherit from generic **ITrafficGenerator**
interface class. VSPERF during its initialization scans content of pkt_gen
directory for all python modules, that inherit from **ITrafficGenerator**. These
modules are automatically added into the list of supported traffic generators.
Example:
Let us create a draft of tools/pkt_gen/sample_tg/sample_tg.py module.
.. code-block:: python
from tools.pkt_gen import trafficgen
class SampleTG(trafficgen.ITrafficGenerator):
"""
A sample traffic generator implementation
"""
pass
VSPERF is immediately aware of the new class:
.. code-block:: console
$ ./vsperf --list-trafficgen
Output should look like:
.. code-block:: console
Classes derived from: ITrafficGenerator
======
* Dummy: A dummy traffic generator whose data is generated by the user.
* IxNet: A wrapper around IXIA IxNetwork applications.
* Ixia: A wrapper around the IXIA traffic generator.
* Moongen: Moongen Traffic generator wrapper.
* TestCenter: Spirent TestCenter
* Trex: Trex Traffic generator wrapper.
* Xena: Xena Traffic generator wrapper class
Step 3 - configuration
======================
All configuration values, required for correct traffic generator function, are passed
from VSPERF to the traffic generator in a dictionary. Default values shared among
all traffic generators are defined in **conf/03_traffic.conf** within **TRAFFIC**
dictionary. Default values are loaded by **ITrafficGenerator** interface class
automatically, so it is not needed to load them explicitly. In case that there are
any traffic generator specific default values, then they should be set within class
specific **__init__** function.
VSPERF passes test specific configuration within **traffic** dictionary to every
start and send function. So implementation of these functions must ensure,
that default values are updated with the testcase specific values. Proper merge
of values is assured by call of **merge_spec** function from **conf** module.
Example of **merge_spec** usage in **tools/pkt_gen/sample_tg/sample_tg.py** module:
.. code-block:: python
from conf import merge_spec
def start_rfc2544_throughput(self, traffic=None, duration=30):
self._params = {}
self._params['traffic'] = self.traffic_defaults.copy()
if traffic:
self._params['traffic'] = merge_spec(
self._params['traffic'], traffic)
Step 4 - generic functions
==========================
There are some generic functions, which every traffic generator should provide.
Although these functions are mainly optional, at least empty implementation must
be provided. This is required, so that developer is explicitly aware of these
functions.
The **connect** function is called from the traffic generator controller from its
**__enter__** method. This function should assure proper connection initialization
between DUT and traffic generator. In case, that such implementation is not needed,
empty implementation is required.
The **disconnect** function should perform clean up of any connection specific
actions called from the **connect** function.
Example in **tools/pkt_gen/sample_tg/sample_tg.py** module:
.. code-block:: python
def connect(self):
pass
def disconnect(self):
pass
.. _step-5-supported-traffic-types:
Step 5 - supported traffic types
================================
Currently VSPERF supports three different types of tests for traffic generators,
these are identified in vsperf through the traffic type, which include:
* RFC2544 throughput - Send fixed size packets at different rates, using
traffic configuration, until minimum rate at which no packet loss is
detected is found. Methods with its implementation have suffix
**_rfc2544_throughput**.
* RFC2544 back2back - Send fixed size packets at a fixed rate, using traffic
configuration, for specified time interval. Methods with its
implementation have suffix **_rfc2544_back2back**.
* continuous flow - Send fixed size packets at given framerate, using traffic
configuration, for specified time interval. Methods with its
implementation have suffix **_cont_traffic**.
In general, both synchronous and asynchronous interfaces must be implemented
for each traffic type. Synchronous functions start with prefix **send_**.
Asynchronous with prefixes **start_** and **wait_** in case of throughput
and back2back and **start_** and **stop_** in case of continuous traffic type.
Example of synchronous interfaces:
.. code-block:: python
def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
lossrate=0.0):
def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
lossrate=0.0):
def send_cont_traffic(self, traffic=None, duration=20):
Example of asynchronous interfaces:
.. code-block:: python
def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20,
lossrate=0.0):
def wait_rfc2544_throughput(self):
def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20,
lossrate=0.0):
def wait_rfc2544_back2back(self):
def start_cont_traffic(self, traffic=None, duration=20):
def stop_cont_traffic(self):
Description of parameters used by **send**, **start**, **wait** and **stop**
functions:
* param **traffic**: A dictionary with detailed definition of traffic
pattern. It contains following parameters to be implemented by
traffic generator.
Note: Traffic dictionary has also virtual switch related parameters,
which are not listed below.
Note: There are parameters specific to testing of tunnelling protocols,
which are discussed in detail at :ref:`integration-tests` userguide.
* param **traffic_type**: One of the supported traffic types,
e.g. **rfc2544_throughput**, **rfc2544_continuous**,
**rfc2544_back2back** or **burst**.
* param **bidir**: Specifies if generated traffic will be full-duplex
(true) or half-duplex (false).
* param **frame_rate**: Defines desired percentage of frame
rate used during continuous stream tests.
* param **burst_size**: Defines a number of frames in the single burst,
which is sent by burst traffic type. Burst size is applied for each
direction, i.e. the total number of tx frames will be 2*burst_size
in case of bidirectional traffic.
* param **multistream**: Defines number of flows simulated by traffic
generator. Value 0 disables MultiStream feature.
* param **stream_type**: Stream Type defines ISO OSI network layer
used for simulation of multiple streams.
Supported values:
* **L2** - iteration of destination MAC address
* **L3** - iteration of destination IP address
* **L4** - iteration of destination port of selected transport protocol
* param **l2**: A dictionary with data link layer details, e.g. **srcmac**,
**dstmac** and **framesize**.
* param **l3**: A dictionary with network layer details, e.g. **srcip**,
**dstip**, **proto** and l3 on/off switch **enabled**.
* param **l4**: A dictionary with transport layer details, e.g. **srcport**,
**dstport** and l4 on/off switch **enabled**.
* param **vlan**: A dictionary with vlan specific parameters,
e.g. **priority**, **cfi**, **id** and vlan on/off switch **enabled**.
* param **tests**: Number of times the test is executed.
* param **duration**: Duration of continuous test or per iteration duration
in case of RFC2544 throughput or back2back traffic types.
* param **lossrate**: Acceptable lossrate percentage.
Step 6 - passing back results
=============================
It is expected that methods **send**, **wait** and **stop** will return
values measured by traffic generator within a dictionary. Dictionary keys
are defined in **ResultsConstants** implemented in
**core/results/results_constants.py**. Please check sections for RFC2544
Throughput & Continuous and for Back2Back. The same key names should
be used by all traffic generator implementations.
|