summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/high-availability/keepalived.conf.tmpl16
-rw-r--r--interface-definitions/high-availability.xml.in37
-rwxr-xr-xsmoketest/scripts/cli/test_ha_vrrp.py30
3 files changed, 77 insertions, 6 deletions
diff --git a/data/templates/high-availability/keepalived.conf.tmpl b/data/templates/high-availability/keepalived.conf.tmpl
index bb54752fc..68c707f17 100644
--- a/data/templates/high-availability/keepalived.conf.tmpl
+++ b/data/templates/high-availability/keepalived.conf.tmpl
@@ -28,6 +28,9 @@ vrrp_instance {{ name }} {
virtual_router_id {{ group_config.vrid }}
priority {{ group_config.priority }}
advert_int {{ group_config.advertise_interval }}
+{% if group_config.track is defined and group_config.track.exclude_vrrp_interface is defined %}
+ dont_track_primary
+{% endif %}
{% if group_config.no_preempt is not defined and group_config.preempt_delay is defined and group_config.preempt_delay is not none %}
preempt_delay {{ group_config.preempt_delay }}
{% elif group_config.no_preempt is defined %}
@@ -61,8 +64,8 @@ vrrp_instance {{ name }} {
{% endif %}
{% if group_config.address is defined and group_config.address is not none %}
virtual_ipaddress {
-{% for addr in group_config.address %}
- {{ addr }}
+{% for addr, addr_config in group_config.address.items() %}
+ {{ addr }}{{ ' dev ' + addr_config.interface if addr_config.interface is defined }}
{% endfor %}
}
{% endif %}
@@ -73,6 +76,13 @@ vrrp_instance {{ name }} {
{% endfor %}
}
{% endif %}
+{% if group_config.track is defined and group_config.track.interface is defined and group_config.track.interface is not none %}
+ track_interface {
+{% for interface in group_config.track.interface %}
+ {{ interface }}
+{% endfor %}
+ }
+{% endif %}
{% if group_config.health_check is defined and group_config.health_check.script is defined and group_config.health_check.script is not none %}
track_script {
healthcheck_{{ name }}
@@ -113,8 +123,8 @@ vrrp_sync_group {{ name }} {
{% endfor %}
{% endif %}
-# Virtual-server configuration
{% if virtual_server is defined and virtual_server is not none %}
+# Virtual-server configuration
{% for vserver, vserver_config in virtual_server.items() %}
virtual_server {{ vserver }} {{ vserver_config.port }} {
delay_loop {{ vserver_config.delay_loop }}
diff --git a/interface-definitions/high-availability.xml.in b/interface-definitions/high-availability.xml.in
index f46343c76..ee1d70484 100644
--- a/interface-definitions/high-availability.xml.in
+++ b/interface-definitions/high-availability.xml.in
@@ -177,8 +177,37 @@
<valueless/>
</properties>
</leafNode>
+ <node name="track">
+ <properties>
+ <help>Track settings</help>
+ </properties>
+ <children>
+ <leafNode name="exclude-vrrp-interface">
+ <properties>
+ <valueless/>
+ <help>Disable track state of main interface</help>
+ </properties>
+ </leafNode>
+ <leafNode name="interface">
+ <properties>
+ <help>Interface name state check</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py --broadcast</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
#include <include/vrrp-transition-script.xml.i>
- <leafNode name="address">
+ <tagNode name="address">
<properties>
<help>Virtual IP address</help>
<valueHelp>
@@ -193,9 +222,11 @@
<validator name="ipv4-host"/>
<validator name="ipv6-host"/>
</constraint>
- <multi/>
</properties>
- </leafNode>
+ <children>
+ #include <include/generic-interface-broadcast.xml.i>
+ </children>
+ </tagNode>
<leafNode name="excluded-address">
<properties>
<help>Virtual address (If you need additional IPv4 and IPv6 in same group)</help>
diff --git a/smoketest/scripts/cli/test_ha_vrrp.py b/smoketest/scripts/cli/test_ha_vrrp.py
index a37ce7e64..68905e447 100755
--- a/smoketest/scripts/cli/test_ha_vrrp.py
+++ b/smoketest/scripts/cli/test_ha_vrrp.py
@@ -166,5 +166,35 @@ class TestVRRP(VyOSUnitTestSHIM.TestCase):
for group in groups:
self.assertIn(f'{group}', config)
+ def test_04_exclude_vrrp_interface(self):
+ group = 'VyOS-WAN'
+ none_vrrp_interface = 'eth2'
+ vlan_id = '24'
+ vip = '100.64.24.1/24'
+ vip_dev = '192.0.2.2/24'
+ vrid = '150'
+ group_base = base_path + ['vrrp', 'group', group]
+
+ self.cli_set(['interfaces', 'ethernet', vrrp_interface, 'vif', vlan_id, 'address', '100.64.24.11/24'])
+ self.cli_set(group_base + ['interface', f'{vrrp_interface}.{vlan_id}'])
+ self.cli_set(group_base + ['address', vip])
+ self.cli_set(group_base + ['address', vip_dev, 'interface', none_vrrp_interface])
+ self.cli_set(group_base + ['track', 'exclude-vrrp-interface'])
+ self.cli_set(group_base + ['track', 'interface', none_vrrp_interface])
+ self.cli_set(group_base + ['vrid', vrid])
+
+ # commit changes
+ self.cli_commit()
+
+ config = getConfig(f'vrrp_instance {group}')
+
+ self.assertIn(f'interface {vrrp_interface}.{vlan_id}', config)
+ self.assertIn(f'virtual_router_id {vrid}', config)
+ self.assertIn(f'dont_track_primary', config)
+ self.assertIn(f' {vip}', config)
+ self.assertIn(f' {vip_dev} dev {none_vrrp_interface}', config)
+ self.assertIn(f'track_interface', config)
+ self.assertIn(f' {none_vrrp_interface}', config)
+
if __name__ == '__main__':
unittest.main(verbosity=2)