diff --git a/data/templates/mdns-repeater/avahi-daemon.j2 b/data/templates/mdns-repeater/avahi-daemon.conf.j2
similarity index 76%
rename from data/templates/mdns-repeater/avahi-daemon.j2
rename to data/templates/mdns-repeater/avahi-daemon.conf.j2
index e0dfd897e..d562c048f 100644
--- a/data/templates/mdns-repeater/avahi-daemon.j2
+++ b/data/templates/mdns-repeater/avahi-daemon.conf.j2
@@ -1,25 +1,27 @@
 ### Autogenerated by service_mdns-repeater.py ###
 [server]
-use-ipv4=yes
-use-ipv6=yes
+use-ipv4={{ 'yes' if ip_version in ['ipv4', 'both'] else 'no' }}
+use-ipv6={{ 'yes' if ip_version in ['ipv6', 'both'] else 'no' }}
 allow-interfaces={{ interface | join(', ') }}
 {% if browse_domain is vyos_defined and browse_domain | length %}
 browse-domains={{ browse_domain | join(', ') }}
 {% endif %}
 disallow-other-stacks=no
 
 [wide-area]
 enable-wide-area=yes
 
 [publish]
 disable-publishing=yes
 disable-user-service-publishing=yes
 publish-addresses=no
 publish-hinfo=no
 publish-workstation=no
+publish-aaaa-on-ipv4=no
+publish-a-on-ipv6=no
 
 [reflector]
 enable-reflector=yes
 {% if allow_service is vyos_defined and allow_service | length %}
 reflect-filters={{ allow_service | join(', ') }}
 {% endif %}
diff --git a/interface-definitions/service-mdns-repeater.xml.in b/interface-definitions/service-mdns-repeater.xml.in
index 653dbbbe4..67870946c 100644
--- a/interface-definitions/service-mdns-repeater.xml.in
+++ b/interface-definitions/service-mdns-repeater.xml.in
@@ -1,57 +1,82 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="service">
     <children>
       <node name="mdns">
         <properties>
           <help>Multicast DNS (mDNS) parameters</help>
         </properties>
         <children>
           <node name="repeater" owner="${vyos_conf_scripts_dir}/service_mdns-repeater.py">
             <properties>
               <help>mDNS repeater configuration</help>
               <priority>990</priority>
             </properties>
             <children>
               #include <include/generic-disable-node.xml.i>
               #include <include/generic-interface-multi.xml.i>
+              <leafNode name="ip-version">
+                <properties>
+                  <help>IP address version to use</help>
+                  <valueHelp>
+                    <format>_ipv4</format>
+                    <description>Use only IPv4 address</description>
+                  </valueHelp>
+                  <valueHelp>
+                    <format>_ipv6</format>
+                    <description>Use only IPv6 address</description>
+                  </valueHelp>
+                  <valueHelp>
+                    <format>both</format>
+                    <description>Use both IPv4 and IPv6 address</description>
+                  </valueHelp>
+                  <completionHelp>
+                    <list>ipv4 ipv6 both</list>
+                  </completionHelp>
+                  <constraint>
+                    <regex>(ipv[46]|both)</regex>
+                  </constraint>
+                  <constraintErrorMessage>IP Version must be literal 'ipv4', 'ipv6' or 'both'</constraintErrorMessage>
+                </properties>
+                <defaultValue>both</defaultValue>
+              </leafNode>
               <leafNode name="browse-domain">
                 <properties>
                   <help>mDNS browsing domains in addition to the default one</help>
                   <valueHelp>
                     <format>txt</format>
                     <description>mDNS browsing domain</description>
                   </valueHelp>
                   <constraint>
                     <validator name="fqdn"/>
                   </constraint>
                   <multi/>
                 </properties>
               </leafNode>
               <leafNode name="allow-service">
                 <properties>
                   <help>Allowed mDNS services to be repeated</help>
                   <valueHelp>
                     <format>txt</format>
                     <description>mDNS service</description>
                   </valueHelp>
                   <constraint>
                     <regex>[-_.a-zA-Z0-9]+</regex>
                   </constraint>
                   <constraintErrorMessage>Service name must be alphanumeric and can contain hyphens and underscores</constraintErrorMessage>
                   <multi/>
                 </properties>
               </leafNode>
               <leafNode name="vrrp-disable">
                 <properties>
                   <help>Disables mDNS repeater on VRRP interfaces not in MASTER state</help>
                   <valueless/>
                 </properties>
               </leafNode>
             </children>
           </node>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_service_mdns-repeater.py b/smoketest/scripts/cli/test_service_mdns-repeater.py
index 9a9839025..f2fb3b509 100755
--- a/smoketest/scripts/cli/test_service_mdns-repeater.py
+++ b/smoketest/scripts/cli/test_service_mdns-repeater.py
@@ -1,74 +1,134 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2020-2023 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
 
 from configparser import ConfigParser
+from vyos.configsession import ConfigSessionError
 from vyos.utils.process import process_named_running
 
 base_path = ['service', 'mdns', 'repeater']
 intf_base = ['interfaces', 'dummy']
 config_file = '/run/avahi-daemon/avahi-daemon.conf'
 
 
 class TestServiceMDNSrepeater(VyOSUnitTestSHIM.TestCase):
+    def setUp(self):
+        # Start with a clean CLI instance
+        self.cli_delete(base_path)
+
+        # Service required a configured IP address on the interface
+        self.cli_set(intf_base + ['dum10', 'address', '192.0.2.1/30'])
+        self.cli_set(intf_base + ['dum10', 'ipv6', 'address', 'no-default-link-local'])
+        self.cli_set(intf_base + ['dum20', 'address', '192.0.2.5/30'])
+        self.cli_set(intf_base + ['dum20', 'address', '2001:db8:0:2::5/64'])
+        self.cli_set(intf_base + ['dum30', 'address', '192.0.2.9/30'])
+        self.cli_set(intf_base + ['dum30', 'address', '2001:db8:0:2::9/64'])
+        self.cli_set(intf_base + ['dum40', 'address', '2001:db8:0:2::11/64'])
+        self.cli_commit()
+
     def tearDown(self):
         # Check for running process
         self.assertTrue(process_named_running('avahi-daemon'))
 
         self.cli_delete(base_path)
         self.cli_delete(intf_base + ['dum10'])
         self.cli_delete(intf_base + ['dum20'])
+        self.cli_delete(intf_base + ['dum30'])
+        self.cli_delete(intf_base + ['dum40'])
         self.cli_commit()
 
         # Check that there is no longer a running process
         self.assertFalse(process_named_running('avahi-daemon'))
 
-    def test_service(self):
+    def test_service_dual_stack(self):
         # mDNS browsing domains in addition to the default one (local)
         domains = ['dom1.home.arpa', 'dom2.home.arpa']
 
         # mDNS services to be repeated
         services = ['_ipp._tcp', '_smb._tcp', '_ssh._tcp']
 
-        # Service required a configured IP address on the interface
-        self.cli_set(intf_base + ['dum10', 'address', '192.0.2.1/30'])
-        self.cli_set(intf_base + ['dum20', 'address', '192.0.2.5/30'])
-
-        self.cli_set(base_path + ['interface', 'dum10'])
+        self.cli_set(base_path + ['ip-version', 'both'])
         self.cli_set(base_path + ['interface', 'dum20'])
+        self.cli_set(base_path + ['interface', 'dum30'])
 
         for domain in domains:
             self.cli_set(base_path + ['browse-domain', domain])
 
         for service in services:
             self.cli_set(base_path + ['allow-service', service])
 
         self.cli_commit()
 
         # Validate configuration values
         conf = ConfigParser(delimiters='=')
         conf.read(config_file)
 
-        self.assertEqual(conf['server']['allow-interfaces'], 'dum10, dum20')
+        self.assertEqual(conf['server']['use-ipv4'], 'yes')
+        self.assertEqual(conf['server']['use-ipv6'], 'yes')
+        self.assertEqual(conf['server']['allow-interfaces'], 'dum20, dum30')
         self.assertEqual(conf['server']['browse-domains'], ', '.join(domains))
         self.assertEqual(conf['reflector']['enable-reflector'], 'yes')
         self.assertEqual(conf['reflector']['reflect-filters'], ', '.join(services))
 
+    def test_service_ipv4(self):
+        # partcipating interfaces should have IPv4 addresses
+        self.cli_set(base_path + ['ip-version', 'ipv4'])
+        self.cli_set(base_path + ['interface', 'dum10'])
+        self.cli_set(base_path + ['interface', 'dum40'])
+
+        # exception is raised if partcipating interfaces do not have IPv4 address
+        with self.assertRaises(ConfigSessionError):
+            self.cli_commit()
+        self.cli_delete(base_path + ['interface', 'dum40'])
+        self.cli_set(base_path + ['interface', 'dum20'])
+        self.cli_commit()
+
+        # Validate configuration values
+        conf = ConfigParser(delimiters='=')
+        conf.read(config_file)
+
+        self.assertEqual(conf['server']['use-ipv4'], 'yes')
+        self.assertEqual(conf['server']['use-ipv6'], 'no')
+        self.assertEqual(conf['server']['allow-interfaces'], 'dum10, dum20')
+        self.assertEqual(conf['reflector']['enable-reflector'], 'yes')
+
+    def test_service_ipv6(self):
+        # partcipating interfaces should have IPv6 addresses
+        self.cli_set(base_path + ['ip-version', 'ipv6'])
+        self.cli_set(base_path + ['interface', 'dum10'])
+        self.cli_set(base_path + ['interface', 'dum30'])
+
+        # exception is raised if partcipating interfaces do not have IPv4 address
+        with self.assertRaises(ConfigSessionError):
+            self.cli_commit()
+        self.cli_delete(base_path + ['interface', 'dum10'])
+        self.cli_set(base_path + ['interface', 'dum40'])
+        self.cli_commit()
+
+        # Validate configuration values
+        conf = ConfigParser(delimiters='=')
+        conf.read(config_file)
+
+        self.assertEqual(conf['server']['use-ipv4'], 'no')
+        self.assertEqual(conf['server']['use-ipv6'], 'yes')
+        self.assertEqual(conf['server']['allow-interfaces'], 'dum30, dum40')
+        self.assertEqual(conf['reflector']['enable-reflector'], 'yes')
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/src/conf_mode/service_mdns-repeater.py b/src/conf_mode/service_mdns-repeater.py
index a2c90b537..6909731ff 100755
--- a/src/conf_mode/service_mdns-repeater.py
+++ b/src/conf_mode/service_mdns-repeater.py
@@ -1,130 +1,138 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2017-2022 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 from json import loads
 from sys import exit
-from netifaces import ifaddresses, interfaces, AF_INET
+from netifaces import ifaddresses, interfaces, AF_INET, AF_INET6
 
 from vyos.config import Config
 from vyos.ifconfig.vrrp import VRRP
 from vyos.template import render
 from vyos.utils.process import call
 from vyos import ConfigError
 from vyos import airbag
 airbag.enable()
 
 config_file = '/run/avahi-daemon/avahi-daemon.conf'
 vrrp_running_file = '/run/mdns_vrrp_active'
 
 def get_config(config=None):
     if config:
         conf = config
     else:
         conf = Config()
+
     base = ['service', 'mdns', 'repeater']
-    mdns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+    if not conf.exists(base):
+        return None
+
+    mdns = conf.get_config_dict(base, key_mangling=('-', '_'),
+                                no_tag_node_value_mangle=True,
+                                get_first_key=True,
+                                with_recursive_defaults=True)
 
     if mdns:
         mdns['vrrp_exists'] = conf.exists('high-availability vrrp')
     return mdns
 
 def verify(mdns):
-    if not mdns:
-        return None
-
-    if 'disable' in mdns:
+    if not mdns or 'disable' in mdns:
         return None
 
     # We need at least two interfaces to repeat mDNS advertisments
     if 'interface' not in mdns or len(mdns['interface']) < 2:
         raise ConfigError('mDNS repeater requires at least 2 configured interfaces!')
 
     # For mdns-repeater to work it is essential that the interfaces has
     # an IPv4 address assigned
     for interface in mdns['interface']:
         if interface not in interfaces():
             raise ConfigError(f'Interface "{interface}" does not exist!')
 
-        if AF_INET not in ifaddresses(interface):
+        if mdns['ip_version'] in ['ipv4', 'both'] and AF_INET not in ifaddresses(interface):
             raise ConfigError('mDNS repeater requires an IPv4 address to be '
                                   f'configured on interface "{interface}"')
 
+        if mdns['ip_version'] in ['ipv6', 'both'] and AF_INET6 not in ifaddresses(interface):
+            raise ConfigError('mDNS repeater requires an IPv6 address to be '
+                                  f'configured on interface "{interface}"')
+
     return None
 
 # Get VRRP states from interfaces, returns only interfaces where state is MASTER
 def get_vrrp_master(interfaces):
     json_data = loads(VRRP.collect('json'))
     for group in json_data:
         if 'data' in group:
             if 'ifp_ifname' in group['data']:
                 iface = group['data']['ifp_ifname']
                 state = group['data']['state'] # 2 = Master
                 if iface in interfaces and state != 2:
                     interfaces.remove(iface)
     return interfaces
 
 def generate(mdns):
     if not mdns:
         return None
 
     if 'disable' in mdns:
         print('Warning: mDNS repeater will be deactivated because it is disabled')
         return None
 
     if mdns['vrrp_exists'] and 'vrrp_disable' in mdns:
         mdns['interface'] = get_vrrp_master(mdns['interface'])
 
         if len(mdns['interface']) < 2:
             return None
 
-    render(config_file, 'mdns-repeater/avahi-daemon.j2', mdns)
+    render(config_file, 'mdns-repeater/avahi-daemon.conf.j2', mdns)
     return None
 
 def apply(mdns):
     if not mdns or 'disable' in mdns:
         call('systemctl stop avahi-daemon.service')
         if os.path.exists(config_file):
             os.unlink(config_file)
 
         if os.path.exists(vrrp_running_file):
             os.unlink(vrrp_running_file)
     else:
         if 'vrrp_disable' not in mdns and os.path.exists(vrrp_running_file):
             os.unlink(vrrp_running_file)
 
         if mdns['vrrp_exists'] and 'vrrp_disable' in mdns:
             if not os.path.exists(vrrp_running_file):
                 os.mknod(vrrp_running_file) # vrrp script looks for this file to update mdns repeater
 
             if len(mdns['interface']) < 2:
                 call('systemctl stop avahi-daemon.service')
                 return None
 
         call('systemctl restart avahi-daemon.service')
 
     return None
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         exit(1)