confd,statd: add support for link aggregates

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2025-02-12 23:21:08 +01:00
committed by Tobias Waldekranz
parent ec2e161649
commit 78499757b0
9 changed files with 644 additions and 120 deletions
@@ -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