mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 04:53:01 +02:00
confd,statd: add support for link aggregates
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
committed by
Tobias Waldekranz
parent
ec2e161649
commit
78499757b0
@@ -451,6 +451,34 @@ class Iface:
|
||||
self.pvid = get_json_data('', self.data, 'infix-interfaces:bridge-port', 'pvid')
|
||||
self.stp_state = get_json_data('', self.data, 'infix-interfaces:bridge-port',
|
||||
'stp', 'cist', 'state')
|
||||
|
||||
self.lag_mode = get_json_data('', self.data, 'infix-interfaces:lag', 'mode')
|
||||
if self.lag_mode:
|
||||
self.lag_type = get_json_data('', self.data, 'infix-interfaces:lag', 'static', 'mode')
|
||||
if self.lag_mode == "lacp":
|
||||
self.lag_hash = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'hash')
|
||||
self.lacp_id = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'aggregator-id')
|
||||
self.lacp_actor_key = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'actor-key')
|
||||
self.lacp_partner_key = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'partner-key')
|
||||
self.lacp_partner_mac = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'partner-mac')
|
||||
self.lacp_sys_prio = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'system-priority')
|
||||
else:
|
||||
self.lag_hash = get_json_data('', self.data, 'infix-interfaces:lag', 'static', 'hash')
|
||||
self.link_updelay = get_json_data('', self.data, 'infix-interfaces:lag', 'link-monitor', 'debounce', 'up')
|
||||
self.link_downdelay = get_json_data('', self.data, 'infix-interfaces:lag', 'link-monitor', 'debounce', 'down')
|
||||
|
||||
self.lacp_mode = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'mode')
|
||||
rate = get_json_data('', self.data, 'infix-interfaces:lag', 'lacp', 'rate')
|
||||
self.lacp_rate = "fast (1s)" if rate == "fast" else "slow (30 sec)"
|
||||
|
||||
self.lag = get_json_data('', self.data, 'infix-interfaces:lag-port', 'lag')
|
||||
if self.lag:
|
||||
self.lag_state = get_json_data('', self.data, 'infix-interfaces:lag-port', 'state')
|
||||
self.lacp_id = get_json_data('', self.data, 'infix-interfaces:lag-port', 'lacp', 'aggregator-id')
|
||||
self.lacp_state = get_json_data('', self.data, 'infix-interfaces:lag-port', 'lacp', 'actor-state')
|
||||
self.lacp_pstate = get_json_data('', self.data, 'infix-interfaces:lag-port', 'lacp', 'partner-state')
|
||||
self.link_failures = get_json_data('', self.data, 'infix-interfaces:lag-port', 'link-failures')
|
||||
|
||||
self.containers = get_json_data('', self.data, 'infix-interfaces:container-network', 'containers')
|
||||
|
||||
|
||||
@@ -491,6 +519,9 @@ class Iface:
|
||||
def is_bridge(self):
|
||||
return self.type == "infix-if-type:bridge"
|
||||
|
||||
def is_lag(self):
|
||||
return self.type == "infix-if-type:lag"
|
||||
|
||||
def is_veth(self):
|
||||
return self.data['type'] == "infix-if-type:veth"
|
||||
|
||||
@@ -635,6 +666,59 @@ class Iface:
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
def pr_proto_lag(self, member=True):
|
||||
data_str = ""
|
||||
|
||||
row = f"{'lag':<{Pad.proto}}"
|
||||
if member:
|
||||
state = self.lag_state.upper()
|
||||
if self.oper() == "up":
|
||||
row += Decore.green(f"{state:<{Pad.state}}")
|
||||
else:
|
||||
row += Decore.yellow(f"{state:<{Pad.state}}")
|
||||
if self.lacp_state:
|
||||
lacp = ', '.join(self.lacp_state)
|
||||
data_str += lacp
|
||||
else:
|
||||
dec = Decore.green if self.oper() == "up" else Decore.yellow
|
||||
row += dec(f"{self.oper().upper():<{Pad.state}}")
|
||||
data_str += f"{self.lag_mode}"
|
||||
if self.lag_mode == "lacp":
|
||||
data_str += f": {self.lacp_mode}"
|
||||
data_str += f", rate: {self.lacp_rate}"
|
||||
data_str += f", hash: {self.lag_hash}"
|
||||
else:
|
||||
data_str += f": {self.lag_type}"
|
||||
data_str += f", hash: {self.lag_hash}"
|
||||
|
||||
if data_str:
|
||||
row += f"{data_str:<{Pad.data}}"
|
||||
|
||||
print(row)
|
||||
|
||||
def pr_lag(self, _ifaces):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_lag(member=False)
|
||||
|
||||
lowers = []
|
||||
for _iface in [Iface(data) for data in _ifaces]:
|
||||
if _iface.lag and _iface.lag == self.name:
|
||||
lowers.append(_iface)
|
||||
|
||||
if lowers:
|
||||
self.pr_proto_eth(pipe='│')
|
||||
self.pr_proto_ipv4(pipe='│')
|
||||
self.pr_proto_ipv6(pipe='│')
|
||||
else:
|
||||
self.pr_proto_eth(pipe=' ')
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
for i, lower in enumerate(lowers):
|
||||
pipe = '└ ' if (i == len(lowers) -1) else '├ '
|
||||
lower.pr_name(pipe)
|
||||
lower.pr_proto_lag()
|
||||
|
||||
def pr_veth(self, _ifaces):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_veth()
|
||||
@@ -716,6 +800,32 @@ class Iface:
|
||||
if self.phys_address:
|
||||
print(f"{'physical address':<{20}}: {self.phys_address}")
|
||||
|
||||
if self.lag_mode:
|
||||
print(f"{'lag mode':<{20}}: {self.lag_mode}")
|
||||
if self.lag_mode == "lacp":
|
||||
print(f"{'lag hash':<{20}}: {self.lag_hash}")
|
||||
print(f"{'lacp mode':<{20}}: {self.lacp_mode}")
|
||||
print(f"{'lacp rate':<{20}}: {self.lacp_rate}")
|
||||
print(f"{'lacp aggregate id':<{20}}: {self.lacp_id}")
|
||||
print(f"{'lacp system priority':<{20}}: {self.lacp_sys_prio}")
|
||||
print(f"{'lacp actor key':<{20}}: {self.lacp_actor_key}")
|
||||
print(f"{'lacp partner key':<{20}}: {self.lacp_partner_key}")
|
||||
print(f"{'lacp partner mac':<{20}}: {self.lacp_partner_mac}")
|
||||
else:
|
||||
print(f"{'lag type':<{20}}: {self.lag_type}")
|
||||
print(f"{'lag hash':<{20}}: {self.lag_hash}")
|
||||
print(f"{'link debounce up':<{20}}: {self.link_updelay} msec")
|
||||
print(f"{'link debounce down':<{20}}: {self.link_downdelay} msec")
|
||||
|
||||
if self.lag:
|
||||
print(f"{'lag member':<{20}}: {self.lag}")
|
||||
print(f"{'lag member state':<{20}}: {self.lag_state}")
|
||||
if self.lacp_state:
|
||||
print(f"{'lacp aggregate id':<{20}}: {self.lacp_id}")
|
||||
print(f"{'lacp actor state':<{20}}: {', '.join(self.lacp_state)}")
|
||||
print(f"{'lacp partner state':<{20}}: {', '.join(self.lacp_pstate)}")
|
||||
print(f"{'link failure count':<{20}}: {self.link_failures}")
|
||||
|
||||
if self.ipv4_addr:
|
||||
first = True
|
||||
for addr in self.ipv4_addr:
|
||||
@@ -872,6 +982,10 @@ def pr_interface_list(json):
|
||||
iface.pr_bridge(ifaces)
|
||||
continue
|
||||
|
||||
if iface.is_lag():
|
||||
iface.pr_lag(ifaces)
|
||||
continue
|
||||
|
||||
if iface.is_veth():
|
||||
iface.pr_veth(ifaces)
|
||||
continue
|
||||
@@ -892,11 +1006,14 @@ def pr_interface_list(json):
|
||||
iface.pr_vlan(ifaces)
|
||||
continue
|
||||
|
||||
# These interfaces are printed by there parent, such as bridge
|
||||
# These interfaces are printed by their parent, such as bridge
|
||||
if iface.lower_if:
|
||||
continue
|
||||
if iface.bridge:
|
||||
continue
|
||||
if iface.lag:
|
||||
continue
|
||||
|
||||
print_interface(iface)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
"""The lag/bond oper-status always follows the carrier"""
|
||||
|
||||
|
||||
def lower(iplink):
|
||||
"""Return a dictionary of the status of a lag member"""
|
||||
port = {
|
||||
"lag": iplink['master'],
|
||||
}
|
||||
|
||||
info = iplink['linkinfo']['info_slave_data']
|
||||
if info:
|
||||
# active or backup link
|
||||
port['state'] = info['state'].lower()
|
||||
port['link-failures'] = info['link_failure_count']
|
||||
|
||||
# On etherlike interfaces and tap interfaces oper-status lies
|
||||
# if info['mii_status'] == "DOWN":
|
||||
# iface['oper-status'] = "down"
|
||||
|
||||
# Initialize lacp dict only if we encounter LACP-related fields
|
||||
if 'ad_aggregator_id' in info:
|
||||
port['lacp'] = {}
|
||||
port['lacp']['aggregator-id'] = info['ad_aggregator_id']
|
||||
port['lacp']['actor-state'] = info['ad_actor_oper_port_state_str']
|
||||
port['lacp']['partner-state'] = info['ad_partner_oper_port_state_str']
|
||||
else:
|
||||
port['state'] = 'backup'
|
||||
port['link-failures'] = 0
|
||||
|
||||
return port
|
||||
|
||||
|
||||
def lag(iplink):
|
||||
"""Return a dictionary of the status of the lag"""
|
||||
mode = {
|
||||
"balance-xor": "static",
|
||||
"802.3ad": "lacp",
|
||||
}
|
||||
hash_policy = {
|
||||
"layer2": "layer2",
|
||||
"layer3+4": "layer3-4",
|
||||
"layer2+3": "layer2-3",
|
||||
"encap2+3": "encap2-3",
|
||||
"encap3+4": "encap3-4",
|
||||
"vlan+srcmac": "vlan-srcmac",
|
||||
}
|
||||
bond = {}
|
||||
|
||||
info = iplink["linkinfo"]["info_data"]
|
||||
if info:
|
||||
bond["mode"] = mode.get(info['mode'], "static")
|
||||
if bond["mode"] == "lacp":
|
||||
bond["lacp"] = {
|
||||
"mode": 'active' if info['ad_lacp_active'] == "on" else 'passive',
|
||||
"rate": info['ad_lacp_rate'],
|
||||
"hash": hash_policy.get(info['xmit_hash_policy'], "layer2"),
|
||||
}
|
||||
|
||||
if 'ad_info' in info:
|
||||
bond["lacp"]["aggregator-id"] = info['ad_info']['aggregator']
|
||||
bond["lacp"]["actor-key"] = info['ad_info']['actor_key']
|
||||
bond["lacp"]["partner-key"] = info['ad_info']['partner_key']
|
||||
bond["lacp"]["partner-mac"] = info['ad_info']['partner_mac']
|
||||
if 'ad_actor_sys_prio' in info:
|
||||
bond["lacp"]["system-priority"] = info['ad_actor_sys_prio']
|
||||
else:
|
||||
bond["static"] = {
|
||||
"mode": info['mode'],
|
||||
"hash": info['xmit_hash_policy']
|
||||
}
|
||||
|
||||
bond["link-monitor"] = {
|
||||
"debounce": {
|
||||
"up": info['updelay'],
|
||||
"down": info['downdelay']
|
||||
}
|
||||
}
|
||||
|
||||
return bond
|
||||
@@ -3,6 +3,7 @@ from . import common
|
||||
from . import bridge
|
||||
from . import ethernet
|
||||
from . import ip
|
||||
from . import lag
|
||||
from . import tun
|
||||
from . import veth
|
||||
from . import vlan
|
||||
@@ -117,16 +118,16 @@ def interface(iplink, ipaddr):
|
||||
interface["infix-interfaces:bridge"] = br
|
||||
if brport := bridge.lower(iplink):
|
||||
interface["infix-interfaces:bridge-port"] = brport
|
||||
# case "infix-if-type:lag":
|
||||
# if l := lag.lag(iplink):
|
||||
# interface["infix-interfaces:lag"] = l
|
||||
case "infix-if-type:lag":
|
||||
if lg := lag.lag(iplink):
|
||||
interface["infix-interfaces:lag"] = lg
|
||||
case "infix-if-type:ethernet":
|
||||
if eth := ethernet.ethernet(iplink):
|
||||
interface["ieee802-ethernet-interface:ethernet"] = eth
|
||||
case "infix-if-type:vxlan":
|
||||
if vxlan := tun.vxlan(iplink):
|
||||
interface["infix-interfaces:vxlan"] = vxlan
|
||||
case "infix-if-type:gre"|"infix-if-type:gretap":
|
||||
case "infix-if-type:gre" | "infix-if-type:gretap":
|
||||
if gre := tun.gre(iplink):
|
||||
interface["infix-interfaces:gre"] = gre
|
||||
case "infix-if-type:veth":
|
||||
@@ -140,9 +141,9 @@ def interface(iplink, ipaddr):
|
||||
case "infix-interfaces:bridge-port":
|
||||
if brport := bridge.lower(iplink):
|
||||
interface["infix-interfaces:bridge-port"] = brport
|
||||
# case "infix-interfaces:lag-port":
|
||||
# if lagport := lag.lower(iplink):
|
||||
# interface["infix-interfaces:lag-port"] = lagport
|
||||
case "infix-interfaces:lag-port":
|
||||
if lagport := lag.lower(iplink):
|
||||
interface["infix-interfaces:lag-port"] = lagport
|
||||
|
||||
return interface
|
||||
|
||||
|
||||
Reference in New Issue
Block a user