diff --git a/data/templates/frr/static_mcast.frr.j2 b/data/templates/frr/static_mcast.frr.j2
index 491d4b54a..54b2790b0 100644
--- a/data/templates/frr/static_mcast.frr.j2
+++ b/data/templates/frr/static_mcast.frr.j2
@@ -1,20 +1,11 @@
 !
-{% for route_gr in old_mroute %}
-{%     for nh in old_mroute[route_gr] %}
-{%         if old_mroute[route_gr][nh] %}
-no ip mroute {{ route_gr }} {{ nh }} {{ old_mroute[route_gr][nh] }}
-{%         else %}
-no ip mroute {{ route_gr }} {{ nh }}
-{%         endif %}
-{%     endfor %}
-{% endfor %}
 {% for route_gr in mroute %}
 {%     for nh in mroute[route_gr] %}
 {%         if mroute[route_gr][nh] %}
 ip mroute {{ route_gr }} {{ nh }} {{ mroute[route_gr][nh] }}
 {%         else %}
 ip mroute {{ route_gr }} {{ nh }}
 {%         endif %}
 {%     endfor %}
 {% endfor %}
 !
diff --git a/smoketest/scripts/cli/test_protocols_static_multicast.py b/smoketest/scripts/cli/test_protocols_static_multicast.py
new file mode 100755
index 000000000..9fdda236f
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_static_multicast.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2024 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
+
+
+base_path = ['protocols', 'static', 'multicast']
+
+
+class TestProtocolsStaticMulticast(VyOSUnitTestSHIM.TestCase):
+
+    def tearDown(self):
+        self.cli_delete(base_path)
+        self.cli_commit()
+
+        mroute = self.getFRRconfig('ip mroute', end='')
+        self.assertFalse(mroute)
+
+    def test_01_static_multicast(self):
+
+        self.cli_set(base_path + ['route', '224.202.0.0/24', 'next-hop', '224.203.0.1'])
+        self.cli_set(base_path + ['interface-route', '224.203.0.0/24', 'next-hop-interface', 'eth0'])
+
+        self.cli_commit()
+
+        # Verify FRR bgpd configuration
+        frrconfig = self.getFRRconfig('ip mroute', end='')
+
+        self.assertIn('ip mroute 224.202.0.0/24 224.203.0.1', frrconfig)
+        self.assertIn('ip mroute 224.203.0.0/24 eth0', frrconfig)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py
index 7f6ae3680..2bf794042 100755
--- a/src/conf_mode/protocols_static_multicast.py
+++ b/src/conf_mode/protocols_static_multicast.py
@@ -1,120 +1,137 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2020 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 ipaddress import IPv4Address
 from sys import exit
 
 from vyos import ConfigError
+from vyos import frr
 from vyos.config import Config
 from vyos.utils.process import call
-from vyos.template import render
+from vyos.template import render, render_to_string
 
 from vyos import airbag
 airbag.enable()
 
 config_file = r'/tmp/static_mcast.frr'
 
 # Get configuration for static multicast route
 def get_config(config=None):
     if config:
         conf = config
     else:
         conf = Config()
     mroute = {
         'old_mroute' : {},
         'mroute' : {}
     }
 
     base_path = "protocols static multicast"
 
     if not (conf.exists(base_path) or conf.exists_effective(base_path)):
         return None
 
     conf.set_level(base_path)
 
     # Get multicast effective routes
     for route in conf.list_effective_nodes('route'):
         mroute['old_mroute'][route] = {}
         for next_hop in conf.list_effective_nodes('route {0} next-hop'.format(route)):
             mroute['old_mroute'][route].update({
                 next_hop : conf.return_value('route {0} next-hop {1} distance'.format(route, next_hop))
             })
 
     # Get multicast effective interface-routes
     for route in conf.list_effective_nodes('interface-route'):
         if not route in  mroute['old_mroute']:
             mroute['old_mroute'][route] = {}
         for next_hop in conf.list_effective_nodes('interface-route {0} next-hop-interface'.format(route)):
             mroute['old_mroute'][route].update({
                 next_hop : conf.return_value('interface-route {0} next-hop-interface {1} distance'.format(route, next_hop))
             })
 
     # Get multicast routes
     for route in conf.list_nodes('route'):
         mroute['mroute'][route] = {}
         for next_hop in conf.list_nodes('route {0} next-hop'.format(route)):
             mroute['mroute'][route].update({
                 next_hop : conf.return_value('route {0} next-hop {1} distance'.format(route, next_hop))
             })
 
     # Get multicast interface-routes
     for route in conf.list_nodes('interface-route'):
         if not route in  mroute['mroute']:
             mroute['mroute'][route] = {}
         for next_hop in conf.list_nodes('interface-route {0} next-hop-interface'.format(route)):
             mroute['mroute'][route].update({
                 next_hop : conf.return_value('interface-route {0} next-hop-interface {1} distance'.format(route, next_hop))
             })
 
     return mroute
 
 def verify(mroute):
     if mroute is None:
         return None
 
     for route in mroute['mroute']:
         route = route.split('/')
         if IPv4Address(route[0]) < IPv4Address('224.0.0.0'):
             raise ConfigError(route + " not a multicast network")
 
+
 def generate(mroute):
     if mroute is None:
         return None
 
-    render(config_file, 'frr/static_mcast.frr.j2', mroute)
+    mroute['new_frr_config'] = render_to_string('frr/static_mcast.frr.j2', mroute)
     return None
 
+
 def apply(mroute):
     if mroute is None:
         return None
+    static_daemon = 'staticd'
+
+    frr_cfg = frr.FRRConfig()
+    frr_cfg.load_configuration(static_daemon)
 
-    if os.path.exists(config_file):
-        call(f'vtysh -d staticd -f {config_file}')
-        os.remove(config_file)
+    if 'old_mroute' in mroute:
+        for route_gr in mroute['old_mroute']:
+            for nh in mroute['old_mroute'][route_gr]:
+                if mroute['old_mroute'][route_gr][nh]:
+                    frr_cfg.modify_section(f'^ip mroute {route_gr} {nh} {mroute["old_mroute"][route_gr][nh]}')
+                else:
+                    frr_cfg.modify_section(f'^ip mroute {route_gr} {nh}')
+
+    if 'new_frr_config' in mroute:
+        frr_cfg.add_before(frr.default_add_before, mroute['new_frr_config'])
+
+    frr_cfg.commit_configuration(static_daemon)
 
     return None
 
+
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         exit(1)