mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 04:33:00 +02:00
cli_pretty: Add per-port status to show bridge stp
This commit is contained in:
@@ -20,6 +20,15 @@ class PadMdb:
|
||||
group = 20
|
||||
ports = 45
|
||||
|
||||
class PadStpPort:
|
||||
port = 12
|
||||
id = 7
|
||||
state = 12
|
||||
role = 12
|
||||
edge = 6
|
||||
designated = 31
|
||||
|
||||
total = 12 + 7 + 12 + 12 + 6 + 31
|
||||
|
||||
class PadRoute:
|
||||
dest = 30
|
||||
@@ -70,6 +79,10 @@ class Decore():
|
||||
def invert(txt):
|
||||
return Decore.decorate("7", txt)
|
||||
|
||||
@staticmethod
|
||||
def bold(txt):
|
||||
return Decore.decorate("1", txt)
|
||||
|
||||
@staticmethod
|
||||
def red(txt):
|
||||
return Decore.decorate("31", txt, "39")
|
||||
@@ -326,6 +339,17 @@ class STPBridgeID:
|
||||
)
|
||||
return f"{prio:1x}.{sysid:03x}.{addr}"
|
||||
|
||||
class STPPortID:
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
|
||||
def __str__(self):
|
||||
prio, pid = (
|
||||
self.id["priority"],
|
||||
self.id["port-id"],
|
||||
)
|
||||
return f"{prio:1x}.{pid:03x}"
|
||||
|
||||
|
||||
class Iface:
|
||||
def __init__(self, data):
|
||||
@@ -722,9 +746,15 @@ def find_iface(_ifaces, name):
|
||||
return False
|
||||
|
||||
|
||||
def version_sort(iface):
|
||||
return [int(x) if x.isdigit() else x for x in re.split(r'(\d+)',
|
||||
iface['name'])]
|
||||
def version_sort(s):
|
||||
return [int(x) if x.isdigit() else x for x in re.split(r'(\d+)', s)]
|
||||
|
||||
def ifname_sort(iface):
|
||||
return version_sort(iface["name"])
|
||||
|
||||
def brport_sort(iface):
|
||||
brname = iface.get("infix-interfaces:bridge-port", {}).get("bridge", "")
|
||||
return version_sort(brname) + version_sort(iface["name"])
|
||||
|
||||
|
||||
def print_interface(iface):
|
||||
@@ -743,7 +773,7 @@ def pr_interface_list(json):
|
||||
print(Decore.invert(hdr))
|
||||
|
||||
ifaces = sorted(json["ietf-interfaces:interfaces"]["interface"],
|
||||
key=version_sort)
|
||||
key=ifname_sort)
|
||||
iface = find_iface(ifaces, "lo")
|
||||
if iface:
|
||||
iface.pr_loopback()
|
||||
@@ -813,7 +843,7 @@ def show_bridge_mdb(json):
|
||||
sys.exit(1)
|
||||
|
||||
ifaces = sorted(json["ietf-interfaces:interfaces"]["interface"],
|
||||
key=version_sort)
|
||||
key=ifname_sort)
|
||||
for iface in [Iface(data) for data in ifaces]:
|
||||
if iface.type != "infix-if-type:bridge":
|
||||
continue
|
||||
@@ -828,19 +858,84 @@ def show_bridge_mdb(json):
|
||||
iface.pr_vlans_mdb(iface.name)
|
||||
|
||||
|
||||
|
||||
def show_bridge_stp_port(ifname, brport):
|
||||
stp = brport["stp"]
|
||||
|
||||
state = stp["cist"]["state"]
|
||||
if state == "forwarding":
|
||||
state = Decore.green(f"{state.upper():<{PadStpPort.state}}")
|
||||
else:
|
||||
state = Decore.yellow(f"{state.upper():<{PadStpPort.state}}")
|
||||
|
||||
role = stp["cist"]["role"]
|
||||
if role == "root":
|
||||
role = Decore.bold(f"{role:<{PadStpPort.role}}")
|
||||
else:
|
||||
role = f"{role:<{PadStpPort.role}}"
|
||||
|
||||
designated = "unknown"
|
||||
if cdesbr := stp["cist"].get("designated", {}).get("bridge-id"):
|
||||
brid = str(STPBridgeID(cdesbr))
|
||||
|
||||
cdesport = stp["cist"]["designated"].get("port-id")
|
||||
port = str(STPPortID(cdesport)) if cdesport else "UNKNOWN"
|
||||
designated = f"{brid} ({port})"
|
||||
|
||||
row = (
|
||||
f"{ifname:<{PadStpPort.port}}"
|
||||
f"{str(STPPortID(stp['cist']['port-id'])):<{PadStpPort.id}}"
|
||||
f"{state}"
|
||||
f"{role}"
|
||||
f"{'yes' if stp['edge'] else 'no':<{PadStpPort.edge}}"
|
||||
f"{designated:<{PadStpPort.designated}}"
|
||||
)
|
||||
print(row)
|
||||
|
||||
def show_bridge_stp(json):
|
||||
if not json.get("ietf-interfaces:interfaces"):
|
||||
print("Error, top level \"ietf-interfaces:interface\" missing")
|
||||
sys.exit(1)
|
||||
|
||||
brs = sorted(filter(lambda i: i.get("type") == "infix-if-type:bridge",
|
||||
json["ietf-interfaces:interfaces"].get("interface",[])))
|
||||
json["ietf-interfaces:interfaces"].get("interface",[])),
|
||||
key=ifname_sort)
|
||||
|
||||
for i, br in enumerate(brs):
|
||||
if i:
|
||||
print()
|
||||
Iface(br).pr_stp()
|
||||
|
||||
ports = sorted(filter(lambda i: i.get("infix-interfaces:bridge-port"),
|
||||
json["ietf-interfaces:interfaces"].get("interface",[])),
|
||||
key=brport_sort)
|
||||
if not ports:
|
||||
return
|
||||
|
||||
print()
|
||||
hdr = (
|
||||
f"{'PORT':<{PadStpPort.port}}"
|
||||
f"{'ID':<{PadStpPort.id}}"
|
||||
f"{'STATE':<{PadStpPort.state}}"
|
||||
f"{'ROLE':<{PadStpPort.role}}"
|
||||
f"{'EDGE':<{PadStpPort.edge}}"
|
||||
f"{'DESIGNATED BRIDGE':<{PadStpPort.designated}}"
|
||||
)
|
||||
print(Decore.invert(hdr))
|
||||
|
||||
lastbr = None
|
||||
for port in ports:
|
||||
brport = port["infix-interfaces:bridge-port"]
|
||||
if not brport.get("stp"):
|
||||
continue
|
||||
|
||||
if brport["bridge"] != lastbr:
|
||||
lastbr = brport["bridge"]
|
||||
separator = f"{'bridge:'+lastbr:<{PadStpPort.total}}"
|
||||
print(Decore.gray_bg(separator))
|
||||
|
||||
show_bridge_stp_port(port["name"], brport)
|
||||
|
||||
|
||||
def show_routing_table(json, ip):
|
||||
if not json.get("ietf-routing:routing"):
|
||||
|
||||
Reference in New Issue
Block a user