blob: 7566b1f95ab162f9545576e44c1aa1cb654fa967 [file] [log] [blame]
"""
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_tbl_id.bt_set \
and bti.sub_domain_id == r.br_tbl_id.bt_sub_domain \
and bti.hdr_len_id == r.br_tbl_id.bt_hdr_len_id \
and bp == r.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 __str__(self):
return self.object_id()
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
def encode_paths(self):
br_paths = []
for p in self.paths:
lstack = []
for l in p.nh_labels:
if type(l) == VppMplsLabel:
lstack.append(l.encode())
else:
lstack.append({'label': l, 'ttl': 255})
n_labels = len(lstack)
while (len(lstack) < 16):
lstack.append({})
br_paths.append({'next_hop': p.nh_addr,
'weight': 1,
'afi': 0,
'preference': 0,
'table_id': p.nh_table_id,
'next_hop_id': p.next_hop_id,
'is_udp_encap': p.is_udp_encap,
'n_labels': n_labels,
'label_stack': lstack})
return br_paths
def add_vpp_config(self):
self._test.vapi.bier_route_add_del(
self.tbl_id,
self.bp,
self.encode_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.encode_paths(),
is_add=0)
def __str__(self):
return self.object_id()
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 __str__(self):
return self.object_id()
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 __str__(self):
return self.object_id()
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 __str__(self):
return self.object_id()
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)