blob: 6bd49c06da95796cc899008e51b8307c7c07ffc9 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +02002"""GSO functional tests"""
3
4#
5# Add tests for:
6# - GSO
7# - Verify that sending Jumbo frame without GSO enabled correctly
8# - Verify that sending Jumbo frame with GSO enabled correctly
9# - Verify that sending Jumbo frame with GSO enabled only on ingress interface
10#
11import unittest
12
13from scapy.packet import Raw
14from scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
Mohsin Kazmi0b042092020-04-17 16:50:56 +000015from scapy.layers.inet6 import ipv6nh, IPerror6
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020016from scapy.layers.inet import TCP, ICMP
17from scapy.layers.vxlan import VXLAN
18from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
19
20from framework import VppTestCase, VppTestRunner
21from vpp_object import VppObject
22from vpp_interface import VppInterface
23from vpp_ip import DpoProto
24from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +020025from vpp_ipip_tun_interface import VppIpIpTunInterface
Mohsin Kazmi0b042092020-04-17 16:50:56 +000026from vpp_vxlan_tunnel import VppVxlanTunnel
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020027from socket import AF_INET, AF_INET6, inet_pton
28from util import reassemble4
29
30
31""" Test_gso is a subclass of VPPTestCase classes.
32 GSO tests.
33"""
34
35
36class TestGSO(VppTestCase):
37 """ GSO Test Case """
38
39 def __init__(self, *args):
40 VppTestCase.__init__(self, *args)
41
42 @classmethod
43 def setUpClass(self):
44 super(TestGSO, self).setUpClass()
Mohsin Kazmi0b042092020-04-17 16:50:56 +000045 res = self.create_pg_interfaces(range(2))
46 res_gso = self.create_pg_interfaces(range(2, 4), 1, 1460)
47 self.create_pg_interfaces(range(4, 5), 1, 8940)
48 self.pg_interfaces.append(res[0])
49 self.pg_interfaces.append(res[1])
50 self.pg_interfaces.append(res_gso[0])
51 self.pg_interfaces.append(res_gso[1])
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020052
53 @classmethod
54 def tearDownClass(self):
55 super(TestGSO, self).tearDownClass()
56
57 def setUp(self):
58 super(TestGSO, self).setUp()
Mohsin Kazmi0b042092020-04-17 16:50:56 +000059 for i in self.pg_interfaces:
60 i.admin_up()
61 i.config_ip4()
62 i.config_ip6()
63 i.disable_ipv6_ra()
64 i.resolve_arp()
65 i.resolve_ndp()
66
67 self.single_tunnel_bd = 10
68 self.vxlan = VppVxlanTunnel(self, src=self.pg0.local_ip4,
69 dst=self.pg0.remote_ip4,
70 vni=self.single_tunnel_bd)
Mohsin Kazmi0b042092020-04-17 16:50:56 +000071
72 self.vxlan2 = VppVxlanTunnel(self, src=self.pg0.local_ip6,
73 dst=self.pg0.remote_ip6,
74 vni=self.single_tunnel_bd)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +020075
76 self.ipip4 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip4,
77 self.pg0.remote_ip4)
78 self.ipip6 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip6,
79 self.pg0.remote_ip6)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020080
81 def tearDown(self):
82 super(TestGSO, self).tearDown()
83 if not self.vpp_dead:
84 for i in self.pg_interfaces:
85 i.unconfig_ip4()
86 i.unconfig_ip6()
87 i.admin_down()
88
89 def test_gso(self):
90 """ GSO test """
91 #
92 # Send jumbo frame with gso disabled and DF bit is set
93 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020094 p4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
95 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4,
96 flags='DF') /
97 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +020098 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +020099
100 rxs = self.send_and_expect(self.pg0, [p4], self.pg0)
101
102 for rx in rxs:
103 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
104 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
105 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
106 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
107 self.assertEqual(rx[ICMP].type, 3) # "dest-unreach"
108 self.assertEqual(rx[ICMP].code, 4) # "fragmentation-needed"
109
110 #
111 # Send jumbo frame with gso enabled and DF bit is set
112 # input and output interfaces support GSO
113 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200114 p41 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
115 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4,
116 flags='DF') /
117 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200118 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200119
120 rxs = self.send_and_expect(self.pg2, [p41], self.pg3)
121
122 for rx in rxs:
123 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
124 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
125 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
126 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
127 self.assertEqual(rx[IP].len, 65240) # 65200 + 20 (IP) + 20 (TCP)
128 self.assertEqual(rx[TCP].sport, 1234)
129 self.assertEqual(rx[TCP].dport, 1234)
130
131 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000132 # ipv6
133 #
134 p61 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
135 IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6) /
136 TCP(sport=1234, dport=1234) /
137 Raw(b'\xa5' * 65200))
138
139 rxs = self.send_and_expect(self.pg2, [p61], self.pg3)
140
141 for rx in rxs:
142 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
143 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
144 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
145 self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
146 self.assertEqual(rx[IPv6].plen, 65220) # 65200 + 20 (TCP)
147 self.assertEqual(rx[TCP].sport, 1234)
148 self.assertEqual(rx[TCP].dport, 1234)
149
150 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200151 # Send jumbo frame with gso enabled only on input interface
152 # and DF bit is set. GSO packet will be chunked into gso_size
153 # data payload
154 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000155 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200156 p42 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000157 IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200158 flags='DF') /
159 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200160 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200161
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000162 rxs = self.send_and_expect(self.pg2, [p42], self.pg0, 45)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200163 size = 0
164 for rx in rxs:
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000165 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
166 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200167 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000168 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200169 self.assertEqual(rx[TCP].sport, 1234)
170 self.assertEqual(rx[TCP].dport, 1234)
171
172 size = rxs[44][TCP].seq + rxs[44][IP].len - 20 - 20
173 self.assertEqual(size, 65200)
174
175 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000176 # ipv6
177 #
178 p62 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
179 IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
180 TCP(sport=1234, dport=1234) /
181 Raw(b'\xa5' * 65200))
182
183 rxs = self.send_and_expect(self.pg2, [p62], self.pg0, 45)
184 size = 0
185 for rx in rxs:
186 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
187 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
188 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
189 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
190 self.assertEqual(rx[TCP].sport, 1234)
191 self.assertEqual(rx[TCP].dport, 1234)
192
193 size = rxs[44][TCP].seq + rxs[44][IPv6].plen - 20
194 self.assertEqual(size, 65200)
195
196 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200197 # Send jumbo frame with gso enabled only on input interface
198 # and DF bit is unset. GSO packet will be fragmented.
199 #
200 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000201 self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200202
203 p43 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
204 IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4) /
205 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200206 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200207
208 rxs = self.send_and_expect(self.pg2, [p43], self.pg1, 119)
209 size = 0
210 for rx in rxs:
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200211 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
212 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
213 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
214 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
215 size += rx[IP].len - 20
216 size -= 20 # TCP header
217 self.assertEqual(size, 65200)
218
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200219 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000220 # IPv6
221 # Send jumbo frame with gso enabled only on input interface.
222 # ICMPv6 Packet Too Big will be sent back to sender.
223 #
224 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
225 p63 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
226 IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6) /
227 TCP(sport=1234, dport=1234) /
228 Raw(b'\xa5' * 65200))
229
230 rxs = self.send_and_expect(self.pg2, [p63], self.pg2, 1)
231 for rx in rxs:
232 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
233 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
234 self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
235 self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
236 self.assertEqual(rx[IPv6].plen, 1240) # MTU - IPv6 header
237 self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
238 self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
239 self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
240 self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
241 self.assertEqual(rx[IPerror6].plen - 20, 65200)
242
243 #
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200244 # Send jumbo frame with gso enabled only on input interface with 9K MTU
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000245 # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
246 # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200247 #
248 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000249 self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
250 p44 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
251 IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4) /
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200252 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200253 Raw(b'\xa5' * 65200))
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200254
255 self.pg1.enable_capture()
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000256 rxs = self.send_and_expect(self.pg4, [p44], self.pg1, 33)
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200257 size = 0
258 for rx in rxs:
259 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
260 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000261 self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200262 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
263 size = rxs[32][TCP].seq + rxs[32][IP].len - 20 - 20
264 self.assertEqual(size, 65200)
265
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000266 #
267 # IPv6
268 #
269 p64 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
270 IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6) /
271 TCP(sport=1234, dport=1234) /
272 Raw(b'\xa5' * 65200))
273
274 self.pg1.enable_capture()
275 rxs = self.send_and_expect(self.pg4, [p64], self.pg1, 34)
276 size = 0
277 for rx in rxs:
278 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
279 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
280 self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
281 self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
282 size = rxs[33][TCP].seq + rxs[33][IPv6].plen - 20
283 self.assertEqual(size, 65200)
284
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000285 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
286 enable_disable=0)
287 self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index,
288 enable_disable=0)
289
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000290 def test_gso_vxlan(self):
291 """ GSO VXLAN test """
292 self.logger.info(self.vapi.cli("sh int addr"))
293 #
294 # Send jumbo frame with gso enabled only on input interface and
295 # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
296 # into BD.
297 #
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200298
299 #
300 # enable ipv4/vxlan
301 #
302 self.vxlan.add_vpp_config()
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000303 self.vapi.sw_interface_set_l2_bridge(
304 rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd)
305 self.vapi.sw_interface_set_l2_bridge(
306 rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd)
307 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
308
309 #
310 # IPv4/IPv4 - VXLAN
311 #
312 p45 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
313 IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
314 TCP(sport=1234, dport=1234) /
315 Raw(b'\xa5' * 65200))
316
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000317 rxs = self.send_and_expect(self.pg2, [p45], self.pg0, 45)
318 size = 0
319 for rx in rxs:
320 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
321 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
322 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
323 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
324 self.assertEqual(rx[VXLAN].vni, 10)
325 inner = rx[VXLAN].payload
326 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
327 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
328 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
329 self.assertEqual(inner[IP].dst, "172.16.3.3")
330 size += inner[IP].len - 20 - 20
331 self.assertEqual(size, 65200)
332
333 #
334 # IPv4/IPv6 - VXLAN
335 #
336 p65 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
337 IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
338 TCP(sport=1234, dport=1234) /
339 Raw(b'\xa5' * 65200))
340
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000341 rxs = self.send_and_expect(self.pg2, [p65], self.pg0, 45)
342 size = 0
343 for rx in rxs:
344 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
345 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
346 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
347 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
348 self.assertEqual(rx[VXLAN].vni, 10)
349 inner = rx[VXLAN].payload
350 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
351 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
352 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
353 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
354 size += inner[IPv6].plen - 20
355 self.assertEqual(size, 65200)
356
357 #
358 # disable ipv4/vxlan
359 #
360 self.vxlan.remove_vpp_config()
361
362 #
363 # enable ipv6/vxlan
364 #
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200365 self.vxlan2.add_vpp_config()
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000366 self.vapi.sw_interface_set_l2_bridge(
367 rx_sw_if_index=self.vxlan2.sw_if_index,
368 bd_id=self.single_tunnel_bd)
369
370 #
371 # IPv6/IPv4 - VXLAN
372 #
373 p46 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
374 IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
375 TCP(sport=1234, dport=1234) /
376 Raw(b'\xa5' * 65200))
377
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000378 rxs = self.send_and_expect(self.pg2, [p46], self.pg0, 45)
379 size = 0
380 for rx in rxs:
381 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
382 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
383 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
384 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
385 self.assertEqual(rx[VXLAN].vni, 10)
386 inner = rx[VXLAN].payload
387 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
388 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
389 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
390 self.assertEqual(inner[IP].dst, "172.16.3.3")
391 size += inner[IP].len - 20 - 20
392 self.assertEqual(size, 65200)
393
394 #
395 # IPv6/IPv6 - VXLAN
396 #
397 p66 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
398 IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
399 TCP(sport=1234, dport=1234) /
400 Raw(b'\xa5' * 65200))
401
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000402 rxs = self.send_and_expect(self.pg2, [p66], self.pg0, 45)
403 size = 0
404 for rx in rxs:
405 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
406 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
407 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
408 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
409 self.assertEqual(rx[VXLAN].vni, 10)
410 inner = rx[VXLAN].payload
411 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
412 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
413 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
414 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
415 size += inner[IPv6].plen - 20
416 self.assertEqual(size, 65200)
417
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200418 #
419 # disable ipv4/vxlan
420 #
421 self.vxlan2.remove_vpp_config()
422
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000423 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
424 enable_disable=0)
425
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200426 def test_gso_ipip(self):
427 """ GSO IPIP test """
428 self.logger.info(self.vapi.cli("sh int addr"))
429 #
430 # Send jumbo frame with gso enabled only on input interface and
431 # create IPIP tunnel on VPP pg0.
432 #
433 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
434
435 #
436 # enable ipip4
437 #
438 self.ipip4.add_vpp_config()
439
440 # Set interface up and enable IP on it
441 self.ipip4.admin_up()
442 self.ipip4.set_unnumbered(self.pg0.sw_if_index)
443
444 # Add IPv4 routes via tunnel interface
445 self.ip4_via_ip4_tunnel = VppIpRoute(
446 self, "172.16.10.0", 24,
447 [VppRoutePath("0.0.0.0",
448 self.ipip4.sw_if_index,
449 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
450 self.ip4_via_ip4_tunnel.add_vpp_config()
451
452 #
453 # IPv4/IPv4 - IPIP
454 #
455 p47 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
456 IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
457 TCP(sport=1234, dport=1234) /
458 Raw(b'\xa5' * 65200))
459
460 rxs = self.send_and_expect(self.pg2, [p47], self.pg0, 45)
461 size = 0
462 for rx in rxs:
463 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
464 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
465 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
466 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
467 self.assertEqual(rx[IP].proto, 4) # ipencap
468 inner = rx[IP].payload
469 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
470 self.assertEqual(inner[IP].dst, "172.16.10.3")
471 size += inner[IP].len - 20 - 20
472 self.assertEqual(size, 65200)
473
474 self.ip6_via_ip4_tunnel = VppIpRoute(
475 self, "fd01:10::", 64,
476 [VppRoutePath("::",
477 self.ipip4.sw_if_index,
478 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
479 self.ip6_via_ip4_tunnel.add_vpp_config()
480 #
481 # IPv4/IPv6 - IPIP
482 #
483 p67 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
484 IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
485 TCP(sport=1234, dport=1234) /
486 Raw(b'\xa5' * 65200))
487
488 rxs = self.send_and_expect(self.pg2, [p67], self.pg0, 45)
489 size = 0
490 for rx in rxs:
491 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
492 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
493 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
494 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
495 self.assertEqual(rx[IP].proto, 41) # ipv6
496 inner = rx[IP].payload
497 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
498 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
499 size += inner[IPv6].plen - 20
500 self.assertEqual(size, 65200)
501
502 #
503 # Send jumbo frame with gso enabled only on input interface and
504 # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
505 # tunnel - IPSec use case
506 #
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000507 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
508 enable_disable=0)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200509 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index)
510
511 rxs = self.send_and_expect(self.pg2, [p47], self.pg0, 45)
512 size = 0
513 for rx in rxs:
514 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
515 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
516 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
517 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
518 self.assertEqual(rx[IP].proto, 4) # ipencap
519 inner = rx[IP].payload
520 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
521 self.assertEqual(inner[IP].dst, "172.16.10.3")
522 size += inner[IP].len - 20 - 20
523 self.assertEqual(size, 65200)
524
525 #
526 # disable ipip4
527 #
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000528 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index,
529 enable_disable=0)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200530 self.ip4_via_ip4_tunnel.remove_vpp_config()
531 self.ip6_via_ip4_tunnel.remove_vpp_config()
532 self.ipip4.remove_vpp_config()
533
534 #
535 # enable ipip6
536 #
537 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
538 self.ipip6.add_vpp_config()
539
540 # Set interface up and enable IP on it
541 self.ipip6.admin_up()
542 self.ipip6.set_unnumbered(self.pg0.sw_if_index)
543
544 # Add IPv4 routes via tunnel interface
545 self.ip4_via_ip6_tunnel = VppIpRoute(
546 self, "172.16.10.0", 24,
547 [VppRoutePath("0.0.0.0",
548 self.ipip6.sw_if_index,
549 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
550 self.ip4_via_ip6_tunnel.add_vpp_config()
551
552 #
553 # IPv6/IPv4 - IPIP
554 #
555 p48 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
556 IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
557 TCP(sport=1234, dport=1234) /
558 Raw(b'\xa5' * 65200))
559
560 rxs = self.send_and_expect(self.pg2, [p48], self.pg0, 45)
561 size = 0
562 for rx in rxs:
563 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
564 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
565 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
566 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
567 self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
568 inner = rx[IPv6].payload
569 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
570 self.assertEqual(inner[IP].dst, "172.16.10.3")
571 size += inner[IP].len - 20 - 20
572 self.assertEqual(size, 65200)
573
574 self.ip6_via_ip6_tunnel = VppIpRoute(
575 self, "fd01:10::", 64,
576 [VppRoutePath("::",
577 self.ipip6.sw_if_index,
578 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
579 self.ip6_via_ip6_tunnel.add_vpp_config()
580
581 #
582 # IPv6/IPv6 - IPIP
583 #
584 p68 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
585 IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
586 TCP(sport=1234, dport=1234) /
587 Raw(b'\xa5' * 65200))
588
589 rxs = self.send_and_expect(self.pg2, [p68], self.pg0, 45)
590 size = 0
591 for rx in rxs:
592 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
593 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
594 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
595 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
596 self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
597 inner = rx[IPv6].payload
598 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
599 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
600 size += inner[IPv6].plen - 20
601 self.assertEqual(size, 65200)
602
603 #
604 # disable ipip6
605 #
606 self.ip4_via_ip6_tunnel.remove_vpp_config()
607 self.ip6_via_ip6_tunnel.remove_vpp_config()
608 self.ipip6.remove_vpp_config()
609
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000610 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
611 enable_disable=0)
612
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200613if __name__ == '__main__':
614 unittest.main(testRunner=VppTestRunner)