diff options
author | Christian Poessinger <christian@poessinger.com> | 2020-04-07 22:02:49 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2020-04-07 22:02:49 +0200 |
commit | fcce4714146a39f608ddd141338547a5a952c63f (patch) | |
tree | 3b521908928e0cae15c2e8f8979088b5f7d2c0a5 /src/conf_mode | |
parent | 681576fff6a268ed04ae1a73ad7771882672cdb6 (diff) | |
download | vyos-1x-fcce4714146a39f608ddd141338547a5a952c63f.tar.gz vyos-1x-fcce4714146a39f608ddd141338547a5a952c63f.zip |
bridge: T2232: prevent deletion of enslaved interfaces
Interfaces enslaved to a bridge are not allowed to be deleted. If an interface
is deleted from the config but it is still enslaved to a bridge will cause a
configuration error on the subsequent boot.
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-x | src/conf_mode/interfaces-bonding.py | 19 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-bridge.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-dummy.py | 11 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-geneve.py | 13 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-l2tpv3.py | 11 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-openvpn.py | 10 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-pseudo-ethernet.py | 8 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-vxlan.py | 11 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wireguard.py | 12 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wireless.py | 10 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wirelessmodem.py | 9 |
11 files changed, 99 insertions, 18 deletions
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py index 19f43f725..6a002bc06 100755 --- a/src/conf_mode/interfaces-bonding.py +++ b/src/conf_mode/interfaces-bonding.py @@ -24,9 +24,8 @@ from vyos.ifconfig import BondIf from vyos.ifconfig_vlan import apply_vlan_config, verify_vlan_config from vyos.configdict import list_diff, vlan_to_dict from vyos.config import Config +from vyos.util import run, is_bridge_member from vyos import ConfigError -from vyos.util import run - default_config_data = { 'address': [], @@ -278,17 +277,23 @@ def get_config(): def verify(bond): + if bond['deleted']: + interface = bond['intf'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) + return None + if len (bond['arp_mon_tgt']) > 16: raise ConfigError('The maximum number of targets that can be specified is 16') if bond['primary']: if bond['mode'] not in ['active-backup', 'balance-tlb', 'balance-alb']: raise ConfigError('Mode dependency failed, primary not supported ' \ - 'in this mode.'.format()) - - if bond['primary'] not in bond['member']: - raise ConfigError('Interface "{}" is not part of the bond' \ - .format(bond['primary'])) + 'in mode "{}"!'.format(bond['mode'])) vrf_name = bond['vrf'] if vrf_name and vrf_name not in interfaces(): diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index 28e5957e4..79247ee51 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -243,6 +243,9 @@ def verify(bridge): if intf['name'] not in interfaces(): raise ConfigError('Can not add non existing interface "{}" to bridge "{}"'.format(intf['name'], bridge['intf'])) + if intf['name'] == 'lo': + raise ConfigError('Loopback interface "lo" can not be added to a bridge') + # bridge members are not allowed to be bond members, too for intf in bridge['member']: for bond in conf.list_nodes('interfaces bonding'): diff --git a/src/conf_mode/interfaces-dummy.py b/src/conf_mode/interfaces-dummy.py index b7b75517d..a256103af 100755 --- a/src/conf_mode/interfaces-dummy.py +++ b/src/conf_mode/interfaces-dummy.py @@ -23,6 +23,7 @@ from netifaces import interfaces from vyos.ifconfig import DummyIf from vyos.configdict import list_diff from vyos.config import Config +from vyos.util import is_bridge_member from vyos import ConfigError default_config_data = { @@ -78,6 +79,16 @@ def get_config(): return dummy def verify(dummy): + if dummy['deleted']: + interface = dummy['intf'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) + return None + vrf_name = dummy['vrf'] if vrf_name and vrf_name not in interfaces(): raise ConfigError(f'VRF "{vrf_name}" does not exist') diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py index eaa678d3e..e47473d76 100755 --- a/src/conf_mode/interfaces-geneve.py +++ b/src/conf_mode/interfaces-geneve.py @@ -18,11 +18,12 @@ import os from sys import exit from copy import deepcopy +from netifaces import interfaces from vyos.config import Config -from vyos.ifconfig import GeneveIf, Interface +from vyos.ifconfig import GeneveIf +from vyos.util import is_bridge_member from vyos import ConfigError -from netifaces import interfaces default_config_data = { 'address': [], @@ -92,7 +93,13 @@ def get_config(): def verify(geneve): if geneve['deleted']: - # bail out early + interface = geneve['intf'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None if not geneve['remote']: diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py index d71e3908c..0400cb849 100755 --- a/src/conf_mode/interfaces-l2tpv3.py +++ b/src/conf_mode/interfaces-l2tpv3.py @@ -22,7 +22,7 @@ from copy import deepcopy from vyos.config import Config from vyos.ifconfig import L2TPv3If, Interface from vyos import ConfigError -from vyos.util import run +from vyos.util import run, is_bridge_member from netifaces import interfaces default_config_data = { @@ -154,8 +154,15 @@ def get_config(): def verify(l2tpv3): + interface = l2tpv3['intf'] + if l2tpv3['deleted']: - # bail out early + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None if not l2tpv3['local_address']: diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 1fe1143cd..e9b40bb38 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -31,7 +31,7 @@ from shutil import rmtree from vyos.config import Config from vyos.defaults import directories as vyos_data_dir from vyos.ifconfig import VTunIf -from vyos.util import process_running, cmd +from vyos.util import process_running, cmd, is_bridge_member from vyos.validate import is_addr_assigned from vyos import ConfigError @@ -444,8 +444,16 @@ def get_config(): def verify(openvpn): if openvpn['deleted']: + interface = openvpn['intf'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None + if not openvpn['mode']: raise ConfigError('Must specify OpenVPN operation mode') diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index 56d4fdfc3..50b5a12a0 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -24,6 +24,7 @@ from vyos.ifconfig import MACVLANIf from vyos.ifconfig_vlan import apply_vlan_config, verify_vlan_config from vyos.configdict import list_diff, vlan_to_dict from vyos.config import Config +from vyos.util import is_bridge_member from vyos import ConfigError default_config_data = { @@ -217,6 +218,13 @@ def get_config(): def verify(peth): if peth['deleted']: + interface = peth['intf'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None if not peth['link']: diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py index 1f9636729..b9bfb242a 100755 --- a/src/conf_mode/interfaces-vxlan.py +++ b/src/conf_mode/interfaces-vxlan.py @@ -18,11 +18,12 @@ import os from sys import exit from copy import deepcopy +from netifaces import interfaces from vyos.config import Config from vyos.ifconfig import VXLANIf, Interface +from vyos.util import is_bridge_member from vyos import ConfigError -from netifaces import interfaces default_config_data = { 'address': [], @@ -148,7 +149,13 @@ def get_config(): def verify(vxlan): if vxlan['deleted']: - # bail out early + interface = vxlan['intf'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None if vxlan['mtu'] < 1500: diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py index 4fa0dd8c0..54121a6c1 100755 --- a/src/conf_mode/interfaces-wireguard.py +++ b/src/conf_mode/interfaces-wireguard.py @@ -24,7 +24,7 @@ from netifaces import interfaces from vyos import ConfigError from vyos.config import Config from vyos.configdict import list_diff -from vyos.util import run +from vyos.util import run, is_bridge_member from vyos.ifconfig import WireGuardIf kdir = r'/config/auth/wireguard' @@ -179,6 +179,16 @@ def verify(c): if not c: return None + if c['delete']: + interface = c['intfc'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) + return None + if not os.path.exists(c['pk']): raise ConfigError( "No keys found, generate them by executing: \'run generate wireguard [keypair|named-keypairs]\'") diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index 188d0ee22..4c70b1478 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -29,7 +29,7 @@ from vyos.configdict import list_diff, vlan_to_dict from vyos.defaults import directories as vyos_data_dir from vyos.ifconfig import WiFiIf from vyos.ifconfig_vlan import apply_vlan_config, verify_vlan_config -from vyos.util import process_running, chmod_x, chown_file, run +from vyos.util import process_running, chmod_x, chown_file, run, is_bridge_member from vyos import ConfigError user = 'root' @@ -554,8 +554,16 @@ def get_config(): def verify(wifi): if wifi['deleted']: + interface = wifi['intfc'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None + if wifi['op_mode'] != 'monitor' and not wifi['ssid']: raise ConfigError('SSID must be set for {}'.format(wifi['intf'])) diff --git a/src/conf_mode/interfaces-wirelessmodem.py b/src/conf_mode/interfaces-wirelessmodem.py index 5e10cfce7..a93b20d27 100755 --- a/src/conf_mode/interfaces-wirelessmodem.py +++ b/src/conf_mode/interfaces-wirelessmodem.py @@ -23,7 +23,7 @@ from netifaces import interfaces from vyos.config import Config from vyos.defaults import directories as vyos_data_dir -from vyos.util import chown_file, chmod_x, cmd, run +from vyos.util import chown_file, chmod_x, cmd, run, is_bridge_member from vyos import ConfigError default_config_data = { @@ -115,6 +115,13 @@ def get_config(): def verify(wwan): if wwan['deleted']: + interface = wwan['intfc'] + is_member, bridge = is_bridge_member(interface) + if is_member: + # can not use a f'' formatted-string here as bridge would not get + # expanded in the print statement + raise ConfigError('Can not delete interface "{0}" as it ' \ + 'is a member of bridge "{1}"!'.format(interface, bridge)) return None if not wwan['apn']: |