diff --git a/data/templates/dhcp-server/kea-dhcp6.conf.j2 b/data/templates/dhcp-server/kea-dhcp6.conf.j2
index 3ab21551b..2f0de6b30 100644
--- a/data/templates/dhcp-server/kea-dhcp6.conf.j2
+++ b/data/templates/dhcp-server/kea-dhcp6.conf.j2
@@ -1,52 +1,61 @@
 {
     "Dhcp6": {
         "interfaces-config": {
 {% if listen_interface is vyos_defined %}
             "interfaces": {{ listen_interface | tojson }},
 {% else %}
             "interfaces": [ "*" ],
 {% endif %}
             "service-sockets-max-retries": 5,
             "service-sockets-retry-wait-time": 5000
         },
         "control-socket": {
             "socket-type": "unix",
             "socket-name": "/run/kea/dhcp6-ctrl-socket"
         },
         "lease-database": {
             "type": "memfile",
             "persist": true,
             "name": "{{ lease_file }}"
         },
         "hooks-libraries": [
+{% if disable_route_autoinstall is not vyos_defined %}
+            {
+                "library": "/usr/lib/{{ machine }}-linux-gnu/kea/hooks/libdhcp_run_script.so",
+                "parameters": {
+                    "name": "/usr/libexec/vyos/system/on-dhcpv6-event.sh",
+                    "sync": false
+                }
+            },
+{% endif %}
             {
                 "library": "/usr/lib/{{ machine }}-linux-gnu/kea/hooks/libdhcp_lease_cmds.so",
                 "parameters": {}
             }
         ],
         "option-data": [
 {% if global_parameters.name_server is vyos_defined %}
             {
                 "name": "dns-servers",
                 "code": 23,
                 "space": "dhcp6",
                 "csv-format": true,
                 "data": "{{ global_parameters.name_server | join(", ") }}"
             }{{ ',' if preference is vyos_defined else '' }}
 {% endif %}
 {% if preference is vyos_defined %}
             {
                 "name": "preference",
                 "code": 7,
                 "space": "dhcp6",
                 "csv-format": true,
                 "data": "{{ preference }}"
             }
 {% endif %}
         ],
 {% if shared_network_name is vyos_defined %}
         "shared-networks": {{ shared_network_name | kea6_shared_network_json }}
 {% endif %}
 
     }
 }
diff --git a/interface-definitions/service_dhcpv6-server.xml.in b/interface-definitions/service_dhcpv6-server.xml.in
index 07cbfc85d..73ea69cc0 100644
--- a/interface-definitions/service_dhcpv6-server.xml.in
+++ b/interface-definitions/service_dhcpv6-server.xml.in
@@ -1,291 +1,297 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="service">
     <children>
       <node name="dhcpv6-server" owner="${vyos_conf_scripts_dir}/service_dhcpv6-server.py">
         <properties>
           <help>DHCP for IPv6 (DHCPv6) server</help>
           <priority>900</priority>
         </properties>
         <children>
           #include <include/generic-disable-node.xml.i>
           #include <include/listen-interface-multi-broadcast.xml.i>
+          <leafNode name="disable-route-autoinstall">
+            <properties>
+              <help>Do not install routes for delegated prefixes</help>
+              <valueless/>
+            </properties>
+          </leafNode>
           <node name="global-parameters">
             <properties>
               <help>Additional global parameters for DHCPv6 server</help>
             </properties>
             <children>
               #include <include/name-server-ipv6.xml.i>
             </children>
           </node>
           <leafNode name="preference">
             <properties>
               <help>Preference of this DHCPv6 server compared with others</help>
               <valueHelp>
                 <format>u32:0-255</format>
                 <description>DHCPv6 server preference (0-255)</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 0-255"/>
               </constraint>
               <constraintErrorMessage>Preference must be between 0 and 255</constraintErrorMessage>
             </properties>
           </leafNode>
           <tagNode name="shared-network-name">
             <properties>
               <help>DHCPv6 shared network name</help>
               <constraint>
                 #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i>
               </constraint>
               <constraintErrorMessage>Invalid DHCPv6 shared network name. May only contain letters, numbers and .-_</constraintErrorMessage>
             </properties>
             <children>
               #include <include/generic-disable-node.xml.i>
               #include <include/generic-description.xml.i>
               <leafNode name="interface">
                 <properties>
                   <help>Optional interface for this shared network to accept requests from</help>
                   <completionHelp>
                     <script>${vyos_completion_dir}/list_interfaces</script>
                   </completionHelp>
                   <valueHelp>
                     <format>txt</format>
                     <description>Interface name</description>
                   </valueHelp>
                   <constraint>
                     #include <include/constraint/interface-name.xml.i>
                   </constraint>
                 </properties>
               </leafNode>
               <node name="common-options">
                 <properties>
                   <help>Common options to distribute to all clients, including stateless clients</help>
                 </properties>
                 <children>
                   <leafNode name="info-refresh-time">
                     <properties>
                       <help>Time (in seconds) that stateless clients should wait between refreshing the information they were given</help>
                       <valueHelp>
                         <format>u32:1-4294967295</format>
                         <description>DHCPv6 information refresh time</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 1-4294967295"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   #include <include/dhcp/domain-search.xml.i>
                   #include <include/name-server-ipv6.xml.i>
                 </children>
               </node>
               <tagNode name="subnet">
                 <properties>
                   <help>IPv6 DHCP subnet for this shared network</help>
                   <valueHelp>
                     <format>ipv6net</format>
                     <description>IPv6 address and prefix length</description>
                   </valueHelp>
                   <constraint>
                     <validator name="ipv6-prefix"/>
                   </constraint>
                 </properties>
                 <children>
                   #include <include/dhcp/option-v6.xml.i>
                   <tagNode name="range">
                     <properties>
                       <help>Parameters setting ranges for assigning IPv6 addresses</help>
                       <constraint>
                         #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i>
                       </constraint>
                       <constraintErrorMessage>Invalid range name, may only be alphanumeric, dot and hyphen</constraintErrorMessage>
                     </properties>
                     <children>
                       #include <include/dhcp/option-v6.xml.i>
                       <leafNode name="prefix">
                         <properties>
                           <help>IPv6 prefix defining range of addresses to assign</help>
                           <valueHelp>
                             <format>ipv6net</format>
                             <description>IPv6 address and prefix length</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv6-prefix"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="start">
                         <properties>
                           <help>First in range of consecutive IPv6 addresses to assign</help>
                           <valueHelp>
                             <format>ipv6</format>
                             <description>IPv6 address</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv6-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="stop">
                         <properties>
                           <help>Last in range of consecutive IPv6 addresses</help>
                           <valueHelp>
                             <format>ipv6</format>
                             <description>IPv6 address</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv6-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                     </children>
                   </tagNode>
                   <node name="lease-time">
                     <properties>
                       <help>Parameters relating to the lease time</help>
                     </properties>
                     <children>
                       <leafNode name="default">
                         <properties>
                           <help>Default time (in seconds) that will be assigned to a lease</help>
                           <valueHelp>
                             <format>u32:1-4294967295</format>
                             <description>DHCPv6 valid lifetime</description>
                           </valueHelp>
                           <constraint>
                             <validator name="numeric" argument="--range 1-4294967295"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="maximum">
                         <properties>
                           <help>Maximum time (in seconds) that will be assigned to a lease</help>
                           <valueHelp>
                             <format>u32:1-4294967295</format>
                             <description>Maximum lease time in seconds</description>
                           </valueHelp>
                           <constraint>
                             <validator name="numeric" argument="--range 1-4294967295"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="minimum">
                         <properties>
                           <help>Minimum time (in seconds) that will be assigned to a lease</help>
                           <valueHelp>
                             <format>u32:1-4294967295</format>
                             <description>Minimum lease time in seconds</description>
                           </valueHelp>
                           <constraint>
                             <validator name="numeric" argument="--range 1-4294967295"/>
                           </constraint>
                         </properties>
                       </leafNode>
                     </children>
                   </node>
                   <node name="prefix-delegation">
                     <properties>
                       <help>Parameters relating to IPv6 prefix delegation</help>
                     </properties>
                     <children>
                       <tagNode name="prefix">
                         <properties>
                           <help>IPv6 prefix to be used in prefix delegation</help>
                           <valueHelp>
                             <format>ipv6</format>
                             <description>IPv6 prefix used in prefix delegation</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv6-address"/>
                           </constraint>
                         </properties>
                         <children>
                           <leafNode name="prefix-length">
                             <properties>
                               <help>Length in bits of prefix</help>
                               <valueHelp>
                                 <format>u32:32-64</format>
                                 <description>Prefix length (32-64)</description>
                               </valueHelp>
                               <constraint>
                                 <validator name="numeric" argument="--range 32-64"/>
                               </constraint>
                               <constraintErrorMessage>Prefix length must be between 32 and 64</constraintErrorMessage>
                             </properties>
                           </leafNode>
                           <leafNode name="delegated-length">
                             <properties>
                               <help>Length in bits of prefixes to be delegated</help>
                               <valueHelp>
                                 <format>u32:32-64</format>
                                 <description>Delegated prefix length (32-64)</description>
                               </valueHelp>
                               <constraint>
                                 <validator name="numeric" argument="--range 32-96"/>
                               </constraint>
                               <constraintErrorMessage>Delegated prefix length must be between 32 and 96</constraintErrorMessage>
                             </properties>
                           </leafNode>
                         </children>
                       </tagNode>
                     </children>
                   </node>
                   <tagNode name="static-mapping">
                     <properties>
                       <help>Hostname for static mapping reservation</help>
                       <constraint>
                         <validator name="fqdn"/>
                       </constraint>
                       <constraintErrorMessage>Invalid static mapping hostname</constraintErrorMessage>
                     </properties>
                     <children>
                       #include <include/dhcp/option-v6.xml.i>
                       #include <include/generic-disable-node.xml.i>
                       #include <include/interface/mac.xml.i>
                       #include <include/interface/duid.xml.i>
                       <leafNode name="ipv6-address">
                         <properties>
                           <help>Client IPv6 address for this static mapping</help>
                           <valueHelp>
                             <format>ipv6</format>
                             <description>IPv6 address for this static mapping</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv6-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="ipv6-prefix">
                         <properties>
                           <help>Client IPv6 prefix for this static mapping</help>
                           <valueHelp>
                             <format>ipv6net</format>
                             <description>IPv6 prefix for this static mapping</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv6-prefix"/>
                           </constraint>
                         </properties>
                       </leafNode>
                     </children>
                   </tagNode>
                   <leafNode name="subnet-id">
                     <properties>
                       <help>Unique ID mapped to leases in the lease file</help>
                       <valueHelp>
                         <format>u32</format>
                         <description>Unique subnet ID</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 1-4294967295"/>
                       </constraint>
                     </properties>
                   </leafNode>
                 </children>
               </tagNode>
             </children>
           </tagNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/src/etc/sudoers.d/vyos b/src/etc/sudoers.d/vyos
index c099446ba..63a944f41 100644
--- a/src/etc/sudoers.d/vyos
+++ b/src/etc/sudoers.d/vyos
@@ -1,57 +1,60 @@
 #
 # VyOS modifications to sudo configuration
 #
 Defaults syslog_goodpri=info
 Defaults env_keep+=VYATTA_*
 
 #
 # Command groups allowed for operator users
 #
 Cmnd_Alias IPTABLES = /sbin/iptables --list -n,\
 		      /sbin/iptables -L -vn,\
                       /sbin/iptables -L * -vn,\
 		      /sbin/iptables -t * -L *, \
                       /sbin/iptables -Z *,\
 		      /sbin/iptables -Z -t nat, \
                       /sbin/iptables -t * -Z *
 Cmnd_Alias IP6TABLES = /sbin/ip6tables -t * -Z *, \
                        /sbin/ip6tables -t * -L *
 Cmnd_Alias CONNTRACK = /usr/sbin/conntrack -L *, \
                        /usr/sbin/conntrack -G *, \
 		       /usr/sbin/conntrack -E *
 Cmnd_Alias IPFLUSH = /sbin/ip route flush cache, \
 		     /sbin/ip route flush cache *,\
 		     /sbin/ip neigh flush to *, \
 		     /sbin/ip neigh flush dev *, \
                      /sbin/ip -f inet6 route flush cache, \
 		     /sbin/ip -f inet6 route flush cache *,\
 		     /sbin/ip -f inet6 neigh flush to *, \
 		     /sbin/ip -f inet6 neigh flush dev *
 Cmnd_Alias ETHTOOL = /sbin/ethtool -p *, \
                      /sbin/ethtool -S *, \
                      /sbin/ethtool -a *, \
                      /sbin/ethtool -c *, \
                      /sbin/ethtool -i *
 Cmnd_Alias DMIDECODE = /usr/sbin/dmidecode
 Cmnd_Alias DISK    = /usr/bin/lsof, /sbin/fdisk -l *, /sbin/sfdisk -d *
 Cmnd_Alias DATE    = /bin/date, /usr/sbin/ntpdate
 Cmnd_Alias PPPOE_CMDS = /sbin/pppd, /sbin/poff, /usr/sbin/pppstats
 Cmnd_Alias PCAPTURE = /usr/bin/tcpdump
 Cmnd_Alias HWINFO   = /usr/bin/lspci
 Cmnd_Alias FORCE_CLUSTER = /usr/share/heartbeat/hb_takeover, \
                            /usr/share/heartbeat/hb_standby
 Cmnd_Alias DIAGNOSTICS = /bin/ip vrf exec * /bin/ping *,       \
                          /bin/ip vrf exec * /bin/traceroute *, \
                          /bin/ip vrf exec * /usr/bin/mtr *, \
                          /usr/libexec/vyos/op_mode/*
+Cmnd_Alias KEA_IP6_ROUTES = /sbin/ip -6 route replace *,\
+                           /sbin/ip -6 route del *
 %operator ALL=NOPASSWD: DATE, IPTABLES, ETHTOOL, IPFLUSH, HWINFO, \
 			PPPOE_CMDS, PCAPTURE, /usr/sbin/wanpipemon, \
                         DMIDECODE, DISK, CONNTRACK, IP6TABLES,  \
                         FORCE_CLUSTER, DIAGNOSTICS
 
 # Allow any user to run files in sudo-users
 %users ALL=NOPASSWD: /opt/vyatta/bin/sudo-users/
 
 # Allow members of group sudo to execute any command
 %sudo ALL=NOPASSWD: ALL
 
+_kea ALL=NOPASSWD: KEA_IP6_ROUTES
diff --git a/src/system/on-dhcpv6-event.sh b/src/system/on-dhcpv6-event.sh
new file mode 100755
index 000000000..fcc88ae6f
--- /dev/null
+++ b/src/system/on-dhcpv6-event.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+#
+# 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/>.
+#
+#
+
+if [ $# -lt 1 ]; then
+  echo Invalid args
+  logger -s -t on-dhcpv6-event "Invalid args \"$@\""
+  exit 1
+fi
+
+action=$1
+
+case "$action" in
+  lease6_renew|lease6_recover)
+    exit 0
+    ;;
+
+  lease6_release|lease6_expire|lease6_decline)
+    ifname=$QUERY6_IFACE_NAME
+    client_ip=$LEASE6_ADDRESS
+    client_prefix_len=$LEASE6_PREFIX_LEN
+
+    if [[ "$LEASE6_TYPE" != "IA_PD" ]]; then
+      exit 0
+    fi
+
+    sudo -n /sbin/ip -6 route del ${client_ip}/${client_prefix_len} \
+      dev ${ifname} \
+      proto static
+
+    exit 0
+    ;;
+
+  leases6_committed)
+    for ((i = 0; i < $LEASES6_SIZE; i++)); do
+      ifname=$QUERY6_IFACE_NAME
+      requester_link_local=$QUERY6_REMOTE_ADDR
+      client_type_var="LEASES6_AT${i}_TYPE"
+      client_ip_var="LEASES6_AT${i}_ADDRESS"
+      client_prefix_len_var="LEASES6_AT${i}_PREFIX_LEN"
+
+      client_type=${!client_type_var}
+
+      if [[ "$client_type" != "IA_PD" ]]; then
+        continue
+      fi
+
+      client_ip=${!client_ip_var}
+      client_prefix_len=${!client_prefix_len_var}
+      
+      sudo -n /sbin/ip -6 route replace ${client_ip}/${client_prefix_len} \
+        via ${requester_link_local} \
+        dev ${ifname} \
+        proto static
+    done
+
+    exit 0
+    ;;
+
+  *)
+    logger -s -t on-dhcpv6-event "Invalid command \"$1\""
+    exit 1
+    ;;
+esac