diff options
| author | Christian Breunig <christian@breunig.cc> | 2025-01-07 13:17:13 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-07 14:17:13 +0200 |
| commit | 08c00548ec11329774d315f745dbbd007c986bfe (patch) | |
| tree | 0f64fd098603f90a5b2a9071eaaa3574da3a4d0c /python/vyos/ifconfig/interface.py | |
| parent | fb651c09f07b8aba45f2d31cfb3851e9e9c82ef0 (diff) | |
| download | veeos-1x-08c00548ec11329774d315f745dbbd007c986bfe.tar.gz veeos-1x-08c00548ec11329774d315f745dbbd007c986bfe.zip | |
vyos.ifconfig: T7018: drop 'iftype' class attribute (#4280)
Under very rare cases we can run into a race condition where interfaces are
still in creation phase but are already referenced..
This can trigger:
File "/usr/libexec/vyos/conf_mode/system_conntrack.py", line 270, in <module>
apply(c)
File "/usr/libexec/vyos/conf_mode/system_conntrack.py", line 249, in apply
call_dependents()
File "/usr/lib/python3/dist-packages/vyos/configdep.py", line 147, in call_dependents
f()
File "/usr/lib/python3/dist-packages/vyos/configdep.py", line 118, in func_impl
run_config_mode_script(script, config)
File "/usr/lib/python3/dist-packages/vyos/configdep.py", line 106, in run_config_mode_script
mod.verify(c)
File "/usr/libexec/vyos//conf_mode/service_conntrack-sync.py", line 72, in verify
if len(get_ipv4(interface)) < 1:
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/vyos/template.py", line 458, in get_ipv4
return Interface(interface).get_addr_v4()
^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 334, in __init__
if not self.iftype:
^^^^^^^^^^^
AttributeError: 'Interface' object has no attribute 'iftype'
This commit removes the code path in question and the class attribute check.
The reason for the iftype attribute in the past was a common _create() method
serving for all interface types. As we already have a lot of derived
implementations and not all honor the classes iftype/type member - or even
worse honor it only in 50% of the occurrences it's time to drop it.
Diffstat (limited to 'python/vyos/ifconfig/interface.py')
| -rw-r--r-- | python/vyos/ifconfig/interface.py | 23 |
1 files changed, 4 insertions, 19 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index de821ab60..07075fd1b 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -29,7 +29,6 @@ from netifaces import AF_INET6 from netaddr import EUI from netaddr import mac_unix_expanded -from vyos.base import ConfigError from vyos.configdict import list_diff from vyos.configdict import dict_merge from vyos.configdict import get_vlan_ids @@ -74,7 +73,6 @@ class Interface(Control): OperationalClass = Operational options = ['debug', 'create'] - required = [] default = { 'debug': True, 'create': True, @@ -336,22 +334,10 @@ class Interface(Control): super().__init__(**kargs) if not self.exists(ifname): - # Any instance of Interface, such as Interface('eth0') can be used - # safely to access the generic function in this class as 'type' is - # unset, the class can not be created - if not hasattr(self, 'iftype'): - raise ConfigError(f'Interface "{ifname}" has no "iftype" attribute defined!') - self.config['type'] = self.iftype - # Should an Instance of a child class (EthernetIf, DummyIf, ..) # be required, then create should be set to False to not accidentally create it. # In case a subclass does not define it, we use get to set the default to True - if self.config.get('create',True): - for k in self.required: - if k not in kargs: - name = self.default['type'] - raise ConfigError(f'missing required option {k} for {name} {ifname} creation') - + if self.config.get('create', True): self._create() # If we can not connect to the interface then let the caller know # as the class could not be correctly initialised @@ -364,13 +350,14 @@ class Interface(Control): self.operational = self.OperationalClass(ifname) self.vrrp = VRRP(ifname) - def _create(self): + def _create(self, type: str=''): # Do not create interface that already exist or exists in netns netns = self.config.get('netns', None) if self.exists(f'{self.ifname}', netns=netns): return - cmd = 'ip link add dev {ifname} type {type}'.format(**self.config) + cmd = f'ip link add dev {self.ifname}' + if type: cmd += f' type {type}' if 'netns' in self.config: cmd = f'ip netns exec {netns} {cmd}' self._cmd(cmd) @@ -1954,8 +1941,6 @@ class Interface(Control): class VLANIf(Interface): """ Specific class which abstracts 802.1q and 802.1ad (Q-in-Q) VLAN interfaces """ - iftype = 'vlan' - def _create(self): # bail out early if interface already exists if self.exists(f'{self.ifname}'): |
