ipsec: IPSec protection for multi-point tunnel interfaces
[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(b'\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     @property
141     def packed(self):
142         if self.eid_type == LispEIDType.IP4:
143             return socket.inet_pton(socket.AF_INET, self.eid_address)
144         elif self.eid_type == LispEIDType.IP6:
145             return socket.inet_pton(socket.AF_INET6, self.eid_address)
146         elif self.eid_type == LispEIDType.MAC:
147             return Exception('Unimplemented')
148         raise Exception('Unknown EID type {!s}!'.format(self.eid_type))
149
150
151 class VppLispMapping(VppObject):
152     """ Represents common features for remote and local LISP mapping in VPP """
153
154     def __init__(self, test, eid, vni=0, priority=1, weight=1):
155         self._eid = LispEID(eid)
156         self._test = test
157         self._priority = priority
158         self._weight = weight
159         self._vni = vni
160
161     @property
162     def test(self):
163         return self._test
164
165     @property
166     def vni(self):
167         return self._vni
168
169     @property
170     def eid(self):
171         return self._eid
172
173     @property
174     def priority(self):
175         return self._priority
176
177     @property
178     def weight(self):
179         return self._weight
180
181     def get_lisp_mapping_dump_entry(self):
182         return self.test.vapi.lisp_eid_table_dump(
183             eid_set=1, prefix_length=self._eid.prefix_length,
184             vni=self._vni, eid_type=self._eid.eid_type,
185             eid=self._eid.packed)
186
187     def query_vpp_config(self):
188         mapping = self.get_lisp_mapping_dump_entry()
189         return mapping
190
191     def object_id(self):
192         return 'lisp-mapping-[%s]-%s-%s-%s' % (
193             self.vni, self.eid, self.priority, self.weight)
194
195
196 class VppLocalMapping(VppLispMapping):
197     """ LISP Local mapping """
198     def __init__(self, test, eid, ls_name, vni=0, priority=1, weight=1,
199                  key_id=LispKeyIdType.NONE, key=''):
200         super(VppLocalMapping, self).__init__(test, eid, vni, priority, weight)
201         self._ls_name = ls_name
202         self._key_id = key_id
203         self._key = key
204
205     @property
206     def ls_name(self):
207         return self._ls_name
208
209     @property
210     def key_id(self):
211         return self._key_id
212
213     @property
214     def key(self):
215         return self._key
216
217     def add_vpp_config(self):
218         self.test.vapi.lisp_add_del_local_eid(
219                 ls_name=self._ls_name, eid_type=self._eid.eid_type,
220                 eid=self._eid.packed, prefix_len=self._eid.prefix_length,
221                 vni=self._vni, key_id=self._key_id, key=self._key)
222         self._test.registry.register(self, self.test.logger)
223
224     def remove_vpp_config(self):
225         self.test.vapi.lisp_add_del_local_eid(
226                 ls_name=self._ls_name, eid_type=self._eid.eid_type,
227                 eid=self._eid.packed, prefix_len=self._eid.prefix_length,
228                 vni=self._vni, is_add=0)
229
230     def object_id(self):
231         return 'lisp-eid-local-mapping-%s[%d]' % (self._eid, self._vni)
232
233
234 class VppRemoteMapping(VppLispMapping):
235
236     def __init__(self, test, eid, rlocs=None, vni=0, priority=1, weight=1):
237         super(VppRemoteMapping, self).__init__(test, eid, vni, priority,
238                                                weight)
239         self._rlocs = rlocs
240
241     @property
242     def rlocs(self):
243         return self._rlocs
244
245     def add_vpp_config(self):
246         self.test.vapi.lisp_add_del_remote_mapping(
247                 rlocs=self._rlocs, eid_type=self._eid.eid_type,
248                 eid=self._eid.packed, eid_prefix_len=self._eid.prefix_length,
249                 vni=self._vni, rlocs_num=len(self._rlocs))
250         self._test.registry.register(self, self.test.logger)
251
252     def remove_vpp_config(self):
253         self.test.vapi.lisp_add_del_remote_mapping(
254                 eid_type=self._eid.eid_type, eid=self._eid.packed,
255                 eid_prefix_len=self._eid.prefix_length, vni=self._vni,
256                 is_add=0, rlocs_num=0)
257
258     def object_id(self):
259         return 'lisp-eid-remote-mapping-%s[%d]' % (self._eid, self._vni)
260
261
262 class VppLispAdjacency(VppObject):
263     """ Represents LISP adjacency in VPP """
264
265     def __init__(self, test, leid, reid, vni=0):
266         self._leid = LispEID(leid)
267         self._reid = LispEID(reid)
268         if self._leid.eid_type != self._reid.eid_type:
269             raise Exception('remote and local EID are different types!')
270         self._vni = vni
271         self._test = test
272
273     @property
274     def test(self):
275         return self._test
276
277     @property
278     def leid(self):
279         return self._leid
280
281     @property
282     def reid(self):
283         return self._reid
284
285     @property
286     def vni(self):
287         return self._vni
288
289     def add_vpp_config(self):
290         self.test.vapi.lisp_add_del_adjacency(
291                 leid=self._leid.packed,
292                 reid=self._reid.packed, eid_type=self._leid.eid_type,
293                 leid_len=self._leid.prefix_length,
294                 reid_len=self._reid.prefix_length, vni=self._vni)
295         self._test.registry.register(self, self.test.logger)
296
297     @staticmethod
298     def eid_equal(eid, eid_type, eid_data, prefix_len):
299         if eid.eid_type != eid_type:
300             return False
301
302         if eid_type == LispEIDType.IP4 or eid_type == LispEIDType.IP6:
303             if eid.prefix_length != prefix_len:
304                 return False
305
306         if eid.packed != eid_data[0:eid.data_length]:
307             return False
308
309         return True
310
311     def query_vpp_config(self):
312         res = self.test.vapi.lisp_adjacencies_get(vni=self._vni)
313         for adj in res.adjacencies:
314             if self.eid_equal(self._leid, adj.eid_type, adj.leid,
315                               adj.leid_prefix_len) and \
316                 self.eid_equal(self._reid, adj.eid_type, adj.reid,
317                                adj.reid_prefix_len):
318                 return True
319         return False
320
321     def remove_vpp_config(self):
322         self.test.vapi.lisp_add_del_adjacency(
323                 leid=self._leid.packed,
324                 reid=self._reid.packed, eid_type=self._leid.eid_type,
325                 leid_len=self._leid.prefix_length,
326                 reid_len=self._reid.prefix_length, vni=self._vni, is_add=0)
327
328     def object_id(self):
329         return 'lisp-adjacency-%s-%s[%d]' % (self._leid, self._reid, self._vni)