Typos. A bunch of typos I've been collecting.
[vpp.git] / test / test_pipe.py
1 #!/usr/bin/env python
2 from socket import AF_INET, AF_INET6, inet_pton
3
4 from framework import VppTestCase, VppTestRunner
5 from vpp_interface import VppInterface
6 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
7
8 from scapy.packet import Raw
9 from scapy.layers.l2 import Ether
10 from scapy.layers.inet import IP, UDP
11
12
13 class VppPipe(VppInterface):
14     """
15     VPP Pipe
16     """
17
18     @property
19     def east(self):
20         return self.result.pipe_sw_if_index[1]
21
22     @property
23     def west(self):
24         return self.result.pipe_sw_if_index[0]
25
26     def __init__(self, test, instance=0xffffffff):
27         super(VppPipe, self).__init__(test)
28         self._test = test
29         self.instance = instance
30
31     def add_vpp_config(self):
32         self.result = self._test.vapi.pipe_create(
33             0 if self.instance == 0xffffffff else 1,
34             self.instance)
35         self.set_sw_if_index(self.result.sw_if_index)
36
37     def remove_vpp_config(self):
38         self._test.vapi.pipe_delete(
39             self.result.sw_if_index)
40
41     def __str__(self):
42         return self.object_id()
43
44     def object_id(self):
45         return "pipe-%d" % (self._sw_if_index)
46
47     def query_vpp_config(self):
48         pipes = self._test.vapi.pipe_dump()
49         for p in pipes:
50             if p.sw_if_index == self.result.sw_if_index:
51                 return True
52         return False
53
54     def set_unnumbered(self, ip_sw_if_index, is_add=True):
55         res = self._test.vapi.sw_interface_set_unnumbered(ip_sw_if_index,
56                                                           self.east, is_add)
57         res = self._test.vapi.sw_interface_set_unnumbered(ip_sw_if_index,
58                                                           self.west, is_add)
59
60
61 class TestPipe(VppTestCase):
62     """ Pipes """
63
64     def setUp(self):
65         super(TestPipe, self).setUp()
66
67         self.create_pg_interfaces(range(4))
68
69         for i in self.pg_interfaces:
70             i.admin_up()
71
72     def tearDown(self):
73         for i in self.pg_interfaces:
74             i.admin_down()
75
76         super(TestPipe, self).tearDown()
77
78     def test_pipe(self):
79         """ Pipes """
80
81         pipes = [VppPipe(self), VppPipe(self, 10)]
82
83         for p in pipes:
84             p.add_vpp_config()
85             p.admin_up()
86
87         #
88         # L2 cross-connect pipe0 east with pg0 and west with pg1
89         #
90         self.vapi.sw_interface_set_l2_xconnect(self.pg0.sw_if_index,
91                                                pipes[0].east,
92                                                enable=1)
93         self.vapi.sw_interface_set_l2_xconnect(pipes[0].east,
94                                                self.pg0.sw_if_index,
95                                                enable=1)
96         self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
97                                                pipes[0].west,
98                                                enable=1)
99         self.vapi.sw_interface_set_l2_xconnect(pipes[0].west,
100                                                self.pg1.sw_if_index,
101                                                enable=1)
102
103         # test bi-directional L2 flow pg0<->pg1
104         p = (Ether(src=self.pg0.remote_mac,
105                    dst=self.pg1.remote_mac) /
106              IP(src="1.1.1.1",
107                 dst="1.1.1.2") /
108              UDP(sport=1234, dport=1234) /
109              Raw('\xa5' * 100))
110
111         self.send_and_expect(self.pg0, p * 65, self.pg1)
112         self.send_and_expect(self.pg1, p * 65, self.pg0)
113
114         #
115         # Attach ACL to ensure features are run on the pipe
116         #
117         rule_1 = ({'is_permit': 0,
118                    'is_ipv6': 0,
119                    'proto': 17,
120                    'srcport_or_icmptype_first': 1234,
121                    'srcport_or_icmptype_last': 1234,
122                    'src_ip_prefix_len': 32,
123                    'src_ip_addr': inet_pton(AF_INET, "1.1.1.1"),
124                    'dstport_or_icmpcode_first': 1234,
125                    'dstport_or_icmpcode_last': 1234,
126                    'dst_ip_prefix_len': 32,
127                    'dst_ip_addr': inet_pton(AF_INET, "1.1.1.2")})
128         acl = self.vapi.acl_add_replace(acl_index=4294967295,
129                                         r=[rule_1])
130
131         # Apply the ACL on the pipe on output
132         self.vapi.acl_interface_set_acl_list(pipes[0].east,
133                                              0,
134                                              [acl.acl_index])
135         self.send_and_assert_no_replies(self.pg0, p * 65)
136         self.send_and_expect(self.pg1, p * 65, self.pg0)
137
138         # remove from output and apply on input
139         self.vapi.acl_interface_set_acl_list(pipes[0].east,
140                                              0,
141                                              [])
142         self.vapi.acl_interface_set_acl_list(pipes[0].west,
143                                              1,
144                                              [acl.acl_index])
145         self.send_and_assert_no_replies(self.pg0, p * 65)
146         self.send_and_expect(self.pg1, p * 65, self.pg0)
147         self.vapi.acl_interface_set_acl_list(pipes[0].west,
148                                              0,
149                                              [])
150         self.send_and_expect(self.pg0, p * 65, self.pg1)
151         self.send_and_expect(self.pg1, p * 65, self.pg0)
152
153         #
154         # L3 routes in two separate tables so a pipe can be used to L3
155         # x-connect
156         #
157         tables = []
158         tables.append(VppIpTable(self, 1))
159         tables.append(VppIpTable(self, 2))
160
161         for t in tables:
162             t.add_vpp_config()
163
164         self.pg2.set_table_ip4(1)
165         self.pg2.config_ip4()
166         self.pg2.resolve_arp()
167         self.pg3.set_table_ip4(2)
168         self.pg3.config_ip4()
169         self.pg3.resolve_arp()
170
171         routes = []
172         routes.append(VppIpRoute(self, "1.1.1.1", 32,
173                                  [VppRoutePath(self.pg3.remote_ip4,
174                                                self.pg3.sw_if_index)],
175                                  table_id=2))
176         routes.append(VppIpRoute(self, "1.1.1.1", 32,
177                                  [VppRoutePath("0.0.0.0", pipes[1].east)],
178                                  table_id=1))
179         routes.append(VppIpRoute(self, "1.1.1.2", 32,
180                                  [VppRoutePath("0.0.0.0", pipes[1].west)],
181                                  table_id=2))
182         routes.append(VppIpRoute(self, "1.1.1.2", 32,
183                                  [VppRoutePath(self.pg2.remote_ip4,
184                                                self.pg2.sw_if_index)],
185                                  table_id=1))
186
187         for r in routes:
188             r.add_vpp_config()
189
190         p_east = (Ether(src=self.pg2.remote_mac,
191                         dst=self.pg2.local_mac) /
192                   IP(src="1.1.1.2",
193                      dst="1.1.1.1") /
194                   UDP(sport=1234, dport=1234) /
195                   Raw('\xa5' * 100))
196
197         # bind the pipe ends to the correct tables
198         self.vapi.sw_interface_set_table(pipes[1].west, 0, 2)
199         self.vapi.sw_interface_set_table(pipes[1].east, 0, 1)
200
201         # IP is not enabled on the pipes at this point
202         self.send_and_assert_no_replies(self.pg2, p_east * 65)
203
204         # IP enable the Pipes by making them unnumbered
205         pipes[0].set_unnumbered(self.pg2.sw_if_index)
206         pipes[1].set_unnumbered(self.pg3.sw_if_index)
207
208         self.send_and_expect(self.pg2, p_east * 65, self.pg3)
209
210         # and the return path
211         p_west = (Ether(src=self.pg3.remote_mac,
212                         dst=self.pg3.local_mac) /
213                   IP(src="1.1.1.1",
214                      dst="1.1.1.2") /
215                   UDP(sport=1234, dport=1234) /
216                   Raw('\xa5' * 100))
217         self.send_and_expect(self.pg3, p_west * 65, self.pg2)
218
219         #
220         # Use ACLs to test features run on the Pipes
221         #
222         self.vapi.acl_interface_set_acl_list(pipes[1].east,
223                                              0,
224                                              [acl.acl_index])
225         self.send_and_assert_no_replies(self.pg2, p_east * 65)
226         self.send_and_expect(self.pg3, p_west * 65, self.pg2)
227
228         # remove from output and apply on input
229         self.vapi.acl_interface_set_acl_list(pipes[1].east,
230                                              0,
231                                              [])
232         self.vapi.acl_interface_set_acl_list(pipes[1].west,
233                                              1,
234                                              [acl.acl_index])
235         self.send_and_assert_no_replies(self.pg2, p_east * 65)
236         self.send_and_expect(self.pg3, p_west * 65, self.pg2)
237         self.vapi.acl_interface_set_acl_list(pipes[1].west,
238                                              0,
239                                              [])
240         self.send_and_expect(self.pg2, p_east * 65, self.pg3)
241         self.send_and_expect(self.pg3, p_west * 65, self.pg2)
242
243         # cleanup (so the tables delete)
244         self.pg2.unconfig_ip4()
245         self.pg2.set_table_ip4(0)
246         self.pg3.unconfig_ip4()
247         self.pg3.set_table_ip4(0)
248         self.vapi.sw_interface_set_table(pipes[1].west, 0, 0)
249         self.vapi.sw_interface_set_table(pipes[1].east, 0, 0)
250
251
252 if __name__ == '__main__':
253     unittest.main(testRunner=VppTestRunner)