diff --git a/config/bondethernet.py b/config/bondethernet.py index 2d7d364..f842236 100644 --- a/config/bondethernet.py +++ b/config/bondethernet.py @@ -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 = [] diff --git a/config/test_bondethernet.py b/config/test_bondethernet.py index c394b9f..c2754d7 100644 --- a/config/test_bondethernet.py +++ b/config/test_bondethernet.py @@ -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)) diff --git a/vpp/vppapi.py b/vpp/vppapi.py index c497551..69ae98d 100644 --- a/vpp/vppapi.py +++ b/vpp/vppapi.py @@ -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] diff --git a/yaml b/yaml new file mode 100644 index 0000000..fb64080 --- /dev/null +++ b/yaml @@ -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 +