Add bond/bridge YAML emitter

Add int_to_mode() and int_to_lb() in config/bondethernet.py to map back
the retrieved values from VPP into their config strings.

Implement bond and bridge settings dumper, dumping all settings even if
they are default. This helps the user understand the configurable
options.
This commit is contained in:
Pim van Pelt
2022-04-05 15:50:49 +00:00
parent 2360d28d0a
commit 0a755a0745
4 changed files with 202 additions and 0 deletions

View File

@ -81,6 +81,20 @@ def mode_to_int(mode):
return -1
def int_to_mode(mode):
""" Returns the string representation in VPP of a given bondethernet mode,
or "" if 'mode' is not a valid id.
See src/vnet/bonding/bond.api and schema.yaml for valid pairs. """
ret = { 1: 'round-robin', 2: 'active-backup', 3: 'xor', 4: 'broadcast', 5: 'lacp' }
try:
return ret[mode]
except:
pass
return ""
def get_lb(yaml, ifname):
""" Return the loadbalance strategy of the BondEthernet as a string. Only
'xor' and 'lacp' modes have loadbalance strategies, so return None if
@ -116,6 +130,21 @@ def lb_to_int(lb):
return -1
def int_to_lb(lb):
""" Returns the string representation in VPP of a given load-balance strategy,
or "" if 'lb' is not a valid int.
See src/vnet/bonding/bond.api and schema.yaml for valid pairs, although
bond.api defined more than we use in vppcfg. """
ret = { 0: 'l2', 1: 'l34', 2: 'l23', 3: 'round-robin', 4: 'broadcast', 5: 'active-backup' }
try:
return ret[lb]
except:
pass
return ""
def validate_bondethernets(yaml):
result = True
msgs = []

View File

@ -49,6 +49,15 @@ class TestBondEthernetMethods(unittest.TestCase):
self.assertEqual(5, bondethernet.mode_to_int("lacp"))
self.assertEqual(-1, bondethernet.mode_to_int("not-exist"))
def test_int_to_mode(self):
self.assertEqual("round-robin", bondethernet.int_to_mode(1))
self.assertEqual("active-backup", bondethernet.int_to_mode(2))
self.assertEqual("xor", bondethernet.int_to_mode(3))
self.assertEqual("broadcast", bondethernet.int_to_mode(4))
self.assertEqual("lacp", bondethernet.int_to_mode(5))
self.assertEqual("", bondethernet.int_to_mode(0))
self.assertEqual("", bondethernet.int_to_mode(6))
def test_get_lb(self):
self.assertEqual('l34', bondethernet.get_lb(self.cfg, "BondEthernet0"))
self.assertEqual('l2', bondethernet.get_lb(self.cfg, "BondEthernet1"))
@ -62,3 +71,12 @@ class TestBondEthernetMethods(unittest.TestCase):
self.assertEqual(4, bondethernet.lb_to_int("broadcast"))
self.assertEqual(5, bondethernet.lb_to_int("active-backup"))
self.assertEqual(-1, bondethernet.lb_to_int("not-exist"))
def test_int_to_lb(self):
self.assertEqual("l2", bondethernet.int_to_lb(0))
self.assertEqual("l34", bondethernet.int_to_lb(1))
self.assertEqual("l23", bondethernet.int_to_lb(2))
self.assertEqual("round-robin", bondethernet.int_to_lb(3))
self.assertEqual("broadcast", bondethernet.int_to_lb(4))
self.assertEqual("active-backup", bondethernet.int_to_lb(5))
self.assertEqual("", bondethernet.int_to_lb(-1))

View File

@ -10,6 +10,7 @@ import fnmatch
import logging
import socket
import yaml
import config.bondethernet as bondethernet
class VPPApi():
def __init__(self, address='/run/vpp/api.sock', clientname='vppcfg'):
@ -275,6 +276,10 @@ class VPPApiDumper(VPPApi):
bond = {"description": ""}
if iface.sw_if_index in self.cache['bondethernet_members']:
bond['interfaces'] = [self.cache['interfaces'][x].interface_name for x in self.cache['bondethernet_members'][iface.sw_if_index]]
mode = bondethernet.int_to_mode(iface.mode)
bond['mode'] = mode
if mode in ['xor', 'lacp']:
bond['load-balance'] = bondethernet.int_to_lb(iface.lb)
config['bondethernets'][iface.interface_name] = bond
for numtags in [ 0, 1, 2 ]:
@ -344,6 +349,16 @@ class VPPApiDumper(VPPApi):
bridge_name = "bd%d" % idx
mtu = 1500
bridge = {"description": ""}
settings = {}
settings['learn'] = iface.learn
settings['unicast-flood'] = iface.flood
settings['unknown-unicast-flood'] = iface.uu_flood
settings['unicast-forward'] = iface.forward
settings['arp-termination'] = iface.arp_term
settings['arp-unicast-forward'] = iface.arp_ufwd
settings['mac-age-minutes'] = int(iface.mac_age)
bridge['settings'] = settings
bvi = None
if iface.bvi_sw_if_index != 2**32-1:
bvi = self.cache['interfaces'][iface.bvi_sw_if_index]

140
yaml Normal file
View File

@ -0,0 +1,140 @@
bondethernets:
BondEthernet0:
description: ''
interfaces:
- GigabitEthernet3/0/0
- GigabitEthernet3/0/1
load-balance: l34
mode: lacp
BondEthernet1:
description: ''
interfaces: []
load-balance: l2
mode: xor
BondEthernet2:
description: ''
interfaces: []
mode: round-robin
bridgedomains:
bd1:
bvi: loop2
description: ''
interfaces:
- BondEthernet0.500
- BondEthernet0.501
mtu: 2000
settings:
arp-termination: false
arp-unicast-forward: false
learn: false
mac-age-minutes: 10
unicast-flood: true
unicast-forward: true
unknown-unicast-flood: true
bd11:
description: ''
mtu: 1500
settings:
arp-termination: false
arp-unicast-forward: false
learn: true
mac-age-minutes: 0
unicast-flood: true
unicast-forward: true
unknown-unicast-flood: true
interfaces:
BondEthernet0:
description: ''
lcp: be0
mtu: 9000
sub-interfaces:
100:
description: ''
encapsulation:
dot1q: 100
exact-match: false
l2xc: BondEthernet0.200
mtu: 2500
200:
description: ''
encapsulation:
dot1q: 200
exact-match: false
l2xc: BondEthernet0.100
mtu: 2500
500:
description: ''
encapsulation:
dot1ad: 500
exact-match: false
mtu: 2000
501:
description: ''
encapsulation:
dot1ad: 501
exact-match: false
mtu: 2000
BondEthernet1:
description: ''
mtu: 9000
state: down
BondEthernet2:
description: ''
mtu: 9000
state: down
GigabitEthernet3/0/0:
description: ''
mtu: 9000
GigabitEthernet3/0/1:
description: ''
mtu: 9000
HundredGigabitEthernet12/0/0:
description: ''
lcp: ice0
mtu: 1500
HundredGigabitEthernet12/0/1:
addresses:
- 192.0.2.17/30
- 2001:db8:3::1/64
description: ''
lcp: ice1
mtu: 9000
sub-interfaces:
1234:
description: ''
encapsulation:
dot1q: 1234
exact-match: true
lcp: ice1.1234
mtu: 1500
1235:
description: ''
encapsulation:
dot1q: 1234
exact-match: true
inner-dot1q: 1000
lcp: ice1.1234.1000
mtu: 1400
vxlan_tunnel1:
description: ''
mtu: 1500
loopbacks:
loop1:
addresses:
- 192.0.2.1/30
description: ''
lcp: bvi1
mtu: 1500
loop2:
addresses:
- 192.0.2.5/30
description: ''
lcp: bvi2
mtu: 1500
vxlan_tunnels:
vxlan_tunnel1:
description: ''
local: 192.0.2.1
remote: 192.0.2.2
vni: 101