| """ |
| BIER Tables and Routes |
| """ |
| |
| import socket |
| from vpp_object import VppObject |
| from vpp_ip_route import MPLS_LABEL_INVALID, VppRoutePath, VppMplsLabel |
| |
| |
| class BIER_HDR_PAYLOAD: |
| BIER_HDR_PROTO_MPLS_DOWN_STREAM = 1 |
| BIER_HDR_PROTO_MPLS_UP_STREAM = 2 |
| BIER_HDR_PROTO_ETHERNET = 3 |
| BIER_HDR_PROTO_IPV4 = 4 |
| BIER_HDR_PROTO_IPV6 = 5 |
| BIER_HDR_PROTO_VXLAN = 6 |
| BIER_HDR_PROTO_CTRL = 7 |
| BIER_HDR_PROTO_OAM = 8 |
| |
| |
| class VppBierTableID(): |
| def __init__(self, sub_domain_id, set_id, hdr_len_id): |
| self.set_id = set_id |
| self.sub_domain_id = sub_domain_id |
| self.hdr_len_id = hdr_len_id |
| |
| |
| def find_bier_table(test, bti): |
| tables = test.vapi.bier_table_dump() |
| for t in tables: |
| if bti.set_id == t.bt_tbl_id.bt_set \ |
| and bti.sub_domain_id == t.bt_tbl_id.bt_sub_domain \ |
| and bti.hdr_len_id == t.bt_tbl_id.bt_hdr_len_id: |
| return True |
| return False |
| |
| |
| def find_bier_route(test, bti, bp): |
| routes = test.vapi.bier_route_dump(bti) |
| for r in routes: |
| if bti.set_id == r.br_route.br_tbl_id.bt_set \ |
| and bti.sub_domain_id == r.br_route.br_tbl_id.bt_sub_domain \ |
| and bti.hdr_len_id == r.br_route.br_tbl_id.bt_hdr_len_id \ |
| and bp == r.br_route.br_bp: |
| return True |
| return False |
| |
| |
| def find_bier_disp_table(test, bdti): |
| tables = test.vapi.bier_disp_table_dump() |
| for t in tables: |
| if bdti == t.bdt_tbl_id: |
| return True |
| return False |
| |
| |
| def find_bier_disp_entry(test, bdti, bp): |
| entries = test.vapi.bier_disp_entry_dump(bdti) |
| for e in entries: |
| if bp == e.bde_bp \ |
| and bdti == e.bde_tbl_id: |
| return True |
| return False |
| |
| |
| def find_bier_imp(test, bti, bp): |
| imps = test.vapi.bier_imp_dump() |
| for i in imps: |
| if bti.set_id == i.bi_tbl_id.bt_set \ |
| and bti.sub_domain_id == i.bi_tbl_id.bt_sub_domain \ |
| and bti.hdr_len_id == i.bi_tbl_id.bt_hdr_len_id \ |
| and bp == i.bi_src: |
| return True |
| return False |
| |
| |
| class VppBierTable(VppObject): |
| """ |
| BIER Table |
| """ |
| |
| def __init__(self, test, id, mpls_label): |
| self._test = test |
| self.id = id |
| self.mpls_label = mpls_label |
| |
| def add_vpp_config(self): |
| self._test.vapi.bier_table_add_del( |
| self.id, |
| self.mpls_label, |
| is_add=1) |
| self._test.registry.register(self, self._test.logger) |
| |
| def remove_vpp_config(self): |
| self._test.vapi.bier_table_add_del( |
| self.id, |
| self.mpls_label, |
| is_add=0) |
| |
| def object_id(self): |
| return "bier-table;[%d:%d:%d]" % (self.id.set_id, |
| self.id.sub_domain_id, |
| self.id.hdr_len_id) |
| |
| def query_vpp_config(self): |
| return find_bier_table(self._test, self.id) |
| |
| |
| class VppBierRoute(VppObject): |
| """ |
| BIER route |
| """ |
| |
| def __init__(self, test, tbl_id, bp, paths): |
| self._test = test |
| self.tbl_id = tbl_id |
| self.bp = bp |
| self.paths = paths |
| self.encoded_paths = [] |
| for path in self.paths: |
| self.encoded_paths.append(path.encode()) |
| |
| def add_vpp_config(self): |
| self._test.vapi.bier_route_add_del( |
| self.tbl_id, |
| self.bp, |
| self.encoded_paths, |
| is_add=1) |
| self._test.registry.register(self, self._test.logger) |
| |
| def remove_vpp_config(self): |
| self._test.vapi.bier_route_add_del( |
| self.tbl_id, |
| self.bp, |
| self.encoded_paths, |
| is_add=0) |
| |
| def update_paths(self, paths): |
| self.paths = paths |
| self.encoded_paths = [] |
| for path in self.paths: |
| self.encoded_paths.append(path.encode()) |
| self._test.vapi.bier_route_add_del( |
| self.tbl_id, |
| self.bp, |
| self.encoded_paths, |
| is_replace=1) |
| |
| def add_path(self, path): |
| self.encoded_paths.append(path.encode()) |
| self._test.vapi.bier_route_add_del( |
| self.tbl_id, |
| self.bp, |
| [path.encode()], |
| is_add=1, |
| is_replace=0) |
| self.paths.append(path) |
| self._test.registry.register(self, self._test.logger) |
| |
| def remove_path(self, path): |
| self.encoded_paths.remove(path.encode()) |
| self._test.vapi.bier_route_add_del( |
| self.tbl_id, |
| self.bp, |
| [path.encode()], |
| is_add=0, |
| is_replace=0) |
| self.paths.remove(path) |
| |
| def remove_all_paths(self): |
| self._test.vapi.bier_route_add_del( |
| self.tbl_id, |
| self.bp, |
| [], |
| is_add=0, |
| is_replace=1) |
| self.paths = [] |
| |
| def object_id(self): |
| return "bier-route;[%d:%d:%d:%d]" % (self.tbl_id.set_id, |
| self.tbl_id.sub_domain_id, |
| self.tbl_id.hdr_len_id, |
| self.bp) |
| |
| def query_vpp_config(self): |
| return find_bier_route(self._test, self.tbl_id, self.bp) |
| |
| |
| class VppBierImp(VppObject): |
| """ |
| BIER route |
| """ |
| |
| def __init__(self, test, tbl_id, src, ibytes): |
| self._test = test |
| self.tbl_id = tbl_id |
| self.ibytes = ibytes |
| self.src = src |
| |
| def add_vpp_config(self): |
| res = self._test.vapi.bier_imp_add( |
| self.tbl_id, |
| self.src, |
| self.ibytes) |
| self.bi_index = res.bi_index |
| self._test.registry.register(self, self._test.logger) |
| |
| def remove_vpp_config(self): |
| self._test.vapi.bier_imp_del( |
| self.bi_index) |
| |
| def object_id(self): |
| return "bier-imp;[%d:%d:%d:%d]" % (self.tbl_id.set_id, |
| self.tbl_id.sub_domain_id, |
| self.tbl_id.hdr_len_id, |
| self.src) |
| |
| def query_vpp_config(self): |
| return find_bier_imp(self._test, self.tbl_id, self.src) |
| |
| |
| class VppBierDispTable(VppObject): |
| """ |
| BIER Disposition Table |
| """ |
| |
| def __init__(self, test, id): |
| self._test = test |
| self.id = id |
| |
| def add_vpp_config(self): |
| self._test.vapi.bier_disp_table_add_del( |
| self.id, |
| is_add=1) |
| self._test.registry.register(self, self._test.logger) |
| |
| def remove_vpp_config(self): |
| self._test.vapi.bier_disp_table_add_del( |
| self.id, |
| is_add=0) |
| |
| def object_id(self): |
| return "bier-disp-table;[%d]" % (self.id) |
| |
| def query_vpp_config(self): |
| return find_bier_disp_table(self._test, self.id) |
| |
| |
| class VppBierDispEntry(VppObject): |
| """ |
| BIER Disposition Entry |
| """ |
| |
| def __init__(self, test, tbl_id, bp, payload_proto, nh_proto, |
| nh, nh_tbl, rpf_id=~0): |
| self._test = test |
| self.tbl_id = tbl_id |
| self.nh_tbl = nh_tbl |
| self.nh_proto = nh_proto |
| self.bp = bp |
| self.payload_proto = payload_proto |
| self.rpf_id = rpf_id |
| self.nh = socket.inet_pton(socket.AF_INET, nh) |
| |
| def add_vpp_config(self): |
| self._test.vapi.bier_disp_entry_add_del( |
| self.tbl_id, |
| self.bp, |
| self.payload_proto, |
| self.nh_proto, |
| self.nh, |
| self.nh_tbl, |
| self.rpf_id, |
| is_add=1) |
| self._test.registry.register(self, self._test.logger) |
| |
| def remove_vpp_config(self): |
| self._test.vapi.bier_disp_entry_add_del( |
| self.tbl_id, |
| self.bp, |
| self.payload_proto, |
| self.nh_proto, |
| self.nh, |
| self.nh_tbl, |
| self.rpf_id, |
| is_add=0) |
| |
| def object_id(self): |
| return "bier-disp-entry;[%d:%d]" % (self.tbl_id, |
| self.bp) |
| |
| def query_vpp_config(self): |
| return find_bier_disp_entry(self._test, self.tbl_id, self.bp) |