tests: refactor. Replace literal constant w/ named constant.
[vpp.git] / test / test_udp.py
1 #!/usr/bin/env python
2 import unittest
3 from framework import VppTestCase, VppTestRunner
4 from vpp_udp_encap import find_udp_encap, VppUdpEncap
5 from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, VppMplsLabel
6
7 from scapy.packet import Raw
8 from scapy.layers.l2 import Ether
9 from scapy.layers.inet import IP, UDP
10 from scapy.layers.inet6 import IPv6
11 from scapy.contrib.mpls import MPLS
12
13 NUM_PKTS = 67
14
15
16 class TestUdpEncap(VppTestCase):
17     """ UDP Encap Test Case """
18
19     @classmethod
20     def setUpClass(cls):
21         super(TestUdpEncap, cls).setUpClass()
22
23     @classmethod
24     def tearDownClass(cls):
25         super(TestUdpEncap, cls).tearDownClass()
26
27     def setUp(self):
28         super(TestUdpEncap, self).setUp()
29
30         # create 2 pg interfaces
31         self.create_pg_interfaces(range(4))
32
33         # setup interfaces
34         # assign them different tables.
35         table_id = 0
36         self.tables = []
37
38         for i in self.pg_interfaces:
39             i.admin_up()
40
41             if table_id != 0:
42                 tbl = VppIpTable(self, table_id)
43                 tbl.add_vpp_config()
44                 self.tables.append(tbl)
45                 tbl = VppIpTable(self, table_id, is_ip6=1)
46                 tbl.add_vpp_config()
47                 self.tables.append(tbl)
48
49             i.set_table_ip4(table_id)
50             i.set_table_ip6(table_id)
51             i.config_ip4()
52             i.resolve_arp()
53             i.config_ip6()
54             i.resolve_ndp()
55             table_id += 1
56
57     def tearDown(self):
58         for i in self.pg_interfaces:
59             i.unconfig_ip4()
60             i.unconfig_ip6()
61             i.ip6_disable()
62             i.set_table_ip4(0)
63             i.set_table_ip6(0)
64             i.admin_down()
65         super(TestUdpEncap, self).tearDown()
66
67     def validate_outer4(self, rx, encap_obj):
68         self.assertEqual(rx[IP].src, encap_obj.src_ip_s)
69         self.assertEqual(rx[IP].dst, encap_obj.dst_ip_s)
70         self.assertEqual(rx[UDP].sport, encap_obj.src_port)
71         self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
72
73     def validate_outer6(self, rx, encap_obj):
74         self.assertEqual(rx[IPv6].src, encap_obj.src_ip_s)
75         self.assertEqual(rx[IPv6].dst, encap_obj.dst_ip_s)
76         self.assertEqual(rx[UDP].sport, encap_obj.src_port)
77         self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
78
79     def validate_inner4(self, rx, tx, ttl=None):
80         self.assertEqual(rx[IP].src, tx[IP].src)
81         self.assertEqual(rx[IP].dst, tx[IP].dst)
82         if ttl:
83             self.assertEqual(rx[IP].ttl, ttl)
84         else:
85             self.assertEqual(rx[IP].ttl, tx[IP].ttl)
86
87     def validate_inner6(self, rx, tx):
88         self.assertEqual(rx.src, tx[IPv6].src)
89         self.assertEqual(rx.dst, tx[IPv6].dst)
90         self.assertEqual(rx.hlim, tx[IPv6].hlim)
91
92     def test_udp_encap(self):
93         """ UDP Encap test
94         """
95
96         #
97         # construct a UDP encap object through each of the peers
98         # v4 through the first two peers, v6 through the second.
99         #
100         udp_encap_0 = VppUdpEncap(self,
101                                   self.pg0.local_ip4,
102                                   self.pg0.remote_ip4,
103                                   330, 440)
104         udp_encap_1 = VppUdpEncap(self,
105                                   self.pg1.local_ip4,
106                                   self.pg1.remote_ip4,
107                                   331, 441,
108                                   table_id=1)
109         udp_encap_2 = VppUdpEncap(self,
110                                   self.pg2.local_ip6,
111                                   self.pg2.remote_ip6,
112                                   332, 442,
113                                   table_id=2)
114         udp_encap_3 = VppUdpEncap(self,
115                                   self.pg3.local_ip6,
116                                   self.pg3.remote_ip6,
117                                   333, 443,
118                                   table_id=3)
119         udp_encap_0.add_vpp_config()
120         udp_encap_1.add_vpp_config()
121         udp_encap_2.add_vpp_config()
122         udp_encap_3.add_vpp_config()
123
124         self.logger.info(self.vapi.cli("sh udp encap"))
125
126         self.assertTrue(find_udp_encap(self, udp_encap_2))
127         self.assertTrue(find_udp_encap(self, udp_encap_3))
128         self.assertTrue(find_udp_encap(self, udp_encap_0))
129         self.assertTrue(find_udp_encap(self, udp_encap_1))
130
131         #
132         # Routes via each UDP encap object - all combinations of v4 and v6.
133         #
134         route_4o4 = VppIpRoute(self, "1.1.0.1", 32,
135                                [VppRoutePath("0.0.0.0",
136                                              0xFFFFFFFF,
137                                              is_udp_encap=1,
138                                              next_hop_id=udp_encap_0.id)])
139         route_4o6 = VppIpRoute(self, "1.1.2.1", 32,
140                                [VppRoutePath("0.0.0.0",
141                                              0xFFFFFFFF,
142                                              is_udp_encap=1,
143                                              next_hop_id=udp_encap_2.id)])
144         route_6o4 = VppIpRoute(self, "2001::1", 128,
145                                [VppRoutePath("0.0.0.0",
146                                              0xFFFFFFFF,
147                                              is_udp_encap=1,
148                                              next_hop_id=udp_encap_1.id)],
149                                is_ip6=1)
150         route_6o6 = VppIpRoute(self, "2001::3", 128,
151                                [VppRoutePath("0.0.0.0",
152                                              0xFFFFFFFF,
153                                              is_udp_encap=1,
154                                              next_hop_id=udp_encap_3.id)],
155                                is_ip6=1)
156         route_4o4.add_vpp_config()
157         route_4o6.add_vpp_config()
158         route_6o6.add_vpp_config()
159         route_6o4.add_vpp_config()
160
161         #
162         # 4o4 encap
163         #
164         p_4o4 = (Ether(src=self.pg0.remote_mac,
165                        dst=self.pg0.local_mac) /
166                  IP(src="2.2.2.2", dst="1.1.0.1") /
167                  UDP(sport=1234, dport=1234) /
168                  Raw('\xa5' * 100))
169         rx = self.send_and_expect(self.pg0, p_4o4*NUM_PKTS, self.pg0)
170         for p in rx:
171             self.validate_outer4(p, udp_encap_0)
172             p = IP(p["UDP"].payload.load)
173             self.validate_inner4(p, p_4o4)
174         self.assertEqual(udp_encap_0.get_stats()['packets'], NUM_PKTS)
175
176         #
177         # 4o6 encap
178         #
179         p_4o6 = (Ether(src=self.pg0.remote_mac,
180                        dst=self.pg0.local_mac) /
181                  IP(src="2.2.2.2", dst="1.1.2.1") /
182                  UDP(sport=1234, dport=1234) /
183                  Raw('\xa5' * 100))
184         rx = self.send_and_expect(self.pg0, p_4o6*NUM_PKTS, self.pg2)
185         for p in rx:
186             self.validate_outer6(p, udp_encap_2)
187             p = IP(p["UDP"].payload.load)
188             self.validate_inner4(p, p_4o6)
189         self.assertEqual(udp_encap_2.get_stats()['packets'], NUM_PKTS)
190
191         #
192         # 6o4 encap
193         #
194         p_6o4 = (Ether(src=self.pg0.remote_mac,
195                        dst=self.pg0.local_mac) /
196                  IPv6(src="2001::100", dst="2001::1") /
197                  UDP(sport=1234, dport=1234) /
198                  Raw('\xa5' * 100))
199         rx = self.send_and_expect(self.pg0, p_6o4*NUM_PKTS, self.pg1)
200         for p in rx:
201             self.validate_outer4(p, udp_encap_1)
202             p = IPv6(p["UDP"].payload.load)
203             self.validate_inner6(p, p_6o4)
204         self.assertEqual(udp_encap_1.get_stats()['packets'], NUM_PKTS)
205
206         #
207         # 6o6 encap
208         #
209         p_6o6 = (Ether(src=self.pg0.remote_mac,
210                        dst=self.pg0.local_mac) /
211                  IPv6(src="2001::100", dst="2001::3") /
212                  UDP(sport=1234, dport=1234) /
213                  Raw('\xa5' * 100))
214         rx = self.send_and_expect(self.pg0, p_6o6*NUM_PKTS, self.pg3)
215         for p in rx:
216             self.validate_outer6(p, udp_encap_3)
217             p = IPv6(p["UDP"].payload.load)
218             self.validate_inner6(p, p_6o6)
219         self.assertEqual(udp_encap_3.get_stats()['packets'], NUM_PKTS)
220
221         #
222         # A route with an output label
223         # the TTL of the inner packet is decremented on LSP ingress
224         #
225         route_4oMPLSo4 = VppIpRoute(self, "1.1.2.22", 32,
226                                     [VppRoutePath("0.0.0.0",
227                                                   0xFFFFFFFF,
228                                                   is_udp_encap=1,
229                                                   next_hop_id=1,
230                                                   labels=[VppMplsLabel(66)])])
231         route_4oMPLSo4.add_vpp_config()
232
233         p_4omo4 = (Ether(src=self.pg0.remote_mac,
234                          dst=self.pg0.local_mac) /
235                    IP(src="2.2.2.2", dst="1.1.2.22") /
236                    UDP(sport=1234, dport=1234) /
237                    Raw('\xa5' * 100))
238         rx = self.send_and_expect(self.pg0, p_4omo4*NUM_PKTS, self.pg1)
239         for p in rx:
240             self.validate_outer4(p, udp_encap_1)
241             p = MPLS(p["UDP"].payload.load)
242             self.validate_inner4(p, p_4omo4, ttl=63)
243         self.assertEqual(udp_encap_1.get_stats()['packets'], 2*NUM_PKTS)
244
245
246 class TestUDP(VppTestCase):
247     """ UDP Test Case """
248
249     @classmethod
250     def setUpClass(cls):
251         super(TestUDP, cls).setUpClass()
252
253     @classmethod
254     def tearDownClass(cls):
255         super(TestUDP, cls).tearDownClass()
256
257     def setUp(self):
258         super(TestUDP, self).setUp()
259         self.vapi.session_enable_disable(is_enabled=1)
260         self.create_loopback_interfaces(2)
261
262         table_id = 0
263
264         for i in self.lo_interfaces:
265             i.admin_up()
266
267             if table_id != 0:
268                 tbl = VppIpTable(self, table_id)
269                 tbl.add_vpp_config()
270
271             i.set_table_ip4(table_id)
272             i.config_ip4()
273             table_id += 1
274
275         # Configure namespaces
276         self.vapi.app_namespace_add_del(namespace_id="0",
277                                         sw_if_index=self.loop0.sw_if_index)
278         self.vapi.app_namespace_add_del(namespace_id="1",
279                                         sw_if_index=self.loop1.sw_if_index)
280
281     def tearDown(self):
282         for i in self.lo_interfaces:
283             i.unconfig_ip4()
284             i.set_table_ip4(0)
285             i.admin_down()
286         self.vapi.session_enable_disable(is_enabled=0)
287         super(TestUDP, self).tearDown()
288
289     def test_udp_transfer(self):
290         """ UDP echo client/server transfer """
291
292         # Add inter-table routes
293         ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
294                             [VppRoutePath("0.0.0.0",
295                                           0xffffffff,
296                                           nh_table_id=1)])
297         ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
298                             [VppRoutePath("0.0.0.0",
299                                           0xffffffff,
300                                           nh_table_id=0)], table_id=1)
301         ip_t01.add_vpp_config()
302         ip_t10.add_vpp_config()
303
304         # Start builtin server and client
305         uri = "udp://" + self.loop0.local_ip4 + "/1234"
306         error = self.vapi.cli("test echo server appns 0 fifo-size 4 no-echo" +
307                               "uri " + uri)
308         if error:
309             self.logger.critical(error)
310             self.assertNotIn("failed", error)
311
312         error = self.vapi.cli("test echo client mbytes 10 appns 1 " +
313                               "fifo-size 4 no-output test-bytes " +
314                               "syn-timeout 2 no-return uri " + uri)
315         if error:
316             self.logger.critical(error)
317             self.assertNotIn("failed", error)
318
319         # Delete inter-table routes
320         ip_t01.remove_vpp_config()
321         ip_t10.remove_vpp_config()
322
323
324 if __name__ == '__main__':
325     unittest.main(testRunner=VppTestRunner)