summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/conf_mode/high-availability.py21
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py28
2 files changed, 29 insertions, 20 deletions
diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py
index e14050dd3..8a959dc79 100755
--- a/src/conf_mode/high-availability.py
+++ b/src/conf_mode/high-availability.py
@@ -88,15 +88,12 @@ def verify(ha):
if not {'password', 'type'} <= set(group_config['authentication']):
raise ConfigError(f'Authentication requires both type and passwortd to be set in VRRP group "{group}"')
- # We can not use a VRID once per interface
+ # Keepalived doesn't allow mixing IPv4 and IPv6 in one group, so we mirror that restriction
+ # We also need to make sure VRID is not used twice on the same interface with the
+ # same address family.
+
interface = group_config['interface']
vrid = group_config['vrid']
- tmp = {'interface': interface, 'vrid': vrid}
- if tmp in used_vrid_if:
- raise ConfigError(f'VRID "{vrid}" can only be used once on interface "{interface}"!')
- used_vrid_if.append(tmp)
-
- # Keepalived doesn't allow mixing IPv4 and IPv6 in one group, so we mirror that restriction
# XXX: filter on map object is destructive, so we force it to list.
# Additionally, filter objects always evaluate to True, empty or not,
@@ -109,6 +106,11 @@ def verify(ha):
raise ConfigError(f'VRRP group "{group}" mixes IPv4 and IPv6 virtual addresses, this is not allowed.\n' \
'Create individual groups for IPv4 and IPv6!')
if vaddrs4:
+ tmp = {'interface': interface, 'vrid': vrid, 'ipver': 'IPv4'}
+ if tmp in used_vrid_if:
+ raise ConfigError(f'VRID "{vrid}" can only be used once on interface "{interface} with address family IPv4"!')
+ used_vrid_if.append(tmp)
+
if 'hello_source_address' in group_config:
if is_ipv6(group_config['hello_source_address']):
raise ConfigError(f'VRRP group "{group}" uses IPv4 but hello-source-address is IPv6!')
@@ -118,6 +120,11 @@ def verify(ha):
raise ConfigError(f'VRRP group "{group}" uses IPv4 but peer-address is IPv6!')
if vaddrs6:
+ tmp = {'interface': interface, 'vrid': vrid, 'ipver': 'IPv6'}
+ if tmp in used_vrid_if:
+ raise ConfigError(f'VRID "{vrid}" can only be used once on interface "{interface} with address family IPv6"!')
+ used_vrid_if.append(tmp)
+
if 'hello_source_address' in group_config:
if is_ipv4(group_config['hello_source_address']):
raise ConfigError(f'VRRP group "{group}" uses IPv6 but hello-source-address is IPv4!')
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index 20f2b1975..4c65bc0b6 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -15,11 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from sys import exit
+from netifaces import interfaces
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdict import is_node_changed
from vyos.configdict import is_source_interface
+from vyos.configdict import leaf_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
@@ -49,6 +51,9 @@ def get_config(config=None):
mode = is_node_changed(conf, ['mode'])
if mode: peth.update({'shutdown_required' : {}})
+ if leaf_node_changed(conf, base + [ifname, 'mode']):
+ peth.update({'rebuild_required': {}})
+
if 'source_interface' in peth:
_, peth['parent'] = get_interface_dict(conf, ['interfaces', 'ethernet'],
peth['source_interface'])
@@ -77,21 +82,18 @@ def generate(peth):
return None
def apply(peth):
- if 'deleted' in peth:
- # delete interface
- MACVLANIf(peth['ifname']).remove()
- return None
+ # Check if the MACVLAN interface already exists
+ if 'rebuild_required' in peth or 'deleted' in peth:
+ if peth['ifname'] in interfaces():
+ p = MACVLANIf(peth['ifname'])
+ # MACVLAN is always needs to be recreated,
+ # thus we can simply always delete it first.
+ p.remove()
- # Check if MACVLAN interface already exists. Parameters like the underlaying
- # source-interface device or mode can not be changed on the fly and the
- # interface needs to be recreated from the bottom.
- if 'mode_old' in peth:
- MACVLANIf(peth['ifname']).remove()
+ if 'deleted' not in peth:
+ p = MACVLANIf(**peth)
+ p.update(peth)
- # It is safe to "re-create" the interface always, there is a sanity check
- # that the interface will only be create if its non existent
- p = MACVLANIf(**peth)
- p.update(peth)
return None
if __name__ == '__main__':