blob: 427b14de5068440d000af397562b3a9b7e8fbf10 [file] [log] [blame]
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001#!/usr/bin/env python
2
3import unittest
4import socket
5import struct
6
7from framework import VppTestCase, VppTestRunner
8from vpp_object import VppObject
9
10from scapy.packet import Raw
11from scapy.layers.l2 import Ether
12from scapy.layers.inet import IP, UDP
13from scapy.layers.inet6 import IPv6
14
15from socket import AF_INET, AF_INET6
16from scapy.utils import inet_pton
17
18
19class VppGbpEndpoint(VppObject):
20 """
21 GDB Endpoint
22 """
23
24 def __init__(self, test, sw_if_index, addr, epg, is_ip6=0):
25 self._test = test
26 self.sw_if_index = sw_if_index
27 self.epg = epg
28 self.addr_p = addr
29 self.is_ip6 = is_ip6
30 if is_ip6:
31 self.addr = inet_pton(AF_INET6, addr)
32 else:
33 self.addr = inet_pton(AF_INET, addr)
34
35 def add_vpp_config(self):
36 self._test.vapi.gbp_endpoint_add_del(
37 1,
38 self.sw_if_index,
39 self.addr,
40 self.is_ip6,
41 self.epg)
42 self._test.registry.register(self, self._test.logger)
43
44 def remove_vpp_config(self):
45 self._test.vapi.gbp_endpoint_add_del(
46 0,
47 self.sw_if_index,
48 self.addr,
49 self.is_ip6,
50 self.epg)
51
52 def __str__(self):
53 return self.object_id()
54
55 def object_id(self):
56 return "gbp-endpoint;[%d:%s:%d]" % (self.sw_if_index,
57 self.addr_p,
58 self.epg)
59
60 def query_vpp_config(self):
61 eps = self._test.vapi.gbp_endpoint_dump()
62 for ep in eps:
63 if ep.endpoint.address == self.addr \
64 and ep.endpoint.sw_if_index == self.sw_if_index:
65 return True
66 return False
67
68
69class VppGbpContract(VppObject):
70 """
71 GDB Contract
72 """
73
74 def __init__(self, test, src_epg, dst_epg, acl_index):
75 self._test = test
76 self.acl_index = acl_index
77 self.src_epg = src_epg
78 self.dst_epg = dst_epg
79
80 def add_vpp_config(self):
81 self._test.vapi.gbp_contract_add_del(
82 1,
83 self.src_epg,
84 self.dst_epg,
85 self.acl_index)
86 self._test.registry.register(self, self._test.logger)
87
88 def remove_vpp_config(self):
89 self._test.vapi.gbp_contract_add_del(
90 0,
91 self.src_epg,
92 self.dst_epg,
93 self.acl_index)
94
95 def __str__(self):
96 return self.object_id()
97
98 def object_id(self):
99 return "gbp-contract;[%d:%s:%d]" % (self.src_epg,
100 self.dst_epg,
101 self.acl_index)
102
103 def query_vpp_config(self):
104 eps = self._test.vapi.gbp_contract_dump()
105 for ep in eps:
106 if ep.contract.src_epg == self.src_epg \
107 and ep.contract.dst_epg == self.dst_epg:
108 return True
109 return False
110
111
112class TestGBP(VppTestCase):
113 """ GBP Test Case """
114
115 def setUp(self):
116 super(TestGBP, self).setUp()
117
118 # create 6 pg interfaces for pg0 to pg5
119 self.create_pg_interfaces(range(6))
120
121 for i in self.pg_interfaces:
122 i.admin_up()
123 i.config_ip4()
124 i.resolve_arp()
125 i.config_ip6()
126 i.resolve_ndp()
127
128 def tearDown(self):
129 for i in self.pg_interfaces:
130 i.unconfig_ip4()
131 i.unconfig_ip6()
132
133 super(TestGBP, self).tearDown()
134
135 def test_gbp4(self):
136 """ Group Based Policy v4 """
137
138 ep1 = VppGbpEndpoint(self,
139 self.pg0.sw_if_index,
140 self.pg0.remote_ip4,
141 220)
142 ep1.add_vpp_config()
143 ep2 = VppGbpEndpoint(self,
144 self.pg1.sw_if_index,
145 self.pg1.remote_ip4,
146 220)
147 ep2.add_vpp_config()
148
149 ep3 = VppGbpEndpoint(self,
150 self.pg2.sw_if_index,
151 self.pg2.remote_ip4,
152 221)
153 ep3.add_vpp_config()
154 ep4 = VppGbpEndpoint(self,
155 self.pg3.sw_if_index,
156 self.pg3.remote_ip4,
157 222)
158 ep4.add_vpp_config()
159
160 self.logger.info(self.vapi.cli("sh gbp endpoint"))
161
162 #
163 # in the abscense of policy, endpoints in the same EPG
164 # can communicate
165 #
166 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
167 dst=self.pg0.local_mac) /
168 IP(src=self.pg0.remote_ip4,
169 dst=self.pg1.remote_ip4) /
170 UDP(sport=1234, dport=1234) /
171 Raw('\xa5' * 100))
172
173 self.send_and_expect(self.pg0, pkt_intra_epg * 65, self.pg1)
174
175 #
176 # in the abscense of policy, endpoints in the different EPG
177 # cannot communicate
178 #
179 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
180 dst=self.pg0.local_mac) /
181 IP(src=self.pg0.remote_ip4,
182 dst=self.pg2.remote_ip4) /
183 UDP(sport=1234, dport=1234) /
184 Raw('\xa5' * 100))
185 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
186 dst=self.pg0.local_mac) /
187 IP(src=self.pg0.remote_ip4,
188 dst=self.pg3.remote_ip4) /
189 UDP(sport=1234, dport=1234) /
190 Raw('\xa5' * 100))
191 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
192 dst=self.pg2.local_mac) /
193 IP(src=self.pg2.remote_ip4,
194 dst=self.pg0.remote_ip4) /
195 UDP(sport=1234, dport=1234) /
196 Raw('\xa5' * 100))
197
198 self.send_and_assert_no_replies(self.pg0,
199 pkt_inter_epg_220_to_221 * 65)
200 self.send_and_assert_no_replies(self.pg0,
201 pkt_inter_epg_221_to_220 * 65)
202
203 #
204 # A uni-directional contract from EPG 220 -> 221
205 #
206 c1 = VppGbpContract(self, 220, 221, 0xffffffff)
207 c1.add_vpp_config()
208
209 self.send_and_expect(self.pg0,
210 pkt_inter_epg_220_to_221 * 65,
211 self.pg2)
212 self.send_and_assert_no_replies(self.pg2,
213 pkt_inter_epg_221_to_220 * 65)
214
215 #
216 # contract for the return direction
217 #
218 c2 = VppGbpContract(self, 221, 220, 0xffffffff)
219 c2.add_vpp_config()
220
221 self.send_and_expect(self.pg0,
222 pkt_inter_epg_220_to_221 * 65,
223 self.pg2)
224 self.send_and_expect(self.pg2,
225 pkt_inter_epg_221_to_220 * 65,
226 self.pg0)
227
228 #
229 # check that inter group is still disabled for the groups
230 # not in the contract.
231 #
232 self.send_and_assert_no_replies(self.pg0,
233 pkt_inter_epg_220_to_222 * 65)
234
235 self.logger.info(self.vapi.cli("sh gbp contract"))
236
237 #
238 # remove both contracts, traffic stops in both directions
239 #
240 c2.remove_vpp_config()
241 c1.remove_vpp_config()
242
243 self.send_and_assert_no_replies(self.pg2,
244 pkt_inter_epg_221_to_220 * 65)
245 self.send_and_assert_no_replies(self.pg0,
246 pkt_inter_epg_220_to_221 * 65)
247 self.send_and_expect(self.pg0, pkt_intra_epg * 65, self.pg1)
248
249 def test_gbp6(self):
250 """ Group Based Policy v6 """
251
252 ep1 = VppGbpEndpoint(self,
253 self.pg0.sw_if_index,
254 self.pg0.remote_ip6,
255 220,
256 is_ip6=1)
257 ep1.add_vpp_config()
258 ep2 = VppGbpEndpoint(self,
259 self.pg1.sw_if_index,
260 self.pg1.remote_ip6,
261 220,
262 is_ip6=1)
263 ep2.add_vpp_config()
264
265 ep3 = VppGbpEndpoint(self,
266 self.pg2.sw_if_index,
267 self.pg2.remote_ip6,
268 221,
269 is_ip6=1)
270 ep3.add_vpp_config()
271 ep4 = VppGbpEndpoint(self,
272 self.pg3.sw_if_index,
273 self.pg3.remote_ip6,
274 222,
275 is_ip6=1)
276 ep4.add_vpp_config()
277
278 self.logger.info(self.vapi.cli("sh gbp endpoint"))
279
280 #
281 # in the abscense of policy, endpoints in the same EPG
282 # can communicate
283 #
284 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
285 dst=self.pg0.local_mac) /
286 IPv6(src=self.pg0.remote_ip6,
287 dst=self.pg1.remote_ip6) /
288 UDP(sport=1234, dport=1234) /
289 Raw('\xa5' * 100))
290
291 self.send_and_expect(self.pg0, pkt_intra_epg * 65, self.pg1)
292
293 #
294 # in the abscense of policy, endpoints in the different EPG
295 # cannot communicate
296 #
297 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
298 dst=self.pg0.local_mac) /
299 IPv6(src=self.pg0.remote_ip6,
300 dst=self.pg2.remote_ip6) /
301 UDP(sport=1234, dport=1234) /
302 Raw('\xa5' * 100))
303 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
304 dst=self.pg0.local_mac) /
305 IPv6(src=self.pg0.remote_ip6,
306 dst=self.pg3.remote_ip6) /
307 UDP(sport=1234, dport=1234) /
308 Raw('\xa5' * 100))
309 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
310 dst=self.pg2.local_mac) /
311 IPv6(src=self.pg2.remote_ip6,
312 dst=self.pg0.remote_ip6) /
313 UDP(sport=1234, dport=1234) /
314 Raw('\xa5' * 100))
315
316 self.send_and_assert_no_replies(self.pg0,
317 pkt_inter_epg_220_to_221 * 65)
318 self.send_and_assert_no_replies(self.pg0,
319 pkt_inter_epg_221_to_220 * 65)
320
321 #
322 # A uni-directional contract from EPG 220 -> 221
323 #
324 c1 = VppGbpContract(self, 220, 221, 0xffffffff)
325 c1.add_vpp_config()
326
327 self.send_and_expect(self.pg0,
328 pkt_inter_epg_220_to_221 * 65,
329 self.pg2)
330 self.send_and_assert_no_replies(self.pg2,
331 pkt_inter_epg_221_to_220 * 65)
332
333 #
334 # contract for the return direction
335 #
336 c2 = VppGbpContract(self, 221, 220, 0xffffffff)
337 c2.add_vpp_config()
338
339 self.send_and_expect(self.pg0,
340 pkt_inter_epg_220_to_221 * 65,
341 self.pg2)
342 self.send_and_expect(self.pg2,
343 pkt_inter_epg_221_to_220 * 65,
344 self.pg0)
345
346 #
347 # check that inter group is still disabled for the groups
348 # not in the contract.
349 #
350 self.send_and_assert_no_replies(self.pg0,
351 pkt_inter_epg_220_to_222 * 65)
352
353 self.logger.info(self.vapi.cli("sh gbp contract"))
354
355 #
356 # remove both contracts, traffic stops in both directions
357 #
358 c2.remove_vpp_config()
359 c1.remove_vpp_config()
360
361 self.send_and_assert_no_replies(self.pg2,
362 pkt_inter_epg_221_to_220 * 65)
363 self.send_and_assert_no_replies(self.pg0,
364 pkt_inter_epg_220_to_221 * 65)
365 self.send_and_expect(self.pg0, pkt_intra_epg * 65, self.pg1)
366
367
368if __name__ == '__main__':
369 unittest.main(testRunner=VppTestRunner)