8e27f25d10fcfcf7c424fc55736b9d93007f0791
[vpp.git] / test / vpp_bier.py
1 """
2   BIER Tables and Routes
3 """
4
5 import socket
6 from vpp_object import VppObject
7 from vpp_ip_route import MPLS_LABEL_INVALID, VppRoutePath, VppMplsLabel
8
9
10 class BIER_HDR_PAYLOAD:
11     BIER_HDR_PROTO_MPLS_DOWN_STREAM = 1
12     BIER_HDR_PROTO_MPLS_UP_STREAM = 2
13     BIER_HDR_PROTO_ETHERNET = 3
14     BIER_HDR_PROTO_IPV4 = 4
15     BIER_HDR_PROTO_IPV6 = 5
16     BIER_HDR_PROTO_VXLAN = 6
17     BIER_HDR_PROTO_CTRL = 7
18     BIER_HDR_PROTO_OAM = 8
19
20
21 class VppBierTableID():
22     def __init__(self, sub_domain_id, set_id, hdr_len_id):
23         self.set_id = set_id
24         self.sub_domain_id = sub_domain_id
25         self.hdr_len_id = hdr_len_id
26
27
28 def find_bier_table(test, bti):
29     tables = test.vapi.bier_table_dump()
30     for t in tables:
31         if bti.set_id == t.bt_tbl_id.bt_set \
32            and bti.sub_domain_id == t.bt_tbl_id.bt_sub_domain \
33            and bti.hdr_len_id == t.bt_tbl_id.bt_hdr_len_id:
34             return True
35     return False
36
37
38 def find_bier_route(test, bti, bp):
39     routes = test.vapi.bier_route_dump(bti)
40     for r in routes:
41         if bti.set_id == r.br_tbl_id.bt_set \
42            and bti.sub_domain_id == r.br_tbl_id.bt_sub_domain \
43            and bti.hdr_len_id == r.br_tbl_id.bt_hdr_len_id \
44            and bp == r.br_bp:
45             return True
46     return False
47
48
49 def find_bier_disp_table(test, bdti):
50     tables = test.vapi.bier_disp_table_dump()
51     for t in tables:
52         if bdti == t.bdt_tbl_id:
53             return True
54     return False
55
56
57 def find_bier_disp_entry(test, bdti, bp):
58     entries = test.vapi.bier_disp_entry_dump(bdti)
59     for e in entries:
60         if bp == e.bde_bp \
61            and bdti == e.bde_tbl_id:
62             return True
63     return False
64
65
66 def find_bier_imp(test, bti, bp):
67     imps = test.vapi.bier_imp_dump()
68     for i in imps:
69         if bti.set_id == i.bi_tbl_id.bt_set \
70            and bti.sub_domain_id == i.bi_tbl_id.bt_sub_domain \
71            and bti.hdr_len_id == i.bi_tbl_id.bt_hdr_len_id \
72            and bp == i.bi_src:
73             return True
74     return False
75
76
77 class VppBierTable(VppObject):
78     """
79     BIER Table
80     """
81
82     def __init__(self, test, id, mpls_label):
83         self._test = test
84         self.id = id
85         self.mpls_label = mpls_label
86
87     def add_vpp_config(self):
88         self._test.vapi.bier_table_add_del(
89             self.id,
90             self.mpls_label,
91             is_add=1)
92         self._test.registry.register(self, self._test.logger)
93
94     def remove_vpp_config(self):
95         self._test.vapi.bier_table_add_del(
96             self.id,
97             self.mpls_label,
98             is_add=0)
99
100     def object_id(self):
101         return "bier-table;[%d:%d:%d]" % (self.id.set_id,
102                                           self.id.sub_domain_id,
103                                           self.id.hdr_len_id)
104
105     def query_vpp_config(self):
106         return find_bier_table(self._test, self.id)
107
108
109 class VppBierRoute(VppObject):
110     """
111     BIER route
112     """
113
114     def __init__(self, test, tbl_id, bp, paths):
115         self._test = test
116         self.tbl_id = tbl_id
117         self.bp = bp
118         self.paths = paths
119
120     def encode_path(self, p):
121         lstack = []
122         for l in p.nh_labels:
123             if type(l) == VppMplsLabel:
124                 lstack.append(l.encode())
125             else:
126                 lstack.append({'label': l, 'ttl': 255})
127         n_labels = len(lstack)
128         while (len(lstack) < 16):
129             lstack.append({})
130         return {'next_hop': p.nh_addr,
131                 'weight': 1,
132                 'afi': p.proto,
133                 'sw_if_index': 0xffffffff,
134                 'preference': 0,
135                 'table_id': p.nh_table_id,
136                 'next_hop_id': p.next_hop_id,
137                 'is_udp_encap': p.is_udp_encap,
138                 'n_labels': n_labels,
139                 'label_stack': lstack}
140
141     def encode_paths(self):
142         br_paths = []
143         for p in self.paths:
144             br_paths.append(self.encode_path(p))
145         return br_paths
146
147     def add_vpp_config(self):
148         self._test.vapi.bier_route_add_del(
149             self.tbl_id,
150             self.bp,
151             self.encode_paths(),
152             is_add=1)
153         self._test.registry.register(self, self._test.logger)
154
155     def remove_vpp_config(self):
156         self._test.vapi.bier_route_add_del(
157             self.tbl_id,
158             self.bp,
159             self.encode_paths(),
160             is_add=0)
161
162     def update_paths(self, paths):
163         self.paths = paths
164         self._test.vapi.bier_route_add_del(
165             self.tbl_id,
166             self.bp,
167             self.encode_paths(),
168             is_replace=1)
169
170     def add_path(self, path):
171         self._test.vapi.bier_route_add_del(
172             self.tbl_id,
173             self.bp,
174             [self.encode_path(path)],
175             is_add=1,
176             is_replace=0)
177         self.paths.append(path)
178         self._test.registry.register(self, self._test.logger)
179
180     def remove_path(self, path):
181         self._test.vapi.bier_route_add_del(
182             self.tbl_id,
183             self.bp,
184             [self.encode_path(path)],
185             is_add=0,
186             is_replace=0)
187         self.paths.remove(path)
188
189     def remove_all_paths(self):
190         self._test.vapi.bier_route_add_del(
191             self.tbl_id,
192             self.bp,
193             [],
194             is_add=0,
195             is_replace=1)
196         self.paths = []
197
198     def object_id(self):
199         return "bier-route;[%d:%d:%d:%d]" % (self.tbl_id.set_id,
200                                              self.tbl_id.sub_domain_id,
201                                              self.tbl_id.hdr_len_id,
202                                              self.bp)
203
204     def query_vpp_config(self):
205         return find_bier_route(self._test, self.tbl_id, self.bp)
206
207
208 class VppBierImp(VppObject):
209     """
210     BIER route
211     """
212
213     def __init__(self, test, tbl_id, src, ibytes):
214         self._test = test
215         self.tbl_id = tbl_id
216         self.ibytes = ibytes
217         self.src = src
218
219     def add_vpp_config(self):
220         res = self._test.vapi.bier_imp_add(
221             self.tbl_id,
222             self.src,
223             self.ibytes)
224         self.bi_index = res.bi_index
225         self._test.registry.register(self, self._test.logger)
226
227     def remove_vpp_config(self):
228         self._test.vapi.bier_imp_del(
229             self.bi_index)
230
231     def object_id(self):
232         return "bier-imp;[%d:%d:%d:%d]" % (self.tbl_id.set_id,
233                                            self.tbl_id.sub_domain_id,
234                                            self.tbl_id.hdr_len_id,
235                                            self.src)
236
237     def query_vpp_config(self):
238         return find_bier_imp(self._test, self.tbl_id, self.src)
239
240
241 class VppBierDispTable(VppObject):
242     """
243     BIER Disposition Table
244     """
245
246     def __init__(self, test, id):
247         self._test = test
248         self.id = id
249
250     def add_vpp_config(self):
251         self._test.vapi.bier_disp_table_add_del(
252             self.id,
253             is_add=1)
254         self._test.registry.register(self, self._test.logger)
255
256     def remove_vpp_config(self):
257         self._test.vapi.bier_disp_table_add_del(
258             self.id,
259             is_add=0)
260
261     def object_id(self):
262         return "bier-disp-table;[%d]" % (self.id)
263
264     def query_vpp_config(self):
265         return find_bier_disp_table(self._test, self.id)
266
267
268 class VppBierDispEntry(VppObject):
269     """
270     BIER Disposition Entry
271     """
272
273     def __init__(self, test, tbl_id, bp, payload_proto, nh_proto,
274                  nh, nh_tbl, rpf_id=~0):
275         self._test = test
276         self.tbl_id = tbl_id
277         self.nh_tbl = nh_tbl
278         self.nh_proto = nh_proto
279         self.bp = bp
280         self.payload_proto = payload_proto
281         self.rpf_id = rpf_id
282         self.nh = socket.inet_pton(socket.AF_INET, nh)
283
284     def add_vpp_config(self):
285         self._test.vapi.bier_disp_entry_add_del(
286             self.tbl_id,
287             self.bp,
288             self.payload_proto,
289             self.nh_proto,
290             self.nh,
291             self.nh_tbl,
292             self.rpf_id,
293             is_add=1)
294         self._test.registry.register(self, self._test.logger)
295
296     def remove_vpp_config(self):
297         self._test.vapi.bier_disp_entry_add_del(
298             self.tbl_id,
299             self.bp,
300             self.payload_proto,
301             self.nh_proto,
302             self.nh,
303             self.nh_tbl,
304             self.rpf_id,
305             is_add=0)
306
307     def object_id(self):
308         return "bier-disp-entry;[%d:%d]" % (self.tbl_id,
309                                             self.bp)
310
311     def query_vpp_config(self):
312         return find_bier_disp_entry(self._test, self.tbl_id, self.bp)