FIB Interpose Source
[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 __str__(self):
101         return self.object_id()
102
103     def object_id(self):
104         return "bier-table;[%d:%d:%d]" % (self.id.set_id,
105                                           self.id.sub_domain_id,
106                                           self.id.hdr_len_id)
107
108     def query_vpp_config(self):
109         return find_bier_table(self._test, self.id)
110
111
112 class VppBierRoute(VppObject):
113     """
114     BIER route
115     """
116
117     def __init__(self, test, tbl_id, bp, paths):
118         self._test = test
119         self.tbl_id = tbl_id
120         self.bp = bp
121         self.paths = paths
122
123     def encode_paths(self):
124         br_paths = []
125         for p in self.paths:
126             lstack = []
127             for l in p.nh_labels:
128                 if type(l) == VppMplsLabel:
129                     lstack.append(l.encode())
130                 else:
131                     lstack.append({'label': l, 'ttl': 255})
132             n_labels = len(lstack)
133             while (len(lstack) < 16):
134                 lstack.append({})
135             br_paths.append({'next_hop': p.nh_addr,
136                              'weight': 1,
137                              'afi': p.proto,
138                              'sw_if_index': 0xffffffff,
139                              'preference': 0,
140                              'table_id': p.nh_table_id,
141                              'next_hop_id': p.next_hop_id,
142                              'is_udp_encap': p.is_udp_encap,
143                              'n_labels': n_labels,
144                              'label_stack': lstack})
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 __str__(self):
163         return self.object_id()
164
165     def object_id(self):
166         return "bier-route;[%d:%d:%d:%d]" % (self.tbl_id.set_id,
167                                              self.tbl_id.sub_domain_id,
168                                              self.tbl_id.hdr_len_id,
169                                              self.bp)
170
171     def query_vpp_config(self):
172         return find_bier_route(self._test, self.tbl_id, self.bp)
173
174
175 class VppBierImp(VppObject):
176     """
177     BIER route
178     """
179
180     def __init__(self, test, tbl_id, src, ibytes):
181         self._test = test
182         self.tbl_id = tbl_id
183         self.ibytes = ibytes
184         self.src = src
185
186     def add_vpp_config(self):
187         res = self._test.vapi.bier_imp_add(
188             self.tbl_id,
189             self.src,
190             self.ibytes)
191         self.bi_index = res.bi_index
192         self._test.registry.register(self, self._test.logger)
193
194     def remove_vpp_config(self):
195         self._test.vapi.bier_imp_del(
196             self.bi_index)
197
198     def __str__(self):
199         return self.object_id()
200
201     def object_id(self):
202         return "bier-imp;[%d:%d:%d:%d]" % (self.tbl_id.set_id,
203                                            self.tbl_id.sub_domain_id,
204                                            self.tbl_id.hdr_len_id,
205                                            self.src)
206
207     def query_vpp_config(self):
208         return find_bier_imp(self._test, self.tbl_id, self.src)
209
210
211 class VppBierDispTable(VppObject):
212     """
213     BIER Disposition Table
214     """
215
216     def __init__(self, test, id):
217         self._test = test
218         self.id = id
219
220     def add_vpp_config(self):
221         self._test.vapi.bier_disp_table_add_del(
222             self.id,
223             is_add=1)
224         self._test.registry.register(self, self._test.logger)
225
226     def remove_vpp_config(self):
227         self._test.vapi.bier_disp_table_add_del(
228             self.id,
229             is_add=0)
230
231     def __str__(self):
232         return self.object_id()
233
234     def object_id(self):
235         return "bier-disp-table;[%d]" % (self.id)
236
237     def query_vpp_config(self):
238         return find_bier_disp_table(self._test, self.id)
239
240
241 class VppBierDispEntry(VppObject):
242     """
243     BIER Disposition Entry
244     """
245
246     def __init__(self, test, tbl_id, bp, payload_proto, nh_proto,
247                  nh, nh_tbl, rpf_id=~0):
248         self._test = test
249         self.tbl_id = tbl_id
250         self.nh_tbl = nh_tbl
251         self.nh_proto = nh_proto
252         self.bp = bp
253         self.payload_proto = payload_proto
254         self.rpf_id = rpf_id
255         self.nh = socket.inet_pton(socket.AF_INET, nh)
256
257     def add_vpp_config(self):
258         self._test.vapi.bier_disp_entry_add_del(
259             self.tbl_id,
260             self.bp,
261             self.payload_proto,
262             self.nh_proto,
263             self.nh,
264             self.nh_tbl,
265             self.rpf_id,
266             is_add=1)
267         self._test.registry.register(self, self._test.logger)
268
269     def remove_vpp_config(self):
270         self._test.vapi.bier_disp_entry_add_del(
271             self.tbl_id,
272             self.bp,
273             self.payload_proto,
274             self.nh_proto,
275             self.nh,
276             self.nh_tbl,
277             self.rpf_id,
278             is_add=0)
279
280     def __str__(self):
281         return self.object_id()
282
283     def object_id(self):
284         return "bier-disp-entry;[%d:%d]" % (self.tbl_id,
285                                             self.bp)
286
287     def query_vpp_config(self):
288         return find_bier_disp_entry(self._test, self.tbl_id, self.bp)