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, 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.layers.ipsec import ESP
20 from vpp_papi import VppEnum
21 from framework import VppTestCase
22 from asfframework import VppTestRunner
23 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto
24 from vpp_ipip_tun_interface import VppIpIpTunInterface
25 from vpp_vxlan_tunnel import VppVxlanTunnel
27 from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect
28 from template_ipsec import (
34 """ Test_gso is a subclass of VPPTestCase classes.
39 class TestGSO(VppTestCase):
42 def __init__(self, *args):
43 VppTestCase.__init__(self, *args)
47 super(TestGSO, self).setUpClass()
48 res = self.create_pg_interfaces(range(2))
49 res_gso = self.create_pg_interfaces(range(2, 4), 1, 1460)
50 self.create_pg_interfaces(range(4, 5), 1, 8940)
51 self.pg_interfaces.append(res[0])
52 self.pg_interfaces.append(res[1])
53 self.pg_interfaces.append(res_gso[0])
54 self.pg_interfaces.append(res_gso[1])
57 def tearDownClass(self):
58 super(TestGSO, self).tearDownClass()
61 super(TestGSO, self).setUp()
62 for i in self.pg_interfaces:
70 self.single_tunnel_bd = 10
71 self.vxlan = VppVxlanTunnel(
73 src=self.pg0.local_ip4,
74 dst=self.pg0.remote_ip4,
75 vni=self.single_tunnel_bd,
78 self.vxlan2 = VppVxlanTunnel(
80 src=self.pg0.local_ip6,
81 dst=self.pg0.remote_ip6,
82 vni=self.single_tunnel_bd,
85 self.ipip4 = VppIpIpTunInterface(
86 self, self.pg0, self.pg0.local_ip4, self.pg0.remote_ip4
88 self.ipip6 = VppIpIpTunInterface(
89 self, self.pg0, self.pg0.local_ip6, self.pg0.remote_ip6
93 super(TestGSO, self).tearDown()
95 for i in self.pg_interfaces:
103 # Send jumbo frame with gso disabled and DF bit is set
106 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
107 / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, flags="DF")
108 / TCP(sport=1234, dport=1234)
109 / Raw(b"\xa5" * 65200)
112 rxs = self.send_and_expect(self.pg0, [p4], self.pg0)
115 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
116 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
117 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
118 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
119 self.assertEqual(rx[ICMP].type, 3) # "dest-unreach"
120 self.assertEqual(rx[ICMP].code, 4) # "fragmentation-needed"
123 # Send checksum offload frames
126 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
127 / IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4, flags="DF")
128 / TCP(sport=1234, dport=1234)
129 / Raw(b"\xa5" * 1460)
132 rxs = self.send_and_expect(self.pg2, 100 * [p40], self.pg0)
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 payload_len = rx[IP].len - 20 - 20
140 self.assert_ip_checksum_valid(rx)
141 self.assert_tcp_checksum_valid(rx)
142 self.assertEqual(payload_len, len(rx[Raw]))
145 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
146 / IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6)
147 / TCP(sport=1234, dport=1234)
148 / Raw(b"\xa5" * 1440)
151 rxs = self.send_and_expect(self.pg2, 100 * [p60], self.pg0)
154 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
155 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
156 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
157 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
158 payload_len = rx[IPv6].plen - 20
159 self.assert_tcp_checksum_valid(rx)
160 self.assertEqual(payload_len, len(rx[Raw]))
163 # Send jumbo frame with gso enabled and DF bit is set
164 # input and output interfaces support GSO
166 self.vapi.feature_gso_enable_disable(
167 sw_if_index=self.pg3.sw_if_index, enable_disable=1
170 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
171 / IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4, flags="DF")
172 / TCP(sport=1234, dport=1234)
173 / Raw(b"\xa5" * 65200)
176 rxs = self.send_and_expect(self.pg2, 100 * [p41], self.pg3, 100)
179 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
180 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
181 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
182 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
183 self.assertEqual(rx[IP].len, 65240) # 65200 + 20 (IP) + 20 (TCP)
184 self.assertEqual(rx[TCP].sport, 1234)
185 self.assertEqual(rx[TCP].dport, 1234)
191 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
192 / IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6)
193 / TCP(sport=1234, dport=1234)
194 / Raw(b"\xa5" * 65200)
197 rxs = self.send_and_expect(self.pg2, 100 * [p61], self.pg3, 100)
200 self.assertEqual(rx[Ether].src, self.pg3.local_mac)
201 self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
202 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
203 self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
204 self.assertEqual(rx[IPv6].plen, 65220) # 65200 + 20 (TCP)
205 self.assertEqual(rx[TCP].sport, 1234)
206 self.assertEqual(rx[TCP].dport, 1234)
209 # Send jumbo frame with gso enabled only on input interface
210 # and DF bit is set. GSO packet will be chunked into gso_size
213 self.vapi.feature_gso_enable_disable(
214 sw_if_index=self.pg0.sw_if_index, enable_disable=1
217 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
218 / IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4, flags="DF")
219 / TCP(sport=1234, dport=1234)
220 / Raw(b"\xa5" * 65200)
223 rxs = self.send_and_expect(self.pg2, 5 * [p42], self.pg0, 225)
226 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
227 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
228 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
229 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
230 payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
231 self.assert_ip_checksum_valid(rx)
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)
243 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
244 / IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6)
245 / TCP(sport=1234, dport=1234)
246 / Raw(b"\xa5" * 65200)
249 rxs = self.send_and_expect(self.pg2, 5 * [p62], self.pg0, 225)
252 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
253 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
254 self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
255 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
256 payload_len = rx[IPv6].plen - 20
257 self.assert_tcp_checksum_valid(rx)
258 self.assertEqual(rx[TCP].sport, 1234)
259 self.assertEqual(rx[TCP].dport, 1234)
260 self.assertEqual(payload_len, len(rx[Raw]))
262 self.assertEqual(size, 65200 * 5)
265 # Send jumbo frame with gso enabled only on input interface
266 # and DF bit is unset. GSO packet will be fragmented.
268 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
269 self.vapi.feature_gso_enable_disable(
270 sw_if_index=self.pg1.sw_if_index, enable_disable=1
274 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
275 / IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4)
276 / TCP(sport=1234, dport=1234)
277 / Raw(b"\xa5" * 65200)
280 rxs = self.send_and_expect(self.pg2, 5 * [p43], self.pg1, 5 * 119)
283 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
284 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
285 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
286 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
287 self.assert_ip_checksum_valid(rx)
288 size += rx[IP].len - 20
289 size -= 20 * 5 # TCP header
290 self.assertEqual(size, 65200 * 5)
294 # Send jumbo frame with gso enabled only on input interface.
295 # ICMPv6 Packet Too Big will be sent back to sender.
297 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
299 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
300 / IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6)
301 / TCP(sport=1234, dport=1234)
302 / Raw(b"\xa5" * 65200)
305 rxs = self.send_and_expect_some(self.pg2, 5 * [p63], self.pg2, 5)
307 self.assertEqual(rx[Ether].src, self.pg2.local_mac)
308 self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
309 self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
310 self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
311 self.assertEqual(rx[IPv6].plen, 1240) # MTU - IPv6 header
312 self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
313 self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
314 self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
315 self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
316 self.assertEqual(rx[IPerror6].plen - 20, 65200)
319 # Send jumbo frame with gso enabled only on input interface with 9K MTU
320 # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
321 # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
323 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
324 self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
326 Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac)
327 / IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4)
328 / TCP(sport=1234, dport=1234)
329 / Raw(b"\xa5" * 65200)
332 rxs = self.send_and_expect(self.pg4, 5 * [p44], self.pg1, 165)
335 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
336 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
337 self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
338 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
339 payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
340 self.assert_ip_checksum_valid(rx)
341 self.assert_tcp_checksum_valid(rx)
342 self.assertEqual(payload_len, len(rx[Raw]))
344 self.assertEqual(size, 65200 * 5)
350 Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac)
351 / IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6)
352 / TCP(sport=1234, dport=1234)
353 / Raw(b"\xa5" * 65200)
356 rxs = self.send_and_expect(self.pg4, 5 * [p64], self.pg1, 170)
359 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
360 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
361 self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
362 self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
363 payload_len = rx[IPv6].plen - 20
364 self.assert_tcp_checksum_valid(rx)
365 self.assertEqual(payload_len, len(rx[Raw]))
367 self.assertEqual(size, 65200 * 5)
369 self.vapi.feature_gso_enable_disable(
370 sw_if_index=self.pg0.sw_if_index, enable_disable=0
372 self.vapi.feature_gso_enable_disable(
373 sw_if_index=self.pg1.sw_if_index, enable_disable=0
376 def test_gso_vxlan(self):
378 self.logger.info(self.vapi.cli("sh int addr"))
380 # Send jumbo frame with gso enabled only on input interface and
381 # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
388 self.vxlan.add_vpp_config()
389 self.vapi.sw_interface_set_l2_bridge(
390 rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd
392 self.vapi.sw_interface_set_l2_bridge(
393 rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd
395 self.vapi.feature_gso_enable_disable(
396 sw_if_index=self.pg0.sw_if_index, enable_disable=1
403 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
404 / IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags="DF")
405 / TCP(sport=1234, dport=1234)
406 / Raw(b"\xa5" * 65200)
409 rxs = self.send_and_expect(self.pg2, 5 * [p45], self.pg0, 225)
412 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
413 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
414 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
415 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
416 self.assert_ip_checksum_valid(rx)
417 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
418 self.assertEqual(rx[VXLAN].vni, 10)
419 inner = rx[VXLAN].payload
420 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
421 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
422 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
423 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
424 self.assertEqual(inner[IP].dst, "172.16.3.3")
425 self.assert_ip_checksum_valid(inner)
426 self.assert_tcp_checksum_valid(inner)
427 payload_len = inner[IP].len - 20 - 20
428 self.assertEqual(payload_len, len(inner[Raw]))
430 self.assertEqual(size, 65200 * 5)
436 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
437 / IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3")
438 / TCP(sport=1234, dport=1234)
439 / Raw(b"\xa5" * 65200)
442 rxs = self.send_and_expect(self.pg2, 5 * [p65], self.pg0, 225)
445 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
446 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
447 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
448 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
449 self.assert_ip_checksum_valid(rx)
450 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
451 self.assertEqual(rx[VXLAN].vni, 10)
452 inner = rx[VXLAN].payload
453 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
454 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
455 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
456 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
457 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
458 self.assert_tcp_checksum_valid(inner)
459 payload_len = inner[IPv6].plen - 20
460 self.assertEqual(payload_len, len(inner[Raw]))
462 self.assertEqual(size, 65200 * 5)
467 self.vxlan.remove_vpp_config()
472 self.vxlan2.add_vpp_config()
473 self.vapi.sw_interface_set_l2_bridge(
474 rx_sw_if_index=self.vxlan2.sw_if_index, bd_id=self.single_tunnel_bd
481 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
482 / IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags="DF")
483 / TCP(sport=1234, dport=1234)
484 / Raw(b"\xa5" * 65200)
487 rxs = self.send_and_expect(self.pg2, 5 * [p46], self.pg0, 225)
490 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
491 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
492 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
493 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
494 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
495 self.assertEqual(rx[VXLAN].vni, 10)
496 inner = rx[VXLAN].payload
497 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
498 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
499 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
500 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
501 self.assertEqual(inner[IP].dst, "172.16.3.3")
502 self.assert_ip_checksum_valid(inner)
503 self.assert_tcp_checksum_valid(inner)
504 payload_len = inner[IP].len - 20 - 20
505 self.assertEqual(payload_len, len(inner[Raw]))
507 self.assertEqual(size, 65200 * 5)
513 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
514 / IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3")
515 / TCP(sport=1234, dport=1234)
516 / Raw(b"\xa5" * 65200)
519 rxs = self.send_and_expect(self.pg2, 5 * [p66], self.pg0, 225)
522 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
523 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
524 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
525 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
526 self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
527 self.assertEqual(rx[VXLAN].vni, 10)
528 inner = rx[VXLAN].payload
529 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
530 self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
531 self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
532 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
533 self.assertEqual(inner[IPv6].dst, "fd01:3::3")
534 self.assert_tcp_checksum_valid(inner)
535 payload_len = inner[IPv6].plen - 20
536 self.assertEqual(payload_len, len(inner[Raw]))
538 self.assertEqual(size, 65200 * 5)
543 self.vxlan2.remove_vpp_config()
545 self.vapi.feature_gso_enable_disable(
546 sw_if_index=self.pg0.sw_if_index, enable_disable=0
549 def test_gso_ipip(self):
551 self.logger.info(self.vapi.cli("sh int addr"))
553 # Send jumbo frame with gso enabled only on input interface and
554 # create IPIP tunnel on VPP pg0.
556 self.vapi.feature_gso_enable_disable(
557 sw_if_index=self.pg0.sw_if_index, enable_disable=1
563 self.ipip4.add_vpp_config()
565 # Set interface up and enable IP on it
566 self.ipip4.admin_up()
567 self.ipip4.set_unnumbered(self.pg0.sw_if_index)
569 # Add IPv4 routes via tunnel interface
570 self.ip4_via_ip4_tunnel = VppIpRoute(
577 self.ipip4.sw_if_index,
578 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
582 self.ip4_via_ip4_tunnel.add_vpp_config()
588 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
589 / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
590 / TCP(sport=1234, dport=1234)
591 / Raw(b"\xa5" * 65200)
594 rxs = self.send_and_expect(self.pg2, 5 * [p47], self.pg0, 225)
597 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
598 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
599 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
600 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
601 self.assert_ip_checksum_valid(rx)
602 self.assertEqual(rx[IP].proto, 4) # ipencap
603 inner = rx[IP].payload
604 self.assertEqual(rx[IP].len - 20, len(inner))
605 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
606 self.assertEqual(inner[IP].dst, "172.16.10.3")
607 self.assert_ip_checksum_valid(inner)
608 self.assert_tcp_checksum_valid(inner)
609 payload_len = inner[IP].len - 20 - 20
610 self.assertEqual(payload_len, len(inner[Raw]))
612 self.assertEqual(size, 65200 * 5)
614 self.ip6_via_ip4_tunnel = VppIpRoute(
621 self.ipip4.sw_if_index,
622 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
626 self.ip6_via_ip4_tunnel.add_vpp_config()
631 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
632 / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
633 / TCP(sport=1234, dport=1234)
634 / Raw(b"\xa5" * 65200)
637 rxs = self.send_and_expect(self.pg2, 5 * [p67], self.pg0, 225)
640 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
641 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
642 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
643 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
644 self.assert_ip_checksum_valid(rx)
645 self.assertEqual(rx[IP].proto, 41) # ipv6
646 inner = rx[IP].payload
647 self.assertEqual(rx[IP].len - 20, len(inner))
648 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
649 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
650 self.assert_tcp_checksum_valid(inner)
651 payload_len = inner[IPv6].plen - 20
652 self.assertEqual(payload_len, len(inner[Raw]))
654 self.assertEqual(size, 65200 * 5)
657 # Send jumbo frame with gso enabled only on input interface and
658 # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
659 # tunnel - IPSec use case
661 self.vapi.feature_gso_enable_disable(
662 sw_if_index=self.pg0.sw_if_index, enable_disable=0
664 self.vapi.feature_gso_enable_disable(
665 sw_if_index=self.ipip4.sw_if_index, enable_disable=1
668 rxs = self.send_and_expect(self.pg2, 5 * [p47], self.pg0, 225)
671 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
672 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
673 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
674 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
675 self.assert_ip_checksum_valid(rx)
676 self.assertEqual(rx[IP].proto, 4) # ipencap
677 inner = rx[IP].payload
678 self.assertEqual(rx[IP].len - 20, len(inner))
679 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
680 self.assertEqual(inner[IP].dst, "172.16.10.3")
681 self.assert_ip_checksum_valid(inner)
682 self.assert_tcp_checksum_valid(inner)
683 payload_len = inner[IP].len - 20 - 20
684 self.assertEqual(payload_len, len(inner[Raw]))
686 self.assertEqual(size, 65200 * 5)
691 self.vapi.feature_gso_enable_disable(
692 sw_if_index=self.ipip4.sw_if_index, enable_disable=0
694 self.ip4_via_ip4_tunnel.remove_vpp_config()
695 self.ip6_via_ip4_tunnel.remove_vpp_config()
696 self.ipip4.remove_vpp_config()
701 self.vapi.feature_gso_enable_disable(
702 sw_if_index=self.pg0.sw_if_index, enable_disable=1
704 self.ipip6.add_vpp_config()
706 # Set interface up and enable IP on it
707 self.ipip6.admin_up()
708 self.ipip6.set_unnumbered(self.pg0.sw_if_index)
710 # Add IPv4 routes via tunnel interface
711 self.ip4_via_ip6_tunnel = VppIpRoute(
718 self.ipip6.sw_if_index,
719 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
723 self.ip4_via_ip6_tunnel.add_vpp_config()
729 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
730 / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
731 / TCP(sport=1234, dport=1234)
732 / Raw(b"\xa5" * 65200)
735 rxs = self.send_and_expect(self.pg2, 5 * [p48], self.pg0, 225)
738 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
739 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
740 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
741 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
742 self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
743 inner = rx[IPv6].payload
744 self.assertEqual(rx[IPv6].plen, len(inner))
745 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
746 self.assertEqual(inner[IP].dst, "172.16.10.3")
747 self.assert_ip_checksum_valid(inner)
748 self.assert_tcp_checksum_valid(inner)
749 payload_len = inner[IP].len - 20 - 20
750 self.assertEqual(payload_len, len(inner[Raw]))
752 self.assertEqual(size, 65200 * 5)
754 self.ip6_via_ip6_tunnel = VppIpRoute(
761 self.ipip6.sw_if_index,
762 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
766 self.ip6_via_ip6_tunnel.add_vpp_config()
772 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
773 / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
774 / TCP(sport=1234, dport=1234)
775 / Raw(b"\xa5" * 65200)
778 rxs = self.send_and_expect(self.pg2, 5 * [p68], self.pg0, 225)
781 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
782 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
783 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
784 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
785 self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
786 inner = rx[IPv6].payload
787 self.assertEqual(rx[IPv6].plen, len(inner))
788 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
789 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
790 self.assert_tcp_checksum_valid(inner)
791 payload_len = inner[IPv6].plen - 20
792 self.assertEqual(payload_len, len(inner[Raw]))
794 self.assertEqual(size, 65200 * 5)
799 self.ip4_via_ip6_tunnel.remove_vpp_config()
800 self.ip6_via_ip6_tunnel.remove_vpp_config()
801 self.ipip6.remove_vpp_config()
803 self.vapi.feature_gso_enable_disable(
804 sw_if_index=self.pg0.sw_if_index, enable_disable=0
807 def test_gso_ipsec(self):
810 # Send jumbo frame with gso enabled only on input interface and
811 # create IPIP tunnel on VPP pg0.
817 self.ipip4.add_vpp_config()
818 self.vapi.feature_gso_enable_disable(
819 sw_if_index=self.ipip4.sw_if_index, enable_disable=1
822 # Add IPv4 routes via tunnel interface
823 self.ip4_via_ip4_tunnel = VppIpRoute(
830 self.ipip4.sw_if_index,
831 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
835 self.ip4_via_ip4_tunnel.add_vpp_config()
838 self.ipv4_params = IPsecIPv4Params()
839 self.encryption_type = ESP
840 config_tun_params(self.ipv4_params, self.encryption_type, self.ipip4)
842 self.tun_sa_in_v4 = VppIpsecSA(
844 self.ipv4_params.scapy_tun_sa_id,
845 self.ipv4_params.scapy_tun_spi,
846 self.ipv4_params.auth_algo_vpp_id,
847 self.ipv4_params.auth_key,
848 self.ipv4_params.crypt_algo_vpp_id,
849 self.ipv4_params.crypt_key,
850 VppEnum.vl_api_ipsec_proto_t.IPSEC_API_PROTO_ESP,
852 self.tun_sa_in_v4.add_vpp_config()
854 self.tun_sa_out_v4 = VppIpsecSA(
856 self.ipv4_params.vpp_tun_sa_id,
857 self.ipv4_params.vpp_tun_spi,
858 self.ipv4_params.auth_algo_vpp_id,
859 self.ipv4_params.auth_key,
860 self.ipv4_params.crypt_algo_vpp_id,
861 self.ipv4_params.crypt_key,
862 VppEnum.vl_api_ipsec_proto_t.IPSEC_API_PROTO_ESP,
864 self.tun_sa_out_v4.add_vpp_config()
866 self.tun_protect_v4 = VppIpsecTunProtect(
867 self, self.ipip4, self.tun_sa_out_v4, [self.tun_sa_in_v4]
870 self.tun_protect_v4.add_vpp_config()
872 # Set interface up and enable IP on it
873 self.ipip4.admin_up()
874 self.ipip4.set_unnumbered(self.pg0.sw_if_index)
880 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
881 / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
882 / TCP(sport=1234, dport=1234)
883 / Raw(b"\xa5" * 65200)
886 rxs = self.send_and_expect(self.pg2, [ipsec44], self.pg0, 45)
889 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
890 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
891 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
892 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
893 self.assertEqual(rx[IP].proto, 50) # ESP
894 self.assertEqual(rx[ESP].spi, self.ipv4_params.vpp_tun_spi)
895 inner = self.ipv4_params.vpp_tun_sa.decrypt(rx[IP])
896 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
897 self.assertEqual(inner[IP].dst, "172.16.10.3")
898 size += inner[IP].len - 20 - 20
899 self.assertEqual(size, 65200)
901 self.ip6_via_ip4_tunnel = VppIpRoute(
908 self.ipip4.sw_if_index,
909 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
913 self.ip6_via_ip4_tunnel.add_vpp_config()
918 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
919 / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
920 / TCP(sport=1234, dport=1234)
921 / Raw(b"\xa5" * 65200)
924 rxs = self.send_and_expect(self.pg2, [ipsec46], self.pg0, 45)
927 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
928 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
929 self.assertEqual(rx[IP].src, self.pg0.local_ip4)
930 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
931 self.assertEqual(rx[IP].proto, 50) # ESP
932 self.assertEqual(rx[ESP].spi, self.ipv4_params.vpp_tun_spi)
933 inner = self.ipv4_params.vpp_tun_sa.decrypt(rx[IP])
934 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
935 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
936 size += inner[IPv6].plen - 20
937 self.assertEqual(size, 65200)
940 self.tun_protect_v4.remove_vpp_config()
941 self.tun_sa_in_v4.remove_vpp_config()
942 self.tun_sa_out_v4.remove_vpp_config()
947 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index, enable_disable=0)
948 self.ip4_via_ip4_tunnel.remove_vpp_config()
949 self.ip6_via_ip4_tunnel.remove_vpp_config()
950 self.ipip4.remove_vpp_config()
955 self.ipip6.add_vpp_config()
956 self.vapi.feature_gso_enable_disable(self.ipip6.sw_if_index, enable_disable=1)
958 # Set interface up and enable IP on it
959 self.ipip6.admin_up()
960 self.ipip6.set_unnumbered(self.pg0.sw_if_index)
962 # Add IPv4 routes via tunnel interface
963 self.ip4_via_ip6_tunnel = VppIpRoute(
970 self.ipip6.sw_if_index,
971 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
975 self.ip4_via_ip6_tunnel.add_vpp_config()
978 self.ipv6_params = IPsecIPv6Params()
979 self.encryption_type = ESP
980 config_tun_params(self.ipv6_params, self.encryption_type, self.ipip6)
981 self.tun_sa_in_v6 = VppIpsecSA(
983 self.ipv6_params.scapy_tun_sa_id,
984 self.ipv6_params.scapy_tun_spi,
985 self.ipv6_params.auth_algo_vpp_id,
986 self.ipv6_params.auth_key,
987 self.ipv6_params.crypt_algo_vpp_id,
988 self.ipv6_params.crypt_key,
989 VppEnum.vl_api_ipsec_proto_t.IPSEC_API_PROTO_ESP,
991 self.tun_sa_in_v6.add_vpp_config()
993 self.tun_sa_out_v6 = VppIpsecSA(
995 self.ipv6_params.vpp_tun_sa_id,
996 self.ipv6_params.vpp_tun_spi,
997 self.ipv6_params.auth_algo_vpp_id,
998 self.ipv6_params.auth_key,
999 self.ipv6_params.crypt_algo_vpp_id,
1000 self.ipv6_params.crypt_key,
1001 VppEnum.vl_api_ipsec_proto_t.IPSEC_API_PROTO_ESP,
1003 self.tun_sa_out_v6.add_vpp_config()
1005 self.tun_protect_v6 = VppIpsecTunProtect(
1006 self, self.ipip6, self.tun_sa_out_v6, [self.tun_sa_in_v6]
1009 self.tun_protect_v6.add_vpp_config()
1015 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
1016 / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
1017 / TCP(sport=1234, dport=1234)
1018 / Raw(b"\xa5" * 65200)
1021 rxs = self.send_and_expect(self.pg2, [ipsec64], self.pg0, 45)
1024 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1025 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1026 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
1027 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
1028 self.assertEqual(ipv6nh[rx[IPv6].nh], "ESP Header")
1029 self.assertEqual(rx[ESP].spi, self.ipv6_params.vpp_tun_spi)
1030 inner = self.ipv6_params.vpp_tun_sa.decrypt(rx[IPv6])
1031 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
1032 self.assertEqual(inner[IP].dst, "172.16.10.3")
1033 size += inner[IP].len - 20 - 20
1034 self.assertEqual(size, 65200)
1036 self.ip6_via_ip6_tunnel = VppIpRoute(
1043 self.ipip6.sw_if_index,
1044 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
1048 self.ip6_via_ip6_tunnel.add_vpp_config()
1054 Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
1055 / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
1056 / TCP(sport=1234, dport=1234)
1057 / Raw(b"\xa5" * 65200)
1060 rxs = self.send_and_expect(self.pg2, [ipsec66], self.pg0, 45)
1063 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1064 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1065 self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
1066 self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
1067 self.assertEqual(ipv6nh[rx[IPv6].nh], "ESP Header")
1068 self.assertEqual(rx[ESP].spi, self.ipv6_params.vpp_tun_spi)
1069 inner = self.ipv6_params.vpp_tun_sa.decrypt(rx[IPv6])
1070 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
1071 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
1072 size += inner[IPv6].plen - 20
1073 self.assertEqual(size, 65200)
1076 self.tun_protect_v6.remove_vpp_config()
1077 self.tun_sa_in_v6.remove_vpp_config()
1078 self.tun_sa_out_v6.remove_vpp_config()
1083 self.ip4_via_ip6_tunnel.remove_vpp_config()
1084 self.ip6_via_ip6_tunnel.remove_vpp_config()
1085 self.ipip6.remove_vpp_config()
1087 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index, enable_disable=0)
1090 if __name__ == "__main__":
1091 unittest.main(testRunner=VppTestRunner)