2 """GSO functional tests"""
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
13 from scapy.packet import Raw
14 from scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
15 from scapy.layers.inet6 import ipv6nh, IPerror6
16 from scapy.layers.inet import TCP, ICMP
17 from scapy.layers.vxlan import VXLAN
18 from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
20 from framework import VppTestCase, VppTestRunner
21 from vpp_object import VppObject
22 from vpp_interface import VppInterface
23 from vpp_ip import DpoProto
24 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto
25 from vpp_ipip_tun_interface import VppIpIpTunInterface
26 from vpp_vxlan_tunnel import VppVxlanTunnel
27 from socket import AF_INET, AF_INET6, inet_pton
28 from util import reassemble4
31 """ Test_gso is a subclass of VPPTestCase classes.
36 class TestGSO(VppTestCase):
39 def __init__(self, *args):
40 VppTestCase.__init__(self, *args)
44 super(TestGSO, self).setUpClass()
45 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])
54 def tearDownClass(self):
55 super(TestGSO, self).tearDownClass()
58 super(TestGSO, self).setUp()
59 for i in self.pg_interfaces:
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)
72 self.vxlan2 = VppVxlanTunnel(self, src=self.pg0.local_ip6,
73 dst=self.pg0.remote_ip6,
74 vni=self.single_tunnel_bd)
76 self.ipip4 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip4,
78 self.ipip6 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip6,
82 super(TestGSO, self).tearDown()
84 for i in self.pg_interfaces:
92 # Send jumbo frame with gso disabled and DF bit is set
94 p4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
95 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4,
97 TCP(sport=1234, dport=1234) /
100 rxs = self.send_and_expect(self.pg0, [p4], self.pg0)
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"
111 # Send checksum offload frames
113 p40 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
114 IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
116 TCP(sport=1234, dport=1234) /
119 rxs = self.send_and_expect(self.pg2, 100*[p40], self.pg0)
122 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
123 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
124 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
125 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
126 payload_len = rx[IP].len - 20 - 20
127 self.assert_ip_checksum_valid(rx)
128 self.assert_tcp_checksum_valid(rx)
129 self.assertEqual(payload_len, len(rx[Raw]))
131 p60 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
132 IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
133 TCP(sport=1234, dport=1234) /
136 rxs = self.send_and_expect(self.pg2, 100*[p60], self.pg0)
139 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
140 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
141 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
142 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
143 payload_len = rx[IPv6].plen - 20
144 self.assert_tcp_checksum_valid(rx)
145 self.assertEqual(payload_len, len(rx[Raw]))
148 # Send jumbo frame with gso enabled and DF bit is set
149 # input and output interfaces support GSO
151 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg3.sw_if_index,
153 p41 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
154 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4,
156 TCP(sport=1234, dport=1234) /
157 Raw(b'\xa5' * 65200))
159 rxs = self.send_and_expect(self.pg2, 100*[p41], self.pg3, 100)
162 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
163 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
164 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
165 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
166 self.assertEqual(rx[IP].len, 65240) # 65200 + 20 (IP) + 20 (TCP)
167 self.assertEqual(rx[TCP].sport, 1234)
168 self.assertEqual(rx[TCP].dport, 1234)
173 p61 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
174 IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6) /
175 TCP(sport=1234, dport=1234) /
176 Raw(b'\xa5' * 65200))
178 rxs = self.send_and_expect(self.pg2, 100*[p61], self.pg3, 100)
181 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
182 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
183 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
184 self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
185 self.assertEqual(rx[IPv6].plen, 65220) # 65200 + 20 (TCP)
186 self.assertEqual(rx[TCP].sport, 1234)
187 self.assertEqual(rx[TCP].dport, 1234)
190 # Send jumbo frame with gso enabled only on input interface
191 # and DF bit is set. GSO packet will be chunked into gso_size
194 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
196 p42 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
197 IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
199 TCP(sport=1234, dport=1234) /
200 Raw(b'\xa5' * 65200))
202 rxs = self.send_and_expect(self.pg2, 5*[p42], self.pg0, 225)
205 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
206 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
207 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
208 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
209 payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
210 self.assert_ip_checksum_valid(rx)
211 self.assert_tcp_checksum_valid(rx)
212 self.assertEqual(rx[TCP].sport, 1234)
213 self.assertEqual(rx[TCP].dport, 1234)
214 self.assertEqual(payload_len, len(rx[Raw]))
216 self.assertEqual(size, 65200*5)
221 p62 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
222 IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
223 TCP(sport=1234, dport=1234) /
224 Raw(b'\xa5' * 65200))
226 rxs = self.send_and_expect(self.pg2, 5*[p62], self.pg0, 225)
229 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
230 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
231 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
232 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
233 payload_len = rx[IPv6].plen - 20
234 self.assert_tcp_checksum_valid(rx)
235 self.assertEqual(rx[TCP].sport, 1234)
236 self.assertEqual(rx[TCP].dport, 1234)
237 self.assertEqual(payload_len, len(rx[Raw]))
239 self.assertEqual(size, 65200*5)
242 # Send jumbo frame with gso enabled only on input interface
243 # and DF bit is unset. GSO packet will be fragmented.
245 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
246 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg1.sw_if_index,
249 p43 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
250 IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4) /
251 TCP(sport=1234, dport=1234) /
252 Raw(b'\xa5' * 65200))
254 rxs = self.send_and_expect(self.pg2, 5*[p43], self.pg1, 5*119)
257 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
258 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
259 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
260 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
261 self.assert_ip_checksum_valid(rx)
262 size += rx[IP].len - 20
263 size -= 20*5 # TCP header
264 self.assertEqual(size, 65200*5)
268 # Send jumbo frame with gso enabled only on input interface.
269 # ICMPv6 Packet Too Big will be sent back to sender.
271 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
272 p63 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
273 IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6) /
274 TCP(sport=1234, dport=1234) /
275 Raw(b'\xa5' * 65200))
277 rxs = self.send_and_expect(self.pg2, 5*[p63], self.pg2, 5)
279 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
280 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
281 self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
282 self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
283 self.assertEqual(rx[IPv6].plen, 1240) # MTU - IPv6 header
284 self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
285 self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
286 self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
287 self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
288 self.assertEqual(rx[IPerror6].plen - 20, 65200)
291 # Send jumbo frame with gso enabled only on input interface with 9K MTU
292 # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
293 # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
295 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
296 self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
297 p44 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
298 IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4) /
299 TCP(sport=1234, dport=1234) /
300 Raw(b'\xa5' * 65200))
302 rxs = self.send_and_expect(self.pg4, 5*[p44], self.pg1, 165)
305 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
306 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
307 self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
308 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
309 payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
310 self.assert_ip_checksum_valid(rx)
311 self.assert_tcp_checksum_valid(rx)
312 self.assertEqual(payload_len, len(rx[Raw]))
314 self.assertEqual(size, 65200*5)
319 p64 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
320 IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6) /
321 TCP(sport=1234, dport=1234) /
322 Raw(b'\xa5' * 65200))
324 rxs = self.send_and_expect(self.pg4, 5*[p64], self.pg1, 170)
327 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
328 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
329 self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
330 self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
331 payload_len = rx[IPv6].plen - 20
332 self.assert_tcp_checksum_valid(rx)
333 self.assertEqual(payload_len, len(rx[Raw]))
335 self.assertEqual(size, 65200*5)
337 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
339 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg1.sw_if_index,
342 def test_gso_vxlan(self):
343 """ GSO VXLAN test """
344 self.logger.info(self.vapi.cli("sh int addr"))
346 # Send jumbo frame with gso enabled only on input interface and
347 # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
354 self.vxlan.add_vpp_config()
355 self.vapi.sw_interface_set_l2_bridge(
356 rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd)
357 self.vapi.sw_interface_set_l2_bridge(
358 rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd)
359 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
365 p45 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
366 IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
367 TCP(sport=1234, dport=1234) /
368 Raw(b'\xa5' * 65200))
370 rxs = self.send_and_expect(self.pg2, 5*[p45], self.pg0, 225)
373 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
374 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
375 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
376 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
377 self.assert_ip_checksum_valid(rx)
378 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
379 self.assertEqual(rx[VXLAN].vni, 10)
380 inner = rx[VXLAN].payload
381 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
382 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
383 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
384 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
385 self.assertEqual(inner[IP].dst, "172.16.3.3")
386 self.assert_ip_checksum_valid(inner)
387 self.assert_tcp_checksum_valid(inner)
388 payload_len = inner[IP].len - 20 - 20
389 self.assertEqual(payload_len, len(inner[Raw]))
391 self.assertEqual(size, 65200*5)
396 p65 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
397 IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
398 TCP(sport=1234, dport=1234) /
399 Raw(b'\xa5' * 65200))
401 rxs = self.send_and_expect(self.pg2, 5*[p65], self.pg0, 225)
404 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
405 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
406 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
407 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
408 self.assert_ip_checksum_valid(rx)
409 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
410 self.assertEqual(rx[VXLAN].vni, 10)
411 inner = rx[VXLAN].payload
412 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
413 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
414 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
415 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
416 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
417 self.assert_tcp_checksum_valid(inner)
418 payload_len = inner[IPv6].plen - 20
419 self.assertEqual(payload_len, len(inner[Raw]))
421 self.assertEqual(size, 65200*5)
426 self.vxlan.remove_vpp_config()
431 self.vxlan2.add_vpp_config()
432 self.vapi.sw_interface_set_l2_bridge(
433 rx_sw_if_index=self.vxlan2.sw_if_index,
434 bd_id=self.single_tunnel_bd)
439 p46 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
440 IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
441 TCP(sport=1234, dport=1234) /
442 Raw(b'\xa5' * 65200))
444 rxs = self.send_and_expect(self.pg2, 5*[p46], self.pg0, 225)
447 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
448 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
449 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
450 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
451 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
452 self.assertEqual(rx[VXLAN].vni, 10)
453 inner = rx[VXLAN].payload
454 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
455 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
456 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
457 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
458 self.assertEqual(inner[IP].dst, "172.16.3.3")
459 self.assert_ip_checksum_valid(inner)
460 self.assert_tcp_checksum_valid(inner)
461 payload_len = inner[IP].len - 20 - 20
462 self.assertEqual(payload_len, len(inner[Raw]))
464 self.assertEqual(size, 65200*5)
469 p66 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
470 IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
471 TCP(sport=1234, dport=1234) /
472 Raw(b'\xa5' * 65200))
474 rxs = self.send_and_expect(self.pg2, 5*[p66], self.pg0, 225)
477 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
478 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
479 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
480 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
481 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
482 self.assertEqual(rx[VXLAN].vni, 10)
483 inner = rx[VXLAN].payload
484 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
485 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
486 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
487 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
488 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
489 self.assert_tcp_checksum_valid(inner)
490 payload_len = inner[IPv6].plen - 20
491 self.assertEqual(payload_len, len(inner[Raw]))
493 self.assertEqual(size, 65200*5)
498 self.vxlan2.remove_vpp_config()
500 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
503 def test_gso_ipip(self):
504 """ GSO IPIP test """
505 self.logger.info(self.vapi.cli("sh int addr"))
507 # Send jumbo frame with gso enabled only on input interface and
508 # create IPIP tunnel on VPP pg0.
510 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
516 self.ipip4.add_vpp_config()
518 # Set interface up and enable IP on it
519 self.ipip4.admin_up()
520 self.ipip4.set_unnumbered(self.pg0.sw_if_index)
522 # Add IPv4 routes via tunnel interface
523 self.ip4_via_ip4_tunnel = VppIpRoute(
524 self, "172.16.10.0", 24,
525 [VppRoutePath("0.0.0.0",
526 self.ipip4.sw_if_index,
527 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
528 self.ip4_via_ip4_tunnel.add_vpp_config()
533 p47 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
534 IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
535 TCP(sport=1234, dport=1234) /
536 Raw(b'\xa5' * 65200))
538 rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
541 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
542 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
543 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
544 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
545 self.assert_ip_checksum_valid(rx)
546 self.assertEqual(rx[IP].proto, 4) # ipencap
547 inner = rx[IP].payload
548 self.assertEqual(rx[IP].len - 20, len(inner))
549 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
550 self.assertEqual(inner[IP].dst, "172.16.10.3")
551 self.assert_ip_checksum_valid(inner)
552 self.assert_tcp_checksum_valid(inner)
553 payload_len = inner[IP].len - 20 - 20
554 self.assertEqual(payload_len, len(inner[Raw]))
556 self.assertEqual(size, 65200*5)
558 self.ip6_via_ip4_tunnel = VppIpRoute(
559 self, "fd01:10::", 64,
561 self.ipip4.sw_if_index,
562 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
563 self.ip6_via_ip4_tunnel.add_vpp_config()
567 p67 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
568 IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
569 TCP(sport=1234, dport=1234) /
570 Raw(b'\xa5' * 65200))
572 rxs = self.send_and_expect(self.pg2, 5*[p67], self.pg0, 225)
575 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
576 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
577 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
578 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
579 self.assert_ip_checksum_valid(rx)
580 self.assertEqual(rx[IP].proto, 41) # ipv6
581 inner = rx[IP].payload
582 self.assertEqual(rx[IP].len - 20, len(inner))
583 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
584 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
585 self.assert_tcp_checksum_valid(inner)
586 payload_len = inner[IPv6].plen - 20
587 self.assertEqual(payload_len, len(inner[Raw]))
589 self.assertEqual(size, 65200*5)
592 # Send jumbo frame with gso enabled only on input interface and
593 # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
594 # tunnel - IPSec use case
596 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
598 self.vapi.feature_gso_enable_disable(
599 sw_if_index=self.ipip4.sw_if_index,
602 rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
605 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
606 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
607 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
608 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
609 self.assert_ip_checksum_valid(rx)
610 self.assertEqual(rx[IP].proto, 4) # ipencap
611 inner = rx[IP].payload
612 self.assertEqual(rx[IP].len - 20, len(inner))
613 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
614 self.assertEqual(inner[IP].dst, "172.16.10.3")
615 self.assert_ip_checksum_valid(inner)
616 self.assert_tcp_checksum_valid(inner)
617 payload_len = inner[IP].len - 20 - 20
618 self.assertEqual(payload_len, len(inner[Raw]))
620 self.assertEqual(size, 65200*5)
625 self.vapi.feature_gso_enable_disable(
626 sw_if_index=self.ipip4.sw_if_index,
628 self.ip4_via_ip4_tunnel.remove_vpp_config()
629 self.ip6_via_ip4_tunnel.remove_vpp_config()
630 self.ipip4.remove_vpp_config()
635 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
637 self.ipip6.add_vpp_config()
639 # Set interface up and enable IP on it
640 self.ipip6.admin_up()
641 self.ipip6.set_unnumbered(self.pg0.sw_if_index)
643 # Add IPv4 routes via tunnel interface
644 self.ip4_via_ip6_tunnel = VppIpRoute(
645 self, "172.16.10.0", 24,
646 [VppRoutePath("0.0.0.0",
647 self.ipip6.sw_if_index,
648 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
649 self.ip4_via_ip6_tunnel.add_vpp_config()
654 p48 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
655 IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
656 TCP(sport=1234, dport=1234) /
657 Raw(b'\xa5' * 65200))
659 rxs = self.send_and_expect(self.pg2, 5*[p48], self.pg0, 225)
662 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
663 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
664 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
665 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
666 self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
667 inner = rx[IPv6].payload
668 self.assertEqual(rx[IPv6].plen, len(inner))
669 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
670 self.assertEqual(inner[IP].dst, "172.16.10.3")
671 self.assert_ip_checksum_valid(inner)
672 self.assert_tcp_checksum_valid(inner)
673 payload_len = inner[IP].len - 20 - 20
674 self.assertEqual(payload_len, len(inner[Raw]))
676 self.assertEqual(size, 65200*5)
678 self.ip6_via_ip6_tunnel = VppIpRoute(
679 self, "fd01:10::", 64,
681 self.ipip6.sw_if_index,
682 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
683 self.ip6_via_ip6_tunnel.add_vpp_config()
688 p68 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
689 IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
690 TCP(sport=1234, dport=1234) /
691 Raw(b'\xa5' * 65200))
693 rxs = self.send_and_expect(self.pg2, 5*[p68], self.pg0, 225)
696 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
697 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
698 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
699 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
700 self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
701 inner = rx[IPv6].payload
702 self.assertEqual(rx[IPv6].plen, len(inner))
703 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
704 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
705 self.assert_tcp_checksum_valid(inner)
706 payload_len = inner[IPv6].plen - 20
707 self.assertEqual(payload_len, len(inner[Raw]))
709 self.assertEqual(size, 65200*5)
714 self.ip4_via_ip6_tunnel.remove_vpp_config()
715 self.ip6_via_ip6_tunnel.remove_vpp_config()
716 self.ipip6.remove_vpp_config()
718 self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
721 if __name__ == '__main__':
722 unittest.main(testRunner=VppTestRunner)