blob: 45c596485c58a4d08d46caddb536d8fc4499cedf [file] [log] [blame]
Mohsin Kazmif382b062020-08-11 15:00:44 +02001#!/usr/bin/env python3
2"""GRO functional tests"""
3
4#
5# Add tests for:
6# - GRO
7# - Verify that sending 1500 Bytes frame without GRO enabled correctly
8# - Verify that sending 1500 Bytes frame with GRO enabled correctly
9#
10import unittest
11
12from scapy.packet import Raw
Dave Wallace8800f732023-08-31 00:47:44 -040013from scapy.layers.inet6 import IPv6, Ether, IP
14from scapy.layers.inet import TCP
Mohsin Kazmif382b062020-08-11 15:00:44 +020015
Dave Wallace8800f732023-08-31 00:47:44 -040016from framework import VppTestCase
17from asfframework import VppTestRunner
Mohsin Kazmif382b062020-08-11 15:00:44 +020018
19
20""" Test_gro is a subclass of VPPTestCase classes.
21 GRO tests.
22"""
23
24
25class TestGRO(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020026 """GRO Test Case"""
Mohsin Kazmif382b062020-08-11 15:00:44 +020027
28 @classmethod
29 def setUpClass(self):
30 super(TestGRO, self).setUpClass()
31 res = self.create_pg_interfaces(range(2))
32 res_gro = self.create_pg_interfaces(range(2, 3), 1, 1460)
33 self.create_pg_interfaces(range(3, 4), 1, 8940)
34 self.pg_interfaces.append(res[0])
35 self.pg_interfaces.append(res[1])
36 self.pg_interfaces.append(res_gro[0])
37 self.pg2.coalesce_enable()
38 self.pg3.coalesce_enable()
39
40 @classmethod
41 def tearDownClass(self):
42 super(TestGRO, self).tearDownClass()
43
44 def setUp(self):
45 super(TestGRO, self).setUp()
46 for i in self.pg_interfaces:
47 i.admin_up()
48 i.config_ip4()
49 i.config_ip6()
50 i.disable_ipv6_ra()
51 i.resolve_arp()
52 i.resolve_ndp()
53
54 def tearDown(self):
55 super(TestGRO, self).tearDown()
56 if not self.vpp_dead:
57 for i in self.pg_interfaces:
58 i.unconfig_ip4()
59 i.unconfig_ip6()
60 i.admin_down()
61
62 def test_gro(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020063 """GRO test"""
Mohsin Kazmif382b062020-08-11 15:00:44 +020064
65 n_packets = 124
66 #
67 # Send 1500 bytes frame with gro disabled
68 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020069 p4 = (
70 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
71 / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, flags="DF")
72 / TCP(sport=1234, dport=4321)
73 / Raw(b"\xa5" * 1460)
74 )
Mohsin Kazmif382b062020-08-11 15:00:44 +020075
76 rxs = self.send_and_expect(self.pg0, n_packets * p4, self.pg1)
77 for rx in rxs:
78 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
79 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
80 self.assertEqual(rx[IP].src, self.pg0.remote_ip4)
81 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
82 self.assertEqual(rx[TCP].sport, 1234)
83 self.assertEqual(rx[TCP].dport, 4321)
84
85 #
86 # Send 1500 bytes frame with gro enabled on
87 # output interfaces support GRO
88 #
89 p = []
90 s = 0
91 for n in range(0, n_packets):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020092 p.append(
93 (
94 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
95 / IP(src=self.pg0.remote_ip4, dst=self.pg2.remote_ip4, flags="DF")
96 / TCP(sport=1234, dport=4321, seq=s, ack=n, flags="A")
97 / Raw(b"\xa5" * 1460)
98 )
99 )
Mohsin Kazmif382b062020-08-11 15:00:44 +0200100 s += 1460
101
102 rxs = self.send_and_expect(self.pg0, p, self.pg2, n_rx=2)
103
104 i = 0
105 for rx in rxs:
106 i += 1
107 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
108 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
109 self.assertEqual(rx[IP].src, self.pg0.remote_ip4)
110 self.assertEqual(rx[IP].dst, self.pg2.remote_ip4)
111 self.assertEqual(rx[IP].len, 64280) # 1460 * 44 + 40 < 65536
112 self.assertEqual(rx[TCP].sport, 1234)
113 self.assertEqual(rx[TCP].dport, 4321)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200114 self.assertEqual(rx[TCP].ack, (44 * i - 1))
Mohsin Kazmif382b062020-08-11 15:00:44 +0200115
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200116 p4_temp = (
117 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
118 / IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4, flags="DF")
119 / TCP(sport=1234, dport=4321, flags="F")
120 )
Mohsin Kazmif382b062020-08-11 15:00:44 +0200121
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200122 rxs = self.send_and_expect(self.pg2, 100 * [p4_temp], self.pg0, n_rx=100)
Mohsin Kazmif382b062020-08-11 15:00:44 +0200123 rx_coalesce = self.pg2.get_capture(1, timeout=1)
124
125 rx0 = rx_coalesce[0]
126 self.assertEqual(rx0[Ether].src, self.pg2.local_mac)
127 self.assertEqual(rx0[Ether].dst, self.pg2.remote_mac)
128 self.assertEqual(rx0[IP].src, self.pg0.remote_ip4)
129 self.assertEqual(rx0[IP].dst, self.pg2.remote_ip4)
130 self.assertEqual(rx0[IP].len, 52600) # 1460 * 36 + 40
131 self.assertEqual(rx0[TCP].sport, 1234)
132 self.assertEqual(rx0[TCP].dport, 4321)
133
134 for rx in rxs:
135 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
136 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
137 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
138 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
139 self.assertEqual(rx[IP].len, 40)
140 self.assertEqual(rx[TCP].sport, 1234)
141 self.assertEqual(rx[TCP].dport, 4321)
142
Aloys Augustin86490da2021-09-15 16:06:04 +0200143 #
144 # Same test with IPv6
145 #
146 p = []
147 s = 0
148 for n in range(0, 88):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200149 p.append(
150 (
151 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
152 / IPv6(src=self.pg0.remote_ip6, dst=self.pg2.remote_ip6)
153 / TCP(sport=1234, dport=4321, seq=s, ack=n, flags="A")
154 / Raw(b"\xa5" * 1460)
155 )
156 )
Aloys Augustin86490da2021-09-15 16:06:04 +0200157 s += 1460
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200158 p[-1][TCP].flags = "AP" # push to flush second packet
Aloys Augustin86490da2021-09-15 16:06:04 +0200159
160 rxs = self.send_and_expect(self.pg0, p, self.pg2, n_rx=2)
161
162 i = 0
163 for rx in rxs:
164 i += 1
165 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
166 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
167 self.assertEqual(rx[IPv6].src, self.pg0.remote_ip6)
168 self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
169 self.assertEqual(rx[IPv6].plen, 64260) # 1460 * 44 + 20 < 65536
170 self.assertEqual(rx[TCP].sport, 1234)
171 self.assertEqual(rx[TCP].dport, 4321)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200172 self.assertEqual(rx[TCP].ack, (44 * i - 1))
Aloys Augustin86490da2021-09-15 16:06:04 +0200173
174 #
175 # Send a series of 1500 bytes packets each followed by a packet with a
176 # PSH flag. Verify that GRO stops everytime a PSH flag is encountered
177 #
178 p = []
179 s = 0
180 for n in range(0, n_packets):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200181 p.append(
182 (
183 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
184 / IP(src=self.pg0.remote_ip4, dst=self.pg2.remote_ip4, flags="DF")
185 / TCP(sport=1234, dport=4321, seq=s, ack=2 * n, flags="A")
186 / Raw(b"\xa5" * 1460)
187 )
188 )
Aloys Augustin86490da2021-09-15 16:06:04 +0200189 s += 1460
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190 p.append(
191 (
192 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
193 / IP(src=self.pg0.remote_ip4, dst=self.pg2.remote_ip4, flags="DF")
194 / TCP(sport=1234, dport=4321, seq=s, ack=2 * n + 1, flags="AP")
195 / Raw(b"\xa5" * 1340)
196 )
197 )
Aloys Augustin86490da2021-09-15 16:06:04 +0200198 s += 1340
199
200 rxs = self.send_and_expect(self.pg0, p, self.pg2, n_rx=n_packets)
201
202 i = 0
203 for rx in rxs:
204 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
205 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
206 self.assertEqual(rx[IP].src, self.pg0.remote_ip4)
207 self.assertEqual(rx[IP].dst, self.pg2.remote_ip4)
208 self.assertEqual(rx[IP].len, 40 + 1460 + 1340)
209 self.assertEqual(rx[TCP].sport, 1234)
210 self.assertEqual(rx[TCP].dport, 4321)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200211 self.assertEqual(rx[TCP].ack, (2 * i + 1))
Aloys Augustin86490da2021-09-15 16:06:04 +0200212 i += 1
213
214 #
215 # Send a series of 1500 bytes packets each followed by a short packet
216 # with padding. Verify that GRO removes the padding and stops on short
217 # packets
218 #
219 p = []
220 s = 0
221 for n in range(0, n_packets):
222 i = self.pg0
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200223 p.append(
224 (
225 Ether(src=i.remote_mac, dst=i.local_mac)
226 / IP(src=i.remote_ip4, dst=self.pg2.remote_ip4, flags="DF")
227 / TCP(sport=1234, dport=4321, seq=s, ack=2 * n, flags="A")
228 / Raw(b"\xa5" * 1459)
229 )
230 )
Aloys Augustin86490da2021-09-15 16:06:04 +0200231 s += 1459
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200232 p2 = (
233 Ether(src=i.remote_mac, dst=i.local_mac)
234 / IP(src=i.remote_ip4, dst=self.pg2.remote_ip4, flags="DF", len=41)
235 / TCP(sport=1234, dport=4321, seq=s, ack=2 * n + 1, flags="A")
236 / Raw(b"\xa5")
237 )
Aloys Augustin86490da2021-09-15 16:06:04 +0200238 # first compute csum of pkt w/o padding to work around scapy bug
239 p2 = Ether(bytes(p2))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200240 p.append(p2 / Raw(b"\xa5" * 5)) # 1 byte data + 5 bytes padding
Aloys Augustin86490da2021-09-15 16:06:04 +0200241 s += 1
242
243 rxs = self.send_and_expect(self.pg0, p, self.pg2, n_rx=n_packets)
244
245 i = 0
246 for rx in rxs:
247 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
248 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
249 self.assertEqual(rx[IP].src, self.pg0.remote_ip4)
250 self.assertEqual(rx[IP].dst, self.pg2.remote_ip4)
251 self.assertEqual(rx[IP].len, 40 + 1459 + 1)
252 self.assertEqual(rx[TCP].sport, 1234)
253 self.assertEqual(rx[TCP].dport, 4321)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200254 self.assertEqual(rx[TCP].ack, (2 * i + 1))
Aloys Augustin86490da2021-09-15 16:06:04 +0200255 i += 1
256
257
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200258if __name__ == "__main__":
Mohsin Kazmif382b062020-08-11 15:00:44 +0200259 unittest.main(testRunner=VppTestRunner)