1 # Copyright (c) 2017 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Base class for stream profiles for T-rex traffic generator.
21 from random import choice
22 from string import letters
24 from trex_stl_lib.api import *
27 class TrafficStreamsBaseClass(object):
28 """Base class for stream profiles for T-rex traffic generator.
33 {'size': 60, 'pps': 28, 'isg': 0},
34 {'size': 590, 'pps': 20, 'isg': 0.1},
35 {'size': 1514, 'pps': 4, 'isg': 0.2}
38 {'size': 64, 'pps': 28, 'isg': 0},
39 {'size': 570, 'pps': 16, 'isg': 0.1},
40 {'size': 1518, 'pps': 4, 'isg': 0.2}
46 # Default value of frame size, it will be overwritten by the value of
47 # "framesize" parameter of "get_streams" method.
50 # If needed, add your own parameters.
52 def _gen_payload(self, length):
55 If needed, implement your own algorithm.
57 :param length: Length of generated payload.
59 :returns: The generated payload.
64 for _ in range(length):
65 payload += choice(letters)
69 def _get_start_end_ipv6(self, start_ip, end_ip):
70 """Get start host and number of hosts from IPv6 as integer.
72 :param start_ip: Start IPv6.
73 :param end_ip: End IPv6.
74 :type start_ip: string
76 :return: Start host, number of hosts.
78 :raises: ValueError if start_ip is greater then end_ip.
79 :raises: socket.error if the IP addresses are not valid IPv6 addresses.
83 ip1 = socket.inet_pton(socket.AF_INET6, start_ip)
84 ip2 = socket.inet_pton(socket.AF_INET6, end_ip)
86 hi1, lo1 = struct.unpack('!QQ', ip1)
87 hi2, lo2 = struct.unpack('!QQ', ip2)
89 if ((hi1 << 64) | lo1) > ((hi2 << 64) | lo2):
90 raise ValueError("IPv6: start_ip is greater then end_ip")
92 return lo1, abs(int(lo1) - int(lo2))
94 except socket.error as err:
98 def define_packets(self):
99 """Define the packets to be sent from the traffic generator.
101 This method MUST return:
103 return base_pkt_a, base_pkt_b, vm1, vm2
105 vm1 and vm2 CAN be None.
107 :returns: Packets to be sent from the traffic generator.
110 raise NotImplementedError
112 def create_streams(self):
113 """Create traffic streams.
115 Implement your own traffic streams.
117 :returns: Traffic streams.
121 base_pkt_a, base_pkt_b, vm1, vm2 = self.define_packets()
123 # In most cases you will not have to change the code below:
125 # Frame size is defined as an integer, e.g. 64, 1518:
126 if isinstance(self.framesize, int):
128 # Create a base packet and pad it to size
129 payload_len = max(0, self.framesize - len(base_pkt_a) - 4) # No FCS
132 pkt_a = STLPktBuilder(
133 pkt=base_pkt_a / self._gen_payload(payload_len),
136 pkt_b = STLPktBuilder(
137 pkt=base_pkt_b / self._gen_payload(payload_len),
140 # Packets for latency measurement:
142 pkt_lat_a = STLPktBuilder(
143 pkt=base_pkt_a / self._gen_payload(payload_len))
145 pkt_lat_b = STLPktBuilder(
146 pkt=base_pkt_b / self._gen_payload(payload_len))
148 # Create the streams:
150 stream1 = STLStream(packet=pkt_a, mode=STLTXCont(pps=9000))
152 # second traffic stream with a phase of 10ns (inter-stream gap)
153 stream2 = STLStream(packet=pkt_b, isg=10.0,
154 mode=STLTXCont(pps=9000))
156 # Streams for latency measurement:
158 lat_stream1 = STLStream(packet=pkt_lat_a,
159 flow_stats=STLFlowLatencyStats(pg_id=0),
160 mode=STLTXCont(pps=9000))
162 # second traffic stream with a phase of 10ns (inter-stream gap)
163 lat_stream2 = STLStream(packet=pkt_lat_b, isg=10.0,
164 flow_stats=STLFlowLatencyStats(pg_id=1),
165 mode=STLTXCont(pps=9000))
167 return [stream1, stream2, lat_stream1, lat_stream2]
169 # Frame size is defined as a string, e.g.IMIX_v4_1:
170 elif isinstance(self.framesize, str):
175 for stream in self.STREAM_TABLE[self.framesize]:
176 payload_len_a = max(0, stream['size'] - len(base_pkt_a) - 4)
177 payload_len_b = max(0, stream['size'] - len(base_pkt_b) - 4)
178 # Create a base packet and pad it to size
179 pkt_a = STLPktBuilder(
180 pkt=base_pkt_a / self._gen_payload(payload_len_a),
182 pkt_b = STLPktBuilder(
183 pkt=base_pkt_b / self._gen_payload(payload_len_b),
186 # Create the streams:
187 stream1.append(STLStream(packet=pkt_a,
189 mode=STLTXCont(pps=stream['pps'])))
190 stream2.append(STLStream(packet=pkt_b,
192 mode=STLTXCont(pps=stream['pps'])))
194 streams.extend(stream1)
195 streams.extend(stream2)
199 def get_streams(self, **kwargs):
200 """Get traffic streams created by "create_streams" method.
202 If needed, add your own parameters.
204 :param kwargs: Key-value pairs used by "create_streams" method while
206 :returns: Traffic streams.
210 self.framesize = kwargs['framesize']
212 return self.create_streams()