summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/vyos/configdict.py54
-rw-r--r--python/vyos/validate.py41
-rwxr-xr-xsrc/conf_mode/interfaces-bonding.py19
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py27
-rwxr-xr-xsrc/conf_mode/interfaces-macsec.py10
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py3
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py25
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py9
8 files changed, 77 insertions, 111 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index ef1b452a8..4a4a767f3 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -21,8 +21,9 @@ import os
from copy import deepcopy
from vyos.util import vyos_dict_search
-from vyos.validate import is_member
from vyos.xml import defaults
+from vyos.xml import is_tag
+from vyos.xml import is_leaf
from vyos import ConfigError
def retrieve_config(path_hash, base_path, config):
@@ -186,6 +187,47 @@ def T2665_set_dhcpv6pd_defaults(config_dict):
return config_dict
+def is_member(conf, interface, intftype=None):
+ """
+ Checks if passed interface is member of other interface of specified type.
+ intftype is optional, if not passed it will search all known types
+ (currently bridge and bonding)
+
+ Returns:
+ None -> Interface is not a member
+ interface name -> Interface is a member of this interface
+ False -> interface type cannot have members
+ """
+ ret_val = None
+ intftypes = ['bonding', 'bridge']
+ if intftype not in intftypes + [None]:
+ raise ValueError((
+ f'unknown interface type "{intftype}" or it cannot '
+ f'have member interfaces'))
+
+ intftype = intftypes if intftype == None else [intftype]
+
+ # set config level to root
+ old_level = conf.get_level()
+ conf.set_level([])
+
+ for it in intftype:
+ base = ['interfaces', it]
+ 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
+
+ old_level = conf.set_level(old_level)
+ return ret_val
+
def get_interface_dict(config, base, ifname=''):
"""
Common utility function to retrieve and mandgle the interfaces available
@@ -236,17 +278,15 @@ def get_interface_dict(config, base, ifname=''):
# Check if we are a member of a bridge device
bridge = is_member(config, ifname, 'bridge')
- if bridge:
- dict.update({'is_bridge_member' : bridge})
+ if bridge: dict.update({'is_bridge_member' : bridge})
# Check if we are a member of a bond device
bond = is_member(config, ifname, 'bonding')
- if bond:
- dict.update({'is_bond_member' : bond})
+ if bond: dict.update({'is_bond_member' : bond})
+
mac = leaf_node_changed(config, ['mac'])
- if mac:
- dict.update({'mac_old' : mac})
+ if mac: dict.update({'mac_old' : mac})
eui64 = leaf_node_changed(config, ['ipv6', 'address', 'eui64'])
if eui64:
diff --git a/python/vyos/validate.py b/python/vyos/validate.py
index ceeb6888a..691cf3c8e 100644
--- a/python/vyos/validate.py
+++ b/python/vyos/validate.py
@@ -19,7 +19,6 @@ import netifaces
import ipaddress
from vyos.util import cmd
-from vyos import xml
# Important note when you are adding new validation functions:
#
@@ -267,46 +266,6 @@ def assert_mac(m):
raise ValueError(f'{m} is a VRRP MAC address')
-def is_member(conf, interface, intftype=None):
- """
- Checks if passed interface is member of other interface of specified type.
- intftype is optional, if not passed it will search all known types
- (currently bridge and bonding)
-
- Returns:
- None -> Interface is not a member
- interface name -> Interface is a member of this interface
- False -> interface type cannot have members
- """
- ret_val = None
- if intftype not in ['bonding', 'bridge', None]:
- raise ValueError((
- f'unknown interface type "{intftype}" or it cannot '
- f'have member interfaces'))
-
- intftype = ['bonding', 'bridge'] if intftype == None else [intftype]
-
- # set config level to root
- old_level = conf.get_level()
- conf.set_level([])
-
- for it in intftype:
- base = ['interfaces', it]
- for intf in conf.list_nodes(base):
- memberintf = base + [intf, 'member', 'interface']
- if xml.is_tag(memberintf):
- if interface in conf.list_nodes(memberintf):
- ret_val = intf
- break
- elif xml.is_leaf(memberintf):
- if ( conf.exists(memberintf) and
- interface in conf.return_values(memberintf) ):
- ret_val = intf
- break
-
- old_level = conf.set_level(old_level)
- return ret_val
-
def has_address_configured(conf, intf):
"""
Checks if interface has an address configured.
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py
index a9679b47c..5ac4feb77 100755
--- a/src/conf_mode/interfaces-bonding.py
+++ b/src/conf_mode/interfaces-bonding.py
@@ -22,6 +22,7 @@ from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdict import leaf_node_changed
+from vyos.configdict import is_member
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_dhcpv6
@@ -30,7 +31,7 @@ from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ifconfig import BondIf
from vyos.ifconfig import Section
-from vyos.validate import is_member
+from vyos.util import vyos_dict_search
from vyos.validate import has_address_configured
from vyos import ConfigError
from vyos import airbag
@@ -98,14 +99,13 @@ def get_config(config=None):
# also present the interfaces to be removed from the bond as dictionary
bond['member'].update({'interface_remove': tmp})
- if 'member' in bond and 'interface' in bond['member']:
+ if vyos_dict_search('member.interface', bond):
for interface, interface_config in bond['member']['interface'].items():
- # Check if we are a member of another bond device
+ # Check if member interface is already member of another bridge
tmp = is_member(conf, interface, 'bridge')
- if tmp:
- interface_config.update({'is_bridge_member' : tmp})
+ if tmp: interface_config.update({'is_bridge_member' : tmp})
- # Check if we are a member of a bond device
+ # Check if member interface is already member of a bond
tmp = is_member(conf, interface, 'bonding')
if tmp and tmp != bond['ifname']:
interface_config.update({'is_bond_member' : tmp})
@@ -144,10 +144,9 @@ def verify(bond):
verify_vlan_config(bond)
bond_name = bond['ifname']
- if 'member' in bond:
- member = bond.get('member')
- for interface, interface_config in member.get('interface', {}).items():
- error_msg = f'Can not add interface "{interface}" to bond "{bond_name}", '
+ if vyos_dict_search('member.interface', bond):
+ for interface, interface_config in bond['member']['interface'].items():
+ error_msg = f'Can not add interface "{interface}" to bond, '
if interface == 'lo':
raise ConfigError('Loopback interface "lo" can not be added to a bond')
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py
index 47c8c05f9..3bddac023 100755
--- a/src/conf_mode/interfaces-bridge.py
+++ b/src/conf_mode/interfaces-bridge.py
@@ -22,13 +22,15 @@ from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdict import node_changed
+from vyos.configdict import is_member
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_vrf
from vyos.ifconfig import BridgeIf
-from vyos.validate import is_member, has_address_configured
+from vyos.validate import has_address_configured
from vyos.xml import defaults
from vyos.util import cmd
+from vyos.util import vyos_dict_search
from vyos import ConfigError
from vyos import airbag
@@ -54,8 +56,8 @@ def get_config(config=None):
else:
bridge.update({'member': {'interface_remove': tmp }})
- if 'member' in bridge and 'interface' in bridge['member']:
- # XXX TT2665 we need a copy of the dict keys for iteration, else we will get:
+ if vyos_dict_search('member.interface', bridge):
+ # XXX: T2665: we need a copy of the dict keys for iteration, else we will get:
# RuntimeError: dictionary changed size during iteration
for interface in list(bridge['member']['interface']):
for key in ['cost', 'priority']:
@@ -69,20 +71,19 @@ def get_config(config=None):
for interface, interface_config in bridge['member']['interface'].items():
interface_config.update(default_member_values)
- # Check if we are a member of another bridge device
+ # Check if member interface is already member of another bridge
tmp = is_member(conf, interface, 'bridge')
if tmp and tmp != bridge['ifname']:
interface_config.update({'is_bridge_member' : tmp})
- # Check if we are a member of a bond device
+ # Check if member interface is already member of a bond
tmp = is_member(conf, interface, 'bonding')
- if tmp:
- interface_config.update({'is_bond_member' : tmp})
+ if tmp: interface_config.update({'is_bond_member' : tmp})
+
# Bridge members must not have an assigned address
tmp = has_address_configured(conf, interface)
- if tmp:
- interface_config.update({'has_address' : ''})
+ if tmp: interface_config.update({'has_address' : ''})
return bridge
@@ -93,11 +94,9 @@ def verify(bridge):
verify_dhcpv6(bridge)
verify_vrf(bridge)
- if 'member' in bridge:
- member = bridge.get('member')
- bridge_name = bridge['ifname']
- for interface, interface_config in member.get('interface', {}).items():
- error_msg = f'Can not add interface "{interface}" to bridge "{bridge_name}", '
+ if vyos_dict_search('member.interface', bridge):
+ for interface, interface_config in bridge['member']['interface'].items():
+ error_msg = f'Can not add interface "{interface}" to bridge, '
if interface == 'lo':
raise ConfigError('Loopback interface "lo" can not be added to a bridge')
diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py
index 73b62dcf1..abf8b05c3 100755
--- a/src/conf_mode/interfaces-macsec.py
+++ b/src/conf_mode/interfaces-macsec.py
@@ -28,7 +28,6 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_source_interface
-from vyos.validate import is_member
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -62,11 +61,6 @@ def get_config(config=None):
base + ['source-interface'])
macsec.update({'source_interface': source_interface})
- if 'source_interface' in macsec:
- # Check if source interface is used by another bridge
- tmp = is_member(conf, macsec['source_interface'], 'bridge')
- if tmp: macsec.update({'is_bridge_member_source_interface' : tmp})
-
return macsec
@@ -94,10 +88,6 @@ def verify(macsec):
raise ConfigError('Missing mandatory MACsec security '
'keys as encryption is enabled!')
- if 'is_bridge_member_source_interface' in macsec:
- raise ConfigError('source-interface is already member of bridge ' \
- '{is_bridge_member_source_interface}!'.format(**macsec))
-
if 'source_interface' in macsec:
# MACsec adds a 40 byte overhead (32 byte MACsec + 8 bytes VLAN 802.1ad
# and 802.1q) - we need to check the underlaying MTU if our configured
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 958b305dd..f83590209 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -26,10 +26,11 @@ from shutil import rmtree
from vyos.config import Config
from vyos.configdict import list_diff
+from vyos.configdict import is_member
from vyos.ifconfig import VTunIf
from vyos.template import render
from vyos.util import call, chown, chmod_600, chmod_755
-from vyos.validate import is_addr_assigned, is_member, is_ipv4
+from vyos.validate import is_addr_assigned, is_ipv4
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index 98397b28f..ddbef56ac 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -25,7 +25,6 @@ from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.ifconfig import MACVLANIf
-from vyos.validate import is_member
from vyos import ConfigError
from vyos import airbag
@@ -44,19 +43,7 @@ def get_config(config=None):
peth = get_interface_dict(conf, base)
mode = leaf_node_changed(conf, ['mode'])
- if mode:
- peth.update({'mode_old' : mode})
-
- # Check if source-interface is member of a bridge device
- if 'source_interface' in peth:
- bridge = is_member(conf, peth['source_interface'], 'bridge')
- if bridge:
- peth.update({'source_interface_is_bridge_member' : bridge})
-
- # Check if we are a member of a bond device
- bond = is_member(conf, peth['source_interface'], 'bonding')
- if bond:
- peth.update({'source_interface_is_bond_member' : bond})
+ if mode: peth.update({'mode_old' : mode})
return peth
@@ -69,16 +56,6 @@ def verify(peth):
verify_vrf(peth)
verify_address(peth)
- if 'source_interface_is_bridge_member' in peth:
- raise ConfigError(
- 'Source interface "{source_interface}" can not be used as it is already a '
- 'member of bridge "{source_interface_is_bridge_member}"!'.format(**peth))
-
- if 'source_interface_is_bond_member' in peth:
- raise ConfigError(
- 'Source interface "{source_interface}" can not be used as it is already a '
- 'member of bond "{source_interface_is_bond_member}"!'.format(**peth))
-
# use common function to verify VLAN configuration
verify_vlan_config(peth)
return None
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 11d8d6edc..f1d885b15 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -22,10 +22,11 @@ from copy import deepcopy
from netifaces import interfaces
from vyos.config import Config
+from vyos.configdict import is_member
from vyos.ifconfig import Interface, GREIf, GRETapIf, IPIPIf, IP6GREIf, IPIP6If, IP6IP6If, SitIf, Sit6RDIf
from vyos.ifconfig.afi import IP4, IP6
from vyos.configdict import list_diff
-from vyos.validate import is_ipv4, is_ipv6, is_member
+from vyos.validate import is_ipv4, is_ipv6
from vyos import ConfigError
from vyos.dicts import FixedDict
@@ -170,8 +171,8 @@ class ConfigurationState(object):
"""
>>> conf.get_values('addresses', 'address')
will place a list of the new IP present in 'interface dummy dum1 address'
- into the dictionnary entry "-add" (here 'addresses-add') using
- Config.return_values and will add the the one which were removed in into
+ into the dictionnary entry "-add" (here 'addresses-add') using
+ Config.return_values and will add the the one which were removed in into
the entry "-del" (here addresses-del')
"""
add_name = f'{name}-add'
@@ -263,7 +264,7 @@ class ConfigurationState(object):
d = d[lpath[-1]]
# XXX: it should have provided me the content and not the key
self._conf.set_level(l)
- return d
+ return d
def to_api(self):
"""