aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_pg_stream.py
blob: 471c85c43f05121669e2f19d782a8af614d38900 (plain)
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
#!/usr/bin/env python3

import unittest
import time
import re

from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6

from framework import VppTestCase
from asfframework import VppTestRunner


class TestPgStream(VppTestCase):
    """PG Stream Test Case"""

    def __init__(self, *args):
        VppTestCase.__init__(self, *args)

    def setUp(self):
        super(TestPgStream, self).setUp()

        # Create 3 pg interfaces - one each for ethernet, IPv4, and IPv6.
        self.create_pg_interfaces(range(0, 1))
        self.pg_interfaces += self.create_pg_ip4_interfaces(range(1, 2))
        self.pg_interfaces += self.create_pg_ip6_interfaces(range(2, 3))

        for i in self.pg_interfaces:
            i.admin_up()

        for i in [self.pg0, self.pg1]:
            i.config_ip4()

        for i in [self.pg0, self.pg2]:
            i.config_ip6()

        self.pg0.resolve_arp()
        self.pg0.resolve_ndp()

    def tearDown(self):
        super(TestPgStream, self).tearDown()
        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.admin_down()
            i.remove_vpp_config()

    def pg_stream(self, count=100, rate=1e6, packet_size=700):
        rate = str(rate)
        packet_size = str(packet_size)
        count = str(count)

        cmds = [
            "clear trace",
            "trace add pg-input 1000",
            "packet-generator new {{\n"
            "  name pg0-pg1-stream\n"
            "  limit {count}\n"
            "  node ethernet-input\n"
            "  source pg0\n"
            "  rate {rate}\n"
            "  size {packet_size}+{packet_size}\n"
            "  buffer-flags ip4 offload\n"
            "  buffer-offload-flags offload-ip-cksum offload-udp-cksum\n"
            "  data {{\n"
            "    IP4: {src_mac} -> {dst_mac}\n"
            "    UDP: {src} -> {dst}\n"
            "    UDP: 1234 -> 4321\n"
            "    incrementing 100\n"
            "  }}\n"
            "}}\n".format(
                count=count,
                rate=rate,
                packet_size=packet_size,
                src_mac=self.pg0.remote_mac,
                dst_mac=self.pg0.local_mac,
                src=self.pg0.remote_ip4,
                dst=self.pg1.remote_ip4,
            ),
            "packet-generator new {{\n"
            "  name pg0-pg2-stream\n"
            "  limit {count}\n"
            "  node ethernet-input\n"
            "  source pg0\n"
            "  rate {rate}\n"
            "  size {packet_size}+{packet_size}\n"
            "  buffer-flags ip6 offload\n"
            "  buffer-offload-flags offload-udp-cksum\n"
            "  data {{\n"
            "    IP6: {src_mac} -> {dst_mac}\n"
            "    UDP: {src} -> {dst}\n"
            "    UDP: 1234 -> 4321\n"
            "    incrementing 100\n"
            "  }}\n"
            "}}\n".format(
                count=count,
                rate=rate,
                packet_size=packet_size,
                src_mac=self.pg0.remote_mac,
                dst_mac=self.pg0.local_mac,
                src=self.pg0.remote_ip6,
                dst=self.pg2.remote_ip6,
            ),
            "packet-generator new {{\n"
            "  name pg1-pg0-stream\n"
            "  limit {count}\n"
            "  node ip4-input\n"
            "  source pg1\n"
            "  rate {rate}\n"
            "  size {packet_size}+{packet_size}\n"
            "  buffer-flags ip4 offload\n"
            "  buffer-offload-flags offload-ip-cksum offload-udp-cksum\n"
            "  data {{\n"
            "    UDP: {src} -> {dst}\n"
            "    UDP: 1234 -> 4321\n"
            "    incrementing 100\n"
            "  }}\n"
            "}}\n".format(
                count=count,
                rate=rate,
                packet_size=packet_size,
                src=self.pg1.remote_ip4,
                dst=self.pg0.remote_ip4,
            ),
            "packet-generator new {{\n"
            "  name pg2-pg0-stream\n"
            "  limit {count}\n"
            "  node ip6-input\n"
            "  source pg2\n"
            "  rate {rate}\n"
            "  size {packet_size}+{packet_size}\n"
            "  buffer-flags ip6 offload\n"
            "  buffer-offload-flags offload-udp-cksum\n"
            "  data {{\n"
            "    UDP: {src} -> {dst}\n"
            "    UDP: 1234 -> 4321\n"
            "    incrementing 100\n"
            "  }}\n"
            "}}\n".format(
                count=count,
                rate=rate,
                packet_size=packet_size,
                src=self.pg2.remote_ip6,
                dst=self.pg0.remote_ip6,
            ),
            "packet-generator enable",
            "show error",
        ]

        for cmd in cmds:
            r = self.vapi.cli_return_response(cmd)
            if r.retval != 0:
                if hasattr(r, "reply"):
                    self.logger.info(cmd + " FAIL reply " + r.reply)
                else:
                    self.logger.info(cmd + " FAIL retval " + str(r.retval))
            self.assertTrue(r.retval == 0)

        deadline = time.time() + 30
        while self.vapi.cli("show packet-generator").find("Yes") != -1:
            self.sleep(0.01)  # yield
            if time.time() > deadline:
                self.logger.error("Timeout waiting for pg to stop")
                break

        r = self.vapi.cli_return_response("show trace")
        self.assertTrue(r.retval == 0)
        self.assertTrue(hasattr(r, "reply"))
        rv = r.reply
        packets = rv.split("\nPacket ")
        for packet in enumerate(packets, start=1):
            match = re.search(r"stream\s+([\w-]+)", packet[1])
            if match:
                stream_name = match.group(1)
            else:
                continue
            if stream_name == "pg0-pg1-stream":
                look_here = packet[1].find("ethernet-input")
                self.assertNotEqual(look_here, -1)
                search_string = "ip4 offload-ip-cksum offload-udp-cksum  l2-hdr-offset 0 l3-hdr-offset 14 l4-hdr-offset 34"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
                search_string = "ip4 l2-hdr-offset 0 l3-hdr-offset 14 l4-hdr-offset 34"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
            elif stream_name == "pg0-pg2-stream":
                look_here = packet[1].find("ethernet-input")
                self.assertNotEqual(look_here, -1)
                search_string = "ip6 offload-udp-cksum  l2-hdr-offset 0 l3-hdr-offset 14 l4-hdr-offset 54"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
                search_string = "ip6 l2-hdr-offset 0 l3-hdr-offset 14 l4-hdr-offset 54"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
            elif stream_name == "pg1-pg0-stream":
                look_here = packet[1].find("ethernet-input")
                self.assertEqual(look_here, -1)
                look_here = packet[1].find("ip4-input")
                self.assertNotEqual(look_here, -1)
                search_string = "ip4 offload-ip-cksum offload-udp-cksum  l2-hdr-offset 0 l3-hdr-offset 0 l4-hdr-offset 20"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
                search_string = "ip4 l2-hdr-offset 0 l3-hdr-offset 0 l4-hdr-offset 20"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
            elif stream_name == "pg2-pg0-stream":
                look_here = packet[1].find("ethernet-input")
                self.assertEqual(look_here, -1)
                look_here = packet[1].find("ip6-input")
                self.assertNotEqual(look_here, -1)
                search_string = "ip6 offload-udp-cksum  l2-hdr-offset 0 l3-hdr-offset 0 l4-hdr-offset 40"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)
                search_string = "ip6 l2-hdr-offset 0 l3-hdr-offset 0 l4-hdr-offset 40"
                look_here = packet[1].find(search_string)
                self.assertNotEqual(look_here, -1)

        self.logger.info(self.vapi.cli("packet-generator disable"))
        self.logger.info(self.vapi.cli("packet-generator delete pg0-pg1-stream"))
        self.logger.info(self.vapi.cli("packet-generator delete pg0-pg2-stream"))
        self.logger.info(self.vapi.cli("packet-generator delete pg1-pg0-stream"))
        self.logger.info(self.vapi.cli("packet-generator delete pg2-pg0-stream"))

        r = self.vapi.cli_return_response("show buffers")
        self.assertTrue(r.retval == 0)
        self.assertTrue(hasattr(r, "reply"))
        rv = r.reply
        used = int(rv.strip().split("\n")[-1].split()[-1])
        self.assertEqual(used, 0)

    def test_pg_stream(self):
        """PG Stream testing"""
        self.pg_stream(rate=100, packet_size=64)
        self.pg_stream(count=1000, rate=1000)
        self.pg_stream(count=100000, rate=10000, packet_size=1500)
        self.pg_stream(packet_size=4000)


if __name__ == "__main__":
    unittest.main(testRunner=VppTestRunner)