blob: 29a54eb396f61c8995ae94f336012d9023a72190 [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 #
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200111 # Send checksum offload frames
112 #
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,
115 flags='DF') /
116 TCP(sport=1234, dport=1234) /
117 Raw(b'\xa5' * 1460))
118
119 rxs = self.send_and_expect(self.pg2, 100*[p40], self.pg0)
120
121 for rx in rxs:
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]))
130
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) /
134 Raw(b'\xa5' * 1440))
135
136 rxs = self.send_and_expect(self.pg2, 100*[p60], self.pg0)
137
138 for rx in rxs:
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]))
146
147 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200148 # Send jumbo frame with gso enabled and DF bit is set
149 # input and output interfaces support GSO
150 #
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200151 self.vapi.feature_gso_enable_disable(self.pg3.sw_if_index)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200152 p41 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
153 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4,
154 flags='DF') /
155 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200156 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200157
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200158 rxs = self.send_and_expect(self.pg2, 100*[p41], self.pg3, 100)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200159
160 for rx in rxs:
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)
168
169 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000170 # ipv6
171 #
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))
176
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200177 rxs = self.send_and_expect(self.pg2, 100*[p61], self.pg3, 100)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000178
179 for rx in rxs:
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)
187
188 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200189 # Send jumbo frame with gso enabled only on input interface
190 # and DF bit is set. GSO packet will be chunked into gso_size
191 # data payload
192 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000193 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200194 p42 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000195 IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200196 flags='DF') /
197 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200198 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200199
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200200 rxs = self.send_and_expect(self.pg2, 5*[p42], self.pg0, 225)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200201 size = 0
202 for rx in rxs:
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000203 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
204 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200205 self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000206 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200207 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)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200210 self.assertEqual(rx[TCP].sport, 1234)
211 self.assertEqual(rx[TCP].dport, 1234)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200212 self.assertEqual(payload_len, len(rx[Raw]))
213 size += payload_len
214 self.assertEqual(size, 65200*5)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200215
216 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000217 # ipv6
218 #
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))
223
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200224 rxs = self.send_and_expect(self.pg2, 5*[p62], self.pg0, 225)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000225 size = 0
226 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200231 payload_len = rx[IPv6].plen - 20
232 self.assert_tcp_checksum_valid(rx)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000233 self.assertEqual(rx[TCP].sport, 1234)
234 self.assertEqual(rx[TCP].dport, 1234)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200235 self.assertEqual(payload_len, len(rx[Raw]))
236 size += payload_len
237 self.assertEqual(size, 65200*5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000238
239 #
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200240 # Send jumbo frame with gso enabled only on input interface
241 # and DF bit is unset. GSO packet will be fragmented.
242 #
243 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000244 self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200245
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) /
Ole Troan29156492019-10-18 15:26:25 +0200249 Raw(b'\xa5' * 65200))
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200250
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200251 rxs = self.send_and_expect(self.pg2, 5*[p43], self.pg1, 5*119)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200252 size = 0
253 for rx in rxs:
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200254 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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200258 self.assert_ip_checksum_valid(rx)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200259 size += rx[IP].len - 20
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200260 size -= 20*5 # TCP header
261 self.assertEqual(size, 65200*5)
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200262
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200263 #
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000264 # IPv6
265 # Send jumbo frame with gso enabled only on input interface.
266 # ICMPv6 Packet Too Big will be sent back to sender.
267 #
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))
273
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200274 rxs = self.send_and_expect(self.pg2, 5*[p63], self.pg2, 5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000275 for rx in rxs:
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)
286
287 #
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200288 # Send jumbo frame with gso enabled only on input interface with 9K MTU
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000289 # 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
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200291 #
292 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000293 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) /
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200296 TCP(sport=1234, dport=1234) /
Ole Troan29156492019-10-18 15:26:25 +0200297 Raw(b'\xa5' * 65200))
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200298
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200299 rxs = self.send_and_expect(self.pg4, 5*[p44], self.pg1, 165)
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200300 size = 0
301 for rx in rxs:
302 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
303 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000304 self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200305 self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200306 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]))
310 size += payload_len
311 self.assertEqual(size, 65200*5)
Mohsin Kazmi3f1964d2019-08-22 18:40:28 +0200312
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000313 #
314 # IPv6
315 #
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))
320
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200321 rxs = self.send_and_expect(self.pg4, 5*[p64], self.pg1, 170)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000322 size = 0
323 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200328 payload_len = rx[IPv6].plen - 20
329 self.assert_tcp_checksum_valid(rx)
330 self.assertEqual(payload_len, len(rx[Raw]))
331 size += payload_len
332 self.assertEqual(size, 65200*5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000333
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000334 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
335 enable_disable=0)
336 self.vapi.feature_gso_enable_disable(self.pg1.sw_if_index,
337 enable_disable=0)
338
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000339 def test_gso_vxlan(self):
340 """ GSO VXLAN test """
341 self.logger.info(self.vapi.cli("sh int addr"))
342 #
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
345 # into BD.
346 #
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200347
348 #
349 # enable ipv4/vxlan
350 #
351 self.vxlan.add_vpp_config()
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000352 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)
357
358 #
359 # IPv4/IPv4 - VXLAN
360 #
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))
365
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200366 rxs = self.send_and_expect(self.pg2, 5*[p45], self.pg0, 225)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000367 size = 0
368 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200373 self.assert_ip_checksum_valid(rx)
374 self.assert_udp_checksum_valid(rx)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000375 self.assertEqual(rx[VXLAN].vni, 10)
376 inner = rx[VXLAN].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200377 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000378 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")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200382 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]))
386 size += payload_len
387 self.assertEqual(size, 65200*5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000388
389 #
390 # IPv4/IPv6 - VXLAN
391 #
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))
396
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200397 rxs = self.send_and_expect(self.pg2, 5*[p65], self.pg0, 225)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000398 size = 0
399 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200404 self.assert_ip_checksum_valid(rx)
405 self.assert_udp_checksum_valid(rx)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000406 self.assertEqual(rx[VXLAN].vni, 10)
407 inner = rx[VXLAN].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200408 self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000409 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")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200413 self.assert_tcp_checksum_valid(inner)
414 payload_len = inner[IPv6].plen - 20
415 self.assertEqual(payload_len, len(inner[Raw]))
416 size += payload_len
417 self.assertEqual(size, 65200*5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000418
419 #
420 # disable ipv4/vxlan
421 #
422 self.vxlan.remove_vpp_config()
423
424 #
425 # enable ipv6/vxlan
426 #
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200427 self.vxlan2.add_vpp_config()
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000428 self.vapi.sw_interface_set_l2_bridge(
429 rx_sw_if_index=self.vxlan2.sw_if_index,
430 bd_id=self.single_tunnel_bd)
431
432 #
433 # IPv6/IPv4 - VXLAN
434 #
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))
439
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200440 rxs = self.send_and_expect(self.pg2, 5*[p46], self.pg0, 225)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000441 size = 0
442 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200447 self.assert_udp_checksum_valid(rx)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000448 self.assertEqual(rx[VXLAN].vni, 10)
449 inner = rx[VXLAN].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200450 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000451 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")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200455 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]))
459 size += payload_len
460 self.assertEqual(size, 65200*5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000461
462 #
463 # IPv6/IPv6 - VXLAN
464 #
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))
469
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200470 rxs = self.send_and_expect(self.pg2, 5*[p66], self.pg0, 225)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000471 size = 0
472 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200477 self.assert_udp_checksum_valid(rx)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000478 self.assertEqual(rx[VXLAN].vni, 10)
479 inner = rx[VXLAN].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200480 self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000481 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")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200485 self.assert_tcp_checksum_valid(inner)
486 payload_len = inner[IPv6].plen - 20
487 self.assertEqual(payload_len, len(inner[Raw]))
488 size += payload_len
489 self.assertEqual(size, 65200*5)
Mohsin Kazmi0b042092020-04-17 16:50:56 +0000490
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200491 #
492 # disable ipv4/vxlan
493 #
494 self.vxlan2.remove_vpp_config()
495
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000496 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
497 enable_disable=0)
498
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200499 def test_gso_ipip(self):
500 """ GSO IPIP test """
501 self.logger.info(self.vapi.cli("sh int addr"))
502 #
503 # Send jumbo frame with gso enabled only on input interface and
504 # create IPIP tunnel on VPP pg0.
505 #
506 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
507
508 #
509 # enable ipip4
510 #
511 self.ipip4.add_vpp_config()
512
513 # Set interface up and enable IP on it
514 self.ipip4.admin_up()
515 self.ipip4.set_unnumbered(self.pg0.sw_if_index)
516
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()
524
525 #
526 # IPv4/IPv4 - IPIP
527 #
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))
532
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200533 rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200534 size = 0
535 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200540 self.assert_ip_checksum_valid(rx)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200541 self.assertEqual(rx[IP].proto, 4) # ipencap
542 inner = rx[IP].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200543 self.assertEqual(rx[IP].len - 20, len(inner))
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200544 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
545 self.assertEqual(inner[IP].dst, "172.16.10.3")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200546 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]))
550 size += payload_len
551 self.assertEqual(size, 65200*5)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200552
553 self.ip6_via_ip4_tunnel = VppIpRoute(
554 self, "fd01:10::", 64,
555 [VppRoutePath("::",
556 self.ipip4.sw_if_index,
557 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
558 self.ip6_via_ip4_tunnel.add_vpp_config()
559 #
560 # IPv4/IPv6 - IPIP
561 #
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))
566
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200567 rxs = self.send_and_expect(self.pg2, 5*[p67], self.pg0, 225)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200568 size = 0
569 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200574 self.assert_ip_checksum_valid(rx)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200575 self.assertEqual(rx[IP].proto, 41) # ipv6
576 inner = rx[IP].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200577 self.assertEqual(rx[IP].len - 20, len(inner))
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200578 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
579 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200580 self.assert_tcp_checksum_valid(inner)
581 payload_len = inner[IPv6].plen - 20
582 self.assertEqual(payload_len, len(inner[Raw]))
583 size += payload_len
584 self.assertEqual(size, 65200*5)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200585
586 #
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
590 #
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000591 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
592 enable_disable=0)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200593 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index)
594
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200595 rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200596 size = 0
597 for rx in rxs:
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)
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200602 self.assert_ip_checksum_valid(rx)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200603 self.assertEqual(rx[IP].proto, 4) # ipencap
604 inner = rx[IP].payload
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200605 self.assertEqual(rx[IP].len - 20, len(inner))
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200606 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
607 self.assertEqual(inner[IP].dst, "172.16.10.3")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200608 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]))
612 size += payload_len
613 self.assertEqual(size, 65200*5)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200614
615 #
616 # disable ipip4
617 #
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000618 self.vapi.feature_gso_enable_disable(self.ipip4.sw_if_index,
619 enable_disable=0)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200620 self.ip4_via_ip4_tunnel.remove_vpp_config()
621 self.ip6_via_ip4_tunnel.remove_vpp_config()
622 self.ipip4.remove_vpp_config()
623
624 #
625 # enable ipip6
626 #
627 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index)
628 self.ipip6.add_vpp_config()
629
630 # Set interface up and enable IP on it
631 self.ipip6.admin_up()
632 self.ipip6.set_unnumbered(self.pg0.sw_if_index)
633
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()
641
642 #
643 # IPv6/IPv4 - IPIP
644 #
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))
649
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200650 rxs = self.send_and_expect(self.pg2, 5*[p48], self.pg0, 225)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200651 size = 0
652 for rx in rxs:
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
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200659 self.assertEqual(rx[IPv6].plen, len(inner))
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200660 self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
661 self.assertEqual(inner[IP].dst, "172.16.10.3")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200662 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]))
666 size += payload_len
667 self.assertEqual(size, 65200*5)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200668
669 self.ip6_via_ip6_tunnel = VppIpRoute(
670 self, "fd01:10::", 64,
671 [VppRoutePath("::",
672 self.ipip6.sw_if_index,
673 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
674 self.ip6_via_ip6_tunnel.add_vpp_config()
675
676 #
677 # IPv6/IPv6 - IPIP
678 #
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))
683
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200684 rxs = self.send_and_expect(self.pg2, 5*[p68], self.pg0, 225)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200685 size = 0
686 for rx in rxs:
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
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200693 self.assertEqual(rx[IPv6].plen, len(inner))
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200694 self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
695 self.assertEqual(inner[IPv6].dst, "fd01:10::3")
Mohsin Kazmiadf62092020-05-28 20:49:46 +0200696 self.assert_tcp_checksum_valid(inner)
697 payload_len = inner[IPv6].plen - 20
698 self.assertEqual(payload_len, len(inner[Raw]))
699 size += payload_len
700 self.assertEqual(size, 65200*5)
Mohsin Kazmi84f91fa2020-04-23 17:59:49 +0200701
702 #
703 # disable ipip6
704 #
705 self.ip4_via_ip6_tunnel.remove_vpp_config()
706 self.ip6_via_ip6_tunnel.remove_vpp_config()
707 self.ipip6.remove_vpp_config()
708
Mohsin Kazmi1ab8b3c2020-05-05 10:31:17 +0000709 self.vapi.feature_gso_enable_disable(self.pg0.sw_if_index,
710 enable_disable=0)
711
Mohsin Kazmi22e9cfd2019-07-23 11:54:48 +0200712if __name__ == '__main__':
713 unittest.main(testRunner=VppTestRunner)