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(self.pg3.sw_if_index)
152 p41 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
153 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4,
155 TCP(sport=1234, dport=1234) /
156 Raw(b'\xa5' * 65200))
158 rxs = self.send_and_expect(self.pg2, 100*[p41], self.pg3, 100)
161 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
162 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
163 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
164 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
165 self.assertEqual(rx[IP].len, 65240) # 65200 + 20 (IP) + 20 (TCP)
166 self.assertEqual(rx[TCP].sport, 1234)
167 self.assertEqual(rx[TCP].dport, 1234)
172 p61 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
173 IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6) /
174 TCP(sport=1234, dport=1234) /
175 Raw(b'\xa5' * 65200))
177 rxs = self.send_and_expect(self.pg2, 100*[p61], self.pg3, 100)
180 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
181 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
182 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
183 self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
184 self.assertEqual(rx[IPv6].plen, 65220) # 65200 + 20 (TCP)
185 self.assertEqual(rx[TCP].sport, 1234)
186 self.assertEqual(rx[TCP].dport, 1234)
189 # Send jumbo frame with gso enabled only on input interface
190 # and DF bit is set. GSO packet will be chunked into gso_size
193 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
194 p42 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
195 IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
197 TCP(sport=1234, dport=1234) /
198 Raw(b'\xa5' * 65200))
200 rxs = self.send_and_expect(self.pg2, 5*[p42], self.pg0, 225)
203 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
204 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
205 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
206 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
207 payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
208 self.assert_ip_checksum_valid(rx)
209 self.assert_tcp_checksum_valid(rx)
210 self.assertEqual(rx[TCP].sport, 1234)
211 self.assertEqual(rx[TCP].dport, 1234)
212 self.assertEqual(payload_len, len(rx[Raw]))
214 self.assertEqual(size, 65200*5)
219 p62 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
220 IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
221 TCP(sport=1234, dport=1234) /
222 Raw(b'\xa5' * 65200))
224 rxs = self.send_and_expect(self.pg2, 5*[p62], self.pg0, 225)
227 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
228 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
229 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
230 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
231 payload_len = rx[IPv6].plen - 20
232 self.assert_tcp_checksum_valid(rx)
233 self.assertEqual(rx[TCP].sport, 1234)
234 self.assertEqual(rx[TCP].dport, 1234)
235 self.assertEqual(payload_len, len(rx[Raw]))
237 self.assertEqual(size, 65200*5)
240 # Send jumbo frame with gso enabled only on input interface
241 # and DF bit is unset. GSO packet will be fragmented.
243 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
244 self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index)
246 p43 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
247 IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4) /
248 TCP(sport=1234, dport=1234) /
249 Raw(b'\xa5' * 65200))
251 rxs = self.send_and_expect(self.pg2, 5*[p43], self.pg1, 5*119)
254 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
255 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
256 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
257 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
258 self.assert_ip_checksum_valid(rx)
259 size += rx[IP].len - 20
260 size -= 20*5 # TCP header
261 self.assertEqual(size, 65200*5)
265 # Send jumbo frame with gso enabled only on input interface.
266 # ICMPv6 Packet Too Big will be sent back to sender.
268 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
269 p63 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
270 IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6) /
271 TCP(sport=1234, dport=1234) /
272 Raw(b'\xa5' * 65200))
274 rxs = self.send_and_expect(self.pg2, 5*[p63], self.pg2, 5)
276 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
277 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
278 self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
279 self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
280 self.assertEqual(rx[IPv6].plen, 1240) # MTU - IPv6 header
281 self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
282 self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
283 self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
284 self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
285 self.assertEqual(rx[IPerror6].plen - 20, 65200)
288 # Send jumbo frame with gso enabled only on input interface with 9K MTU
289 # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
290 # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
292 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
293 self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
294 p44 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
295 IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4) /
296 TCP(sport=1234, dport=1234) /
297 Raw(b'\xa5' * 65200))
299 rxs = self.send_and_expect(self.pg4, 5*[p44], self.pg1, 165)
302 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
303 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
304 self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
305 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
306 payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
307 self.assert_ip_checksum_valid(rx)
308 self.assert_tcp_checksum_valid(rx)
309 self.assertEqual(payload_len, len(rx[Raw]))
311 self.assertEqual(size, 65200*5)
316 p64 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
317 IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6) /
318 TCP(sport=1234, dport=1234) /
319 Raw(b'\xa5' * 65200))
321 rxs = self.send_and_expect(self.pg4, 5*[p64], self.pg1, 170)
324 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
325 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
326 self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
327 self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
328 payload_len = rx[IPv6].plen - 20
329 self.assert_tcp_checksum_valid(rx)
330 self.assertEqual(payload_len, len(rx[Raw]))
332 self.assertEqual(size, 65200*5)
334 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
336 self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index,
339 def test_gso_vxlan(self):
340 """ GSO VXLAN test """
341 self.logger.info(self.vapi.cli("sh int addr"))
343 # Send jumbo frame with gso enabled only on input interface and
344 # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
351 self.vxlan.add_vpp_config()
352 self.vapi.sw_interface_set_l2_bridge(
353 rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd)
354 self.vapi.sw_interface_set_l2_bridge(
355 rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd)
356 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
361 p45 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
362 IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
363 TCP(sport=1234, dport=1234) /
364 Raw(b'\xa5' * 65200))
366 rxs = self.send_and_expect(self.pg2, 5*[p45], self.pg0, 225)
369 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
370 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
371 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
372 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
373 self.assert_ip_checksum_valid(rx)
374 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
375 self.assertEqual(rx[VXLAN].vni, 10)
376 inner = rx[VXLAN].payload
377 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
378 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
379 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
380 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
381 self.assertEqual(inner[IP].dst, "172.16.3.3")
382 self.assert_ip_checksum_valid(inner)
383 self.assert_tcp_checksum_valid(inner)
384 payload_len = inner[IP].len - 20 - 20
385 self.assertEqual(payload_len, len(inner[Raw]))
387 self.assertEqual(size, 65200*5)
392 p65 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
393 IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
394 TCP(sport=1234, dport=1234) /
395 Raw(b'\xa5' * 65200))
397 rxs = self.send_and_expect(self.pg2, 5*[p65], self.pg0, 225)
400 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
401 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
402 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
403 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
404 self.assert_ip_checksum_valid(rx)
405 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
406 self.assertEqual(rx[VXLAN].vni, 10)
407 inner = rx[VXLAN].payload
408 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
409 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
410 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
411 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
412 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
413 self.assert_tcp_checksum_valid(inner)
414 payload_len = inner[IPv6].plen - 20
415 self.assertEqual(payload_len, len(inner[Raw]))
417 self.assertEqual(size, 65200*5)
422 self.vxlan.remove_vpp_config()
427 self.vxlan2.add_vpp_config()
428 self.vapi.sw_interface_set_l2_bridge(
429 rx_sw_if_index=self.vxlan2.sw_if_index,
430 bd_id=self.single_tunnel_bd)
435 p46 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
436 IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
437 TCP(sport=1234, dport=1234) /
438 Raw(b'\xa5' * 65200))
440 rxs = self.send_and_expect(self.pg2, 5*[p46], self.pg0, 225)
443 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
444 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
445 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
446 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
447 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
448 self.assertEqual(rx[VXLAN].vni, 10)
449 inner = rx[VXLAN].payload
450 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
451 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
452 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
453 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
454 self.assertEqual(inner[IP].dst, "172.16.3.3")
455 self.assert_ip_checksum_valid(inner)
456 self.assert_tcp_checksum_valid(inner)
457 payload_len = inner[IP].len - 20 - 20
458 self.assertEqual(payload_len, len(inner[Raw]))
460 self.assertEqual(size, 65200*5)
465 p66 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
466 IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
467 TCP(sport=1234, dport=1234) /
468 Raw(b'\xa5' * 65200))
470 rxs = self.send_and_expect(self.pg2, 5*[p66], self.pg0, 225)
473 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
474 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
475 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
476 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
477 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
478 self.assertEqual(rx[VXLAN].vni, 10)
479 inner = rx[VXLAN].payload
480 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
481 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
482 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
483 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
484 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
485 self.assert_tcp_checksum_valid(inner)
486 payload_len = inner[IPv6].plen - 20
487 self.assertEqual(payload_len, len(inner[Raw]))
489 self.assertEqual(size, 65200*5)
494 self.vxlan2.remove_vpp_config()
496 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
499 def test_gso_ipip(self):
500 """ GSO IPIP test """
501 self.logger.info(self.vapi.cli("sh int addr"))
503 # Send jumbo frame with gso enabled only on input interface and
504 # create IPIP tunnel on VPP pg0.
506 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
511 self.ipip4.add_vpp_config()
513 # Set interface up and enable IP on it
514 self.ipip4.admin_up()
515 self.ipip4.set_unnumbered(self.pg0.sw_if_index)
517 # Add IPv4 routes via tunnel interface
518 self.ip4_via_ip4_tunnel = VppIpRoute(
519 self, "172.16.10.0", 24,
520 [VppRoutePath("0.0.0.0",
521 self.ipip4.sw_if_index,
522 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
523 self.ip4_via_ip4_tunnel.add_vpp_config()
528 p47 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
529 IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
530 TCP(sport=1234, dport=1234) /
531 Raw(b'\xa5' * 65200))
533 rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
536 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
537 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
538 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
539 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
540 self.assert_ip_checksum_valid(rx)
541 self.assertEqual(rx[IP].proto, 4) # ipencap
542 inner = rx[IP].payload
543 self.assertEqual(rx[IP].len - 20, len(inner))
544 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
545 self.assertEqual(inner[IP].dst, "172.16.10.3")
546 self.assert_ip_checksum_valid(inner)
547 self.assert_tcp_checksum_valid(inner)
548 payload_len = inner[IP].len - 20 - 20
549 self.assertEqual(payload_len, len(inner[Raw]))
551 self.assertEqual(size, 65200*5)
553 self.ip6_via_ip4_tunnel = VppIpRoute(
554 self, "fd01:10::", 64,
556 self.ipip4.sw_if_index,
557 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
558 self.ip6_via_ip4_tunnel.add_vpp_config()
562 p67 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
563 IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
564 TCP(sport=1234, dport=1234) /
565 Raw(b'\xa5' * 65200))
567 rxs = self.send_and_expect(self.pg2, 5*[p67], self.pg0, 225)
570 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
571 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
572 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
573 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
574 self.assert_ip_checksum_valid(rx)
575 self.assertEqual(rx[IP].proto, 41) # ipv6
576 inner = rx[IP].payload
577 self.assertEqual(rx[IP].len - 20, len(inner))
578 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
579 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
580 self.assert_tcp_checksum_valid(inner)
581 payload_len = inner[IPv6].plen - 20
582 self.assertEqual(payload_len, len(inner[Raw]))
584 self.assertEqual(size, 65200*5)
587 # Send jumbo frame with gso enabled only on input interface and
588 # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
589 # tunnel - IPSec use case
591 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
593 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index)
595 rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
598 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
599 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
600 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
601 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
602 self.assert_ip_checksum_valid(rx)
603 self.assertEqual(rx[IP].proto, 4) # ipencap
604 inner = rx[IP].payload
605 self.assertEqual(rx[IP].len - 20, len(inner))
606 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
607 self.assertEqual(inner[IP].dst, "172.16.10.3")
608 self.assert_ip_checksum_valid(inner)
609 self.assert_tcp_checksum_valid(inner)
610 payload_len = inner[IP].len - 20 - 20
611 self.assertEqual(payload_len, len(inner[Raw]))
613 self.assertEqual(size, 65200*5)
618 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index,
620 self.ip4_via_ip4_tunnel.remove_vpp_config()
621 self.ip6_via_ip4_tunnel.remove_vpp_config()
622 self.ipip4.remove_vpp_config()
627 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
628 self.ipip6.add_vpp_config()
630 # Set interface up and enable IP on it
631 self.ipip6.admin_up()
632 self.ipip6.set_unnumbered(self.pg0.sw_if_index)
634 # Add IPv4 routes via tunnel interface
635 self.ip4_via_ip6_tunnel = VppIpRoute(
636 self, "172.16.10.0", 24,
637 [VppRoutePath("0.0.0.0",
638 self.ipip6.sw_if_index,
639 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
640 self.ip4_via_ip6_tunnel.add_vpp_config()
645 p48 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
646 IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
647 TCP(sport=1234, dport=1234) /
648 Raw(b'\xa5' * 65200))
650 rxs = self.send_and_expect(self.pg2, 5*[p48], self.pg0, 225)
653 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
654 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
655 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
656 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
657 self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
658 inner = rx[IPv6].payload
659 self.assertEqual(rx[IPv6].plen, len(inner))
660 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
661 self.assertEqual(inner[IP].dst, "172.16.10.3")
662 self.assert_ip_checksum_valid(inner)
663 self.assert_tcp_checksum_valid(inner)
664 payload_len = inner[IP].len - 20 - 20
665 self.assertEqual(payload_len, len(inner[Raw]))
667 self.assertEqual(size, 65200*5)
669 self.ip6_via_ip6_tunnel = VppIpRoute(
670 self, "fd01:10::", 64,
672 self.ipip6.sw_if_index,
673 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
674 self.ip6_via_ip6_tunnel.add_vpp_config()
679 p68 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
680 IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
681 TCP(sport=1234, dport=1234) /
682 Raw(b'\xa5' * 65200))
684 rxs = self.send_and_expect(self.pg2, 5*[p68], self.pg0, 225)
687 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
688 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
689 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
690 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
691 self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
692 inner = rx[IPv6].payload
693 self.assertEqual(rx[IPv6].plen, len(inner))
694 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
695 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
696 self.assert_tcp_checksum_valid(inner)
697 payload_len = inner[IPv6].plen - 20
698 self.assertEqual(payload_len, len(inner[Raw]))
700 self.assertEqual(size, 65200*5)
705 self.ip4_via_ip6_tunnel.remove_vpp_config()
706 self.ip6_via_ip6_tunnel.remove_vpp_config()
707 self.ipip6.remove_vpp_config()
709 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
712 if __name__ == '__main__':
713 unittest.main(testRunner=VppTestRunner)