3 from framework import VppTestCase, VppTestRunner
5 from vpp_udp_encap import find_udp_encap, VppUdpEncap
6 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, VppMplsLabel, \
9 from scapy.packet import Raw
10 from scapy.layers.l2 import Ether
11 from scapy.layers.inet import IP, UDP
12 from scapy.layers.inet6 import IPv6
13 from scapy.contrib.mpls import MPLS
18 class TestUdpEncap(VppTestCase):
19 """ UDP Encap Test Case """
23 super(TestUdpEncap, cls).setUpClass()
26 def tearDownClass(cls):
27 super(TestUdpEncap, cls).tearDownClass()
30 super(TestUdpEncap, self).setUp()
32 # create 2 pg interfaces
33 self.create_pg_interfaces(range(4))
36 # assign them different tables.
40 for i in self.pg_interfaces:
44 tbl = VppIpTable(self, table_id)
46 self.tables.append(tbl)
47 tbl = VppIpTable(self, table_id, is_ip6=1)
49 self.tables.append(tbl)
51 i.set_table_ip4(table_id)
52 i.set_table_ip6(table_id)
60 for i in self.pg_interfaces:
67 super(TestUdpEncap, self).tearDown()
69 def validate_outer4(self, rx, encap_obj):
70 self.assertEqual(rx[IP].src, encap_obj.src_ip_s)
71 self.assertEqual(rx[IP].dst, encap_obj.dst_ip_s)
72 self.assertEqual(rx[UDP].sport, encap_obj.src_port)
73 self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
75 def validate_outer6(self, rx, encap_obj):
76 self.assertEqual(rx[IPv6].src, encap_obj.src_ip_s)
77 self.assertEqual(rx[IPv6].dst, encap_obj.dst_ip_s)
78 self.assertEqual(rx[UDP].sport, encap_obj.src_port)
79 self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
81 def validate_inner4(self, rx, tx, ttl=None):
82 self.assertEqual(rx[IP].src, tx[IP].src)
83 self.assertEqual(rx[IP].dst, tx[IP].dst)
85 self.assertEqual(rx[IP].ttl, ttl)
87 self.assertEqual(rx[IP].ttl, tx[IP].ttl)
89 def validate_inner6(self, rx, tx):
90 self.assertEqual(rx.src, tx[IPv6].src)
91 self.assertEqual(rx.dst, tx[IPv6].dst)
92 self.assertEqual(rx.hlim, tx[IPv6].hlim)
94 def test_udp_encap(self):
99 # construct a UDP encap object through each of the peers
100 # v4 through the first two peers, v6 through the second.
102 udp_encap_0 = VppUdpEncap(self,
106 udp_encap_1 = VppUdpEncap(self,
111 udp_encap_2 = VppUdpEncap(self,
116 udp_encap_3 = VppUdpEncap(self,
121 udp_encap_0.add_vpp_config()
122 udp_encap_1.add_vpp_config()
123 udp_encap_2.add_vpp_config()
124 udp_encap_3.add_vpp_config()
126 self.logger.info(self.vapi.cli("sh udp encap"))
128 self.assertTrue(find_udp_encap(self, udp_encap_2))
129 self.assertTrue(find_udp_encap(self, udp_encap_3))
130 self.assertTrue(find_udp_encap(self, udp_encap_0))
131 self.assertTrue(find_udp_encap(self, udp_encap_1))
134 # Routes via each UDP encap object - all combinations of v4 and v6.
136 route_4o4 = VppIpRoute(
138 [VppRoutePath("0.0.0.0",
140 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
141 next_hop_id=udp_encap_0.id)])
142 route_4o6 = VppIpRoute(
144 [VppRoutePath("0.0.0.0",
146 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
147 next_hop_id=udp_encap_2.id)])
148 route_6o4 = VppIpRoute(
149 self, "2001::1", 128,
150 [VppRoutePath("0.0.0.0",
152 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
153 next_hop_id=udp_encap_1.id)])
154 route_6o6 = VppIpRoute(
155 self, "2001::3", 128,
156 [VppRoutePath("0.0.0.0",
158 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
159 next_hop_id=udp_encap_3.id)])
160 route_4o6.add_vpp_config()
161 route_6o6.add_vpp_config()
162 route_6o4.add_vpp_config()
163 route_4o4.add_vpp_config()
168 p_4o4 = (Ether(src=self.pg0.remote_mac,
169 dst=self.pg0.local_mac) /
170 IP(src="2.2.2.2", dst="1.1.0.1") /
171 UDP(sport=1234, dport=1234) /
173 rx = self.send_and_expect(self.pg0, p_4o4*NUM_PKTS, self.pg0)
175 self.validate_outer4(p, udp_encap_0)
176 p = IP(p["UDP"].payload.load)
177 self.validate_inner4(p, p_4o4)
178 self.assertEqual(udp_encap_0.get_stats()['packets'], NUM_PKTS)
183 p_4o6 = (Ether(src=self.pg0.remote_mac,
184 dst=self.pg0.local_mac) /
185 IP(src="2.2.2.2", dst="1.1.2.1") /
186 UDP(sport=1234, dport=1234) /
188 rx = self.send_and_expect(self.pg0, p_4o6*NUM_PKTS, self.pg2)
190 self.validate_outer6(p, udp_encap_2)
191 p = IP(p["UDP"].payload.load)
192 self.validate_inner4(p, p_4o6)
193 self.assertEqual(udp_encap_2.get_stats()['packets'], NUM_PKTS)
198 p_6o4 = (Ether(src=self.pg0.remote_mac,
199 dst=self.pg0.local_mac) /
200 IPv6(src="2001::100", dst="2001::1") /
201 UDP(sport=1234, dport=1234) /
203 rx = self.send_and_expect(self.pg0, p_6o4*NUM_PKTS, self.pg1)
205 self.validate_outer4(p, udp_encap_1)
206 p = IPv6(p["UDP"].payload.load)
207 self.validate_inner6(p, p_6o4)
208 self.assertEqual(udp_encap_1.get_stats()['packets'], NUM_PKTS)
213 p_6o6 = (Ether(src=self.pg0.remote_mac,
214 dst=self.pg0.local_mac) /
215 IPv6(src="2001::100", dst="2001::3") /
216 UDP(sport=1234, dport=1234) /
218 rx = self.send_and_expect(self.pg0, p_6o6*NUM_PKTS, self.pg3)
220 self.validate_outer6(p, udp_encap_3)
221 p = IPv6(p["UDP"].payload.load)
222 self.validate_inner6(p, p_6o6)
223 self.assertEqual(udp_encap_3.get_stats()['packets'], NUM_PKTS)
226 # A route with an output label
227 # the TTL of the inner packet is decremented on LSP ingress
229 route_4oMPLSo4 = VppIpRoute(
230 self, "1.1.2.22", 32,
231 [VppRoutePath("0.0.0.0",
233 type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
235 labels=[VppMplsLabel(66)])])
236 route_4oMPLSo4.add_vpp_config()
238 p_4omo4 = (Ether(src=self.pg0.remote_mac,
239 dst=self.pg0.local_mac) /
240 IP(src="2.2.2.2", dst="1.1.2.22") /
241 UDP(sport=1234, dport=1234) /
243 rx = self.send_and_expect(self.pg0, p_4omo4*NUM_PKTS, self.pg1)
245 self.validate_outer4(p, udp_encap_1)
246 p = MPLS(p["UDP"].payload.load)
247 self.validate_inner4(p, p_4omo4, ttl=63)
248 self.assertEqual(udp_encap_1.get_stats()['packets'], 2*NUM_PKTS)
251 class TestUDP(VppTestCase):
252 """ UDP Test Case """
256 super(TestUDP, cls).setUpClass()
259 def tearDownClass(cls):
260 super(TestUDP, cls).tearDownClass()
263 super(TestUDP, self).setUp()
264 self.vapi.session_enable_disable(is_enabled=1)
265 self.create_loopback_interfaces(2)
269 for i in self.lo_interfaces:
273 tbl = VppIpTable(self, table_id)
276 i.set_table_ip4(table_id)
280 # Configure namespaces
281 self.vapi.app_namespace_add_del(namespace_id="0",
282 sw_if_index=self.loop0.sw_if_index)
283 self.vapi.app_namespace_add_del(namespace_id="1",
284 sw_if_index=self.loop1.sw_if_index)
287 for i in self.lo_interfaces:
291 self.vapi.session_enable_disable(is_enabled=0)
292 super(TestUDP, self).tearDown()
294 def test_udp_transfer(self):
295 """ UDP echo client/server transfer """
297 # Add inter-table routes
298 ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
299 [VppRoutePath("0.0.0.0",
302 ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
303 [VppRoutePath("0.0.0.0",
305 nh_table_id=0)], table_id=1)
306 ip_t01.add_vpp_config()
307 ip_t10.add_vpp_config()
309 # Start builtin server and client
310 uri = "udp://" + self.loop0.local_ip4 + "/1234"
311 error = self.vapi.cli("test echo server appns 0 fifo-size 4 no-echo" +
314 self.logger.critical(error)
315 self.assertNotIn("failed", error)
317 error = self.vapi.cli("test echo client mbytes 10 appns 1 " +
318 "fifo-size 4 no-output test-bytes " +
319 "syn-timeout 2 no-return uri " + uri)
321 self.logger.critical(error)
322 self.assertNotIn("failed", error)
324 # Delete inter-table routes
325 ip_t01.remove_vpp_config()
326 ip_t10.remove_vpp_config()
329 if __name__ == '__main__':
330 unittest.main(testRunner=VppTestRunner)