diff options
Diffstat (limited to 'python/vyos')
-rw-r--r-- | python/vyos/configdict.py | 22 | ||||
-rw-r--r-- | python/vyos/ifconfig/bridge.py | 28 | ||||
-rw-r--r-- | python/vyos/ifconfig/interface.py | 60 | ||||
-rw-r--r-- | python/vyos/ifconfig/stp.py | 70 |
4 files changed, 74 insertions, 106 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 02006465c..62df3334c 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -194,11 +194,9 @@ def is_member(conf, interface, intftype=None): interface name -> Interface is a member of this interface False -> interface type cannot have members """ - from vyos.xml import is_tag - from vyos.xml import is_leaf - ret_val = None intftypes = ['bonding', 'bridge'] + if intftype not in intftypes + [None]: raise ValueError(( f'unknown interface type "{intftype}" or it cannot ' @@ -210,19 +208,13 @@ def is_member(conf, interface, intftype=None): old_level = conf.get_level() conf.set_level([]) - for it in intftype: - base = ['interfaces', it] + for iftype in intftype: + base = ['interfaces', iftype] for intf in conf.list_nodes(base): - memberintf = base + [intf, 'member', 'interface'] - if is_tag(memberintf): - if interface in conf.list_nodes(memberintf): - ret_val = intf - break - elif is_leaf(memberintf): - if ( conf.exists(memberintf) and - interface in conf.return_values(memberintf) ): - ret_val = intf - break + member = base + [intf, 'member', 'interface', interface] + if conf.exists(member): + tmp = conf.get_config_dict(member, key_mangling=('-', '_'), get_first_key=True) + ret_val = {intf : tmp} old_level = conf.set_level(old_level) return ret_val diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py index c133a56fc..7867a7387 100644 --- a/python/vyos/ifconfig/bridge.py +++ b/python/vyos/ifconfig/bridge.py @@ -234,25 +234,33 @@ class BridgeIf(Interface): if member in interfaces(): self.del_port(member) - STPBridgeIf = STP.enable(BridgeIf) tmp = vyos_dict_search('member.interface', config) if tmp: for interface, interface_config in tmp.items(): - # if we've come here we already verified the interface - # does not have an addresses configured so just flush - # any remaining ones - Interface(interface).flush_addrs() + # if interface does yet not exist bail out early and + # add it later + if interface not in interfaces(): + continue + + # Bridge lower "physical" interface + lower = Interface(interface) + + # If we've come that far we already verified the interface does + # not have any addresses configured by CLI so just flush any + # remaining ones + lower.flush_addrs() # enslave interface port to bridge self.add_port(interface) - tmp = STPBridgeIf(interface) # set bridge port path cost - value = interface_config.get('cost') - tmp.set_path_cost(value) + if 'cost' in interface_config: + value = interface_config.get('cost') + lower.set_path_cost(value) # set bridge port path priority - value = interface_config.get('priority') - tmp.set_path_priority(value) + if 'priority' in interface_config: + value = interface_config.get('priority') + lower.set_path_priority(value) # Enable/Disable of an interface must always be done at the end of the # derived class to make use of the ref-counting set_admin_state() diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 47ec94bd3..c1f9d14af 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -46,6 +46,7 @@ from vyos.validate import assert_positive from vyos.validate import assert_range from vyos.ifconfig.control import Control +from vyos.ifconfig.stp import STP from vyos.ifconfig.vrrp import VRRP from vyos.ifconfig.operational import Operational from vyos.ifconfig import Section @@ -167,6 +168,18 @@ class Interface(Control): 'validate': assert_positive, 'location': '/proc/sys/net/ipv6/conf/{ifname}/dad_transmits', }, + 'path_cost': { + # XXX: we should set a maximum + 'validate': assert_positive, + 'location': '/sys/class/net/{ifname}/brport/path_cost', + 'errormsg': '{ifname} is not a bridge port member' + }, + 'path_priority': { + # XXX: we should set a maximum + 'validate': assert_positive, + 'location': '/sys/class/net/{ifname}/brport/priority', + 'errormsg': '{ifname} is not a bridge port member' + }, 'proxy_arp': { 'validate': assert_boolean, 'location': '/proc/sys/net/ipv4/conf/{ifname}/proxy_arp', @@ -628,6 +641,28 @@ class Interface(Control): self._admin_state_down_cnt += 1 return self.set_interface('admin_state', state) + def set_path_cost(self, cost): + """ + Set interface path cost, only relevant for STP enabled interfaces + + Example: + + >>> from vyos.ifconfig import Interface + >>> Interface('eth0').set_path_cost(4) + """ + self.set_interface('path_cost', cost) + + def set_path_priority(self, priority): + """ + Set interface path priority, only relevant for STP enabled interfaces + + Example: + + >>> from vyos.ifconfig import Interface + >>> Interface('eth0').set_path_priority(4) + """ + self.set_interface('path_priority', priority) + def set_proxy_arp(self, enable): """ Set per interface proxy ARP configuration @@ -809,24 +844,27 @@ class Interface(Control): # flush all addresses self._cmd(f'ip addr flush dev "{self.ifname}"') - def add_to_bridge(self, br): + def add_to_bridge(self, bridge_dict): """ Adds the interface to the bridge with the passed port config. Returns False if bridge doesn't exist. """ - # check if the bridge exists (on boot it doesn't) - if br not in Section.interfaces('bridge'): - return False - + # drop all interface addresses first self.flush_addrs() - # add interface to bridge - use Section.klass to get BridgeIf class - Section.klass(br)(br, create=False).add_port(self.ifname) - # TODO: port config (STP) + for bridge, bridge_config in bridge_dict.items(): + # add interface to bridge - use Section.klass to get BridgeIf class + Section.klass(bridge)(bridge, create=True).add_port(self.ifname) - return True + # set bridge port path cost + if 'cost' in bridge_config: + self.set_path_cost(bridge_config['cost']) + + # set bridge port path priority + if 'priority' in bridge_config: + self.set_path_cost(bridge_config['priority']) def set_dhcp(self, enable): """ @@ -1047,8 +1085,8 @@ class Interface(Control): # re-add ourselves to any bridge we might have fallen out of if 'is_bridge_member' in config: - bridge = config.get('is_bridge_member') - self.add_to_bridge(bridge) + bridge_dict = config.get('is_bridge_member') + self.add_to_bridge(bridge_dict) # remove no longer required 802.1ad (Q-in-Q VLANs) ifname = config['ifname'] diff --git a/python/vyos/ifconfig/stp.py b/python/vyos/ifconfig/stp.py deleted file mode 100644 index 5e83206c2..000000000 --- a/python/vyos/ifconfig/stp.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library. If not, see <http://www.gnu.org/licenses/>. - - -from vyos.ifconfig.interface import Interface - -from vyos.validate import assert_positive - - -class STP: - """ - A spanning-tree capable interface. This applies only to bridge port member - interfaces! - """ - - @classmethod - def enable (cls, adaptee): - adaptee._sysfs_set = {**adaptee._sysfs_set, **cls._sysfs_set} - adaptee.set_path_cost = cls.set_path_cost - adaptee.set_path_priority = cls.set_path_priority - return adaptee - - _sysfs_set = { - 'path_cost': { - # XXX: we should set a maximum - 'validate': assert_positive, - 'location': '/sys/class/net/{ifname}/brport/path_cost', - 'errormsg': '{ifname} is not a bridge port member' - }, - 'path_priority': { - # XXX: we should set a maximum - 'validate': assert_positive, - 'location': '/sys/class/net/{ifname}/brport/priority', - 'errormsg': '{ifname} is not a bridge port member' - }, - } - - def set_path_cost(self, cost): - """ - Set interface path cost, only relevant for STP enabled interfaces - - Example: - - >>> from vyos.ifconfig import Interface - >>> Interface('eth0').set_path_cost(4) - """ - self.set_interface('path_cost', cost) - - def set_path_priority(self, priority): - """ - Set interface path priority, only relevant for STP enabled interfaces - - Example: - - >>> from vyos.ifconfig import Interface - >>> Interface('eth0').set_path_priority(4) - """ - self.set_interface('path_priority', priority) |