339493cb45757fa66d156bf81ed04fddb97ff2c7
[vpp.git] / test / lisp.py
1 import socket
2
3 from vpp_object import VppObject
4
5
6 class VppLispLocatorSet(VppObject):
7     """ Represents LISP locator set in VPP """
8
9     def __init__(self, test, ls_name):
10         self._test = test
11         self._ls_name = ls_name
12
13     @property
14     def test(self):
15         return self._test
16
17     @property
18     def ls_name(self):
19         return self._ls_name
20
21     def add_vpp_config(self):
22         self.test.vapi.lisp_add_del_locator_set(ls_name=self._ls_name)
23         self._test.registry.register(self, self.test.logger)
24
25     def get_lisp_locator_sets_dump_entry(self):
26         result = self.test.vapi.lisp_locator_set_dump()
27         for ls in result:
28             if ls.ls_name.strip('\x00') == self._ls_name:
29                 return ls
30         return None
31
32     def query_vpp_config(self):
33         return self.get_lisp_locator_sets_dump_entry() is not None
34
35     def remove_vpp_config(self):
36         self.test.vapi.lisp_add_del_locator_set(ls_name=self._ls_name,
37                                                 is_add=0)
38
39     def object_id(self):
40         return 'lisp-locator-set-%s' % self._ls_name
41
42
43 class VppLispLocator(VppObject):
44     """ Represents LISP locator in VPP """
45
46     def __init__(self, test, sw_if_index, ls_name, priority=1, weight=1):
47         self._test = test
48         self._sw_if_index = sw_if_index
49         self._ls_name = ls_name
50         self._priority = priority
51         self._weight = weight
52
53     @property
54     def test(self):
55         """ Test which created this locator """
56         return self._test
57
58     @property
59     def ls_name(self):
60         """ Locator set name """
61         return self._ls_name
62
63     @property
64     def sw_if_index(self):
65         return self._sw_if_index
66
67     @property
68     def priority(self):
69         return self._priority
70
71     @property
72     def weight(self):
73         return self._weight
74
75     def add_vpp_config(self):
76         self.test.vapi.lisp_add_del_locator(ls_name=self._ls_name,
77                                             sw_if_index=self._sw_if_index,
78                                             priority=self._priority,
79                                             weight=self._weight)
80         self._test.registry.register(self, self.test.logger)
81
82     def get_lisp_locator_dump_entry(self):
83         locators = self.test.vapi.lisp_locator_dump(
84                 is_index_set=0, ls_name=self._ls_name)
85         for locator in locators:
86             if locator.sw_if_index == self._sw_if_index:
87                 return locator
88         return None
89
90     def query_vpp_config(self):
91         locator = self.get_lisp_locator_dump_entry()
92         return locator is not None
93
94     def remove_vpp_config(self):
95         self.test.vapi.lisp_add_del_locator(
96                 ls_name=self._ls_name, sw_if_index=self._sw_if_index,
97                 priority=self._priority, weight=self._weight, is_add=0)
98         self._test.registry.register(self, self.test.logger)
99
100     def object_id(self):
101         return 'lisp-locator-%s-%d' % (self._ls_name, self._sw_if_index)
102
103
104 class LispEIDType(object):
105     IP4 = 0
106     IP6 = 1
107     MAC = 2
108
109
110 class LispKeyIdType(object):
111     NONE = 0
112     SHA1 = 1
113     SHA256 = 2
114
115
116 class LispEID(object):
117     """ Lisp endpoint identifier """
118     def __init__(self, eid):
119         self.eid = eid
120
121         # find out whether EID is ip4 prefix, ip6 prefix or MAC
122         if self.eid.find("/") != -1:
123             if self.eid.find(":") == -1:
124                 self.eid_type = LispEIDType.IP4
125                 self.data_length = 4
126             else:
127                 self.eid_type = LispEIDType.IP6
128                 self.data_length = 16
129
130             self.eid_address = self.eid.split("/")[0]
131             self.prefix_length = int(self.eid.split("/")[1])
132         elif self.eid.count(":") == 5:  # MAC address
133             self.eid_type = LispEIDType.MAC
134             self.eid_address = self.eid
135             self.prefix_length = 0
136             self.data_length = 6
137         else:
138             raise Exception('Unsupported EID format {!s}!'.format(eid))
139
140     def __str__(self):
141         if self.eid_type == LispEIDType.IP4:
142             return socket.inet_pton(socket.AF_INET, self.eid_address)
143         elif self.eid_type == LispEIDType.IP6:
144             return socket.inet_pton(socket.AF_INET6, self.eid_address)
145         elif self.eid_type == LispEIDType.MAC:
146             return Exception('Unimplemented')
147         raise Exception('Unknown EID type {!s}!'.format(self.eid_type))
148
149
150 class VppLispMapping(VppObject):
151     """ Represents common features for remote and local LISP mapping in VPP """
152
153     def __init__(self, test, eid, vni=0, priority=1, weight=1):
154         self._eid = LispEID(eid)
155         self._test = test
156         self._priority = priority
157         self._weight = weight
158         self._vni = vni
159
160     @property
161     def test(self):
162         return self._test
163
164     @property
165     def vni(self):
166         return self._vni
167
168     @property
169     def eid(self):
170         return self._eid
171
172     @property
173     def priority(self):
174         return self._priority
175
176     @property
177     def weight(self):
178         return self._weight
179
180     def get_lisp_mapping_dump_entry(self):
181         return self.test.vapi.lisp_eid_table_dump(
182                 eid_set=1, prefix_length=self._eid.prefix_length,
183                 vni=self._vni, eid_type=self._eid.eid_type, eid=str(self._eid))
184
185     def query_vpp_config(self):
186         mapping = self.get_lisp_mapping_dump_entry()
187         return mapping
188
189     def object_id(self):
190         return 'lisp-mapping-[%s]-%s-%s-%s' % (
191             self.vni, self.eid, self.priority, self.weight)
192
193
194 class VppLocalMapping(VppLispMapping):
195     """ LISP Local mapping """
196     def __init__(self, test, eid, ls_name, vni=0, priority=1, weight=1,
197                  key_id=LispKeyIdType.NONE, key=''):
198         super(VppLocalMapping, self).__init__(test, eid, vni, priority, weight)
199         self._ls_name = ls_name
200         self._key_id = key_id
201         self._key = key
202
203     @property
204     def ls_name(self):
205         return self._ls_name
206
207     @property
208     def key_id(self):
209         return self._key_id
210
211     @property
212     def key(self):
213         return self._key
214
215     def add_vpp_config(self):
216         self.test.vapi.lisp_add_del_local_eid(
217                 ls_name=self._ls_name, eid_type=self._eid.eid_type,
218                 eid=str(self._eid), prefix_len=self._eid.prefix_length,
219                 vni=self._vni, key_id=self._key_id, key=self._key)
220         self._test.registry.register(self, self.test.logger)
221
222     def remove_vpp_config(self):
223         self.test.vapi.lisp_add_del_local_eid(
224                 ls_name=self._ls_name, eid_type=self._eid.eid_type,
225                 eid=str(self._eid), prefix_len=self._eid.prefix_length,
226                 vni=self._vni, is_add=0)
227
228     def object_id(self):
229         return 'lisp-eid-local-mapping-%s[%d]' % (self._eid, self._vni)
230
231
232 class VppRemoteMapping(VppLispMapping):
233
234     def __init__(self, test, eid, rlocs=None, vni=0, priority=1, weight=1):
235         super(VppRemoteMapping, self).__init__(test, eid, vni, priority,
236                                                weight)
237         self._rlocs = rlocs
238
239     @property
240     def rlocs(self):
241         return self._rlocs
242
243     def add_vpp_config(self):
244         self.test.vapi.lisp_add_del_remote_mapping(
245                 rlocs=self._rlocs, eid_type=self._eid.eid_type,
246                 eid=str(self._eid), eid_prefix_len=self._eid.prefix_length,
247                 vni=self._vni, rlocs_num=len(self._rlocs))
248         self._test.registry.register(self, self.test.logger)
249
250     def remove_vpp_config(self):
251         self.test.vapi.lisp_add_del_remote_mapping(
252                 eid_type=self._eid.eid_type, eid=str(self._eid),
253                 eid_prefix_len=self._eid.prefix_length, vni=self._vni,
254                 is_add=0, rlocs_num=0)
255
256     def object_id(self):
257         return 'lisp-eid-remote-mapping-%s[%d]' % (self._eid, self._vni)
258
259
260 class VppLispAdjacency(VppObject):
261     """ Represents LISP adjacency in VPP """
262
263     def __init__(self, test, leid, reid, vni=0):
264         self._leid = LispEID(leid)
265         self._reid = LispEID(reid)
266         if self._leid.eid_type != self._reid.eid_type:
267             raise Exception('remote and local EID are different types!')
268         self._vni = vni
269         self._test = test
270
271     @property
272     def test(self):
273         return self._test
274
275     @property
276     def leid(self):
277         return self._leid
278
279     @property
280     def reid(self):
281         return self._reid
282
283     @property
284     def vni(self):
285         return self._vni
286
287     def add_vpp_config(self):
288         self.test.vapi.lisp_add_del_adjacency(
289                 leid=str(self._leid),
290                 reid=str(self._reid), eid_type=self._leid.eid_type,
291                 leid_len=self._leid.prefix_length,
292                 reid_len=self._reid.prefix_length, vni=self._vni)
293         self._test.registry.register(self, self.test.logger)
294
295     @staticmethod
296     def eid_equal(eid, eid_type, eid_data, prefix_len):
297         if eid.eid_type != eid_type:
298             return False
299
300         if eid_type == LispEIDType.IP4 or eid_type == LispEIDType.IP6:
301             if eid.prefix_length != prefix_len:
302                 return False
303
304         if str(eid) != eid_data[0:eid.data_length]:
305             return False
306
307         return True
308
309     def query_vpp_config(self):
310         res = self.test.vapi.lisp_adjacencies_get(vni=self._vni)
311         for adj in res.adjacencies:
312             if self.eid_equal(self._leid, adj.eid_type, adj.leid,
313                               adj.leid_prefix_len) and \
314                 self.eid_equal(self._reid, adj.eid_type, adj.reid,
315                                adj.reid_prefix_len):
316                 return True
317         return False
318
319     def remove_vpp_config(self):
320         self.test.vapi.lisp_add_del_adjacency(
321                 leid=str(self._leid),
322                 reid=str(self._reid), eid_type=self._leid.eid_type,
323                 leid_len=self._leid.prefix_length,
324                 reid_len=self._reid.prefix_length, vni=self._vni, is_add=0)
325
326     def object_id(self):
327         return 'lisp-adjacency-%s-%s[%d]' % (self._leid, self._reid, self._vni)