summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig/interface.py
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-10-17 20:06:36 +0200
committerChristian Poessinger <christian@poessinger.com>2020-10-17 22:06:49 +0200
commitb5ef10cfeb839dca28ae5376bfabafe29ae07aec (patch)
tree10f5858d48e91f93ca440d2cd24c5c78c7a36add /python/vyos/ifconfig/interface.py
parent1353c006469754ae96c1cc4e6238d80e735985bc (diff)
downloadvyos-1x-b5ef10cfeb839dca28ae5376bfabafe29ae07aec.tar.gz
vyos-1x-b5ef10cfeb839dca28ae5376bfabafe29ae07aec.zip
ifconfig: T2985: support on demand bridge creation
The current implementation for bridge based interfaces has an issue which is caused by priority inheritance. We always assumed that the bridge interface will be created last, but this may not be true in all cases, where some interfaces will be created "on demand" - e.g. OpenVPN or late (VXLAN, GENEVE). As we already have a bunch of verify steps in place we should not see a bridge interface leak to the underlaying infrastructure code. This means, whenever an interface will be member of a bridge, and the bridge does yet not exist, we will create it in advance in the interface context, as the bridge code will be run in the same commit but maybe sooner or later. This will also be the solution for T2924.
Diffstat (limited to 'python/vyos/ifconfig/interface.py')
-rw-r--r--python/vyos/ifconfig/interface.py60
1 files changed, 49 insertions, 11 deletions
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']